Skip to content

Commit

Permalink
Merge pull request #228 from rcpch/eatyourpeas/issue227
Browse files Browse the repository at this point in the history
trisomy-21-aap
  • Loading branch information
eatyourpeas authored Oct 27, 2024
2 parents c39f194 + 9274b43 commit e4cf3b2
Show file tree
Hide file tree
Showing 44 changed files with 74,576 additions and 6 deletions.
1,017 changes: 1,017 additions & 0 deletions chart-data/cole-nine-centiles-trisomy-21-aap-female-bmi.json

Large diffs are not rendered by default.

2,646 changes: 2,646 additions & 0 deletions chart-data/cole-nine-centiles-trisomy-21-aap-female-height.json

Large diffs are not rendered by default.

2,646 changes: 2,646 additions & 0 deletions chart-data/cole-nine-centiles-trisomy-21-aap-female-ofc.json

Large diffs are not rendered by default.

2,691 changes: 2,691 additions & 0 deletions chart-data/cole-nine-centiles-trisomy-21-aap-female-weight.json

Large diffs are not rendered by default.

1,017 changes: 1,017 additions & 0 deletions chart-data/cole-nine-centiles-trisomy-21-aap-male-bmi.json

Large diffs are not rendered by default.

2,646 changes: 2,646 additions & 0 deletions chart-data/cole-nine-centiles-trisomy-21-aap-male-height.json

Large diffs are not rendered by default.

2,646 changes: 2,646 additions & 0 deletions chart-data/cole-nine-centiles-trisomy-21-aap-male-ofc.json

Large diffs are not rendered by default.

2,691 changes: 2,691 additions & 0 deletions chart-data/cole-nine-centiles-trisomy-21-aap-male-weight.json

Large diffs are not rendered by default.

1,350 changes: 1,350 additions & 0 deletions chart-data/eighty-five-percent-centiles-trisomy-21-aap-female-bmi.json

Large diffs are not rendered by default.

3,522 changes: 3,522 additions & 0 deletions chart-data/eighty-five-percent-centiles-trisomy-21-aap-female-height.json

Large diffs are not rendered by default.

3,522 changes: 3,522 additions & 0 deletions chart-data/eighty-five-percent-centiles-trisomy-21-aap-female-ofc.json

Large diffs are not rendered by default.

3,582 changes: 3,582 additions & 0 deletions chart-data/eighty-five-percent-centiles-trisomy-21-aap-female-weight.json

Large diffs are not rendered by default.

1,350 changes: 1,350 additions & 0 deletions chart-data/eighty-five-percent-centiles-trisomy-21-aap-male-bmi.json

Large diffs are not rendered by default.

3,522 changes: 3,522 additions & 0 deletions chart-data/eighty-five-percent-centiles-trisomy-21-aap-male-height.json

Large diffs are not rendered by default.

3,522 changes: 3,522 additions & 0 deletions chart-data/eighty-five-percent-centiles-trisomy-21-aap-male-ofc.json

Large diffs are not rendered by default.

3,582 changes: 3,582 additions & 0 deletions chart-data/eighty-five-percent-centiles-trisomy-21-aap-male-weight.json

Large diffs are not rendered by default.

795 changes: 795 additions & 0 deletions chart-data/five-percent-centiles-trisomy-21-aap-female-bmi.json

Large diffs are not rendered by default.

2,062 changes: 2,062 additions & 0 deletions chart-data/five-percent-centiles-trisomy-21-aap-female-height.json

Large diffs are not rendered by default.

2,062 changes: 2,062 additions & 0 deletions chart-data/five-percent-centiles-trisomy-21-aap-female-ofc.json

Large diffs are not rendered by default.

2,097 changes: 2,097 additions & 0 deletions chart-data/five-percent-centiles-trisomy-21-aap-female-weight.json

Large diffs are not rendered by default.

795 changes: 795 additions & 0 deletions chart-data/five-percent-centiles-trisomy-21-aap-male-bmi.json

Large diffs are not rendered by default.

