growthcharts 0.1.0__tar.gz → 0.2.0__tar.gz

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.
Files changed (23) hide show
  1. {growthcharts-0.1.0 → growthcharts-0.2.0}/PKG-INFO +45 -19
  2. {growthcharts-0.1.0 → growthcharts-0.2.0}/README.md +44 -18
  3. growthcharts-0.2.0/growthcharts/child.py +429 -0
  4. growthcharts-0.2.0/growthcharts/infant.py +582 -0
  5. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts/patient.py +37 -0
  6. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts.egg-info/PKG-INFO +45 -19
  7. {growthcharts-0.1.0 → growthcharts-0.2.0}/setup.py +1 -1
  8. growthcharts-0.1.0/growthcharts/child.py +0 -269
  9. growthcharts-0.1.0/growthcharts/infant.py +0 -388
  10. {growthcharts-0.1.0 → growthcharts-0.2.0}/LICENSE.txt +0 -0
  11. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts/__init__.py +0 -0
  12. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts/data/bmiage.csv +0 -0
  13. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts/data/hcageinf.csv +0 -0
  14. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts/data/lenage.csv +0 -0
  15. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts/data/lenageinf.csv +0 -0
  16. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts/data/wtage.csv +0 -0
  17. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts/data/wtageinf.csv +0 -0
  18. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts/data/wtleninf.csv +0 -0
  19. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts.egg-info/SOURCES.txt +0 -0
  20. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts.egg-info/dependency_links.txt +0 -0
  21. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts.egg-info/requires.txt +0 -0
  22. {growthcharts-0.1.0 → growthcharts-0.2.0}/growthcharts.egg-info/top_level.txt +0 -0
  23. {growthcharts-0.1.0 → growthcharts-0.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: growthcharts
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Pediatric Growth Chart Analyzer
5
5
  Home-page: https://drdehghani.ir/
6
6
  Author: Javad Dehghani MD
@@ -29,6 +29,7 @@ Dynamic: requires-dist
29
29
  Dynamic: requires-python
30
30
  Dynamic: summary
31
31
 
32
+ # GrowthCharts
32
33
 
33
34
  **GrowthCharts** is a pediatric growth chart analyzer for infants (0–2 years) and children (2–20 years).
34
35
  It provides Z-score calculation, percentiles, and growth chart visualization based on CDC growth standards.
@@ -66,10 +67,10 @@ baby.plot_hcageinf(title="Head Circumference-for-Age")
66
67
  baby.plot_wtleninf(title="Weight-for-Length")
67
68
 
68
69
  # Calculate Z-scores and percentiles
69
- print(baby.analyze_wtageinf()) # Example output: {'Z': -0.23, 'Percentile': 41.0}
70
- print(baby.analyze_lenageinf()) # Example output: {'Z': 0.12, 'Percentile': 55.0}
71
- print(baby.analyze_hcageinf()) # Example output: {'Z': 0.30, 'Percentile': 62.0}
72
- print(baby.analyze_wtleninf()) # Example output: {'Z': -0.15, 'Percentile': 44.0}
70
+ print(baby.analyze_wtageinf()) # Example: {'Z': -0.23, 'Percentile': 41.0, 'Interpretation': 'Normal'}
71
+ print(baby.analyze_lenageinf()) # Example: {'Z': 0.12, 'Percentile': 55.0, 'Interpretation': 'Normal'}
72
+ print(baby.analyze_hcageinf()) # Example: {'Z': 0.30, 'Percentile': 62.0, 'Interpretation': 'Normal'}
73
+ print(baby.analyze_wtleninf()) # Example: {'Z': -0.15, 'Percentile': 44.0, 'Interpretation': 'Normal'}
73
74
  Child example (2–20 years)
74
75
  from growthcharts import Child
75
76
 
@@ -82,38 +83,63 @@ child.plot_lenage(title="Height-for-Age")
82
83
  child.plot_bmiage(title="BMI-for-Age")
83
84
 
84
85
  # Calculate Z-scores and percentiles
85
- print(child.analyze_wtage()) # Example output: {'Z': 0.12, 'Percentile': 55.0}
86
- print(child.analyze_lenage()) # Example output: {'Z': -0.08, 'Percentile': 47.0}
87
- print(child.analyze_bmiage()) # Example output: {'Z': 0.05, 'Percentile': 52.0}
86
+ print(child.analyze_wtage()) # Example: {'Z': 0.12, 'Percentile': 55.0, 'Interpretation': 'Normal'}
87
+ print(child.analyze_lenage()) # Example: {'Z': -0.08, 'Percentile': 47.0, 'Interpretation': 'Normal'}
88
+ print(child.analyze_bmiage()) # Example: {'Z': 0.05, 'Percentile': 52.0, 'Interpretation': 'Normal'}
88
89
  Classes
89
90
  Patient
90
91
  Base class storing sex, age, weight, and length.
91
-
92
92
  Calculates BMI if both weight and length are provided.
93
93
 
94
94
  Infant(Patient)
95
- Handles infants 0–24 months:
95
+ Handles infants 0–24 months.
96
+
97
+ Plotting methods:
98
+
99
+ plot_wtage
100
+
101
+ plot_lenageinf
102
+
103
+ plot_hcageinf
104
+
105
+ plot_wtleninf
106
+
107
+ Analysis methods:
108
+
109
+ analyze_wtageinf
110
+
111
+ analyze_lenageinf
96
112
 
97
- Plotting methods: plot_wtage, plot_lenageinf, plot_hcageinf, plot_wtleninf
113
+ analyze_hcageinf
98
114
 
99
- Analysis methods: analyze_wtageinf, analyze_lenageinf, analyze_hcageinf, analyze_wtleninf
115
+ analyze_wtleninf
100
116
 
101
117
  Child(Patient)
102
- Handles children 2–20 years:
118
+ Handles children 2–20 years.
103
119
 
104
- Plotting methods: plot_wtage, plot_lenage, plot_bmiage
120
+ Plotting methods:
105
121
 
106
- Analysis methods: analyze_wtage, analyze_lenage, analyze_bmiage
122
+ plot_wtage
123
+
124
+ plot_lenage
125
+
126
+ plot_bmiage
127
+
128
+ Analysis methods:
129
+
130
+ analyze_wtage
131
+
132
+ analyze_lenage
133
+
134
+ analyze_bmiage
107
135
 
108
136
  Data
109
137
  CSV data files for growth standards are included with the package under the data/ folder.
110
138
 
111
139
  Infant: wtageinf.csv, lenageinf.csv, hcageinf.csv, wtleninf.csv
112
-
113
140
  Child: wtage.csv, lenage.csv, bmiage.csv
114
141
 
115
142
  These are loaded automatically by the classes and do not need separate downloading.
116
143
 
117
- ## License
118
-
119
- This project is licensed under the MIT License.
144
+ License
145
+ This project is licensed under the MIT License.
@@ -1,3 +1,4 @@
1
+ # GrowthCharts
1
2
 
2
3
  **GrowthCharts** is a pediatric growth chart analyzer for infants (0–2 years) and children (2–20 years).
3
4
  It provides Z-score calculation, percentiles, and growth chart visualization based on CDC growth standards.
@@ -35,10 +36,10 @@ baby.plot_hcageinf(title="Head Circumference-for-Age")
35
36
  baby.plot_wtleninf(title="Weight-for-Length")
36
37
 
37
38
  # Calculate Z-scores and percentiles
38
- print(baby.analyze_wtageinf()) # Example output: {'Z': -0.23, 'Percentile': 41.0}
39
- print(baby.analyze_lenageinf()) # Example output: {'Z': 0.12, 'Percentile': 55.0}
40
- print(baby.analyze_hcageinf()) # Example output: {'Z': 0.30, 'Percentile': 62.0}
41
- print(baby.analyze_wtleninf()) # Example output: {'Z': -0.15, 'Percentile': 44.0}
39
+ print(baby.analyze_wtageinf()) # Example: {'Z': -0.23, 'Percentile': 41.0, 'Interpretation': 'Normal'}
40
+ print(baby.analyze_lenageinf()) # Example: {'Z': 0.12, 'Percentile': 55.0, 'Interpretation': 'Normal'}
41
+ print(baby.analyze_hcageinf()) # Example: {'Z': 0.30, 'Percentile': 62.0, 'Interpretation': 'Normal'}
42
+ print(baby.analyze_wtleninf()) # Example: {'Z': -0.15, 'Percentile': 44.0, 'Interpretation': 'Normal'}
42
43
  Child example (2–20 years)
43
44
  from growthcharts import Child
44
45
 
@@ -51,38 +52,63 @@ child.plot_lenage(title="Height-for-Age")
51
52
  child.plot_bmiage(title="BMI-for-Age")
52
53
 
53
54
  # Calculate Z-scores and percentiles
54
- print(child.analyze_wtage()) # Example output: {'Z': 0.12, 'Percentile': 55.0}
55
- print(child.analyze_lenage()) # Example output: {'Z': -0.08, 'Percentile': 47.0}
56
- print(child.analyze_bmiage()) # Example output: {'Z': 0.05, 'Percentile': 52.0}
55
+ print(child.analyze_wtage()) # Example: {'Z': 0.12, 'Percentile': 55.0, 'Interpretation': 'Normal'}
56
+ print(child.analyze_lenage()) # Example: {'Z': -0.08, 'Percentile': 47.0, 'Interpretation': 'Normal'}
57
+ print(child.analyze_bmiage()) # Example: {'Z': 0.05, 'Percentile': 52.0, 'Interpretation': 'Normal'}
57
58
  Classes
58
59
  Patient
59
60
  Base class storing sex, age, weight, and length.
60
-
61
61
  Calculates BMI if both weight and length are provided.
62
62
 
63
63
  Infant(Patient)
64
- Handles infants 0–24 months:
64
+ Handles infants 0–24 months.
65
+
66
+ Plotting methods:
67
+
68
+ plot_wtage
69
+
70
+ plot_lenageinf
71
+
72
+ plot_hcageinf
73
+
74
+ plot_wtleninf
75
+
76
+ Analysis methods:
77
+
78
+ analyze_wtageinf
79
+
80
+ analyze_lenageinf
65
81
 
66
- Plotting methods: plot_wtage, plot_lenageinf, plot_hcageinf, plot_wtleninf
82
+ analyze_hcageinf
67
83
 
68
- Analysis methods: analyze_wtageinf, analyze_lenageinf, analyze_hcageinf, analyze_wtleninf
84
+ analyze_wtleninf
69
85
 
70
86
  Child(Patient)
71
- Handles children 2–20 years:
87
+ Handles children 2–20 years.
72
88
 
73
- Plotting methods: plot_wtage, plot_lenage, plot_bmiage
89
+ Plotting methods:
74
90
 
75
- Analysis methods: analyze_wtage, analyze_lenage, analyze_bmiage
91
+ plot_wtage
92
+
93
+ plot_lenage
94
+
95
+ plot_bmiage
96
+
97
+ Analysis methods:
98
+
99
+ analyze_wtage
100
+
101
+ analyze_lenage
102
+
103
+ analyze_bmiage
76
104
 
77
105
  Data
78
106
  CSV data files for growth standards are included with the package under the data/ folder.
79
107
 
80
108
  Infant: wtageinf.csv, lenageinf.csv, hcageinf.csv, wtleninf.csv
81
-
82
109
  Child: wtage.csv, lenage.csv, bmiage.csv
83
110
 
84
111
  These are loaded automatically by the classes and do not need separate downloading.
85
112
 
86
- ## License
87
-
88
- This project is licensed under the MIT License.
113
+ License
114
+ This project is licensed under the MIT License.
@@ -0,0 +1,429 @@
1
+ import pandas as pd
2
+ import matplotlib.pyplot as plt
3
+ import math
4
+ import json
5
+ from scipy.stats import norm
6
+
7
+ from .patient import Patient
8
+ from pathlib import Path
9
+
10
+
11
+ DATA_PATH = Path(__file__).parent / "data"
12
+
13
+
14
+ class Child(Patient):
15
+ """
16
+ Represents a child patient (2–20 years) and provides growth chart analysis
17
+ and visualization based on CDC growth standards.
18
+
19
+ This class extends the Patient class and adds functionality for:
20
+ - Weight-for-age
21
+ - Length-for-age
22
+ - BMI-for-age
23
+
24
+ Supports plotting percentile curves and calculating Z-scores and percentiles
25
+ using the LMS method.
26
+ """
27
+
28
+ # Child 2 to 20 database
29
+ df_wtage = pd.read_csv(DATA_PATH /'wtage.csv', dtype={'Sex': str})
30
+ df_lenage = pd.read_csv(DATA_PATH /'lenage.csv', dtype={'Sex': str})
31
+ df_bmiage = pd.read_csv(DATA_PATH /'bmiage.csv', dtype={'Sex': str})
32
+
33
+ def __init__(self, sex: str, age: int, wt: float = None, length: float = None):
34
+ """
35
+ Initialize a Child object.
36
+
37
+ At least one anthropometric measurement must be provided.
38
+
39
+ Args:
40
+ sex (str): Child sex.
41
+ age (int): Age in months.
42
+ wt (float, optional): Weight in kilograms.
43
+ length (float, optional): Length/height in centimeters.
44
+
45
+ Raises:
46
+ ValueError: If both wt and length are None.
47
+ """
48
+ if wt is None and length is None:
49
+ raise ValueError("At least wt or length must be provided")
50
+
51
+ super().__init__(sex, age, wt, length)
52
+
53
+ def plot_wtage(self, title=None, figsize=(12,7), show=True, ax=None):
54
+ """
55
+ Plot weight-for-age growth chart for the child.
56
+
57
+ This method draws CDC percentile curves and overlays
58
+ the patient's weight measurement.
59
+
60
+ The returned figure can be customized, embedded in apps,
61
+ or saved as an image.
62
+
63
+ Args:
64
+ title (str, optional):
65
+ Custom title for the chart.
66
+
67
+ figsize (tuple, optional):
68
+ Figure size in inches (width, height).
69
+ Default is (12, 7).
70
+
71
+ show (bool, optional):
72
+ Whether to display the plot using matplotlib.
73
+ If False, the plot will not be shown.
74
+ Default is True.
75
+
76
+ ax (matplotlib.axes.Axes, optional):
77
+ Existing matplotlib Axes object for embedding
78
+ in custom layouts or applications.
79
+
80
+ Returns:
81
+ tuple:
82
+ (fig, ax)
83
+
84
+ fig : matplotlib.figure.Figure
85
+ The created matplotlib figure.
86
+
87
+ ax : matplotlib.axes.Axes
88
+ The axes containing the plot.
89
+ """
90
+
91
+ df = self.df_wtage
92
+ sex = self._normalize_sex()
93
+
94
+ data = df[df['Sex'] == sex]
95
+
96
+ if ax is None:
97
+ fig, ax = plt.subplots(figsize=figsize)
98
+ else:
99
+ fig = ax.figure
100
+
101
+ for i, col in enumerate(self.agecolumns[1:]):
102
+
103
+ if i in self.highlight_indices:
104
+ ax.plot(
105
+ data['Agemos'], data[col],
106
+ color='gray', linewidth=2,
107
+ label=col
108
+ )
109
+ else:
110
+ ax.plot(
111
+ data['Agemos'], data[col],
112
+ color='lightgray', linewidth=1
113
+ )
114
+
115
+ if self.wt is not None:
116
+ ax.scatter(
117
+ self.age, self.wt,
118
+ color='red', s=100,
119
+ zorder=5, label="Patient"
120
+ )
121
+
122
+ ax.set_title(title or "Weight for Age")
123
+ ax.set_xlabel("Age (months)")
124
+ ax.set_ylabel("Weight (Kg)")
125
+ ax.grid(True)
126
+ ax.legend()
127
+
128
+ if show:
129
+ plt.show()
130
+
131
+ return fig, ax
132
+
133
+
134
+ def plot_lenage(self, title=None, figsize=(12,7), show=True, ax=None):
135
+ """
136
+ Plot length/height-for-age growth chart for the child.
137
+
138
+ This method draws CDC percentile curves and overlays
139
+ the patient's length or height measurement.
140
+
141
+ The output figure can be customized, embedded in
142
+ applications, or exported as an image file.
143
+
144
+ Args:
145
+ title (str, optional):
146
+ Custom title for the chart.
147
+
148
+ figsize (tuple, optional):
149
+ Figure size in inches (width, height).
150
+ Default is (12, 7).
151
+
152
+ show (bool, optional):
153
+ Whether to display the plot using matplotlib.
154
+ If False, the plot will not be shown.
155
+ Default is True.
156
+
157
+ ax (matplotlib.axes.Axes, optional):
158
+ Existing matplotlib Axes object for embedding
159
+ in custom layouts or applications.
160
+
161
+ Returns:
162
+ tuple:
163
+ (fig, ax)
164
+
165
+ fig : matplotlib.figure.Figure
166
+ The created matplotlib figure.
167
+
168
+ ax : matplotlib.axes.Axes
169
+ The axes containing the plot.
170
+ """
171
+
172
+ df = self.df_lenage
173
+ sex = self._normalize_sex()
174
+
175
+ data = df[df['Sex'] == sex]
176
+
177
+ if ax is None:
178
+ fig, ax = plt.subplots(figsize=figsize)
179
+ else:
180
+ fig = ax.figure
181
+
182
+ for i, col in enumerate(self.agecolumns[1:]):
183
+
184
+ if i in self.highlight_indices:
185
+ ax.plot(
186
+ data['Agemos'], data[col],
187
+ color='gray', linewidth=2,
188
+ label=col
189
+ )
190
+ else:
191
+ ax.plot(
192
+ data['Agemos'], data[col],
193
+ color='lightgray', linewidth=1
194
+ )
195
+
196
+ if self.length is not None:
197
+ ax.scatter(
198
+ self.age, self.length,
199
+ color='red', s=100,
200
+ zorder=5, label="Patient"
201
+ )
202
+
203
+ ax.set_title(title or "Length for Age")
204
+ ax.set_xlabel("Age (months)")
205
+ ax.set_ylabel("Length (cm)")
206
+ ax.grid(True)
207
+ ax.legend()
208
+
209
+ if show:
210
+ plt.show()
211
+
212
+ return fig, ax
213
+
214
+
215
+ def plot_bmiage(self, title=None, figsize=(12,7), show=True, ax=None):
216
+ """
217
+ Plot BMI-for-age growth chart for the child.
218
+
219
+ This method draws CDC BMI percentile curves and overlays
220
+ the patient's calculated BMI value.
221
+
222
+ The resulting figure can be modified, embedded in apps,
223
+ or saved to disk.
224
+
225
+ Args:
226
+ title (str, optional):
227
+ Custom title for the chart.
228
+
229
+ figsize (tuple, optional):
230
+ Figure size in inches (width, height).
231
+ Default is (12, 7).
232
+
233
+ show (bool, optional):
234
+ Whether to display the plot using matplotlib.
235
+ If False, the plot will not be shown.
236
+ Default is True.
237
+
238
+ ax (matplotlib.axes.Axes, optional):
239
+ Existing matplotlib Axes object for embedding
240
+ in custom layouts or applications.
241
+
242
+ Returns:
243
+ tuple:
244
+ (fig, ax)
245
+
246
+ fig : matplotlib.figure.Figure
247
+ The created matplotlib figure.
248
+
249
+ ax : matplotlib.axes.Axes
250
+ The axes containing the plot.
251
+ """
252
+
253
+ df = self.df_bmiage
254
+ sex = self._normalize_sex()
255
+
256
+ data = df[df['Sex'] == sex]
257
+
258
+ if ax is None:
259
+ fig, ax = plt.subplots(figsize=figsize)
260
+ else:
261
+ fig = ax.figure
262
+
263
+ for i, col in enumerate(self.agecolumns[1:]):
264
+
265
+ if i in self.highlight_indices:
266
+ ax.plot(
267
+ data['Agemos'], data[col],
268
+ color='gray', linewidth=2,
269
+ label=col
270
+ )
271
+ else:
272
+ ax.plot(
273
+ data['Agemos'], data[col],
274
+ color='lightgray', linewidth=1
275
+ )
276
+
277
+ if self.wt and self.length and self.length > 0:
278
+ ax.scatter(
279
+ self.age, self.bmi,
280
+ color='red', s=100,
281
+ zorder=5, label="Patient"
282
+ )
283
+
284
+ ax.set_title(title or "BMI for Age")
285
+ ax.set_xlabel("Age (months)")
286
+ ax.set_ylabel("BMI")
287
+ ax.grid(True)
288
+ ax.legend()
289
+
290
+ if show:
291
+ plt.show()
292
+
293
+ return fig, ax
294
+
295
+
296
+ def analyze_wtage(self, return_json=False):
297
+ """
298
+ Analyze weight-for-age using LMS method.
299
+
300
+ Args:
301
+ return_json (bool): If True, returns a JSON string. Default False.
302
+
303
+ Returns:
304
+ dict or JSON: Z-score, percentile, and interpretation.
305
+ """
306
+ df = self.df_wtage
307
+ sex = self._normalize_sex()
308
+ df2 = df[df['Sex'] == sex]
309
+
310
+ row = df2.iloc[(df2['Agemos'] - self.age).abs().argsort()[:1]]
311
+ L, M, S = float(row['L'].values[0]), float(row['M'].values[0]), float(row['S'].values[0])
312
+
313
+ if L != 0:
314
+ z = ((self.wt / M) ** L - 1) / (L * S)
315
+ else:
316
+ z = math.log(self.wt / M) / S
317
+
318
+ percentile = norm.cdf(z) * 100
319
+
320
+ result = {
321
+ "indicator": "Weight-for-Age",
322
+ "value": round(self.wt, 2),
323
+ "unit": None,
324
+ "Age_Months": round(self.age, 2),
325
+ "sex": "Male" if sex == "1" else "Female",
326
+
327
+ "z_score": round(z, 2),
328
+ "percentile": round(percentile, 1),
329
+
330
+ "z_interpretation": self._interpret_z(z),
331
+ "percentile_interpretation": self._interpret_percentile(percentile)
332
+ }
333
+
334
+ if return_json:
335
+ import json
336
+ return json.dumps(result)
337
+
338
+ return result
339
+
340
+
341
+ def analyze_lenage(self, return_json=False):
342
+ """
343
+ Analyze length-for-age using LMS method.
344
+
345
+ Args:
346
+ return_json (bool): If True, returns a JSON string. Default False.
347
+
348
+ Returns:
349
+ dict or JSON: Z-score, percentile, and interpretation.
350
+ """
351
+ df = self.df_lenage
352
+ sex = self._normalize_sex()
353
+ df2 = df[df['Sex'] == sex]
354
+
355
+ row = df2.iloc[(df2['Agemos'] - self.age).abs().argsort()[:1]]
356
+ L, M, S = float(row['L'].values[0]), float(row['M'].values[0]), float(row['S'].values[0])
357
+
358
+ if L != 0:
359
+ z = ((self.length / M) ** L - 1) / (L * S)
360
+ else:
361
+ z = math.log(self.length / M) / S
362
+
363
+ percentile = norm.cdf(z) * 100
364
+
365
+ result = {
366
+ "indicator": "Length-for-Age",
367
+ "value": round(self.length, 2),
368
+ "unit": None,
369
+ "Age_Months": round(self.age, 2),
370
+ "sex": "Male" if sex == "1" else "Female",
371
+
372
+ "z_score": round(z, 2),
373
+ "percentile": round(percentile, 1),
374
+
375
+ "z_interpretation": self._interpret_z(z),
376
+ "percentile_interpretation": self._interpret_percentile(percentile)
377
+ }
378
+
379
+ if return_json:
380
+ import json
381
+ return json.dumps(result)
382
+
383
+ return result
384
+
385
+
386
+ def analyze_bmiage(self, return_json=False):
387
+ """
388
+ Analyze BMI-for-age using LMS method.
389
+
390
+ Args:
391
+ return_json (bool): If True, returns a JSON string. Default False.
392
+
393
+ Returns:
394
+ dict or JSON: Z-score, percentile, and interpretation.
395
+ """
396
+ df = self.df_bmiage
397
+ sex = self._normalize_sex()
398
+ df2 = df[df['Sex'] == sex]
399
+
400
+ row = df2.iloc[(df2['Agemos'] - self.age).abs().argsort()[:1]]
401
+ L, M, S = float(row['L'].values[0]), float(row['M'].values[0]), float(row['S'].values[0])
402
+
403
+ if L != 0:
404
+ z = ((self.bmi / M) ** L - 1) / (L * S)
405
+ else:
406
+ z = math.log(self.bmi / M) / S
407
+
408
+ percentile = norm.cdf(z) * 100
409
+
410
+ result = {
411
+ "indicator": "BMI-for-Age",
412
+ "value": round(self.bmi, 2),
413
+ "unit": None,
414
+ "Age_Months": round(self.age, 2),
415
+ "sex": "Male" if sex == "1" else "Female",
416
+
417
+ "z_score": round(z, 2),
418
+ "percentile": round(percentile, 1),
419
+
420
+ "z_interpretation": self._interpret_z(z),
421
+ "percentile_interpretation": self._interpret_percentile(percentile)
422
+ }
423
+
424
+ if return_json:
425
+ import json
426
+ return json.dumps(result)
427
+
428
+ return result
429
+