Skip to content

Commit

Permalink
Merge pull request #39 from rcpch/eatyourpeas/issue38
Browse files Browse the repository at this point in the history
cdc lay advice strings
  • Loading branch information
eatyourpeas authored Oct 23, 2024
2 parents 7246f09 + 81751b8 commit f6d92e4
Show file tree
Hide file tree
Showing 5 changed files with 421 additions and 32 deletions.
37 changes: 23 additions & 14 deletions rcpchgrowth/centile_bands.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# imports from rcpchgrowth
from rcpchgrowth.constants.reference_constants import COLE_TWO_THIRDS_SDS_NINE_CENTILES, THREE_PERCENT_CENTILES
from .constants import BMI, HEAD_CIRCUMFERENCE,THREE_PERCENT_CENTILE_COLLECTION,COLE_TWO_THIRDS_SDS_NINE_CENTILE_COLLECTION
from .global_functions import rounded_sds_for_centile
from rcpchgrowth.constants.reference_constants import COLE_TWO_THIRDS_SDS_NINE_CENTILES, THREE_PERCENT_CENTILES, UK_WHO, CDC
from .constants import BMI, HEAD_CIRCUMFERENCE,THREE_PERCENT_CENTILE_COLLECTION,COLE_TWO_THIRDS_SDS_NINE_CENTILE_COLLECTION ,FIVE_PERCENT_CENTILES, FIVE_PERCENT_CENTILE_COLLECTION, EIGHTY_FIVE_PERCENT_CENTILES, EIGHTY_FIVE_PERCENT_CENTILE_COLLECTION
from .global_functions import rounded_sds_for_centile, sds_for_centile

# Recommendations from Project board for reporting Centiles

Expand Down Expand Up @@ -37,19 +37,23 @@
def return_suffix(centile: float)->str:
# Converts a cardinal number to an ordinal by adding a suffix 'st', 'nd', 'rd' or 'th'
# Accepts decimals and negative numbers
# This function only works if the centile is received already rounded to 1 decimal place or 2 decimal places if reference is CDC and measurement method is BMI

# Note that if reference is CDC and measurement method is BMI, the centile is rounded to 2 decimal places if centile > 99.9


# centile should not be < 0 or > 100
if centile <=0:
return "below lowest centile.;"
if centile >= 100:
return "above highest centile."

suffix="th" # this is the default

final_number = centile
if (centile > 99 and centile <100) or (centile < 1 and centile > 0):
final_number=round(centile,1)
else:
final_number=int(round(final_number))
if isinstance(centile, float) and centile.is_integer():
final_number = int(centile) # convert to integer if it is a whole number as removes the decimal point

suffix="th" # this is the default

# get the final digit
string_from_number = str(final_number)
Expand All @@ -63,7 +67,7 @@ def return_suffix(centile: float)->str:

