mirror of
https://github.com/gauvainboiche/ketapk.git
synced 2026-09-02 11:13:11 +02:00
refacto: Exporting is now in CSV the values + auto gestion of perfusion
This commit is contained in:
+67
-13
@@ -68,6 +68,31 @@ export const CLINICAL_THRESHOLDS = {
|
||||
}
|
||||
};
|
||||
|
||||
// Unités de perfusion supportées
|
||||
export const INFUSION_UNITS = {
|
||||
MG_KG_H: 'mg_kg_h', // mg/kg/h
|
||||
MCG_KG_MIN: 'mcg_kg_min',// µg/kg/min
|
||||
MG_H: 'mg_h' // mg/h
|
||||
};
|
||||
|
||||
/**
|
||||
* Calcule la dose en mg administrée sur un intervalle de 5 minutes
|
||||
*/
|
||||
export function calculate5MinInfusionDose(rate, unit, weight) {
|
||||
if (!rate || rate <= 0) return 0;
|
||||
|
||||
switch (unit) {
|
||||
case INFUSION_UNITS.MG_KG_H:
|
||||
return (rate * weight) / 12;
|
||||
case INFUSION_UNITS.MCG_KG_MIN:
|
||||
return (rate * weight * 5) / 1000;
|
||||
case INFUSION_UNITS.MG_H:
|
||||
return rate / 12;
|
||||
default:
|
||||
return (rate * weight) / 12;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcul d'un bolus unique à l'instant t
|
||||
*/
|
||||
@@ -85,30 +110,59 @@ export function calculateBolusCp(model, doseMg, weightKg, timeElapsedMin) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Superposition Linéaire des Bolus et Perfusions sur 300 min
|
||||
* Propage la perfusion active sur la timeline (pas de 5 min)
|
||||
* Indique si chaque pas de temps possède une consigne explicite (isExplicit) ou héritée.
|
||||
*/
|
||||
export function generateSimulationData({ model, weightKg, timelineInputs }) {
|
||||
const timeGrid = Array.from({ length: 61 }, (_, i) => i * 5);
|
||||
const cpResults = new Array(61).fill(0);
|
||||
export function processTimelineEvents(timelineInputs, weightKg, infusionUnit) {
|
||||
let currentRate = 0;
|
||||
|
||||
timeGrid.forEach((targetTime, targetIndex) => {
|
||||
return timelineInputs.map((item) => {
|
||||
const isExplicit = item.perfRate !== undefined && item.perfRate !== null && item.perfRate !== '';
|
||||
if (isExplicit) {
|
||||
const parsed = parseFloat(item.perfRate);
|
||||
currentRate = isNaN(parsed) ? 0 : parsed;
|
||||
}
|
||||
|
||||
const bolusMg = parseFloat(item.bolusMg) || 0;
|
||||
const infusionMg5Min = calculate5MinInfusionDose(currentRate, infusionUnit, weightKg);
|
||||
|
||||
return {
|
||||
time: item.time,
|
||||
bolusMg: bolusMg,
|
||||
infusionRate: currentRate,
|
||||
isExplicit: isExplicit,
|
||||
infusionMg5Min: infusionMg5Min
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Superposition Linéaire des Bolus et Perfusions sur 300 min (ng/mL arrondis à l'entier)
|
||||
*/
|
||||
export function generateSimulationData({ model, weightKg, timelineInputs, infusionUnit = INFUSION_UNITS.MG_KG_H }) {
|
||||
const processedTimeline = processTimelineEvents(timelineInputs, weightKg, infusionUnit);
|
||||
const cpResults = [];
|
||||
|
||||
processedTimeline.forEach((targetEvent, targetIndex) => {
|
||||
let totalCp = 0;
|
||||
|
||||
for (let i = 0; i <= targetIndex; i++) {
|
||||
const deltaTime = targetTime - timeGrid[i];
|
||||
const input = timelineInputs[i] || { bolusMg: 0, perfRateMgKgH: 0 };
|
||||
const sourceEvent = processedTimeline[i];
|
||||
const deltaTime = targetEvent.time - sourceEvent.time;
|
||||
|
||||
if (input.bolusMg > 0) {
|
||||
totalCp += calculateBolusCp(model, input.bolusMg, weightKg, deltaTime);
|
||||
if (sourceEvent.bolusMg > 0) {
|
||||
totalCp += calculateBolusCp(model, sourceEvent.bolusMg, weightKg, deltaTime);
|
||||
}
|
||||
|
||||
if (input.perfRateMgKgH > 0) {
|
||||
const perfDoseMg = (input.perfRateMgKgH * weightKg) * (5 / 60);
|
||||
totalCp += calculateBolusCp(model, perfDoseMg, weightKg, deltaTime);
|
||||
if (sourceEvent.infusionMg5Min > 0) {
|
||||
totalCp += calculateBolusCp(model, sourceEvent.infusionMg5Min, weightKg, deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
cpResults[targetIndex] = Math.round(totalCp * 100) / 100;
|
||||
cpResults.push({
|
||||
time: targetEvent.time,
|
||||
cp: Math.round(totalCp)
|
||||
});
|
||||
});
|
||||
|
||||
return cpResults;
|
||||
|
||||
Reference in New Issue
Block a user