Introduction

This package is designed to simplify interacting with the Core REST API using R. The functions in the package are designed to cover common tasks you might want to do. Many of the high level functions make assumptions about the various setting and parameters to the API to simplify usage. If you require control of addition parameters such response or logic options you can easily extend the functions in this package.

The REST API does not currently support configuration changes. This means you can not create of modify entity configurations. This functionality must be done through the application GUI.

All functions that make a HTTP call will return a list with two objects. The first object will be the object returned by the function, such as the entity record, and a second object named response which contains the full http response object.

Due to the way the API functions the list names must be the actual attribute name and must be in all upper case. In addition, because R does not support spaces in variable names, LIMS attribute names can not contain spaces or special characters.(This is good practice anyway.) Underscores are supported.

Note: All of the functionality and limitations for this version of the CoreAPI refer to the first version on the Core REST API, and not the ODATA compliant version. The package will be extended to cover the new functionality at some point.

Function apiCall

The function apiCall is the function that makes all posts the the Core API. This function can be used to json directly to the API. The function is not intended to be call directly buy as part of a higher level functions. However is can be useful for debugging of one off call. The parameters are

Parameter Description
coreApi coreApi object with valid jsessionid and url
body body for request
encode encoding to use for request option are “multipart”, “form”, “json”, “raw”
special passed to buildUrl for special sdk endpoints such as login
useVerbose Use verbose communication for debugging

This function can be used to pass json generated the the CORE REST API tool. The coreApi object is generate with the coreApi function described below. Here is a typical example.

api<-CoreAPI("PATH TO JSON FILE")
login<- CoreAPI::authBasic(api)
response <-CoreAPI::apiCall(login$coreApi,body,"json",,special=NULL,useVerbose=FALSE)
logOut(login$coreApi )

apiCall calls the function buildUrl to build the url including the jsessionId. Currentlly appending the AWSELB parameter using to optimize calls to systems with mutliple nodes is not supported. This will be addressed in future releases.

Authentication

The current API supports basic authentication. Once the user is authenticated a jsession id value is appended to all urls for API calls. The details are in the CORE LIMS documentation here:

https://documentation.corelims.com/docs/v5/SDK/JSON_Web_Service/Best_Practices_for_API_Usage.htm

The authentication process requires two functions calls. The first step is to read the URL, username and password information from a file with the function coreAPI. The input file in in json format as shown below.

            [{                             
              "user": "xxxxxxxxx",         
              "pwd": "xxxxxxxxx",          
              "coreUrl": "http:://xxxx.platformforscience.com",        
              "account": "xxxxxxxxx",       
            }]                             
    

Values for the first three parameters and required and the account entry is only required if the user has access to more than one tenant. If the account parameter is not required pas a zero length string “”. This function return an object which contains the information in the json and a valid jsession ID in the list object named CoreApi.

#get login information

loginInfo<-CoreAPI::coreAPI(CoreAccountInfo="path/account.json")

# authenticate
response<- CoreAPI::authBasic(loginInfo)
  
#print the session ID  
print(response$coreApi$jsessionId)
  
#log out
CoreAPI::logOut(response$coreApi)$success

When to log out is dependent on the workflow. The basic workflow for any interaction with the API is to log into a session, execute all business logic needed to perform your operation (can be one or many calls), and then log out. For best performance, it is NOT recommended to log into a new session for each call.

Create, Get and Updating Entities

Three functions handle the create, retrieve, update and delete (CRUD) functionality for most entities. Note that items in the LIMS can never be deleted, but rather inactivated. Certain entities require specialized functions because of additional parameters specific to the entity. For example sample lots require information about the parent sample to create the proper linkage. However for most entities the three functions outlined in the section will handle the CRUD functionality.

The function createEntity creates an entity. Information about attribute values and associations are passed to the function as lists. Due to the way the API functions the list names must be the actual attribute name and must be in all upper case. In addition, because R does not support spaces in variable names, LIMS attribute names can not contain spaces or special characters. Underscores are supported.

The minimal call to create an entity is:

CoreAPI::createEntity(response$coreApi,entityType)

“response$coreApi”" is the session information and “entityType” can either be a literal string or a character variable with the name of the entity type to be created. The attribute and association values will all default to blank if their values are not passed.