# 11, 12, 13 are special cases as they take 'th'
# get the final 2 digits if not a decimal
if isinstance(final_number, float) and final_number.is_integer() or isinstance(final_number, int):
if isinstance(final_number, float) and final_number.is_integer() or (isinstance(final_number, int) and len(string_from_number) > 1):
final_two_digits = string_from_number[len(string_from_number)-2: len(string_from_number)]
if int(final_two_digits) > 10 and int(final_two_digits) < 14:
suffix = "th"
Expand All @@ -79,7 +83,7 @@ def quarter_distances(centile):
this distance from centile line is used for all centile patterns, regardless of
whether the centile lines are equally spaced apart
"""
sds = rounded_sds_for_centile(centile)
sds = sds_for_centile(centile)
quarter_distance = 0.25 * 0.666
return sds - quarter_distance, sds + quarter_distance

Expand All @@ -96,7 +100,7 @@ def generate_centile_band_ranges(centile_collection):
return centile_bands


def centile_band_for_centile(sds: float, measurement_method: str, centile_format: str)->str:
def centile_band_for_centile(sds: float, measurement_method: str, centile_format: str = COLE_TWO_THIRDS_SDS_NINE_CENTILES, reference=UK_WHO)->str:
"""
this function returns a centile band into which the sds falls
Expand All @@ -108,6 +112,10 @@ def centile_band_for_centile(sds: float, measurement_method: str, centile_format
centile_collection = []
if centile_format == THREE_PERCENT_CENTILES:
centile_collection = THREE_PERCENT_CENTILE_COLLECTION
elif centile_format == FIVE_PERCENT_CENTILES:
centile_collection = FIVE_PERCENT_CENTILE_COLLECTION
elif centile_format == EIGHTY_FIVE_PERCENT_CENTILES:
centile_collection = EIGHTY_FIVE_PERCENT_CENTILE_COLLECTION
elif centile_format == COLE_TWO_THIRDS_SDS_NINE_CENTILES:
centile_collection = COLE_TWO_THIRDS_SDS_NINE_CENTILE_COLLECTION

Expand All @@ -123,12 +131,13 @@ def centile_band_for_centile(sds: float, measurement_method: str, centile_format
elif sds > 6:
return f"This {measurement_method} measurement is well above the normal range. Please review its accuracy."
elif sds <= centile_band_ranges[0][0]:
return f"This {measurement_method} measurement is below the normal range"
return f"This {measurement_method} measurement is below the normal range."
elif sds > centile_band_ranges[-1][1]:
return f"This {measurement_method} measurement is above the normal range"
return f"This {measurement_method} measurement is above the normal range."
else:
#even indices of centile_bands list is always on centile
#odd indices of cnetile_bands list is always between centiles

#odd indices of centile_bands list is always between centiles
for r in range(len(centile_band_ranges)):
if centile_band_ranges[r][0] <= sds < centile_band_ranges[r][1]:
if r%2 == 0:
Expand Down
4 changes: 2 additions & 2 deletions rcpchgrowth/constants/reference_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@
COLE_TWO_THIRDS_SDS_NINE_CENTILES = "cole-nine-centiles"
CENTILE_FORMATS = [THREE_PERCENT_CENTILES, COLE_TWO_THIRDS_SDS_NINE_CENTILES]

THREE_PERCENT_CENTILE_COLLECTION = [3.0, 10.0, 25.0, 50.0, 75.0, 90.0, 97.0]
EIGHTY_FIVE_PERCENT_CENTILE_COLLECTION = [3.0, 5.0, 10.0, 25.0, 50.0, 75.0, 85, 90.0, 95, 98.0, 99.0, 99.9, 99.99] # use for CDC Extended BMI centiles 2022
THREE_PERCENT_CENTILE_COLLECTION = [3.0, 5.0, 10.0, 25.0, 50.0, 75.0, 90.0, 95.0, 97.0]
EIGHTY_FIVE_PERCENT_CENTILE_COLLECTION = [5.0, 10.0, 25.0, 50.0, 75.0, 85.0, 90.0, 95, 98.0, 99.0, 99.9, 99.99] # use for CDC Extended BMI centiles 2022
FIVE_PERCENT_CENTILE_COLLECTION = [5.0, 10.0, 25.0, 50.0, 75.0, 90.0, 95.0]
COLE_TWO_THIRDS_SDS_NINE_CENTILE_COLLECTION = [
0.4,
Expand Down
34 changes: 19 additions & 15 deletions rcpchgrowth/measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ def sds_and_centile_for_measurement_method(
# there has been an age calculation error. Further calculation impossible - this may be due to a date error or because CDC reference data is not available in preterm infants

self.return_measurement_object = self.__create_measurement_object(
reference=reference,
measurement_method=measurement_method,
observation_value=observation_value,
observation_value_error=observation_value_error,
Expand Down Expand Up @@ -287,10 +288,17 @@ def sds_and_centile_for_measurement_method(
chronological_measurement_error = "Not possible to calculate centile"
chronological_measurement_centile = None
try:
if reference == CDC:
if measurement_method == BMI:
centile_format = EIGHTY_FIVE_PERCENT_CENTILES
else:
centile_format = THREE_PERCENT_CENTILES
else:
centile_format = COLE_TWO_THIRDS_SDS_NINE_CENTILES
chronological_centile_band = centile_band_for_centile(
sds=chronological_measurement_sds,
measurement_method=measurement_method,
centile_format=COLE_TWO_THIRDS_SDS_NINE_CENTILES
centile_format=centile_format
)
except TypeError as err:
chronological_measurement_error = "Not possible to calculate centile"
Expand All @@ -309,10 +317,17 @@ def sds_and_centile_for_measurement_method(
corrected_measurement_centile = None

try:
if reference == CDC:
if measurement_method == BMI:
centile_format = EIGHTY_FIVE_PERCENT_CENTILES
else:
centile_format = THREE_PERCENT_CENTILES
else:
centile_format = COLE_TWO_THIRDS_SDS_NINE_CENTILES
corrected_centile_band = centile_band_for_centile(
sds=corrected_measurement_sds,
measurement_method=measurement_method,
centile_format=COLE_TWO_THIRDS_SDS_NINE_CENTILES
centile_format=centile_format
)
except TypeError as err:
corrected_measurement_error = "Not possible to calculate centile"
Expand Down Expand Up @@ -345,6 +360,7 @@ def sds_and_centile_for_measurement_method(
chronological_percentage_median_bmi = None

self.return_measurement_object = self.__create_measurement_object(
reference=reference,
measurement_method=measurement_method,
observation_value=observation_value,
observation_value_error=observation_value_error,
Expand Down Expand Up @@ -527,6 +543,7 @@ def __calculate_ages(

def __create_measurement_object(
self,
reference: str,
measurement_method: str,
observation_value: float,
observation_value_error: str,
Expand Down Expand Up @@ -554,19 +571,6 @@ def __create_measurement_object(
# Only those calculations relevant to the measurement_method requested populate the final JSON
# object.

if corrected_centile_value:
if corrected_centile_value > 99 or corrected_centile_value < 1:
corrected_centile_value = round(corrected_centile_value, 1)
else:
corrected_centile_value = round(corrected_centile_value, 1)

if chronological_centile_value:
if chronological_centile_value > 99 or chronological_centile_value < 1:
chronological_centile_value = round(
chronological_centile_value, 1)
else:
chronological_centile_value = round(chronological_centile_value, 1)

measurement_calculated_values = {
"corrected_sds": corrected_sds_value,
"corrected_centile": corrected_centile_value,
Expand Down
Loading

0 comments on commit f6d92e4

Please sign in to comment.