pediatric-ai-scribe-v3/public/js/calculators/growth.js
2026-05-08 04:05:51 +02:00

48 lines
1.7 KiB
JavaScript

var growthCache = null;
export function loadGrowthLmsData() {
if (growthCache) return Promise.resolve(growthCache);
return fetch('/data/calculators/growth-lms.json', { credentials: 'same-origin' })
.then(function(response) {
if (!response.ok) throw new Error('Failed to load growth LMS data');
return response.json();
})
.then(function(data) {
growthCache = data.lms || {};
return growthCache;
});
}
export function interpolateLMS(lmsTable, val) {
var keys = Object.keys(lmsTable).map(Number).sort(function(a,b){return a-b;});
if (val <= keys[0]) return lmsTable[keys[0]];
if (val >= keys[keys.length-1]) return lmsTable[keys[keys.length-1]];
for (var i = 0; i < keys.length - 1; i++) {
if (val >= keys[i] && val <= keys[i+1]) {
var t = (val - keys[i]) / (keys[i+1] - keys[i]);
var a = lmsTable[keys[i]], b = lmsTable[keys[i+1]];
return { L: a.L + t*(b.L-a.L), M: a.M + t*(b.M-a.M), S: a.S + t*(b.S-a.S) };
}
}
return lmsTable[keys[0]];
}
export function normalCDF(z) {
var a1=0.254829592, a2=-0.284496736, a3=1.421413741, a4=-1.453152027, a5=1.061405429, p=0.3275911;
var sign = z < 0 ? -1 : 1;
z = Math.abs(z) / Math.sqrt(2);
var t = 1 / (1 + p * z);
var y = 1 - (((((a5*t+a4)*t)+a3)*t+a2)*t+a1)*t*Math.exp(-z*z);
return 0.5 * (1 + sign * y);
}
export function calcZFromLMS(value, L, M, S) {
if (Math.abs(L) < 0.001) return Math.log(value / M) / S;
return (Math.pow(value / M, L) - 1) / (L * S);
}
export function calculateLmsPercentile(lmsTable, x, value) {
var lms = interpolateLMS(lmsTable, x);
var z = calcZFromLMS(value, lms.L, lms.M, lms.S);
return { lms: lms, z: z, percentile: normalCDF(z) * 100 };
}