import 'package:fis_measure/configs/patient.dart'; import 'package:fis_measure/interfaces/process/items/item_metas.dart'; import 'package:fis_measure/interfaces/process/items/terms.dart'; import 'package:fis_measure/process/calcuators/trace.dart'; import 'package:fis_measure/process/items/item_feature.dart'; import 'package:fis_measure/process/primitives/combos/flow_area_vti.dart'; import 'package:fis_measure/process/primitives/combos/sv.dart'; import 'package:fis_measure/process/primitives/multi_method/multiple_trace.dart'; import 'package:vid/us/vid_us_unit.dart'; import 'calculator.dart'; import 'formulas/cardiac.dart'; import 'formulas/general.dart'; class FlowVolumeCal extends Calculator { FlowVolumeCal(super.ref); @override void calculate() { if (ref.feature == null) return; final feature = ref.feature!; final diam = pickChildFloatValue(ref.l); if (diam == null) { updateStringValue(""); return; } final flowArea = GeneralFormulas.area(diam, diam); double flowVolTAMAX = double.nan; double flowVolTAMEAN = double.nan; TraceItemFeatureAbstract? traceFeature = ref.trace.feature; if (traceFeature == null) { if (ref.trace.measuredFeatures.isNotEmpty) { traceFeature = ref.trace.measuredFeatures.first; } } if (traceFeature != null) { final countVTIResult = TraceCal.getCountVTI(traceFeature); //FlowVol by TAMAX double coefficent = parseCoefficent(traceFeature); flowVolTAMAX = calculateFlowVol(countVTIResult, flowArea, coefficent); //FlowVol by TAMEAN coefficent = 1; flowVolTAMEAN = calculateFlowVol(countVTIResult, flowArea, coefficent); } for (var output in ref.meta.outputs) { if (output.name == MeasureTerms.FlowVol) { if (flowVolTAMEAN.isNaN) { updateStringValue(""); } else { updateFloatValue(flowVolTAMEAN, unit: VidUsUnit.mls); } } else if (output.name == MeasureTerms.FlowVolTAMAX) { if (!flowVolTAMEAN.isNaN) { feature.updateFloatValue(output, flowVolTAMAX, VidUsUnit.mls); } } else if (output.name == MeasureTerms.FlowArea) { feature.updateFloatValue(output, flowArea, VidUsUnit.cm2); } } } static double parseCoefficent(MeasureItemFeature feature) { // TODO: read from meta args return 0.75; } static double calculateFlowVol( List values, double flowArea, double coefficient) { if (values.isEmpty) { return double.nan; } if (values.length < 2) { return double.nan; } final taMax = values[2]; double flowVol = GeneralFormulas.flowVolTAMAX(flowArea, taMax, coefficient); return flowVol; } } class FlowAreaByVTICal extends Calculator { FlowAreaByVTICal(super.ref); @override void calculate() { if (ref.feature == null) return; final feature = ref.feature!; final diam = pickChildFloatValue(ref.l); feature.values.clear(); updateStringValue(""); if (diam == null) { return; } final diamOutputIndex = ref.l.meta.outputs.indexWhere((e) => e.name == MeasureTerms.Diam); if (diamOutputIndex > -1) { final output = ref.l.meta.outputs[diamOutputIndex]; feature.updateFloatValue(output, diam, VidUsUnit.cm); } double va = double.nan; double dvi = double.nan; double avaIndex = double.nan; double otVti = double.nan; double vti = double.nan; double otSV = double.nan; double otCSA = double.nan; otCSA = GeneralFormulas.csa(diam); // ??? final otFeature = _findTraceOT(); final vtiFeature = _findTraceVTI(); if (otFeature != null) { final countOtVTIResult = TraceCal.getCountVTI(otFeature); otVti = countOtVTIResult[0]; } if (vtiFeature != null) { final countVTIResult = TraceCal.getCountVTI(vtiFeature); vti = countVTIResult[0]; } if (!vti.isNaN && !otVti.isNaN) { va = CardiacFormulas.flowAreaByVTI(diam, otVti, vti); dvi = CardiacFormulas.dviByVTI(otVti, vti); final bsa = GlobalPatientConfig.bsa; if (bsa > 0) { avaIndex = CardiacFormulas.avaIndex(va, bsa); } otSV = GeneralFormulas.svDiam(diam, otVti); otCSA = GeneralFormulas.csa(diam); } if (otFeature != null) { for (var output in ref.trace1.meta.outputs) { if (output.name == MeasureTerms.SV_Trace) { feature.updateStringValue( ItemOutputMeta(output.description, output.description, output.unit), '', ); } else if (output.name == MeasureTerms.VTI) { if (!otVti.isNaN) { feature.updateFloatValue( ItemOutputMeta( output.description, output.description, output.unit), otVti, VidUsUnit.cm, ); } } } } if (vtiFeature != null) { for (var output in ref.trace2.meta.outputs) { if (output.name == MeasureTerms.SV_Trace) { feature.updateStringValue( ItemOutputMeta(output.description, output.description, output.unit), '', ); } else if (output.name == MeasureTerms.VTI) { if (!vti.isNaN) { feature.updateFloatValue( ItemOutputMeta( output.description, output.description, output.unit), vti, VidUsUnit.cm, ); } } } } for (var output in ref.meta.outputs) { switch (output.name) { case MeasureTerms.FlowArea: if (!va.isNaN) { feature.updateFloatValue(output, va, VidUsUnit.cm2); } break; case MeasureTerms.AVAI: if (!avaIndex.isNaN) { feature.updateFloatValue(output, avaIndex, VidUsUnit.cm2m2); } break; case MeasureTerms.DVI: if (!dvi.isNaN) { feature.updateFloatValue(output, dvi, VidUsUnit.None); } break; case MeasureTerms.SV: if (!otSV.isNaN) { feature.updateFloatValue(output, otSV, VidUsUnit.cm3); } break; case MeasureTerms.CSA: if (!otCSA.isNaN) { feature.updateFloatValue(output, otCSA, VidUsUnit.cm2); } break; } } } TraceItemFeatureAbstract? _findTraceOT() { TraceItemFeatureAbstract? traceFeature = ref.trace1.feature; if (traceFeature == null) { if (ref.trace1.measuredFeatures.isNotEmpty) { traceFeature = ref.trace1.measuredFeatures.first; } } return traceFeature; } TraceItemFeatureAbstract? _findTraceVTI() { TraceItemFeatureAbstract? traceFeature = ref.trace2.feature; if (traceFeature == null) { if (ref.trace2.measuredFeatures.isNotEmpty) { traceFeature = ref.trace2.measuredFeatures.first; } } return traceFeature; } }