A list to populate a set of attributes would look like this.

attributeValues<-list(SOURCE_LAB = "New York Medical Center",Number = 5,REQUESTOR="CEP")

On creation this list is only required to have entries for mandatory attributes. On update only attributes in the list will be updated.

Associations require a bit more information. The list required is create with a statement like this.

associations<-list(SAMPLE_ENZYME=data.frame(name="",entitiyId="",barcode="ENZ1"))

The association may be identified by either it entityID or its barcode, or both. Again only mandatory association are required for creation. A call to create an entity with attributes and associations would look like this.

entityType <- "Patient Sample"

attributeValues<-list(SOURCE_LAB = "New York Medical Center",Number = 5,REQUESTOR="CEP")

associations<-list(SAMPLE_ENZYME=data.frame(name="",entitiyId="",barcode="ENZ1"))

CoreAPI::createEntity(response$coreApi,entityType,attributeValues,associations)

An update has a very similar form except the entity barcode is provided to identify what to update.

entityBarcode <-"PS100"

CoreAPI::updateEntity(response$coreApi,entityType,entitybarcode,
                      attributevalues=attributeValues,associations = associations)

The retrieve an entity use the getEntityByBarcode function. Only the entity type and barcode are required.

get<-getEntityByBarcode(response$coreApi, entityType, barcode)

item <- get$entity

For retrieval when on the entityId is known is done with getEntityById

The retrieve an entity use the getEntityByBarcode function. Only the entity type and barcode are required.

get<-getEntityById(response$coreApi, entityType, entityId = "ID")

item <- get$entity

Other parameters, passed as strings, that can be used in create and update are:

parameter value
locationId location id
projectIds project ID
barcode if entity is to be created with a user supplied barcode
useVerbose verbose output for debugging

See the individual function documentation for details.

Attaching Files

Files may be attached either directly to an entity or in a file type attribute. A single function will handle both cases. If the file is to be attached directly to the entity the targetAttributeName value is set to an empty string. Otherwise the targetAttributeName is set to a valid file attribute on the entity. The path to the local file is passed as a string in the parameter filepath. If multiple files need to be attached, multiple function call will be required.

# attach to the attribute named File

 items2<-CoreAPI::attachFile(response$coreApi,barcode,"SAgraph.png",filepath,targetAttributeName="File")

#attach to the entity

attachFile(response$coreApi,barcode,filename="SAgraph.png",filepath=filepath,targetAttributeName="")

A URL for the file object is stored in the entity record. For file attached to a attribute the value is under values$[attribute name]$stringdata as shown below.

item$entity$values$FILE
$stringData
[1] "{'file':'SAgraph.png.16','url':'https://experience.platformforscience.com/corelims?cmd=view-file&entityType=FILE ATTRIBUTE&entityId=9532882'}"

There is no API functionality to see if a file is attached to the entity. Also currently there is not any API functionality to retrieve a file attached to an attribute. The download URL will only work when called from a browser that has been authenticated using the GUI interface. A workaround is possible and will be included it a future release.

Samples and Sample Lots

Samples are created using the createEntity function described above. Sample lots are created with the function createSampleLot. This function is very similar to createEntity but contains an addition parameter for the barcode of the associated sample. A typical create sample and lot sequence is shown below. If multiple lots are required multiple call to createSampleLot are required.

#Create Sample

sample<-createEntity(response$coreApi, "WHOLE BLOOD", attributeValues = attributes)

#get barcode of the sample

sampleBC <-sample$entity$barcode

#Create Lot

item<-createSampleLot(login$coreApi,"WHOLE BLOOD LOT", sampleBarcode=sampleBC,
                      attributes = lotAttributes )

Containers

Basic CRUD functions for containers are done using the createEntity, getEntityByBarcode, and updateEntity functions. To fill a cell in a container the updateCellContents function is used. The required parameters are containerType, containerBarcode, containerCellNum, sampleLotBarcode, amount, amountUnit, concentration, concentrationUnit. All of these parameters are required for successful completion. You can not add additional contents to a cell with the API. If you try to add additional sample to the cell and error is not generated by the API. the request is simply ignored.

Below is a sequence used to create a sample, create a sample lot, create a container, and put the lot in the container.