2,062 changes: 2,062 additions & 0 deletions chart-data/five-percent-centiles-trisomy-21-aap-male-height.json

Large diffs are not rendered by default.

2,062 changes: 2,062 additions & 0 deletions chart-data/five-percent-centiles-trisomy-21-aap-male-ofc.json

Large diffs are not rendered by default.

2,097 changes: 2,097 additions & 0 deletions chart-data/five-percent-centiles-trisomy-21-aap-male-weight.json

Large diffs are not rendered by default.

1,017 changes: 1,017 additions & 0 deletions chart-data/three-percent-centiles-trisomy-21-aap-female-bmi.json

Large diffs are not rendered by default.

2,646 changes: 2,646 additions & 0 deletions chart-data/three-percent-centiles-trisomy-21-aap-female-height.json

Large diffs are not rendered by default.

2,646 changes: 2,646 additions & 0 deletions chart-data/three-percent-centiles-trisomy-21-aap-female-ofc.json

Large diffs are not rendered by default.

2,691 changes: 2,691 additions & 0 deletions chart-data/three-percent-centiles-trisomy-21-aap-female-weight.json

Large diffs are not rendered by default.

1,017 changes: 1,017 additions & 0 deletions chart-data/three-percent-centiles-trisomy-21-aap-male-bmi.json

Large diffs are not rendered by default.

2,646 changes: 2,646 additions & 0 deletions chart-data/three-percent-centiles-trisomy-21-aap-male-height.json

Large diffs are not rendered by default.

2,646 changes: 2,646 additions & 0 deletions chart-data/three-percent-centiles-trisomy-21-aap-male-ofc.json

Large diffs are not rendered by default.

2,691 changes: 2,691 additions & 0 deletions chart-data/three-percent-centiles-trisomy-21-aap-male-weight.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

# local / rcpch imports
from rcpchgrowth import chart_functions, constants
from routers import trisomy_21, turners, uk_who, cdc, utilities
from routers import trisomy_21, trisomy_21_aap, turners, uk_who, cdc, utilities


version='4.2.20' # this is set by bump version
Expand Down Expand Up @@ -40,6 +40,7 @@
app.include_router(uk_who)
app.include_router(turners)
app.include_router(trisomy_21)
app.include_router(trisomy_21_aap)
app.include_router(cdc)
app.include_router(utilities)

