JMP Clinical was released 11 years ago specifically for the analysis and review of ongoing clinical trials centered on standardized and structured data. The intent was that a reviewer would receive data for review in regular intervals (every week or every month) to look for safety and/or efficacy signals using pre-programmed reports, enabling the reviewer to self-serve and dig deeper into the data on-demand. The hope was to expedite the review process as well as uncover anomalies that might otherwise be missed when looking at static tables, listings, and figures.
In addition, a goal of the software was to alleviate the burden placed on programming teams who produce the requested data and standardized reports for the reviewers. This required a lot of time to run programs or edit programs/scripts/macro to accommodate the reviewers' needs and on a frequent basis. Programming and biostatistics groups typically want to focus on data and reports that are unique to the study instead of the usual table or graph that is pretty consistent from study to study, allowing them to give more robust and undistracted attention to the study-specific anomalies that require more statistical or algorithmic knowledge.
For the most part, JMP Clinical met those goals unless we're talking about organizations that have many studies that need to be monitored and/or have frequent data updates. This puts a new burden on data management and biostatistics teams to update the studies within JMP Clinical or puts the burden on the reviewers who were not as proficient in the process or have the time. Also of interest was the ability to modify some of the reports within JMP Clinical and/or run the same review template on a scheduled basis. The demand for automation and extension of JMP Clinical’s capabilities became a frequent request.
Enter the APIs of JMP Clinical. Around JMP Clinical 6, we introduced the framework and infrastructure to make API-based access to common functions/processes programmatically possible. In JMP Clinical 7, the APIs were released and made available using the JMP Scripting Language (JSL). In version 8 (the latest one), more capabilities were released. This post does not go into the details of the development of the APIs. Instead, it focuses on the practical use of them so you can take advantage of them.
I'll share a series of posts on how to invoke and use the APIs. We start simple by introducing the basic syntax and their use. Then we progress into more sophisticated uses while using JSL. And finally, we combine the two categories of APIs invoked within some JSL.
For those not familiar with the terms Study, Review, Report and Review Template within the context of JMP Clinical, please see this link to become acquainted. Also, those not familiar with JSL should read and learn more at this link. Knowledge of both is required to understand the use of the APIs.
For this post, let’s start with the two main categories and what is possible. The two main categories are: Study Management related functions (JMPClinicalStudyManagerAPI) and the Review related functions (JMPClinicalReviewAPI). The idea is to replicate what can be done within the user interface (mainly the button clicks) where user a decision is not needed (like refreshing the metadata for Studies with new data or opening a Review Template and running it for a specific Study). Below are a couple of images that highlight buttons that relate to the Study Management section and the Review section.
Study Management Functions that Relate to JMPClinicalStudyMangerAPI
Review/Review Builder Functions that Related to JMPClinicalReviewAPI
The API is meant to take routine tasks and automate them, like refreshing studies with new metadata or to add/remove content from a Report within a Review Template. Here is a link for the JMPClinicalStudyManagerAPI functions and another link for the JMPClinicalReviewAPI functions for reference.
So, what can this JMPClinicalStudyMangerAPI API do for us? It provides us with two sets of functions: get functions (ones that get information about the studies) and manipulate functions (ones that add, remove or update studies). Here is a table of what is possible with the basic syntax to call that function. The colon (:) separates the API call and the function call. Some of the functions have input and/or returns. See the above links for details on what is expected as an input and return.
Study Management API
|
Get Information Functions
|
Manipulate Study Functions
|
Get list of Study names:
JMPClinicalStudyManagerAPI:getStudyList
|
Add Study:
JMPClinicalStudyManagerAPI:addStudy
|
Get SDTM folder path:
JMPClinicalStudyManagerAPI:getSDTMFolder
|
Refresh Study metadata:
JMPClinicalStudyManagerAPI:refreshStudies
|
Get ADaM folder path:
JMPClinicalStudyManagerAPI:getADaMFolder
|
Delete Study:
JMPClinicalStudyManagerAPI:deleteStudies
|
Get Date Study was added:
JMPClinicalStudyManagerAPI:getInitialDate
|
Update Study with a new Snapshot:
JMPClinicalStudyManagerAPI:updateSnapshot
|
Get Date Study was lasted updated:
JMPClinicalStudyManagerAPI:getLastUpdatedDate
|
Change Study data folders:
JMPClinicalStudyManagerAPI:changeFolders
|
Get Snapshot Enabled Status:
JMPClinicalStudyManagerAPI:getEnableSnapshot
|
Pre-compute Patient Profile data:
JMPClinicalStudyManagerAPI:precomputeProfileData
|
Get Snapshot Number:
JMPClinicalStudyManagerAPI:getSnapshotNumber
|
|
Get list of domains recognized:
JMPClinicalStudyManagerAPI:getDomainList
|
|
Get file size on disk:
JMPClinicalStudyManagerAPI:getSizeOnDisk
|
|
Get Windows OS user ID who created/added Study:
JMPClinicalStudyManagerAPI:getCreatedBy
|
|
Get Windows OS user ID who last updated Study:
JMPClinicalStudyManagerAPI:getLastUpdatedBy
|
|
Now let’s look at the second category, Review functions. This one also has a set of get and manipulate functions but for Reviews and Reports.
Review API
|
Get Information Functions
|
Manipulate Report/Review Functions
|
Get a reference to the Review Builder:
JMPClinicalReviewAPI:getReviewBuilder
|
Close Review Builder:
JMPClinicalReviewAPI:closeReviewBuilder
|
Get the Review Viewer/Builder ID and Title:
JMPClinicalReviewAPI:getReviewViewerIDsAndTitles
|
Open Review Template:
JMPClinicalReviewAPI:openReviewTemplate
|
Get a reference to the Review Viewer:
JMPClinicalReviewAPI:getReviewViewer
|
Add a Report to Review Builder:
JMPClinicalReviewAPI:addReport
|
Get Table of Contents of the Review Viewer/Builder:
JMPClinicalReviewAPI:getReviewTableOfContents
|
Remove Report form Review Builder by Title:
JMPClinicalReviewAPI:removeReportByReportTitle
|
Get a list of Report IDs:
JMPClinicalReviewAPI:getReportIDList
|
Run Report in Review Builder by Title:
JMPClinicalReviewAPI:runReportByReportTitle
|
Get a list of Report Titles:
JMPClinicalReviewAPI:getReportTitleList
|
Run all Reports in Review Builder:
JMPClinicalReviewAPI:runAllReports
|
Get a reference to a Report by ID:
JMPClinicalReviewAPI:getReportByID
|
Save Review Builder contents as a Review:
JMPClinicalReviewAPI:saveReview
|
Get a reference to a Report by Title:
JMPClinicalReviewAPI:getReportByTitle
|
Open a Review in the Review Viewer:
JMPClinicalReviewAPI:openReview
|
Get Report Details by Title:
JMPClinicalReviewAPI:getReportDetailsByTitle
|
Insert Section into a Report:
JMPClinicalReviewAPI:insertSectionIntoReportByTitleAndSectionName
|
Get a reference to the Report Results:
JMPClinicalReviewAPI:getReportResultsByTitle
|
Remove Section from a Report:
JMPClinicalReviewAPI:removeSectionFromReportByTitleAndSectionName
|
Get a reference to the Report Section:
JMPClinicalReviewAPI:getReportSectionByTitleAndSectionName
|
Add to end of Report Section:
JMPClinicalReviewAPI:appendDisplayObjectToReportSectionByTitleAndSectionName
|
Get list of data tables used in Report:
JMPClinicalReviewAPI:getDataTablesForSectionByTitleAndSectionName
|
Add to beginning of Report Section:
JMPClinicalReviewAPI:prependDisplayObjectToReportSectionByTitleAndSectionName
|
So now we have the different functions and what they can do listed. Now it is time to show the basic syntax of their use. The basic form is this:
JMPClinical<Category>API:<function> ({argument(s)}, {namespace}, completeListenerFunction());
I have already introduced the basic call to the Study Management related API functions above when I referred to JMPClinicalStudyManagerAPI. So, if I want to refresh the metadata of the registered studies, it will look something like this:
JMPClinicalStudyManager:refreshStudies ({studyList},{},{});
We will dissect this more and talk about common uses in the next set of posts. For now, I wanted to introduce what is available and how to generally invoke it within a JSL script. The next post will be about an example of the Study Management API, talking more about namespace and completeListener parts of the API Call and start to wrap it in JSL as well as use JSL within it.
Until the next post, take care!