import 'package:fis_measure/configs/cardiac.dart'; import 'package:fis_measure/configs/patient.dart'; import 'package:fis_measure/interfaces/enums/calcuator.dart'; import 'package:fis_measure/interfaces/enums/species.dart'; import 'package:fis_measure/interfaces/process/calculators/values.dart'; import 'package:fis_measure/interfaces/process/items/terms.dart'; import 'package:fis_measure/process/items/top_item.dart'; import 'package:fis_measure/process/primitives/combos/lv_study.dart'; import 'package:fis_measure/process/primitives/straightline.dart'; import 'package:flutter/foundation.dart'; import 'package:vid/us/vid_us_unit.dart'; import 'calculator.dart'; import 'formulas/cardiac.dart'; class LvStudySimpleCal extends LvStudyCalculatorBase { late final StraightLine kidLVIDd; late final StraightLine kidLVIDs; LvStudySimpleCal(super.ref) { kidLVIDd = ref.findChildByName("L1") as StraightLine; kidLVIDs = ref.findChildByName("L2") as StraightLine; } @override void calculate() { if (ref.feature == null) return; final feature = ref.feature!; restoreVals(); v.lvidd = pickChildFloatValue(kidLVIDd); v.lvids = pickChildFloatValue(kidLVIDs); for (var output in ref.meta.outputs) { switch (output.name) { case MeasureTerms.LvStudySimple: feature.updateStringValue(output, ""); break; case MeasureTerms.LVEDV: updateLVEDV(); break; case MeasureTerms.LVESV: updateLVESV(); break; case MeasureTerms.SV: updateSV(); break; case MeasureTerms.EF: updateEF(); break; case MeasureTerms.FS: updatePercentFS(); break; } } } } class LvStudyDistanceGroupCal extends LvStudyCalculatorBase { late final StraightLine kidIVSd; late final StraightLine kidLVIDd; late final StraightLine kidLVPWd; late final StraightLine kidIVSs; late final StraightLine kidLVIDs; late final StraightLine kidLVPWs; LvStudyDistanceGroupCal(super.ref) { kidIVSd = ref.findChildByName(MeasureTerms.IVSd) as StraightLine; kidLVIDd = ref.findChildByName(MeasureTerms.LVIDd) as StraightLine; kidLVPWd = ref.findChildByName(MeasureTerms.LVPWd) as StraightLine; kidIVSs = ref.findChildByName(MeasureTerms.IVSs) as StraightLine; kidLVIDs = ref.findChildByName(MeasureTerms.LVIDs) as StraightLine; kidLVPWs = ref.findChildByName(MeasureTerms.LVPWs) as StraightLine; } @override void calculate() { if (ref.feature == null) return; final feature = ref.feature!; final viewport = feature.hostVisualArea!.viewport!; VidUsUnit yUnit = viewport.yUnit; v = _ValTemp(); FloatValue? ivsd = pickChildToFloatValue(kidIVSd); FloatValue? lvidd = pickChildToFloatValue(kidLVIDd); FloatValue? lvpwd = pickChildToFloatValue(kidLVPWd); FloatValue? ivss = pickChildToFloatValue(kidIVSs); FloatValue? lvids = pickChildToFloatValue(kidLVIDs); FloatValue? lvpws = pickChildToFloatValue(kidLVPWs); v.ivsd = updateCalculateValue(ivsd, yUnit); v.ivss = updateCalculateValue(ivss, yUnit); v.lvidd = updateCalculateValue(lvidd, yUnit); v.lvids = updateCalculateValue(lvids, yUnit); v.lvpwd = updateCalculateValue(lvpwd, yUnit); v.lvpws = updateCalculateValue(lvpws, yUnit); for (var output in ref.meta.outputs) { switch (output.name) { case MeasureTerms.LvStudy: feature.updateStringValue(output, ""); break; case MeasureTerms.LVEDV: updateLVEDV(); break; case MeasureTerms.LVESV: updateLVESV(); break; case MeasureTerms.LVdMass: updateLVdMass(); break; case MeasureTerms.PercentIVS: updatePercentIVS(); break; case MeasureTerms.SV: updateSV(); break; case MeasureTerms.EF: updateEF(); break; case MeasureTerms.FS: updatePercentFS(); break; case MeasureTerms.PercentLVPW: updatePercentLVPW(); break; case MeasureTerms.CO: updateCO(); break; case MeasureTerms.CI: updateCI(); break; case MeasureTerms.SI: updateSI(); break; } } } double? updateCalculateValue(FloatValue? floatValue, VidUsUnit unit) { if (floatValue != null) { if (floatValue.unit == unit) { return floatValue.value; } else { if (floatValue.unit == VidUsUnit.mm && floatValue.unit == VidUsUnit.cm) { return floatValue.value == null ? null : floatValue.value! * 10; } else if (floatValue.unit == VidUsUnit.cm && floatValue.unit == VidUsUnit.mm) { return floatValue.value == null ? null : floatValue.value! / 10; } } } return null; } } class LvStudyCalculatorBase extends Calculator { LvStudyCalculatorBase(super.ref); @protected late _ValTemp v; @override void calculate() { // TODO: implement calculate } void restoreVals() { v = _ValTemp(); } @protected void updateLVEDV() { if (v.lvidd == null) { return; } final lvidd = v.lvidd!; double value = 0; if (GlobalCardiacConfigs.EDVFormulaMode == CardiacEDVFormulaMode.teichholz) { value = CardiacFormulas.edvTeichholz(lvidd); } else if (GlobalCardiacConfigs.EDVFormulaMode == CardiacEDVFormulaMode.cube) { value = CardiacFormulas.edvCube(lvidd); } updateFloatValueByName(MeasureTerms.LVEDV, value, unit: VidUsUnit.ml); v.lvedv = value; } @protected void updateLVESV() { if (v.lvids == null) { return; } final lvids = v.lvids!; double value = 0; if (GlobalCardiacConfigs.EDVFormulaMode == CardiacEDVFormulaMode.teichholz) { value = CardiacFormulas.esvTeichholz(lvids); } else if (GlobalCardiacConfigs.EDVFormulaMode == CardiacEDVFormulaMode.cube) { value = CardiacFormulas.esvCube(lvids); } updateFloatValueByName(MeasureTerms.LVESV, value, unit: VidUsUnit.ml); v.lvesv = value; } @protected void updateLVdMass() { if (v.ivsd == null || v.lvidd == null || v.lvpwd == null) { return; } double value = CardiacFormulas.lvdMass(v.ivsd!, v.lvidd!, v.lvpwd!); updateFloatValueByName(MeasureTerms.LVdMass, value, unit: VidUsUnit.g); } @protected void updatePercentIVS() { if (v.ivsd == null || v.ivss == null) { return; } double value = CardiacFormulas.ivsPercent(v.ivss!, v.ivsd!); updateFloatValueByName(MeasureTerms.PercentIVS, value); } @protected void updateSV() { if (v.lvedv == null || v.lvesv == null) { return; } final edv = v.lvedv!; final esv = v.lvesv!; double value = CardiacFormulas.sv(edv, esv); updateFloatValueByName(MeasureTerms.SV, value, unit: VidUsUnit.ml); v.sv = value; } @protected void updateEF() { if (v.lvedv == null || v.lvesv == null) { return; } final edv = v.lvedv!; final esv = v.lvesv!; double value = CardiacFormulas.ef(edv, esv); updateFloatValueByName(MeasureTerms.EF, value, unit: VidUsUnit.percent); } @protected void updatePercentFS() { if (v.lvidd == null || v.lvids == null) { return; } final lvidd = v.lvidd!; final lvids = v.lvids!; double value = CardiacFormulas.fsPercent(lvidd, lvids); updateFloatValueByName(MeasureTerms.FS, value); } @protected void updatePercentLVPW() { if (v.lvpws == null || v.lvpwd == null) { return; } final lvpws = v.lvpws!; final lvpwd = v.lvpwd!; double value = CardiacFormulas.lvpwPercent(lvpws, lvpwd); updateFloatValueByName(MeasureTerms.PercentLVPW, value); } @protected void updateCO() { if (v.sv == null || v.hr == null) { return; } double value = CardiacFormulas.co(v.sv!, hr: v.hr!); updateFloatValueByName(MeasureTerms.CO, value, unit: VidUsUnit.Lmin); } @protected void updateCI() { if (v.sv == null || v.hr == null) { return; } if (GlobalPatientConfig.bsa == 0) { return; } double value = CardiacFormulas.ci( v.sv!, hr: v.hr!, bsa: GlobalPatientConfig.bsa, ); updateFloatValueByName(MeasureTerms.CI, value, unit: VidUsUnit.Lminm2); } @protected void updateLVEDVI() { if (v.lvedv == null) { return; } if (GlobalPatientConfig.bsa == 0) { return; } final value = CardiacFormulas.lvevi(v.lvedv!, GlobalPatientConfig.bsa); updateFloatValueByName(MeasureTerms.LVEDVI, value, unit: VidUsUnit.mlm2); } @protected void updateLVESVI() { if (v.lvesv == null) { return; } if (GlobalPatientConfig.bsa == 0) { return; } final value = CardiacFormulas.lvevi(v.lvesv!, GlobalPatientConfig.bsa); updateFloatValueByName(MeasureTerms.LVESVI, value, unit: VidUsUnit.mlm2); } @protected void updateSI() { if (v.sv == null) { return; } if (GlobalPatientConfig.bsa == 0) { return; } double value = CardiacFormulas.si(v.sv!, GlobalPatientConfig.bsa); updateFloatValueByName(MeasureTerms.SI, value, unit: VidUsUnit.mlm2); } @protected void updateFloatValueByName( String name, double value, { VidUsUnit? unit, }) { ref.measuredFeatures; final feature = ref.feature!; final outputMeta = ref.meta.outputs.firstWhere((x) => x.name == name); outputMeta.unit = updateUnitBySpeciesType(unit ?? outputMeta.unit, name); feature.updateFloatValue(outputMeta, value, outputMeta.unit); } VidUsUnit updateUnitBySpeciesType(VidUsUnit unit, String name) { if (GlobalPatientConfig.speciesType != SpeciesType.mouse) { return unit; } switch (name) { case MeasureTerms.LVEDV: return VidUsUnit.mil; case MeasureTerms.LVESV: return VidUsUnit.mil; case MeasureTerms.LVEDVI: return VidUsUnit.mil; case MeasureTerms.LVESVI: return VidUsUnit.mil; case MeasureTerms.SI: return VidUsUnit.mlm2; case MeasureTerms.CO: return VidUsUnit.mlmin; case MeasureTerms.CI: return VidUsUnit.mlmincm2; case MeasureTerms.LVdMass: return VidUsUnit.mg; case MeasureTerms.FS: return VidUsUnit.percent; case MeasureTerms.EF: return VidUsUnit.percent; case MeasureTerms.PercentLVPW: return VidUsUnit.percent; case MeasureTerms.SV: return VidUsUnit.mil; case MeasureTerms.SV_Card: return VidUsUnit.mlmin; case MeasureTerms.SV_Diam: return VidUsUnit.cm; case MeasureTerms.SV_Trace: return VidUsUnit.cm; case MeasureTerms.IVSd: return VidUsUnit.mm; case MeasureTerms.LVIDd: return VidUsUnit.mm; case MeasureTerms.LVPWd: return VidUsUnit.mm; case MeasureTerms.IVSs: return VidUsUnit.mg; case MeasureTerms.LVIDs: return VidUsUnit.mm; case MeasureTerms.LVPWs: return VidUsUnit.mm; case MeasureTerms.CO_2D: return VidUsUnit.mlmin; case MeasureTerms.CO_M: // 脉动心输出量 return VidUsUnit.mlmin; case MeasureTerms.CO_P: // 脉动心输出量 return VidUsUnit.mlmin; default: return unit; } } } class _ValTemp { double? ivsd; double? lvidd; double? lvpwd; double? ivss; double? lvids; double? lvpws; double? lvedv; double? lvesv; double? sv; int? hr = GlobalPatientConfig.hr; // TODO: from vid ext }