flow.dart 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import 'package:fis_measure/configs/patient.dart';
  2. import 'package:fis_measure/interfaces/process/items/item_metas.dart';
  3. import 'package:fis_measure/interfaces/process/items/terms.dart';
  4. import 'package:fis_measure/process/calcuators/trace.dart';
  5. import 'package:fis_measure/process/items/item_feature.dart';
  6. import 'package:fis_measure/process/primitives/combos/flow_area_vti.dart';
  7. import 'package:fis_measure/process/primitives/combos/sv.dart';
  8. import 'package:fis_measure/process/primitives/multi_method/multiple_trace.dart';
  9. import 'package:vid/us/vid_us_unit.dart';
  10. import 'calculator.dart';
  11. import 'formulas/cardiac.dart';
  12. import 'formulas/general.dart';
  13. class FlowVolumeCal extends Calculator<Sv, double> {
  14. FlowVolumeCal(super.ref);
  15. @override
  16. void calculate() {
  17. if (ref.feature == null) return;
  18. final feature = ref.feature!;
  19. final diam = pickChildFloatValue(ref.l);
  20. if (diam == null) {
  21. updateStringValue("");
  22. return;
  23. }
  24. final flowArea = GeneralFormulas.area(diam, diam);
  25. double flowVolTAMAX = double.nan;
  26. double flowVolTAMEAN = double.nan;
  27. TraceItemFeatureAbstract? traceFeature = ref.trace.feature;
  28. if (traceFeature == null) {
  29. if (ref.trace.measuredFeatures.isNotEmpty) {
  30. traceFeature = ref.trace.measuredFeatures.first;
  31. }
  32. }
  33. if (traceFeature != null) {
  34. final countVTIResult = TraceCal.getCountVTI(traceFeature);
  35. //FlowVol by TAMAX
  36. double coefficent = parseCoefficent(traceFeature);
  37. flowVolTAMAX = calculateFlowVol(countVTIResult, flowArea, coefficent);
  38. //FlowVol by TAMEAN
  39. coefficent = 1;
  40. flowVolTAMEAN = calculateFlowVol(countVTIResult, flowArea, coefficent);
  41. }
  42. for (var output in ref.meta.outputs) {
  43. if (output.name == MeasureTerms.FlowVol) {
  44. if (flowVolTAMEAN.isNaN) {
  45. updateStringValue("");
  46. } else {
  47. updateFloatValue(flowVolTAMEAN, unit: VidUsUnit.cm3s);
  48. }
  49. } else if (output.name == MeasureTerms.FlowVolTAMAX) {
  50. if (!flowVolTAMEAN.isNaN) {
  51. feature.updateFloatValue(output, flowVolTAMAX, VidUsUnit.cm3s);
  52. }
  53. } else if (output.name == MeasureTerms.FlowArea) {
  54. feature.updateFloatValue(output, flowArea, VidUsUnit.cm2);
  55. }
  56. }
  57. }
  58. static double parseCoefficent(MeasureItemFeature feature) {
  59. // TODO: read from meta args
  60. return 0.75;
  61. }
  62. static double calculateFlowVol(
  63. List<double> values, double flowArea, double coefficient) {
  64. if (values.isEmpty) {
  65. return double.nan;
  66. }
  67. if (values.length < 2) {
  68. return double.nan;
  69. }
  70. final taMax = values[2];
  71. double flowVol = GeneralFormulas.flowVolTAMAX(flowArea, taMax, coefficient);
  72. return flowVol;
  73. }
  74. }
  75. class FlowAreaByVTICal extends Calculator<FlowAreaByVti, double> {
  76. FlowAreaByVTICal(super.ref);
  77. @override
  78. void calculate() {
  79. if (ref.feature == null) return;
  80. final feature = ref.feature!;
  81. final diam = pickChildFloatValue(ref.l);
  82. feature.values.clear();
  83. updateStringValue("");
  84. if (diam == null) {
  85. return;
  86. }
  87. final diamOutputIndex =
  88. ref.l.meta.outputs.indexWhere((e) => e.name == MeasureTerms.Diam);
  89. if (diamOutputIndex > -1) {
  90. final output = ref.l.meta.outputs[diamOutputIndex];
  91. feature.updateFloatValue(output, diam, VidUsUnit.cm);
  92. }
  93. double va = double.nan;
  94. double dvi = double.nan;
  95. double avaIndex = double.nan;
  96. double otVti = double.nan;
  97. double vti = double.nan;
  98. double otSV = double.nan;
  99. double otCSA = double.nan;
  100. otCSA = GeneralFormulas.csa(diam); // ???
  101. final otFeature = _findTraceOT();
  102. final vtiFeature = _findTraceVTI();
  103. if (otFeature != null) {
  104. final countOtVTIResult = TraceCal.getCountVTI(otFeature);
  105. otVti = countOtVTIResult[0];
  106. }
  107. if (vtiFeature != null) {
  108. final countVTIResult = TraceCal.getCountVTI(vtiFeature);
  109. vti = countVTIResult[0];
  110. }
  111. if (!vti.isNaN && !otVti.isNaN) {
  112. va = CardiacFormulas.flowAreaByVTI(diam, otVti, vti);
  113. dvi = CardiacFormulas.dviByVTI(otVti, vti);
  114. final bsa = GlobalPatientConfig.bsa;
  115. if (bsa > 0) {
  116. avaIndex = CardiacFormulas.avaIndex(va, bsa);
  117. }
  118. otSV = GeneralFormulas.svDiam(diam, otVti);
  119. otCSA = GeneralFormulas.csa(diam);
  120. }
  121. if (otFeature != null) {
  122. for (var output in ref.trace1.meta.outputs) {
  123. if (output.name == MeasureTerms.SV_Trace) {
  124. feature.updateStringValue(
  125. ItemOutputMeta(output.description, output.description, output.unit),
  126. '',
  127. );
  128. } else if (output.name == MeasureTerms.VTI) {
  129. if (!otVti.isNaN) {
  130. feature.updateFloatValue(
  131. ItemOutputMeta(
  132. output.description, output.description, output.unit),
  133. otVti,
  134. VidUsUnit.cm,
  135. );
  136. }
  137. }
  138. }
  139. }
  140. if (vtiFeature != null) {
  141. for (var output in ref.trace2.meta.outputs) {
  142. if (output.name == MeasureTerms.SV_Trace) {
  143. feature.updateStringValue(
  144. ItemOutputMeta(output.description, output.description, output.unit),
  145. '',
  146. );
  147. } else if (output.name == MeasureTerms.VTI) {
  148. if (!vti.isNaN) {
  149. feature.updateFloatValue(
  150. ItemOutputMeta(
  151. output.description, output.description, output.unit),
  152. vti,
  153. VidUsUnit.cm,
  154. );
  155. }
  156. }
  157. }
  158. }
  159. for (var output in ref.meta.outputs) {
  160. switch (output.name) {
  161. case MeasureTerms.FlowArea:
  162. if (!va.isNaN) {
  163. feature.updateFloatValue(output, va, VidUsUnit.cm2);
  164. }
  165. break;
  166. case MeasureTerms.AVAI:
  167. if (!avaIndex.isNaN) {
  168. feature.updateFloatValue(output, avaIndex, VidUsUnit.cm2m2);
  169. }
  170. break;
  171. case MeasureTerms.DVI:
  172. if (!dvi.isNaN) {
  173. feature.updateFloatValue(output, dvi, VidUsUnit.None);
  174. }
  175. break;
  176. case MeasureTerms.SV:
  177. if (!otSV.isNaN) {
  178. feature.updateFloatValue(output, otSV, VidUsUnit.cm3);
  179. }
  180. break;
  181. case MeasureTerms.CSA:
  182. if (!otCSA.isNaN) {
  183. feature.updateFloatValue(output, otCSA, VidUsUnit.cm2);
  184. }
  185. break;
  186. }
  187. }
  188. }
  189. TraceItemFeatureAbstract? _findTraceOT() {
  190. TraceItemFeatureAbstract? traceFeature = ref.trace1.feature;
  191. if (traceFeature == null) {
  192. if (ref.trace1.measuredFeatures.isNotEmpty) {
  193. traceFeature = ref.trace1.measuredFeatures.first;
  194. }
  195. }
  196. return traceFeature;
  197. }
  198. TraceItemFeatureAbstract? _findTraceVTI() {
  199. TraceItemFeatureAbstract? traceFeature = ref.trace2.feature;
  200. if (traceFeature == null) {
  201. if (ref.trace2.measuredFeatures.isNotEmpty) {
  202. traceFeature = ref.trace2.measuredFeatures.first;
  203. }
  204. }
  205. return traceFeature;
  206. }
  207. }