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'; import 'unit_formulas/index.dart'; class LvStudySimpleCal extends LvStudyCalculatorBase<LvStudy> { 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(); uv.lvidd = pickChildToFloatValue(kidLVIDd)?.toUnitFloatValue(); uv.lvids = pickChildToFloatValue(kidLVIDs)?.toUnitFloatValue(); 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; case MeasureTerms.LVIDdIndex: updateLVIDdIndex(); break; case MeasureTerms.LVIDsIndex: updateLVIDsIndex(); break; case MeasureTerms.LVIDdN: updateLVIDdN(); break; case MeasureTerms.LVIDsN: updateLVIDsN(); break; } } } } class LvStudyDistanceGroupCal extends LvStudyCalculatorBase<LvStudy> { 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; restoreVals(); FloatValue? ivsd = pickChildToFloatValue(kidIVSd); FloatValue? lvidd = pickChildToFloatValue(kidLVIDd); FloatValue? lvpwd = pickChildToFloatValue(kidLVPWd); FloatValue? ivss = pickChildToFloatValue(kidIVSs); FloatValue? lvids = pickChildToFloatValue(kidLVIDs); FloatValue? lvpws = pickChildToFloatValue(kidLVPWs); uv.ivsd = ivsd?.toUnitFloatValue(); uv.ivss = ivss?.toUnitFloatValue(); uv.lvidd = lvidd?.toUnitFloatValue(); uv.lvids = lvids?.toUnitFloatValue(); uv.lvpwd = lvpwd?.toUnitFloatValue(); uv.lvpws = lvpws?.toUnitFloatValue(); 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; case MeasureTerms.LVIDdIndex: updateLVIDdIndex(); break; case MeasureTerms.LVIDsIndex: updateLVIDsIndex(); break; case MeasureTerms.LVIDdN: updateLVIDdN(); break; case MeasureTerms.LVIDsN: updateLVIDsN(); 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<T extends TopMeasureItem> extends Calculator<T, double> { LvStudyCalculatorBase(super.ref); @protected late _ValTemp v; @protected late _UnitValTemp uv; @override void calculate() { // TODO: implement calculate } void restoreVals() { v = _ValTemp(); uv = _UnitValTemp(); } @protected void updateLVEDV() { if (uv.lvidd == null) { return; } UnitFloatValue? unitValue; if (GlobalCardiacConfigs.EDVFormulaMode == CardiacEDVFormulaMode.teichholz) { unitValue = UnitFormulas.cardiac.edvTech(uv.lvidd!); } else if (GlobalCardiacConfigs.EDVFormulaMode == CardiacEDVFormulaMode.cube) { unitValue = UnitFormulas.cardiac.edvCube(uv.lvidd!); } if (unitValue != null) { updateFloatValueByName( MeasureTerms.LVEDV, unitValue.value, unit: unitValue.unit, ); } uv.lvedv = unitValue; } @protected void updateLVESV() { if (uv.lvids == null) { return; } double value = 0; UnitFloatValue? unitValue; if (GlobalCardiacConfigs.EDVFormulaMode == CardiacEDVFormulaMode.teichholz) { unitValue = UnitFormulas.cardiac.edvTech(uv.lvids!); } else if (GlobalCardiacConfigs.EDVFormulaMode == CardiacEDVFormulaMode.cube) { unitValue = UnitFormulas.cardiac.esvCube(uv.lvids!); } updateFloatValueByName(MeasureTerms.LVESV, value, unit: VidUsUnit.ml); if (unitValue != null) { updateFloatValueByName( MeasureTerms.LVESV, unitValue.value, unit: unitValue.unit, ); } uv.lvesv = unitValue; } @protected void updateLVdMass() { if (uv.ivsd == null || uv.lvidd == null || uv.lvpwd == null) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.lvdMass(uv.ivsd!, uv.ivsd!, uv.lvpwd!); updateFloatValueByName( MeasureTerms.LVdMass, unitValue.value, unit: unitValue.unit, ); } @protected void updatePercentIVS() { if (uv.ivsd == null || uv.ivss == null) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.ivsPercent(uv.ivss!, uv.ivsd!); updateFloatValueByName( MeasureTerms.PercentIVS, unitValue.value, unit: unitValue.unit, ); } @protected void updateSV() { if (uv.lvedv == null || uv.lvesv == null) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.sv(uv.lvedv!, uv.lvesv!); updateFloatValueByName( MeasureTerms.SV, unitValue.value, unit: unitValue.unit, ); uv.sv = unitValue; } @protected void updateEF() { if (uv.lvedv == null || uv.lvesv == null) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.ef(uv.lvedv!, uv.lvesv!); updateFloatValueByName( MeasureTerms.EF, unitValue.value, unit: VidUsUnit.percent, ); } @protected void updatePercentFS() { if (uv.lvidd == null || uv.lvids == null) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.ef(uv.lvedv!, uv.lvesv!); updateFloatValueByName( MeasureTerms.EF, unitValue.value, unit: VidUsUnit.percent, ); } @protected void updatePercentLVPW() { if (uv.lvpws == null || uv.lvpwd == null) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.lvpwPercent(uv.lvpws!, uv.lvpwd!); updateFloatValueByName( MeasureTerms.PercentLVPW, unitValue.value, unit: unitValue.unit, ); } @protected void updateCO() { if (uv.sv == null || uv.hr == null) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.co(uv.sv!, hr: uv.hr!); updateFloatValueByName( MeasureTerms.CO, unitValue.value, unit: unitValue.unit, ); } @protected void updateCI() { if (uv.sv == null || uv.hr == null) { return; } if (GlobalPatientConfig.bsa == 0) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac .ci(uv.sv!, hr: uv.hr!, bsa: GlobalPatientConfig.bsa); updateFloatValueByName( MeasureTerms.CI, unitValue.value, unit: unitValue.unit, ); } @protected void updateLVEDVI() { if (uv.lvedv == null) { return; } if (GlobalPatientConfig.bsa == 0) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.lvevi(uv.lvedv!, bsa: GlobalPatientConfig.bsa); updateFloatValueByName( MeasureTerms.LVEDVI, unitValue.value, unit: unitValue.unit, ); } @protected void updateLVESVI() { if (uv.lvesv == null) { return; } if (GlobalPatientConfig.bsa == 0) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.lvevi(uv.lvesv!, bsa: GlobalPatientConfig.bsa); updateFloatValueByName( MeasureTerms.LVESVI, unitValue.value, unit: unitValue.unit, ); } @protected void updateSI() { if (uv.sv == null) { return; } if (GlobalPatientConfig.bsa == 0) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.si(uv.sv!, bsa: GlobalPatientConfig.bsa); updateFloatValueByName( MeasureTerms.SI, unitValue.value, unit: unitValue.unit, ); } @protected void updateLVIDdIndex() { if (uv.lvidd == null) { return; } if (GlobalPatientConfig.bsa == 0) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.lvidIndex(uv.lvidd!, bsa: GlobalPatientConfig.bsa); updateFloatValueByName( MeasureTerms.LVIDdIndex, unitValue.value, unit: unitValue.unit, ); } @protected void updateLVIDsIndex() { if (uv.lvids == null) { return; } if (GlobalPatientConfig.bsa == 0) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.lvidIndex(uv.lvids!, bsa: GlobalPatientConfig.bsa); updateFloatValueByName( MeasureTerms.LVIDsIndex, unitValue.value, unit: unitValue.unit, ); } @protected void updateLVIDdN() { if (uv.lvidd == null) { return; } if (GlobalPatientConfig.weight == 0) { return; } UnitFloatValue unitValue = UnitFormulas.cardiac.lvidIndex(uv.lvidd!, bsa: GlobalPatientConfig.bsa); updateFloatValueByName( MeasureTerms.LVIDdN, unitValue.value, unit: unitValue.unit, ); } @protected void updateLVIDsN() { if (uv.lvids == null) { return; } if (GlobalPatientConfig.weight == 0) { return; } var unitWeightValue = UnitFloatValue(GlobalPatientConfig.weight, VidUsUnit.kg); UnitFloatValue unitValue = UnitFormulas.cardiac.lvidN(uv.lvids!, unitWeightValue); updateFloatValueByName( MeasureTerms.LVIDsN, unitValue.value, unit: unitValue.unit, ); } @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); feature.updateFloatValue(outputMeta, value, unit ?? 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 } class _UnitValTemp { UnitFloatValue? ivsd; UnitFloatValue? lvidd; UnitFloatValue? lvpwd; UnitFloatValue? ivss; UnitFloatValue? lvids; UnitFloatValue? lvpws; UnitFloatValue? lvedv; UnitFloatValue? lvesv; UnitFloatValue? sv; int? hr = GlobalPatientConfig.hr; // TODO: from vid ext }