Selaa lähdekoodia

1、新增小鼠的测量公式

guanxinyi 10 kuukautta sitten
vanhempi
commit
ea8f3bdbca

+ 10 - 0
lib/configs/patient.dart

@@ -2,6 +2,8 @@
 
 import 'dart:math' as math;
 
+import 'package:fis_measure/interfaces/enums/species.dart';
+
 abstract class GlobalPatientConfig {
   static double weight = 0;
   static double height = 0;
@@ -22,4 +24,12 @@ abstract class GlobalPatientConfig {
 
   /// 心率
   static int? hr;
+
+  /// 物种类型
+  static SpeciesType speciesType = SpeciesType.general;
+
+  /// 切换物种
+  static switchSpecies(SpeciesType type) {
+    speciesType = type;
+  }
 }

+ 4 - 0
lib/interfaces/enums/species.dart

@@ -0,0 +1,4 @@
+enum SpeciesType {
+  general,
+  mouse,
+}

+ 143 - 24
lib/process/calcuators/formulas/cardiac.dart

@@ -1,20 +1,84 @@
 import 'dart:math' as math;
 
-import 'package:fis_common/logger/logger.dart';
 import 'package:fis_measure/configs/cardiac.dart';
+import 'package:fis_measure/configs/patient.dart';
+import 'package:fis_measure/interfaces/enums/species.dart';
+import 'package:fis_measure/process/calcuators/formulas/general.dart';
 import 'package:fis_measure/utils/number.dart';
 
-import 'general.dart';
-
 class CardiacFormulas {
-  CardiacFormulas._();
+  static final ICardiacFormulaStrategy _singleton =
+      GlobalPatientConfig.speciesType != SpeciesType.general
+          ? BaseCardiacFormulas()
+          : MouseCardiacFormulas();
+
+  static double teiIndex(double co, double et) => _singleton.teiIndex(co, et);
+  static double ef(double edv, double esv) => _singleton.ef(edv, esv);
+  static double edvTeichholz(double lvidd) => _singleton.edvTeichholz(lvidd);
+  static double edvCube(double lvidd) => _singleton.edvCube(lvidd);
+  static double esvTeichholz(double lvids) => _singleton.esvTeichholz(lvids);
+  static double esvCube(double lvids) => _singleton.esvCube(lvids);
+  static double sv(double edv, double esv) => _singleton.sv(edv, esv);
+  static double co(double sv, {required int hr}) => _singleton.co(sv, hr: hr);
+  static double ci(double sv, {required int hr, required double bsa}) =>
+      _singleton.ci(sv, hr: hr, bsa: bsa);
+  static double lvdMass(double ivsd, double lvidd, double lvpwd) =>
+      _singleton.lvdMass(ivsd, lvidd, lvpwd);
+  static double lvdMassAL(
+          double lvadSaxEpi, double lvadSaxEndo, double lvldApical) =>
+      _singleton.lvdMassAL(lvadSaxEpi, lvadSaxEndo, lvldApical);
+  static double lvdMassIndex(double lvdmass, double bsa) =>
+      _singleton.lvdMassIndex(lvdmass, bsa);
+  static double fsPercent(double lvidd, double lvids) =>
+      _singleton.fsPercent(lvidd, lvids);
+  static double ivsPercent(double ivss, double ivsd) =>
+      _singleton.ivsPercent(ivss, ivsd);
+  static double lvpwPercent(double lvpws, double lvpwd) =>
+      _singleton.lvpwPercent(lvpws, lvpwd);
+  static double mamPercent(double mapse, double lvidd, double lvids) =>
+      _singleton.mamPercent(mapse, lvidd, lvids);
+  static double si(double sv, double bsa) => _singleton.si(sv, bsa);
+  static double flowAreaByVTI(double otDiam, double otvti, double vti) =>
+      _singleton.flowAreaByVTI(otDiam, otvti, vti);
+  static double dviByVTI(double otvti, double vti) =>
+      _singleton.dviByVTI(otvti, vti);
+  static double avaIndex(double avaByVTI, double bsa) =>
+      _singleton.avaIndex(avaByVTI, bsa);
+
+  CardiacFormulas._internal(); // 私有构造函数
+}
 
+abstract class ICardiacFormulaStrategy {
+  double teiIndex(double co, double et);
+  double ef(double edv, double esv);
+  double edvTeichholz(double lvidd);
+  double edvCube(double lvidd);
+  double esvTeichholz(double lvids);
+  double esvCube(double lvids);
+  double sv(double edv, double esv);
+  double co(double sv, {required int hr});
+  double ci(double sv, {required int hr, required double bsa});
+  double lvdMass(double ivsd, double lvidd, double lvpwd);
+  double lvdMassAL(double lvadSaxEpi, double lvadSaxEndo, double lvldApical);
+  double lvdMassIndex(double lvdmass, double bsa);
+  double fsPercent(double lvidd, double lvids);
+  double ivsPercent(double ivss, double ivsd);
+  double lvpwPercent(double lvpws, double lvpwd);
+  double mamPercent(double mapse, double lvidd, double lvids);
+  double si(double sv, double bsa);
+  double flowAreaByVTI(double otDiam, double otvti, double vti);
+  double dviByVTI(double otvti, double vti);
+  double avaIndex(double avaByVTI, double bsa);
+}
+
+class BaseCardiacFormulas implements ICardiacFormulaStrategy {
   /// IMP
   ///
   /// Formula: `(CO-ET)/ET`
   ///
   /// Result Unit: `None`
-  static double teiIndex(double co, double et) {
+  @override
+  double teiIndex(double co, double et) {
     double imp = 0.0;
     if (et != 0.0) {
       imp = (((co).abs() - (et).abs()) / et).abs();
@@ -30,7 +94,8 @@ class CardiacFormulas {
   /// [esv] Unit: `cm³`
   ///
   /// Result Unit: `None`
-  static double ef(double edv, double esv) {
+  @override
+  double ef(double edv, double esv) {
     // 这行判断暂时注释掉是为了使实际表现与旧版一致
     // if (edv < esv) {
     //   return double.nan;
@@ -45,7 +110,8 @@ class CardiacFormulas {
   /// [lvidd] Unit: `cm`
   ///
   /// Result Unit: `cm³`
-  static double edvTeichholz(double lvidd) {
+  @override
+  double edvTeichholz(double lvidd) {
     double edv = double.nan;
     if (!NumUtil.almostEquals(lvidd, 0)) {
       edv = 7.0 * math.pow(lvidd, 3) / (2.4 + lvidd);
@@ -60,7 +126,8 @@ class CardiacFormulas {
   /// [lvidd] Unit: `cm`
   ///
   /// Result Unit: `cm³`
-  static double edvCube(double lvidd) {
+  @override
+  double edvCube(double lvidd) {
     double edv = double.nan;
     if (!NumUtil.almostEquals(lvidd, 0)) {
       edv = math.pow(lvidd, 3).toDouble();
@@ -75,7 +142,8 @@ class CardiacFormulas {
   /// [lvids] Unit: `cm`
   ///
   /// Result Unit: `cm³`
-  static double esvTeichholz(double lvids) {
+  @override
+  double esvTeichholz(double lvids) {
     // 计算公式相同,入参不同
     return edvTeichholz(lvids);
   }
@@ -87,18 +155,21 @@ class CardiacFormulas {
   /// [lvids] Unit: `cm`
   ///
   /// Result Unit: `cm³`
-  static double esvCube(double lvids) {
+  @override
+  double esvCube(double lvids) {
     // 计算公式相同,入参不同
     return edvCube(lvids);
   }
 
   /// SV
-  static double sv(double edv, double esv) {
+  @override
+  double sv(double edv, double esv) {
     return edv - esv;
   }
 
   /// CO
-  static double co(
+  @override
+  double co(
     double sv, {
     required int hr,
   }) {
@@ -106,7 +177,8 @@ class CardiacFormulas {
   }
 
   /// CI
-  static double ci(
+  @override
+  double ci(
     double sv, {
     required int hr,
     required double bsa,
@@ -115,7 +187,8 @@ class CardiacFormulas {
   }
 
   /// LVdMass
-  static double lvdMass(double ivsd, double lvidd, double lvpwd) {
+  @override
+  double lvdMass(double ivsd, double lvidd, double lvpwd) {
     const density = GlobalCardiacConfigs.density;
     const correctionFactor = GlobalCardiacConfigs.correctionFactor;
     double part1 = math.pow(ivsd + lvidd + lvpwd, 3).toDouble();
@@ -125,7 +198,8 @@ class CardiacFormulas {
   }
 
   /// LVd Mass AL
-  static double lvdMassAL(
+  @override
+  double lvdMassAL(
     double lvadSaxEpi,
     double lvadSaxEndo,
     double lvldApical,
@@ -141,27 +215,32 @@ class CardiacFormulas {
   }
 
   /// LVd Mass Index
-  static double lvdMassIndex(double lvdmass, double bsa) {
+  @override
+  double lvdMassIndex(double lvdmass, double bsa) {
     return lvdmass / bsa * 1000;
   }
 
   /// %FS
-  static double fsPercent(double lvidd, double lvids) {
+  @override
+  double fsPercent(double lvidd, double lvids) {
     return ((lvidd - lvids) / lvidd) * 100;
   }
 
   /// %IVS
-  static double ivsPercent(double ivss, double ivsd) {
+  @override
+  double ivsPercent(double ivss, double ivsd) {
     return ((ivss - ivsd) / ivsd) * 100;
   }
 
   /// %LVPW
-  static double lvpwPercent(double lvpws, double lvpwd) {
+  @override
+  double lvpwPercent(double lvpws, double lvpwd) {
     return ((lvpws - lvpwd) / lvpwd) * 100;
   }
 
   /// MAM%
-  static double mamPercent(double mapse, double lvidd, double lvids) {
+  @override
+  double mamPercent(double mapse, double lvidd, double lvids) {
     return mapse / (lvidd - lvids + mapse) * 100;
   }
 
@@ -174,7 +253,8 @@ class CardiacFormulas {
   /// [bsa] m²
   ///
   /// return `cm³/m²`
-  static double si(double sv, double bsa) {
+  @override
+  double si(double sv, double bsa) {
     double si = sv / bsa;
     return si;
   }
@@ -189,7 +269,8 @@ class CardiacFormulas {
   /// <param name="otvti">cm</param>
   /// <param name="vti">cm</param>
   /// <returns>cm^2</returns>
-  static double flowAreaByVTI(double otDiam, double otvti, double vti) {
+  @override
+  double flowAreaByVTI(double otDiam, double otvti, double vti) {
     double sv = 0.25 * math.pi * math.pow(otDiam, 2) * otvti / vti;
     return sv;
   }
@@ -197,7 +278,8 @@ class CardiacFormulas {
   /// <param name="otvti">cm</param>
   /// <param name="vti">cm</param>
   /// <returns>Unit None</returns>
-  static double dviByVTI(double otvti, double vti) {
+  @override
+  double dviByVTI(double otvti, double vti) {
     double dvi = double.nan;
     if (!GeneralFormulas.doubleAlmostEquals(vti, 0)) {
       dvi = otvti / vti;
@@ -211,7 +293,8 @@ class CardiacFormulas {
   /// <param name="avaByVTI">cm2</param>
   /// <param name="bsa">m2</param>
   /// <returns>cm2/m2</returns>
-  static double avaIndex(double avaByVTI, double bsa) {
+  @override
+  double avaIndex(double avaByVTI, double bsa) {
     double index = double.nan;
     if (!GeneralFormulas.doubleAlmostEquals(bsa, 0)) {
       index = avaByVTI / bsa;
@@ -219,3 +302,39 @@ class CardiacFormulas {
     return index;
   }
 }
+
+class MouseCardiacFormulas extends BaseCardiacFormulas {
+  MouseCardiacFormulas() : super();
+
+  @override
+  double teiIndex(double co, double et) {
+    double imp = 0.0;
+    if (et != 0.0) {
+      imp = (((co).abs() - (et).abs()) / et).abs();
+    }
+    return imp;
+  }
+
+  /// SV
+  @override
+  double sv(double edv, double esv) {
+    return 0;
+  }
+
+  /// EF
+  /// Formula: `(EDV - ESV )/EDV`
+  ///
+  /// [edv] Unit: `cm³`
+  ///
+  /// [esv] Unit: `cm³`
+  ///
+  /// Result Unit: `None`
+  @override
+  double ef(double edv, double esv) {
+    // 这行判断暂时注释掉是为了使实际表现与旧版一致
+    // if (edv < esv) {
+    //   return double.nan;
+    // }
+    return 0.5;
+  }
+}