Expand Down Expand Up @@ -77,7 +78,7 @@ def root():
# This data is only generated once and then is stored and served from file.
def generate_and_store_chart_data():
for centile_format in [constants.COLE_TWO_THIRDS_SDS_NINE_CENTILES, constants.THREE_PERCENT_CENTILES, constants.FIVE_PERCENT_CENTILES, constants.EIGHTY_FIVE_PERCENT_CENTILES]:
for reference in constants.REFERENCES + [constants.CDC]:
for reference in constants.REFERENCES + [constants.CDC] + [constants.TRISOMY_21_AAP]:
for sex in constants.SEXES:
for measurement_method in constants.MEASUREMENT_METHODS:
# Don't generate files for Turner's for references we don't have (males or non-height measurements)
Expand Down
150 changes: 150 additions & 0 deletions openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,156 @@
}
}
},
"/trisomy-21-aap/calculation": {
"post": {
"tags": [
"trisomy-21-aap"
],
"summary": "Trisomy 21 Aap Calculation",
"description": "## Trisomy-21 AAP Centile and SDS Calculations\n\n* These are the 'standard' centiles for US children with trisomy-21. It uses the American Academy of Pediatrics dataset (American Academy of Pediatrics (AAP) Trisomy 21 reference. Zemel BS, Pipan M, Stallings VA, Hall W, Schgadt K, Freedman DS, Thorpe P. Growth Charts for Children with Down Syndrome in the U.S. Pediatrics, 2015).\n* UK users should use the UK Down Syndrome Growth Charts included in the RCPCHGrowth package and provide on a separate endpoint.\n* Returns a single centile/SDS calculation for the selected `measurement_method`.\n* Gestational age correction will be applied automatically if appropriate according to the gestational age at birth data supplied.\n* Available `measurement_method`s are: `height`, `weight`, `bmi`, or `ofc` (OFC = occipitofrontal circumference = 'head circumference').\n* Note that BMI must be precalculated for the `bmi` function.\n* Dates will discard anything after first 'T' in `YYYY-MM-DDTHH:MM:SS.milliseconds+TZ` etc\n* Bone ages are not supported for this reference.\n* Optional events can be passed in as a list of strings - each list is associated with a measurement",
"operationId": "trisomy_21_aap_calculation_trisomy_21_aap_calculation_post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MeasurementRequest",
"examples": [
{
"birth_date": "2020-04-12",
"observation_date": "2028-06-12",
"observation_value": 115,
"sex": "female",
"gestation_weeks": 40,
"gestation_days": 0,
"measurement_method": "height",
"bone_age": 10,
"bone_age_centile": 98,
"bone_age_sds": 2.0,
"bone_age_text": "This bone age is advanced",
"bone_age_type": "greulich-pyle",
"events_text": [
"Growth hormone start",
"Growth Hormone Deficiency diagnosis"
]
}
]
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MeasurementObject"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/trisomy-21-aap/chart-coordinates": {
"post": {
"tags": [
"trisomy-21-aap"
],
"summary": "Trisomy 21 Aap Chart Coordinates",
"description": "## trisomy-21-aap Chart Coordinates data.\n\n* Returns coordinates for constructing the lines of a traditional growth chart, in JSON format\n* Requires a sex ('male' or 'female' lowercase) and a measurement_method ('height', 'weight' ,'bmi', 'ofc')\n* If custom centiles/sds collections (individually or as a collection) are required, accepts a list of float values (up to 15) as centile_format parameter\n* The is_sds boolean flag (default false) specifies if the custom list is of SDS or centiles.\n* In addition to the custom list, \"cole-nine-centiles\" or \"three-percent-centiles\" can be specified which are standard collections.\n* If no centile_format is supplied, \"cole-nine-centiles\" are returned as a default.",
"operationId": "trisomy_21_aap_chart_coordinates_trisomy_21_aap_chart_coordinates_post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ChartCoordinateRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Centile_Data"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/trisomy-21-aap/fictional-child-data": {
"post": {
"tags": [
"trisomy-21-aap"
],
"summary": "Fictional Child Data",
"description": "## trisomy-21-aap Fictional Child Data Endpoint\n\n* Generates synthetic data for demonstration or testing purposes",
"operationId": "fictional_child_data_trisomy_21_aap_fictional_child_data_post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FictionalChildRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/MeasurementObject"
},
"type": "array",
"title": "Response Fictional Child Data Trisomy 21 Aap Fictional Child Data Post"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/cdc/calculation": {
"post": {
"tags": [
Expand Down
2 changes: 1 addition & 1 deletion requirements/common-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ pydantic == 2.*

# rcpch dependencies
# python package which does the centile and SDS calculations
rcpchgrowth==4.1.1
rcpchgrowth==4.2.1
1 change: 1 addition & 0 deletions routers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
from .turner import turners
from .trisomy21 import trisomy_21
from .cdc import cdc
from .trisomy21aap import trisomy_21_aap
from .utilities import utilities
198 changes: 198 additions & 0 deletions routers/trisomy21aap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
"""
trisomy-21-aap router
"""

# Standard imports
import json
from pathlib import Path
from typing import List
from pprint import pprint

# Third party imports
from schemas.response_schema_classes import Centile_Data, MeasurementObject
from fastapi import APIRouter, Body, HTTPException

# RCPCH imports
from rcpchgrowth import (
Measurement,
constants,
generate_fictional_child_data,
create_chart,
)
from rcpchgrowth.constants.reference_constants import TRISOMY_21_AAP
from schemas import MeasurementRequest, ChartCoordinateRequest, FictionalChildRequest

# set up the API router
trisomy_21_aap = APIRouter(
prefix="/trisomy-21-aap",
)


@trisomy_21_aap.post("/calculation", tags=["trisomy-21-aap"], response_model=MeasurementObject)
def trisomy_21_aap_calculation(
measurementRequest: MeasurementRequest = Body(
...,
examples=[
{
"birth_date": "2020-04-12",
"observation_date": "2028-06-12",
"observation_value": 115,
"sex": "female",
"gestation_weeks": 40,
"gestation_days": 0,
"measurement_method": "height",
"bone_age": 10,
"bone_age_centile": 98,
"bone_age_sds": 2.0,
"bone_age_text": "This bone age is advanced",
"bone_age_type": "greulich-pyle",
"events_text": [
"Growth hormone start",
"Growth Hormone Deficiency diagnosis",
],
}
],
)
):
"""
## Trisomy-21 AAP Centile and SDS Calculations
* These are the 'standard' centiles for US children with trisomy-21. It uses the American Academy of Pediatrics dataset (American Academy of Pediatrics (AAP) Trisomy 21 reference. Zemel BS, Pipan M, Stallings VA, Hall W, Schgadt K, Freedman DS, Thorpe P. Growth Charts for Children with Down Syndrome in the U.S. Pediatrics, 2015).
* UK users should use the UK Down Syndrome Growth Charts included in the RCPCHGrowth package and provide on a separate endpoint.
* Returns a single centile/SDS calculation for the selected `measurement_method`.
* Gestational age correction will be applied automatically if appropriate according to the gestational age at birth data supplied.
* Available `measurement_method`s are: `height`, `weight`, `bmi`, or `ofc` (OFC = occipitofrontal circumference = 'head circumference').
* Note that BMI must be precalculated for the `bmi` function.
* Dates will discard anything after first 'T' in `YYYY-MM-DDTHH:MM:SS.milliseconds+TZ` etc
* Bone ages are not supported for this reference.
* Optional events can be passed in as a list of strings - each list is associated with a measurement
"""
try:
calculation = Measurement(
reference=constants.TRISOMY_21_AAP,
birth_date=measurementRequest.birth_date,
gestation_days=measurementRequest.gestation_days,
gestation_weeks=measurementRequest.gestation_weeks,
measurement_method=measurementRequest.measurement_method,
observation_date=measurementRequest.observation_date,
observation_value=measurementRequest.observation_value,
sex=measurementRequest.sex,
bone_age=None,
bone_age_centile=None,
bone_age_sds=None,
bone_age_text=None,
bone_age_type=None,
events_text=measurementRequest.events_text,
).measurement
except ValueError as err:
print(err.args)
return err.args, 422

calculation["measurement_calculated_values"]["corrected_centile"] = round(calculation["measurement_calculated_values"]["corrected_centile"],4)
calculation["measurement_calculated_values"]["chronological_centile"] = round(calculation["measurement_calculated_values"]["chronological_centile"],4)
calculation["plottable_data"]["centile_data"]["corrected_decimal_age_data"]["centile"] = round(calculation["plottable_data"]["centile_data"]["corrected_decimal_age_data"]["centile"],4)
calculation["plottable_data"]["centile_data"]["chronological_decimal_age_data"]["centile"] = round(calculation["plottable_data"]["centile_data"]["chronological_decimal_age_data"]["centile"],4)
calculation["plottable_data"]["sds_data"]["corrected_decimal_age_data"]["centile"] = round(calculation["plottable_data"]["sds_data"]["corrected_decimal_age_data"]["centile"],4)
calculation["plottable_data"]["sds_data"]["chronological_decimal_age_data"]["centile"] = round(calculation["plottable_data"]["sds_data"]["chronological_decimal_age_data"]["centile"],4)
return calculation


@trisomy_21_aap.post("/chart-coordinates", tags=["trisomy-21-aap"], response_model=Centile_Data)
def trisomy_21_aap_chart_coordinates(chartParams: ChartCoordinateRequest):
"""
## trisomy-21-aap Chart Coordinates data.
* Returns coordinates for constructing the lines of a traditional growth chart, in JSON format
* Requires a sex ('male' or 'female' lowercase) and a measurement_method ('height', 'weight' ,'bmi', 'ofc')
* If custom centiles/sds collections (individually or as a collection) are required, accepts a list of float values (up to 15) as centile_format parameter
* The is_sds boolean flag (default false) specifies if the custom list is of SDS or centiles.
* In addition to the custom list, "cole-nine-centiles" or "three-percent-centiles" can be specified which are standard collections.
* If no centile_format is supplied, "cole-nine-centiles" are returned as a default.
\f
[
"height": [
{
sds: -1.64,
trisomy_21_aap_infants: [.....],
trisomy_21_aap_children: [
{
label: 5, `this is the centile
x: 4, `this is the decimal age
y: 91.535 `this is the measurement
}
....
]
}
],
... repeat for weight, bmi, ofc, based on which measurements supplied. If only height data supplied, only height centile data returned
]
"""
chart_data = None
if type(chartParams.centile_format) is list:
# custom centiles requested - calculate these and return. Do not persist.
try:
chart_data = create_chart(
TRISOMY_21_AAP,
chartParams.centile_format,
measurement_method=chartParams.measurement_method,
sex=chartParams.sex,
is_sds=chartParams.is_sds,
)
except:
return HTTPException(
status_code=422,
detail=f"Error creating {chartParams.sex} {chartParams.measurement_method} trisomy-21-aap chart on the server, using {chartParams.centile_format} centile format.",
)
else:
chart_data_file = Path(
f"chart-data/{chartParams.centile_format}-{constants.TRISOMY_21_AAP}-{chartParams.sex}-{chartParams.measurement_method}.json"
)
if chart_data_file.exists():
print(
f"Chart data file exists for {chartParams.centile_format}-{constants.TRISOMY_21_AAP}-{chartParams.sex}-{chartParams.measurement_method}."
)
with open(
f"chart-data/{chartParams.centile_format}-{constants.TRISOMY_21_AAP}-{chartParams.sex}-{chartParams.measurement_method}.json",
"r",
) as file:
chart_data = json.load(file)
else:
return HTTPException(
status_code=422,
detail=f"Item not found: chart-data/{chartParams.centile_format}-{constants.TRISOMY_21_AAP}-{chartParams.sex}-{chartParams.measurement_method}.json",
)
return {"centile_data": chart_data}


@trisomy_21_aap.post(
"/fictional-child-data", tags=["trisomy-21-aap"], response_model=List[MeasurementObject]
)
def fictional_child_data(fictional_child_request: FictionalChildRequest):
"""
## trisomy-21-aap Fictional Child Data Endpoint
* Generates synthetic data for demonstration or testing purposes
"""
try:
life_course_fictional_child_data = generate_fictional_child_data(
measurement_method=fictional_child_request.measurement_method,
sex=fictional_child_request.sex,
start_chronological_age=fictional_child_request.start_chronological_age,
end_age=fictional_child_request.end_age,
gestation_weeks=fictional_child_request.gestation_weeks,
gestation_days=fictional_child_request.gestation_days,
measurement_interval_type=fictional_child_request.measurement_interval_type,
measurement_interval_number=fictional_child_request.measurement_interval_number,
start_sds=fictional_child_request.start_sds,
drift=fictional_child_request.drift,
drift_range=fictional_child_request.drift_range,
noise=fictional_child_request.noise,
noise_range=fictional_child_request.noise_range,
reference=constants.TRISOMY_21_AAP,
)
return life_course_fictional_child_data
except:
return HTTPException(
status_code=422,
detail=f"Not possible to create trisomy-21-aap fictional child data.",
)
2 changes: 1 addition & 1 deletion tests/test_data/test_midparental_height_cdc_valid.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tests/test_data/test_midparental_height_ukwho_valid.json

Large diffs are not rendered by default.

Loading

0 comments on commit e4cf3b2

Please sign in to comment.