Help for old friends
JAMES - Old version up to Dec 2021
Stef van Buuren, Arjan Huizing (TNO Child Health)
Source:vignettes/articles/oldfriends.Rmd
oldfriends.Rmd
library(james)
This document is the README of the first JAMES version supported up to December 2021. The version will not be further developed but remain operational until Nov 2022 on <groeidiagrammen.nl>. Use <james.groeidiagrammen.nl> for the current version.
Joint Automatic Measurement and Evaluation System (JAMES)
JAMES is an experimental web service for creating and interpreting charts of child growth and development. The current version
- provides access to high-quality growth charts used by the Dutch youth health care;
- interchanges data coded according to the Basisdataset JGZ;
- screens for abnormal height, weight and head circumference;
- converts developmental data into the D-score;
- predicts future growth and development.
The service can be used by anyone interested in high-quality charts for monitoring and evaluating childhood growth. This document highlights some applications of JAMES, and provides pointers to relevant background information.
Deprecation note
We will be offering Docker containers running JAMES from January 2022 onwards, and phase out the functionality described below. Work in progress is at https://app.swaggerhub.com/apis/stefvanbuuren/james.
Check whether JAMES is running
JAMES is currently located at url groeidiagrammen.nl
.
[NOTE: From April 2022 onwards, use
james.groeidiagrammen.nl
] The sections below use
curl
for illustration, but any HTTP
client
will work.
In order to check whether the JAMES server is running, try generating
some random numbers by calling stats::rnorm()
, in a
terminal window as follows,
Primary JAMES user functionality
Function | Description | Interesting URL’s | Contents |
---|---|---|---|
list_charts |
List available growth charts | R/.val/json |
Table of charts, JSON |
R/.val/text |
Table of charts, text | ||
upload_data |
Validate, convert and store input data | messages/json |
parse messages, JSON |
draw_chart |
Draw chart, predict future growth | graphics/1/svglite |
chart, svglite format |
graphics/1/png |
chart, png format |
||
messages/json |
parse, graph messages, JSON | ||
request_site |
Site URL with personalised charts | R/.val/json |
site URL, JSON |
messages/json |
parse, site messages, JSON | ||
calculate_dscore |
Calculate the D-score for each visit | R/.val/json |
D-score table, JSON |
screen_growth |
Screen growth along JGZ guidelines | R/.val/json |
screening table, JSON |
messages/json |
parse, screen msg, JSON | ||
custom_list |
Create list with custom returns | R/.val/json |
list of returns, JSON |
The primary user functions cover out wide range of activities. Let us look into these in some more detail.
Available growth charts
The site https://groeidiagrammen.nl/ocpu/lib/james/www/ provides a quick round-trip of growth charts. JAMES currently offers 394 different charts, divided into three chart groups:
- 140 charts for children of various etnicities, age groups and outcomes (Talma et al. 2010);
- 240 charts specifically designed for preterms (Bocca-Tjeertes et al. 2012);
- 14 charts based on the WHO Child Growth Standards (WHO 2006);
The list_charts()
function in JAMES function produces a
tabular overview of all charts.
We may uses any HTTP client to download the list of growth charts.
Many systems have the curl
command already installed. We
download the list into a JSON file by the following request:
curl https://groeidiagrammen.nl/ocpu/lib/james/R/list_charts/json -d "" -o ~/Downloads/jamescharts.json
A request to list_charts
on JAMES will yield a response
like
Response [https://groeidiagrammen.nl/ocpu/library/james/R/list_charts]
Date: 2020-09-02 13:29
Status: 201
Content-Type: text/plain; charset=utf-8
Size: 248 B
/ocpu/tmp/x07c4471d08dbd3/R/.val
/ocpu/tmp/x07c4471d08dbd3/R/list_charts
/ocpu/tmp/x07c4471d08dbd3/stdout
/ocpu/tmp/x07c4471d08dbd3/source
/ocpu/tmp/x07c4471d08dbd3/console
/ocpu/tmp/x07c4471d08dbd3/info
/ocpu/tmp/x07c4471d08dbd3/files/DESCRIPTION
The status is 201 (Resources created), and the unique session
{key}
is x07c4471d08dbd3
. Note that this
changes with each request, so if you are replicating these commands, be
sure to change {key}
accordingly. Session keys and their
url’s remain valid for 2 hours. See https://www.opencpu.org/api.html for succinct
documentation of the OpenCPU interface.
Not all information that JAMES return is interesting. In this case,
we would like to see the table of charts in JSON format. We may these
obtain this table from the URL
https://groeidiagrammen.nl/ocpu/tmp/x07c4471d08dbd3/R/.val/json
.
The first entry looks like
{
"chartgrp": "nl2010",
"chartcode": "HJAA",
"population": "HS",
"sex": "male",
"design": "A",
"side": "front",
"language": "dutch",
"week": ""
}
The central field is chartcode
, which contains a unique
4-7 character code identifying the particular chart. In this example,
code HJAA
represents a chart for boys with Indo-Surinamese
background (population HS
) and design A
(chart
with head circumference, length and weight for boys aged 0-15 months).
The codes are compatible and extend those used in Talma et al. (2010).
Requesting a growth chart
We may download growth chart HJAA
with the
draw_chart()
function as follows:
curl https://groeidiagrammen.nl/ocpu/library/james/R/draw_chart -d "chartcode='HJAA'&selector='chartcode'"
This produces the following output
/ocpu/tmp/x038e163dc6de71/R/.val
/ocpu/tmp/x038e163dc6de71/R/draw_chart
/ocpu/tmp/x038e163dc6de71/graphics/1
/ocpu/tmp/x038e163dc6de71/stdout
/ocpu/tmp/x038e163dc6de71/source
/ocpu/tmp/x038e163dc6de71/console
/ocpu/tmp/x038e163dc6de71/info
/ocpu/tmp/x038e163dc6de71/files/DESCRIPTION
View the chart in the browser by pasting the following into the url address field:
or download the growth chart as
curl -o mychart.svg 'https://groeidiagrammen.nl/ocpu/tmp/x038e163dc6de71/graphics/1/svglite?width=8.27&height=11.69' -H 'Cache-Control: max-age=0'
In order to obtain the right canvas size, the URL needs to be in
quotes and the request needs -H 'Cache-Control: max-age=0'
option added.
Adding data to charts
Until now, we have only seen empty growth charts. This section describes various ways to add child data to the charts.
Data format
The BDS
JGZ 3.2.5 protocol facilitates the exchange of data between parties
active in the Dutch youth health care. The format is basically a
codebook of variables. Each variable has a number:
bdsnummer
. JAMES adopts the format, and accepts data in
JSON format according to a JSON
schema.
A minimal example of the data according to the schema is:
Save the file client3.json on your local system by
which produces a file called client3.json
in your
working directory.
For testing purposes, you may change its values, but please keep the general structure intact.
Charting the child data, JSON file
The following curl
command uploads and converts the
file, and plots the data on a growth chart:
curl -F 'txt=@client3.json' https://groeidiagrammen.nl/ocpu/library/james/R/draw_chart
/ocpu/tmp/x0f59c6526dba8a/R/.val
/ocpu/tmp/x0f59c6526dba8a/R/draw_chart
/ocpu/tmp/x0f59c6526dba8a/graphics/1
/ocpu/tmp/x0f59c6526dba8a/stdout
/ocpu/tmp/x0f59c6526dba8a/source
/ocpu/tmp/x0f59c6526dba8a/console
/ocpu/tmp/x0f59c6526dba8a/info
/ocpu/tmp/x0f59c6526dba8a/files/client3.json
/ocpu/tmp/x0f59c6526dba8a/files/DESCRIPTION
As before, you can draw the chart by pasting the following URL in the browser:
JAMES automatically selected the length-by-age chart for preterm girls born at a gestational age of 27 weeks.
Charting the child data, JSON string
Send the child’s data as a JSON string instead of a file provides
some more flexibility. The following code assumes that utility
jq
is installed.
First, convert the JSON file into a JSON string, with double quotes
("
) properly escaped.
Then run the following command requesting chart code
PMAAN27
:
curl https://groeidiagrammen.nl/ocpu/library/james/R/draw_chart -d "txt=$var&chartcode='PMAAN27'&selector='chartcode'"
The results returns an URL pointing to an A4 formatted different chart for preterm girls with the points added.
There are many more options possible. See the help in:
Data cache
JAMES takes the following general steps to plot data:
- The client sends a request that posts the child data;
- The server validates the input;
- The server transforms the data into JAMES internal format;
- The server adds the data points to the chart;
- The server sends a response to the client;
- The client interprets the response.
All JAMES functions support the complete set of actions through the
txt
parameter, as used above. In addition, many functions
also accept the cached result from steps 1-3 as input through the
loc
parameter. More in particular, the loc
method saves the result after step 3, and feeds the location of the
converted data into a second request that applies the plotting. Both
txt
and loc
methods yield the same result.
The obvious advantage of caching is that validation has only to be done once. In cases where the user needs multiple analyses for the same child, for example for building an interactive site, caching may result in snappier behaviour. It may also be easier to diagnose errors in the input data. On the other hand, caching also requires some more work on the client side. The nature of the application determines which method works best.
Example of data cache
An example, let’s create a chart in two steps. We first upload the
data using upload_data()
, which accepts JSON input and
return the location with the uploaded data.
curl https://groeidiagrammen.nl/ocpu/library/james/R/upload_data -d "txt=$var"
/ocpu/tmp/x02691745d874cc/R/.val
/ocpu/tmp/x02691745d874cc/R/upload_data
/ocpu/tmp/x02691745d874cc/stdout
/ocpu/tmp/x02691745d874cc/source
/ocpu/tmp/x02691745d874cc/console
/ocpu/tmp/x02691745d874cc/info
/ocpu/tmp/x02691745d874cc/files/DESCRIPTION
We create the chart by
Request a dedicated url to the chart site
The child’s data can be plotted on any of the available charts using a child chart site. We can construct a child’s site by means of the following request.
curl https://groeidiagrammen.nl/ocpu/library/james/R/request_site/json -d "txt=$var"
["https://groeidiagrammen.nl/ocpu/lib/james/www/?loc=https://groeidiagrammen.nl/ocpu/tmp/x0dde6c563edb40/"]
This command uploads and checks the input data, and appends the result URL to the site base URL. The combined URL starts a personalised site with the child’s data.
Alternatively, if we already obtained a loc
parameters,
we can combine that with the site base URL as follows.
curl https://groeidiagrammen.nl/ocpu/library/james/R/request_site/json -d "loc='https://groeidiagrammen.nl/ocpu/tmp/x02691745d874cc/'"
["https://groeidiagrammen.nl/ocpu/lib/james/www/?loc=https://groeidiagrammen.nl/ocpu/tmp/x02691745d874cc/"]
There are three ways to choose which chart is being plotted:
- JAMES picks a default chart;
- The developer provides a
chartcode
parameter; - The end user manipulates the interactive controls.
Options 1 and 2 determine the first chart that is shown to the end user.
Site with default chart
The default chart picked by JAMES is currently hard-wired as the child’s height chart that contains the most recent measurements. If the child is a pre-term (gestational age <= 36 weeks) and younger than 4 years, then JAMES chooses the appropriate preterm chart.
The chart site with the default start can be started by combining the uploaded data and the main site at (https://groeidiagrammen.nl/ocpu/lib/james/www/) as
curl "https://groeidiagrammen.nl/ocpu/lib/james/www/?loc=https://groeidiagrammen.nl/ocpu/tmp/x06938035d05dac/"
Pasting this url in your browser starts the site with the child’s data.
Site with developer-specified chart
Starting the site at a given growth chart is possible by specifying
the chartcode
parameters. For example, we may initialize
the site at chart PMAAN27
by
curl "https://groeidiagrammen.nl/ocpu/lib/james/www/?loc=https://groeidiagrammen.nl/ocpu/tmp/x06938035d05dac/&chartcode=PMAAN27"
The site now starts with PMAAN27
instead of
PMAHN27
. Any chart can be chosen. It is the responsibility
of the developer that the choice is sensible given the child’s data.
Screen growth curves according to JGZ guidelines
screen_growth
| Screen growth curves according to JGZ
guidelines
We obtain the screening results as
[
{
"Categorie": 1000,
"CategorieOmschrijving": "Lengte",
"Code": 1031,
"CodeOmschrijving": "Het advies volgens de JGZ-richtlijn lengtegroei is als volgt: In principe geen verwijzing nodig, naar eigen inzicht handelen.",
"Versie": "1.6.0",
"Leeftijd0": "20181111",
"Leeftijd1": "20181211"
},
{
"Categorie": 2000,
"CategorieOmschrijving": "Gewicht",
"Code": 2031,
"CodeOmschrijving": "Het advies volgens de JGZ-richtlijn overgewicht is als volgt: In principe geen verwijzing nodig, naar eigen inzicht handelen.",
"Versie": "1.6.0",
"Leeftijd0": "20181111",
"Leeftijd1": "20181211"
},
{
"Categorie": 3000,
"CategorieOmschrijving": "Hoofdomtrek",
"Code": 3031,
"CodeOmschrijving": "In principe geen verwijzing nodig, naar eigen inzicht handelen.",
"Versie": "1.6.0",
"Leeftijd0": "20181111",
"Leeftijd1": "20181211"
}
]
Create one request with list of return values
In some cases, we would like to bundle return values from a custom
set of calls. That is the job of custom_list
. The current
version of custom_list
will return a site URL (created by
request_site
), a table of screening results (created by
screen_growth
) and the last D-score (created by
calculate_dscore
). For example, the calls
curl https://groeidiagrammen.nl/ocpu/library/james/R/custom_list -d "txt=$var"
curl https://groeidiagrammen.nl//ocpu/tmp/x098464a29301fe/R/.val/json
return
{
"UrlGroeicurven": "https://groeidiagrammen.nl/ocpu/lib/james/www/?loc=https://groeidiagrammen.nl/ocpu/tmp/x03ee2514b1b1d2/",
"Resultaten": [
{
"Categorie": 1000,
"CategorieOmschrijving": "Lengte",
"Code": 1031,
"CodeOmschrijving": "Het advies volgens de JGZ-richtlijn lengtegroei is als volgt: In principe geen verwijzing nodig, naar eigen inzicht handelen.",
"Versie": "1.6.0",
"Leeftijd0": "20181111",
"Leeftijd1": "20181211"
},
{
"Categorie": 2000,
"CategorieOmschrijving": "Gewicht",
"Code": 2031,
"CodeOmschrijving": "Het advies volgens de JGZ-richtlijn overgewicht is als volgt: In principe geen verwijzing nodig, naar eigen inzicht handelen.",
"Versie": "1.6.0",
"Leeftijd0": "20181111",
"Leeftijd1": "20181211"
},
{
"Categorie": 3000,
"CategorieOmschrijving": "Hoofdomtrek",
"Code": 3031,
"CodeOmschrijving": "In principe geen verwijzing nodig, naar eigen inzicht handelen.",
"Versie": "1.6.0",
"Leeftijd0": "20181111",
"Leeftijd1": "20181211"
}
]
}
which contains the return values generated by
request_site
(called “UrlGroeicurven” here) and by
screen_growth
(called “Resultaten” here). There no result
for calculate_dscore
because the data do not contain any
developmental scores that would be needed to calculate a D-score.
In principle, custom_list
provides an option for clients
to bundle the results of multiple requests into one call. The current
functionality, however, is limited to what is indicated in this
section.
Legacy functionality
This following table lists functions that are active in the current version, but that we will not further develop. Please replace them by the suggested alternative.
Function | Description | Preferred alternative |
---|---|---|
convert_bds_ind |
Validate, convert, store input (server) | upload_data |
fetch_loc |
Validate, convert, store input (server) | upload_data |
upload_txt |
Validate, convert, store input (client) | jamesclient::upload_txt |
draw_chart_bds |
Draw chart from uploaded | draw_chart(txt = ...) |
draw_chart_ind |
Draw chart from cached data | draw_chart(loc = ...) |
screen_curves |
Screen growth along JGZ guidelines |
screen_growth , custom_list
|
This following table lists argument names that are active in the current version, but that will be phased out for consistency. Please replace them by the suggested alternative.
Argument | Description | Preferred alternative |
---|---|---|
bds_data |
JSON input data | txt |
ind_loc |
Location with cached data. | loc |
location |
Location with cached data. | loc |
?ind= |
URL query parameter for cached data | ?loc= |
At some point these functions and argument names will be deprecated and removed.
Next steps
Things that were still on the wish list in Sept 2019:
- transfer JAMES to url james.tno.nl [wait for docker version]
- allow for more input formats [NOW support for both
txt
andloc
] - add https protocol [DONE]
- add functionality to test for Dutch guidelines for referral [DONE, 3 guidelines]
- add functionality to predict individual growth curves [DONE]
- extend functionality to include the -score charts [DONE]
Architecture
The growth charts in JAMES are programmed in R
. JAMES
makes these available through the OpenCPU system for scientific
computing and reproducible research. The system allows for easy
integration of growth charts into any HTTP
compliant client
by means of OpenCPU’s API. JAMES is a RESTful
webservice.
About
Work in progress. Direct suggestions and inquiries to Stef van Buuren (stef.vanbuuren at tno.nl), https://stefvanbuuren.name, https://github.com/stefvanbuuren.