import 'package:fis_measure/interfaces/date_types/vector.dart'; import 'package:fis_measure/interfaces/process/calculators/values.dart'; import 'package:fis_measure/interfaces/process/items/terms.dart'; import 'package:fis_measure/process/calcuators/formulas/cardiac.dart'; import 'package:fis_measure/process/calcuators/formulas/urology.dart'; import 'package:fis_measure/process/primitives/combos/two_straightline.dart'; import 'package:fis_measure/process/primitives/straightline.dart'; import 'package:vid/us/vid_us_unit.dart'; import 'calculator.dart'; import 'formulas/general.dart'; class TwoDistanceCalBase extends Calculator { TwoDistanceCalBase(TwoStraightLine ref) : super(ref); @override void calculate() { // TODO: implement calculate } } class ResidualUrineCal extends Calculator { ResidualUrineCal(TwoStraightLine ref) : super(ref); @override void calculate() { if (ref.feature == null) return; final x = _pickChildValue(ref.x); final y = _pickChildValue(ref.y); final feature = ref.feature!; final viewport = feature.hostVisualArea!.viewport!; if (x != null && y != null) { final value = UrologyFormulas.calcRUV( x, y, ); updateFloatValue(value); } } double? _pickChildValue(StraightLine item) { if (item.calculator == null) return null; ValueBase? value; if (item.measuredFeatures.isNotEmpty) { value = item.measuredFeatures.first.value; } else if (item.feature != null) { value = item.feature!.value; } if (value != null) { return (value as FloatValue).value ?? 0; } return null; } } class TwoDistanceVolumeCal extends Calculator { TwoDistanceVolumeCal(TwoStraightLine ref) : super(ref); @override void calculate() { if (ref.feature == null) return; final f1 = findChildFeature(ref.child1); final f2 = findChildFeature(ref.child2); if (f1 == null || f2 == null) return; final feature = ref.feature!; final val1 = f1.value?.pickFloat() ?? 0; final val2 = f2.value?.pickFloat() ?? 0; final unitY = f1.hostVisualArea!.viewport!.yUnit; for (var ouput in ref.meta.outputs) { if (ouput.name == MeasureTerms.Volume) { var volume = GeneralFormulas.volumeTwoLine(val1, val2); final unit = unitY == VidUsUnit.cm ? VidUsUnit.cm3 : VidUsUnit.None; feature.updateFloatValue( ouput, roundDouble(volume, ouput.fractionalDigits), unit, ); } else if (ouput.name == MeasureTerms.AvgDistance) { double avg = (val1 + val2) / 2; feature.updateFloatValue( ouput, roundDouble(avg, ouput.fractionalDigits), unitY, ); } } } } class TwoDistanceSumCal extends Calculator { TwoDistanceSumCal(TwoStraightLine ref) : super(ref); @override void calculate() { if (ref.feature == null) return; final f1 = findChildFeature(ref.child1); final f2 = findChildFeature(ref.child2); if (f1 == null || f2 == null) return; final feature = ref.feature!; final val1 = f1.value?.pickFloat() ?? 0; final val2 = f2.value?.pickFloat() ?? 0; var unitY = f1.hostVisualArea!.viewport!.yUnit; if (unitY == VidUsUnit.None) { if (f1.value != null) { unitY = f1.value!.unit; } } for (var ouput in ref.meta.outputs) { if (ouput.name == MeasureTerms.Distance) { var dis = val1 + val2; feature.updateFloatValue( ouput, roundDouble(dis, ouput.fractionalDigits), unitY, ); } else if (ouput.name == MeasureTerms.AvgDistance) { double avg = (val1 + val2) / 2; feature.updateFloatValue( ouput, roundDouble(avg, ouput.fractionalDigits), unitY, ); } } } } class TwoStraightLineAngleCal extends Calculator { TwoStraightLineAngleCal(TwoStraightLine ref) : super(ref); @override void calculate() { if (ref.feature == null) return; final f1 = findChildFeature(ref.child1); final f2 = findChildFeature(ref.child2); if (f1 == null || f2 == null) return; if (f1.innerPoints.length == f2.innerPoints.length) { var l1 = f1.innerPoints[0] - f1.innerPoints[1]; var l2 = f2.innerPoints[0] - f2.innerPoints[1]; var value = (DVector.angleBetween(l1, l2)).abs(); updateFloatValue(value, unit: VidUsUnit.degree, useRound: true); } } } class IvsThckCal extends Calculator { IvsThckCal(TwoStraightLine ref) : super(ref); @override void calculate() { if (ref.feature == null) return; final len1 = pickChildFloatValue(ref.child1) ?? 0; final len2 = pickChildFloatValue(ref.child2) ?? 0; final ivs = calcIvs(len1, len2); updateFloatValue(ivs, unit: VidUsUnit.percent, useRound: true); } static double calcIvs(double ivsd, double ivss) { if (ivsd == 0) { return 0; } return (ivss - ivsd) / ivsd * 100; } } abstract class EFCal extends Calculator { EFCal(TwoStraightLine twoStraightLine) : super(twoStraightLine); @override void calculate() { if (ref.feature == null) return; double lvidd = pickChildFloatValue(ref.child1) ?? 0; double lvids = pickChildFloatValue(ref.child2) ?? 0; List edvAndEsv = onCalculateEdvEsv(lvidd, lvids); assert(edvAndEsv.length == 2, 'edvAndEsv.length == 2'); double edv = edvAndEsv[0]; double esv = edvAndEsv[1]; double ef = CardiacFormulas.ef(edv, esv); updateFloatValue(ef, unit: VidUsUnit.percent, useRound: true); } List onCalculateEdvEsv(double lvidd, double lvids); } class EfTeichCal extends EFCal { EfTeichCal(TwoStraightLine ref) : super(ref); @override List onCalculateEdvEsv(double lvidd, double lvids) { double edv = CardiacFormulas.edvTeichholz(lvidd); double esv = CardiacFormulas.edvTeichholz(lvids); return [edv, esv]; } }