api<-CoreAPI::coreAPI(CoreAccountInfo = "testfiles/account.json")

#login

login<-CoreAPI::authBasic(tapi)

#create sample

sample<- CoreAPI::createEntity(r$coreApi,"Patient Sample")

sampleBarcode<-sample$entity$barcode

#create lot

lot<-CoreAPI::createSampleLot(r$coreApi,"PATIENT SAMPLE LOT",sampleBarcode)

#create container

cont <- CoreAPI::createEntity(r$coreApi,containerType)

cont_barcode <- cont$entity$barcode

#fill container

filledContainer<-CoreAPI::updateCellContents(r$coreApi,containerType, 
                                             cont_barcode,"1", lot_barcode,2, "ml", 3, "uM")
   
#log out    
    
out<-CoreAPI::logOut(r$coreApi)

There are also two functions to directly access cell contents and transfer contents. The function getCellContents gets information about a cell contents using the container barcode and cell number.

cell<-getCellContents(login$coreApi,"VIA9","1")

The function transferCellContents moves contents from one cell to another. The cell ID numbers are required for the source and destination cells. These can be obtained by running getCellContents on a container. Is important to include valid values for the amount and concentration along with valid units.

contCell <- CoreAPI::getCellContents(r$coreApi,cont$entity$barcode,"1")

sourceCellID <-contCell$entity$cells[[1]]$cellId

cont2Cell<- CoreAPI::getCellContents(r$coreApi,cont2$entity$barcode,"1")

destCellID <- cont2Cell$entity$cells[[1]]$cellId


move<-transferCellContents(r$coreApi,sourceCellID,destCellID,amount,concentration,
                                            amountUnit, concentrationUnit,useVerbose = FALSE)

The final function is getContainerLineage. This function used a container barcode as input and returns the parent and child containers as lists.

lineage<-CoreAPI::getContainerLineage(r$coreApi,cont$entity$barcode)

Experiments and Assays

Basic functionality for experiments are accomplished using the createEntity, getEntityByBarcode, and updateEntity functions. Experiment Samples are unique identifiers for sample lots within the context of a specific experiment. These entities are used to track sample lot in and experiment and the data collected on those lot.

In the general user interface, these are automatically created when you add samples or containers to an experiment. However in the web service, you will need to explicitly create experiment samples or add a container to an experiment in order to create experiment samples. Since you may also need to query or update experiment samples, there are commands for those functions. Once an experiment in created there are two options for adding samples to the experiment.

Adding containers to a experiment

Adding containers to an experiment automatically creates experiment samples. The function updateExperimentContainers adds a container and it contents to an experiment. And sequence to add a container is below.

 item <- CoreAPI::createEntity(r$coreApi,entityType = experimentType,
                               attributeValues = list(TEST_ATTRIBUTE = "a value"),
                               associations = list(EXPERIMENT_ASSAY=
                               data.frame(name="",entityId ="",barcode=assayBarcode),
                               EXPERIMENT_PROTOCOL=
                               data.frame(name="",entityId ="",barcode=protocolBarcode))
                              )

newExptbarcode <-item$entity$barcode

#add a container which creates an experiment sample

update<-CoreAPI::updateExperimentContainers(r$coreApi,containerBarcode, experimentType,                                                                     newExptbarcode,useVerbose = FALSE)

Adding sample lots to a experiment

Adding lot to a experiment done using the createExperimentSample function. This takes a sample lot barcode and experiment barcode as input. And sequence to add a sample lot to an experiment is shown below.

secondSample<-CoreAPI::createExperimentSample(r$coreApi,experimentSampleType,sampleLot,newExptbarcode,useVerbose=FALSE)

Adding assay and retrieving data

Once sample are added to an experiment assay data is added using the updateExperimentSampleData functions. This function add data to the attributes defined in the assay associated to the experiment. Experiment data can be retrieved using the getExperimentSamples function which returns the sample data along with assay data.

exptdata1<-CoreAPI::updateExperimentSampleData(r$coreApi,experimentSampleType,expt$entity$experimentSamples[[1]]                                                $barcode,assayAttributeValues1,useVerbose=FALSE)


expt<-CoreAPI::getExperimentSamples(r$coreApi,"TEST EXPERIMENT",newExptbarcode,useVerbose=FALSE)