growthcharts 0.1.0__py3-none-any.whl → 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- growthcharts/child.py +320 -160
- growthcharts/infant.py +387 -193
- growthcharts/patient.py +37 -0
- {growthcharts-0.1.0.dist-info → growthcharts-0.2.0.dist-info}/METADATA +45 -19
- {growthcharts-0.1.0.dist-info → growthcharts-0.2.0.dist-info}/RECORD +8 -8
- {growthcharts-0.1.0.dist-info → growthcharts-0.2.0.dist-info}/WHEEL +0 -0
- {growthcharts-0.1.0.dist-info → growthcharts-0.2.0.dist-info}/licenses/LICENSE.txt +0 -0
- {growthcharts-0.1.0.dist-info → growthcharts-0.2.0.dist-info}/top_level.txt +0 -0
growthcharts/infant.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
import matplotlib.pyplot as plt
|
|
3
|
+
import json
|
|
3
4
|
import math
|
|
4
5
|
from scipy.stats import norm
|
|
5
6
|
|
|
@@ -66,181 +67,349 @@ class Infant(Patient):
|
|
|
66
67
|
|
|
67
68
|
self.hc = hc
|
|
68
69
|
|
|
69
|
-
def plot_wtageinf(self, title=None):
|
|
70
|
+
def plot_wtageinf(self, title=None, figsize=(12,7), show=True, ax=None):
|
|
70
71
|
"""
|
|
71
|
-
|
|
72
|
+
Plot weight-for-age growth chart for infants.
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
This method draws CDC infant weight percentile curves
|
|
75
|
+
and overlays the patient's weight measurement.
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
Title of the plot.
|
|
78
|
-
"""
|
|
77
|
+
The resulting figure can be customized, embedded
|
|
78
|
+
in applications, or exported as an image file.
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
Args:
|
|
81
|
+
title (str, optional):
|
|
82
|
+
Custom title for the chart.
|
|
81
83
|
|
|
82
|
-
|
|
84
|
+
figsize (tuple, optional):
|
|
85
|
+
Figure size in inches (width, height).
|
|
86
|
+
Default is (12, 7).
|
|
83
87
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
show (bool, optional):
|
|
89
|
+
Whether to display the plot using matplotlib.
|
|
90
|
+
If False, the plot will not be shown.
|
|
91
|
+
Default is True.
|
|
92
|
+
|
|
93
|
+
ax (matplotlib.axes.Axes, optional):
|
|
94
|
+
Existing matplotlib Axes object for embedding
|
|
95
|
+
in custom layouts or applications.
|
|
90
96
|
|
|
91
|
-
|
|
97
|
+
Returns:
|
|
98
|
+
tuple:
|
|
99
|
+
(fig, ax)
|
|
92
100
|
|
|
93
|
-
|
|
101
|
+
fig : matplotlib.figure.Figure
|
|
102
|
+
The created matplotlib figure.
|
|
103
|
+
|
|
104
|
+
ax : matplotlib.axes.Axes
|
|
105
|
+
The axes containing the plot.
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
df = self.df_wtageinf
|
|
109
|
+
sex = self._normalize_sex()
|
|
110
|
+
|
|
111
|
+
data = df[df['Sex'] == sex]
|
|
112
|
+
|
|
113
|
+
if ax is None:
|
|
114
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
115
|
+
else:
|
|
116
|
+
fig = ax.figure
|
|
94
117
|
|
|
95
118
|
for i, col in enumerate(self.agecolumns[1:]):
|
|
96
119
|
|
|
97
120
|
if i in self.highlight_indices:
|
|
98
|
-
|
|
121
|
+
ax.plot(
|
|
99
122
|
data['Agemos'], data[col],
|
|
100
123
|
color='gray', linewidth=2,
|
|
101
|
-
label=
|
|
124
|
+
label=col
|
|
102
125
|
)
|
|
103
126
|
else:
|
|
104
|
-
|
|
127
|
+
ax.plot(
|
|
105
128
|
data['Agemos'], data[col],
|
|
106
129
|
color='lightgray', linewidth=1
|
|
107
130
|
)
|
|
108
131
|
|
|
109
132
|
if self.wt is not None:
|
|
110
|
-
|
|
111
|
-
|
|
133
|
+
ax.scatter(
|
|
134
|
+
self.age, self.wt,
|
|
135
|
+
color='red', s=100,
|
|
136
|
+
zorder=5, label="Patient"
|
|
137
|
+
)
|
|
112
138
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
plt.show()
|
|
139
|
+
ax.set_title(title or "Infant Weight for Age")
|
|
140
|
+
ax.set_xlabel("Age (months)")
|
|
141
|
+
ax.set_ylabel("Weight (Kg)")
|
|
142
|
+
ax.grid(True)
|
|
143
|
+
ax.legend()
|
|
119
144
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
Plot length-for-age growth chart.
|
|
145
|
+
if show:
|
|
146
|
+
plt.show()
|
|
123
147
|
|
|
124
|
-
|
|
148
|
+
return fig, ax
|
|
125
149
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
Title of the plot.
|
|
150
|
+
|
|
151
|
+
def plot_lenageinf(self, title=None, figsize=(12,7), show=True, ax=None):
|
|
129
152
|
"""
|
|
153
|
+
Plot length-for-age growth chart for infants.
|
|
130
154
|
|
|
131
|
-
|
|
155
|
+
This method draws CDC infant length percentile curves
|
|
156
|
+
and overlays the patient's length measurement.
|
|
132
157
|
|
|
133
|
-
|
|
158
|
+
The generated figure can be customized, embedded
|
|
159
|
+
in applications, or saved to disk.
|
|
134
160
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
self.sex = '2'
|
|
139
|
-
else:
|
|
140
|
-
raise TypeError('define sex as m or f')
|
|
161
|
+
Args:
|
|
162
|
+
title (str, optional):
|
|
163
|
+
Custom title for the chart.
|
|
141
164
|
|
|
142
|
-
|
|
165
|
+
figsize (tuple, optional):
|
|
166
|
+
Figure size in inches (width, height).
|
|
167
|
+
Default is (12, 7).
|
|
143
168
|
|
|
144
|
-
|
|
169
|
+
show (bool, optional):
|
|
170
|
+
Whether to display the plot using matplotlib.
|
|
171
|
+
If False, the plot will not be shown.
|
|
172
|
+
Default is True.
|
|
173
|
+
|
|
174
|
+
ax (matplotlib.axes.Axes, optional):
|
|
175
|
+
Existing matplotlib Axes object for embedding
|
|
176
|
+
in custom layouts or applications.
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
tuple:
|
|
180
|
+
(fig, ax)
|
|
181
|
+
|
|
182
|
+
fig : matplotlib.figure.Figure
|
|
183
|
+
The created matplotlib figure.
|
|
184
|
+
|
|
185
|
+
ax : matplotlib.axes.Axes
|
|
186
|
+
The axes containing the plot.
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
df = self.df_lenageinf
|
|
190
|
+
sex = self._normalize_sex()
|
|
191
|
+
|
|
192
|
+
data = df[df['Sex'] == sex]
|
|
193
|
+
|
|
194
|
+
if ax is None:
|
|
195
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
196
|
+
else:
|
|
197
|
+
fig = ax.figure
|
|
145
198
|
|
|
146
199
|
for i, col in enumerate(self.agecolumns[1:]):
|
|
147
200
|
|
|
148
201
|
if i in self.highlight_indices:
|
|
149
|
-
|
|
202
|
+
ax.plot(
|
|
150
203
|
data['Agemos'], data[col],
|
|
151
204
|
color='gray', linewidth=2,
|
|
152
|
-
label=
|
|
205
|
+
label=col
|
|
153
206
|
)
|
|
154
207
|
else:
|
|
155
|
-
|
|
208
|
+
ax.plot(
|
|
156
209
|
data['Agemos'], data[col],
|
|
157
210
|
color='lightgray', linewidth=1
|
|
158
211
|
)
|
|
159
212
|
|
|
160
213
|
if self.length is not None:
|
|
161
|
-
|
|
162
|
-
|
|
214
|
+
ax.scatter(
|
|
215
|
+
self.age, self.length,
|
|
216
|
+
color='red', s=100,
|
|
217
|
+
zorder=5, label="Patient"
|
|
218
|
+
)
|
|
163
219
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
plt.show()
|
|
220
|
+
ax.set_title(title or "Infant Length for Age")
|
|
221
|
+
ax.set_xlabel("Age (months)")
|
|
222
|
+
ax.set_ylabel("Length (cm)")
|
|
223
|
+
ax.grid(True)
|
|
224
|
+
ax.legend()
|
|
170
225
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
Plot head circumference-for-age growth chart.
|
|
226
|
+
if show:
|
|
227
|
+
plt.show()
|
|
174
228
|
|
|
175
|
-
|
|
229
|
+
return fig, ax
|
|
176
230
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
Title of the plot.
|
|
231
|
+
|
|
232
|
+
def plot_hcageinf(self, title=None, figsize=(12,7), show=True, ax=None):
|
|
180
233
|
"""
|
|
234
|
+
Plot head circumference-for-age growth chart for infants.
|
|
181
235
|
|
|
182
|
-
|
|
236
|
+
This method draws CDC head circumference percentile curves
|
|
237
|
+
and overlays the patient's head circumference measurement.
|
|
183
238
|
|
|
184
|
-
|
|
239
|
+
The output figure can be customized, embedded in apps,
|
|
240
|
+
or exported as an image file.
|
|
185
241
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
242
|
+
Args:
|
|
243
|
+
title (str, optional):
|
|
244
|
+
Custom title for the chart.
|
|
245
|
+
|
|
246
|
+
figsize (tuple, optional):
|
|
247
|
+
Figure size in inches (width, height).
|
|
248
|
+
Default is (12, 7).
|
|
249
|
+
|
|
250
|
+
show (bool, optional):
|
|
251
|
+
Whether to display the plot using matplotlib.
|
|
252
|
+
If False, the plot will not be shown.
|
|
253
|
+
Default is True.
|
|
192
254
|
|
|
193
|
-
|
|
255
|
+
ax (matplotlib.axes.Axes, optional):
|
|
256
|
+
Existing matplotlib Axes object for embedding
|
|
257
|
+
in custom layouts or applications.
|
|
194
258
|
|
|
195
|
-
|
|
259
|
+
Returns:
|
|
260
|
+
tuple:
|
|
261
|
+
(fig, ax)
|
|
262
|
+
|
|
263
|
+
fig : matplotlib.figure.Figure
|
|
264
|
+
The created matplotlib figure.
|
|
265
|
+
|
|
266
|
+
ax : matplotlib.axes.Axes
|
|
267
|
+
The axes containing the plot.
|
|
268
|
+
"""
|
|
269
|
+
|
|
270
|
+
df = self.df_hcageinf
|
|
271
|
+
sex = self._normalize_sex()
|
|
272
|
+
|
|
273
|
+
data = df[df['Sex'] == sex]
|
|
274
|
+
|
|
275
|
+
if ax is None:
|
|
276
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
277
|
+
else:
|
|
278
|
+
fig = ax.figure
|
|
196
279
|
|
|
197
280
|
for i, col in enumerate(self.agecolumns[1:]):
|
|
198
281
|
|
|
199
282
|
if i in self.highlight_indices:
|
|
200
|
-
|
|
283
|
+
ax.plot(
|
|
201
284
|
data['Agemos'], data[col],
|
|
202
285
|
color='gray', linewidth=2,
|
|
203
|
-
label=
|
|
286
|
+
label=col
|
|
204
287
|
)
|
|
205
288
|
else:
|
|
206
|
-
|
|
289
|
+
ax.plot(
|
|
207
290
|
data['Agemos'], data[col],
|
|
208
291
|
color='lightgray', linewidth=1
|
|
209
292
|
)
|
|
210
293
|
|
|
211
294
|
if self.hc is not None:
|
|
212
|
-
|
|
213
|
-
|
|
295
|
+
ax.scatter(
|
|
296
|
+
self.age, self.hc,
|
|
297
|
+
color='red', s=100,
|
|
298
|
+
zorder=5, label="Patient"
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
ax.set_title(title or "Head Circumference for Age")
|
|
302
|
+
ax.set_xlabel("Age (months)")
|
|
303
|
+
ax.set_ylabel("HC (cm)")
|
|
304
|
+
ax.grid(True)
|
|
305
|
+
ax.legend()
|
|
306
|
+
|
|
307
|
+
if show:
|
|
308
|
+
plt.show()
|
|
309
|
+
|
|
310
|
+
return fig, ax
|
|
311
|
+
|
|
312
|
+
def plot_wtleninf(self, title=None, figsize=(12,7), show=True, ax=None):
|
|
313
|
+
"""
|
|
314
|
+
Plot weight-for-length growth chart for infants.
|
|
315
|
+
|
|
316
|
+
This method draws CDC weight-for-length percentile curves
|
|
317
|
+
and overlays the patient's weight and length measurement.
|
|
318
|
+
|
|
319
|
+
It is mainly used for nutritional and growth status
|
|
320
|
+
assessment in infants.
|
|
321
|
+
|
|
322
|
+
The generated figure can be customized, embedded in
|
|
323
|
+
applications, or exported as an image file.
|
|
324
|
+
|
|
325
|
+
Args:
|
|
326
|
+
title (str, optional):
|
|
327
|
+
Custom title for the chart.
|
|
328
|
+
|
|
329
|
+
figsize (tuple, optional):
|
|
330
|
+
Figure size in inches (width, height).
|
|
331
|
+
Default is (12, 7).
|
|
332
|
+
|
|
333
|
+
show (bool, optional):
|
|
334
|
+
Whether to display the plot using matplotlib.
|
|
335
|
+
If False, the plot will not be shown.
|
|
336
|
+
Default is True.
|
|
337
|
+
|
|
338
|
+
ax (matplotlib.axes.Axes, optional):
|
|
339
|
+
Existing matplotlib Axes object for embedding
|
|
340
|
+
in custom layouts or applications.
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
tuple:
|
|
344
|
+
(fig, ax)
|
|
345
|
+
|
|
346
|
+
fig : matplotlib.figure.Figure
|
|
347
|
+
The created matplotlib figure.
|
|
348
|
+
|
|
349
|
+
ax : matplotlib.axes.Axes
|
|
350
|
+
The axes containing the plot.
|
|
351
|
+
"""
|
|
352
|
+
|
|
353
|
+
df = self.df_wtleninf
|
|
354
|
+
sex = self._normalize_sex()
|
|
355
|
+
|
|
356
|
+
data = df[df['Sex'] == sex]
|
|
357
|
+
|
|
358
|
+
if ax is None:
|
|
359
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
360
|
+
else:
|
|
361
|
+
fig = ax.figure
|
|
362
|
+
|
|
363
|
+
for i, col in enumerate(self.lencolumns[1:]):
|
|
364
|
+
|
|
365
|
+
if i in self.highlight_indices:
|
|
366
|
+
ax.plot(
|
|
367
|
+
data['Length'], data[col],
|
|
368
|
+
color='gray', linewidth=2,
|
|
369
|
+
label=col
|
|
370
|
+
)
|
|
371
|
+
else:
|
|
372
|
+
ax.plot(
|
|
373
|
+
data['Length'], data[col],
|
|
374
|
+
color='lightgray', linewidth=1
|
|
375
|
+
)
|
|
214
376
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
377
|
+
if self.wt is not None and self.length is not None:
|
|
378
|
+
ax.scatter(
|
|
379
|
+
self.length, self.wt,
|
|
380
|
+
color='red', s=100,
|
|
381
|
+
zorder=5, label="Patient"
|
|
382
|
+
)
|
|
221
383
|
|
|
222
|
-
|
|
384
|
+
ax.set_title(title or "Weight for Length")
|
|
385
|
+
ax.set_xlabel("Length (cm)")
|
|
386
|
+
ax.set_ylabel("Weight (Kg)")
|
|
387
|
+
ax.grid(True)
|
|
388
|
+
ax.legend()
|
|
389
|
+
|
|
390
|
+
if show:
|
|
391
|
+
plt.show()
|
|
392
|
+
|
|
393
|
+
return fig, ax
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def analyze_wtageinf(self, as_json=False):
|
|
223
398
|
"""
|
|
224
|
-
Analyze weight-for-age using LMS method.
|
|
399
|
+
Analyze weight-for-age using LMS method (WHO/CDC).
|
|
225
400
|
|
|
226
401
|
Returns:
|
|
227
|
-
dict:
|
|
228
|
-
Z-score and
|
|
402
|
+
dict or json:
|
|
403
|
+
Z-score, percentile, and interpretation.
|
|
229
404
|
"""
|
|
230
405
|
|
|
231
406
|
df = self.df_wtageinf
|
|
232
407
|
|
|
233
|
-
|
|
408
|
+
sex = self._normalize_sex()
|
|
234
409
|
|
|
235
|
-
|
|
236
|
-
self.sex = '1'
|
|
237
|
-
elif self.sex in ['f', '2']:
|
|
238
|
-
self.sex = '2'
|
|
239
|
-
else:
|
|
240
|
-
raise TypeError('define sex as m or f')
|
|
241
|
-
|
|
242
|
-
df2 = df[df['Sex'] == self.sex]
|
|
410
|
+
df2 = df[df['Sex'] == sex]
|
|
243
411
|
|
|
412
|
+
# Closest age row
|
|
244
413
|
row = df2.iloc[
|
|
245
414
|
(df2['Agemos'] - self.age).abs().argsort()[:1]
|
|
246
415
|
]
|
|
@@ -249,6 +418,7 @@ class Infant(Patient):
|
|
|
249
418
|
M = float(row['M'].values[0])
|
|
250
419
|
S = float(row['S'].values[0])
|
|
251
420
|
|
|
421
|
+
# LMS Z-score
|
|
252
422
|
if L != 0:
|
|
253
423
|
z = ((self.wt / M) ** L - 1) / (L * S)
|
|
254
424
|
else:
|
|
@@ -256,133 +426,157 @@ class Infant(Patient):
|
|
|
256
426
|
|
|
257
427
|
percentile = norm.cdf(z) * 100
|
|
258
428
|
|
|
259
|
-
|
|
260
|
-
"
|
|
261
|
-
"
|
|
429
|
+
result = {
|
|
430
|
+
"indicator": "Weight-for-Age",
|
|
431
|
+
"value": round(self.wt, 2),
|
|
432
|
+
"unit": "kg",
|
|
433
|
+
"age_months": round(self.age, 2),
|
|
434
|
+
"sex": "Male" if sex == "1" else "Female",
|
|
435
|
+
|
|
436
|
+
"z_score": round(z, 2),
|
|
437
|
+
"percentile": round(percentile, 1),
|
|
438
|
+
|
|
439
|
+
"z_interpretation": self._interpret_z(z),
|
|
440
|
+
"percentile_interpretation": self._interpret_percentile(percentile)
|
|
262
441
|
}
|
|
263
442
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
Analyze length-for-age using LMS method.
|
|
443
|
+
if as_json:
|
|
444
|
+
return json.dumps(result, ensure_ascii=False)
|
|
267
445
|
|
|
268
|
-
|
|
269
|
-
dict:
|
|
270
|
-
Z-score and percentile.
|
|
271
|
-
"""
|
|
446
|
+
return result
|
|
272
447
|
|
|
273
|
-
df = self.df_lenageinf
|
|
274
448
|
|
|
275
|
-
|
|
449
|
+
def analyze_lenageinf(self, return_json=False):
|
|
450
|
+
"""
|
|
451
|
+
Analyze length-for-age using LMS method.
|
|
276
452
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
elif self.sex in ['f', '2']:
|
|
280
|
-
self.sex = '2'
|
|
281
|
-
else:
|
|
282
|
-
raise TypeError('define sex as m or f')
|
|
453
|
+
Args:
|
|
454
|
+
return_json (bool): If True, returns a JSON string. Default False.
|
|
283
455
|
|
|
284
|
-
|
|
456
|
+
Returns:
|
|
457
|
+
dict or JSON: Z-score, percentile, and interpretation.
|
|
458
|
+
"""
|
|
459
|
+
df = self.df_lenageinf
|
|
460
|
+
sex = self._normalize_sex()
|
|
461
|
+
df2 = df[df['Sex'] == sex]
|
|
285
462
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
]
|
|
463
|
+
row = df2.iloc[(df2['Agemos'] - self.age).abs().argsort()[:1]]
|
|
464
|
+
L, M, S = float(row['L'].values[0]), float(row['M'].values[0]), float(row['S'].values[0])
|
|
289
465
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
466
|
+
if L != 0:
|
|
467
|
+
z = ((self.length / M) ** L - 1) / (L * S)
|
|
468
|
+
else:
|
|
469
|
+
z = math.log(self.length / M) / S
|
|
293
470
|
|
|
294
|
-
|
|
295
|
-
z = ((self.length / M) ** L - 1) / (L * S)
|
|
296
|
-
else:
|
|
297
|
-
z = math.log(self.length / M) / S
|
|
471
|
+
percentile = norm.cdf(z) * 100
|
|
298
472
|
|
|
299
|
-
percentile = norm.cdf(z) * 100
|
|
300
473
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
474
|
+
result = {
|
|
475
|
+
"indicator": "Length-for-Age",
|
|
476
|
+
"value": round(self.length, 2),
|
|
477
|
+
"unit": "cm",
|
|
478
|
+
"age_months": round(self.age, 2),
|
|
479
|
+
"sex": "Male" if sex == "1" else "Female",
|
|
305
480
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
Analyze head circumference-for-age using LMS method.
|
|
481
|
+
"z_score": round(z, 2),
|
|
482
|
+
"percentile": round(percentile, 1),
|
|
309
483
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
"""
|
|
484
|
+
"z_interpretation": self._interpret_z(z),
|
|
485
|
+
"percentile_interpretation": self._interpret_percentile(percentile)
|
|
486
|
+
}
|
|
314
487
|
|
|
315
|
-
|
|
488
|
+
if return_json:
|
|
489
|
+
import json
|
|
490
|
+
return json.dumps(result)
|
|
316
491
|
|
|
317
|
-
|
|
492
|
+
return result
|
|
318
493
|
|
|
319
|
-
if self.sex in ['m', '1']:
|
|
320
|
-
self.sex = '1'
|
|
321
|
-
elif self.sex in ['f', '2']:
|
|
322
|
-
self.sex = '2'
|
|
323
|
-
else:
|
|
324
|
-
raise TypeError('define sex as m or f')
|
|
325
494
|
|
|
326
|
-
|
|
495
|
+
def analyze_hcageinf(self, return_json=False):
|
|
496
|
+
"""
|
|
497
|
+
Analyze head circumference-for-age using LMS method.
|
|
327
498
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
]
|
|
499
|
+
Args:
|
|
500
|
+
return_json (bool): If True, returns a JSON string. Default False.
|
|
331
501
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
502
|
+
Returns:
|
|
503
|
+
dict or JSON: Z-score, percentile, and interpretation.
|
|
504
|
+
"""
|
|
505
|
+
df = self.df_hcageinf
|
|
506
|
+
sex = self._normalize_sex()
|
|
507
|
+
df2 = df[df['Sex'] == sex]
|
|
335
508
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
else:
|
|
339
|
-
z = math.log(self.hc / M) / S
|
|
509
|
+
row = df2.iloc[(df2['Agemos'] - self.age).abs().argsort()[:1]]
|
|
510
|
+
L, M, S = float(row['L'].values[0]), float(row['M'].values[0]), float(row['S'].values[0])
|
|
340
511
|
|
|
341
|
-
|
|
512
|
+
if L != 0:
|
|
513
|
+
z = ((self.hc / M) ** L - 1) / (L * S)
|
|
514
|
+
else:
|
|
515
|
+
z = math.log(self.hc / M) / S
|
|
342
516
|
|
|
343
|
-
|
|
344
|
-
"Z": round(z, 2),
|
|
345
|
-
"Percentile": round(percentile, 2)
|
|
346
|
-
}
|
|
517
|
+
percentile = norm.cdf(z) * 100
|
|
347
518
|
|
|
348
|
-
|
|
349
|
-
"""
|
|
350
|
-
|
|
519
|
+
result = {
|
|
520
|
+
"indicator": "Head Circumference-for-Age",
|
|
521
|
+
"value": round(self.hc, 2),
|
|
522
|
+
"unit": "cm",
|
|
523
|
+
"age_months": round(self.age, 2),
|
|
524
|
+
"sex": "Male" if sex == "1" else "Female",
|
|
351
525
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
Z-score and percentile.
|
|
355
|
-
"""
|
|
526
|
+
"z_score": round(z, 2),
|
|
527
|
+
"percentile": round(percentile, 1),
|
|
356
528
|
|
|
357
|
-
|
|
529
|
+
"z_interpretation": self._interpret_z(z),
|
|
530
|
+
"percentile_interpretation": self._interpret_percentile(percentile)
|
|
531
|
+
}
|
|
358
532
|
|
|
359
|
-
|
|
533
|
+
if return_json:
|
|
534
|
+
import json
|
|
535
|
+
return json.dumps(result)
|
|
360
536
|
|
|
361
|
-
|
|
362
|
-
self.sex = '1'
|
|
363
|
-
elif self.sex in ['f', '2']:
|
|
364
|
-
self.sex = '2'
|
|
365
|
-
else:
|
|
366
|
-
raise TypeError('define sex as m or f')
|
|
537
|
+
return result
|
|
367
538
|
|
|
368
|
-
df2 = df[df['Sex'] == self.sex]
|
|
369
539
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
540
|
+
def analyze_wtleninf(self, return_json=False):
|
|
541
|
+
"""
|
|
542
|
+
Analyze weight-for-length using LMS method.
|
|
373
543
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
S = float(row['S'].values[0])
|
|
544
|
+
Args:
|
|
545
|
+
return_json (bool): If True, returns a JSON string. Default False.
|
|
377
546
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
547
|
+
Returns:
|
|
548
|
+
dict or JSON: Z-score, percentile, and interpretation.
|
|
549
|
+
"""
|
|
550
|
+
df = self.df_wtleninf
|
|
551
|
+
sex = self._normalize_sex()
|
|
552
|
+
df2 = df[df['Sex'] == sex]
|
|
382
553
|
|
|
383
|
-
|
|
554
|
+
row = df2.iloc[(df2['Length'] - self.length).abs().argsort()[:1]]
|
|
555
|
+
L, M, S = float(row['L'].values[0]), float(row['M'].values[0]), float(row['S'].values[0])
|
|
384
556
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
557
|
+
if L != 0:
|
|
558
|
+
z = ((self.wt / M) ** L - 1) / (L * S)
|
|
559
|
+
else:
|
|
560
|
+
z = math.log(self.wt / M) / S
|
|
561
|
+
|
|
562
|
+
percentile = norm.cdf(z) * 100
|
|
563
|
+
|
|
564
|
+
result = {
|
|
565
|
+
"indicator": "Weight-for-Length",
|
|
566
|
+
"value": round(self.wt, 2),
|
|
567
|
+
"unit": None,
|
|
568
|
+
"length_cm": round(self.length, 2),
|
|
569
|
+
"sex": "Male" if sex == "1" else "Female",
|
|
570
|
+
|
|
571
|
+
"z_score": round(z, 2),
|
|
572
|
+
"percentile": round(percentile, 1),
|
|
573
|
+
|
|
574
|
+
"z_interpretation": self._interpret_z(z),
|
|
575
|
+
"percentile_interpretation": self._interpret_percentile(percentile)
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
if return_json:
|
|
579
|
+
import json
|
|
580
|
+
return json.dumps(result)
|
|
581
|
+
|
|
582
|
+
return result
|