From f55ede707c4d89c8cbc9055861b6e435832189df Mon Sep 17 00:00:00 2001 From: Levan Bokeria Date: Mon, 14 Apr 2025 15:28:27 +0100 Subject: [PATCH 1/8] removing models that have not been tested --- src/ModularCirc/Models/KPat5MixedModel.py | 136 ------------------ .../Models/KPat5MixedModel_parameters.py | 108 -------------- .../Models/KorakianitisMaynardModel.py | 114 --------------- .../KorakianitisMaynardModel_parameters.py | 88 ------------ .../Models/KorakianitisMixedMaynardModel.py | 113 --------------- ...orakianitisMixedMaynardModel_parameters.py | 88 ------------ src/ModularCirc/Models/KorakianitisModel.py | 104 -------------- .../Models/KorakianitisModel_parameters.py | 98 ------------- .../Models/MixedHeartMaynard4eWindkessel.py | 132 ----------------- ...ixedHeartMaynard4eWindkessel_parameters.py | 132 ----------------- 10 files changed, 1113 deletions(-) delete mode 100644 src/ModularCirc/Models/KPat5MixedModel.py delete mode 100644 src/ModularCirc/Models/KPat5MixedModel_parameters.py delete mode 100644 src/ModularCirc/Models/KorakianitisMaynardModel.py delete mode 100644 src/ModularCirc/Models/KorakianitisMaynardModel_parameters.py delete mode 100644 src/ModularCirc/Models/KorakianitisMixedMaynardModel.py delete mode 100644 src/ModularCirc/Models/KorakianitisMixedMaynardModel_parameters.py delete mode 100644 src/ModularCirc/Models/KorakianitisModel.py delete mode 100644 src/ModularCirc/Models/KorakianitisModel_parameters.py delete mode 100644 src/ModularCirc/Models/MixedHeartMaynard4eWindkessel.py delete mode 100644 src/ModularCirc/Models/MixedHeartMaynard4eWindkessel_parameters.py diff --git a/src/ModularCirc/Models/KPat5MixedModel.py b/src/ModularCirc/Models/KPat5MixedModel.py deleted file mode 100644 index 30aa2e1..0000000 --- a/src/ModularCirc/Models/KPat5MixedModel.py +++ /dev/null @@ -1,136 +0,0 @@ -from .OdeModel import OdeModel -from .KorakianitisModel_parameters import KorakianitisModel_parameters as k2006 -from .ParametersObject import ParametersObject as po -from ..Components import Rlc_component, Valve_simple_bernoulli, HC_mixed_elastance - -FULL_NAMES =[ - 'LeftA', - 'MiValve', - 'LeftV', - 'AoV', - 'SysAoSin', - 'SysArt', - 'SysVen', - 'RightA', - 'TriValve', - 'RightV', - 'PulV', - 'PulArtSin', - 'PulArt0', - 'PulArt1', - 'PulArt2', - 'PulArt3', - 'PulArt4', - 'PulVen', -] - -class KPat5MixedModel(OdeModel): - def __init__(self, time_setup_dict, parobj:po=k2006, suppress_printing:bool=False) -> None: - super().__init__(time_setup_dict) - self.name = 'KorakianitisModel' - - if not suppress_printing: print(parobj) - - # The components... - for key, name in zip(parobj.components.keys(), FULL_NAMES): - if key in parobj._vessels: - class_ = Rlc_component - elif key in parobj._valves: - class_ = Valve_simple_bernoulli - elif key in parobj._chambers: - class_ = HC_mixed_elastance - else: - raise Exception(f'Component name {key} not in the model list.') - self.components[key] = class_(name=name, - time_object=self.time_object, - **parobj[key].to_dict()) - if key not in parobj._valves: - self.set_v_sv(key) - # else: - # self.set_phi_sv(key) - self.components[key].setup() - - self.connect_modules(self.components['lv'], - self.components['ao'], - plabel='p_lv', - qlabel='q_ao') - self.connect_modules(self.components['ao'], - self.components['sas'], - plabel='p_sas', - qlabel='q_ao') - self.connect_modules(self.components['sas'], - self.components['sat'], - plabel='p_sat', - qlabel='q_sas') - self.connect_modules(self.components['sat'], - self.components['svn'], - plabel='p_svn', - qlabel='q_sat') - self.connect_modules(self.components['svn'], - self.components['ra'], - plabel='p_ra', - qlabel='q_svn') - self.connect_modules(self.components['ra'], - self.components['ti'], - plabel='p_ra', - qlabel='q_ti') - self.connect_modules(self.components['ti'], - self.components['rv'], - plabel='p_rv', - qlabel='q_ti') - self.connect_modules(self.components['rv'], - self.components['po'], - plabel='p_rv', - qlabel='q_po') - self.connect_modules(self.components['po'], - self.components['pas'], - plabel='p_pas', - qlabel='q_po') - ############################################ - self.connect_modules(self.components['pas'], - self.components['pat0'], - plabel='p_pat0', - qlabel='q_pas') - self.connect_modules(self.components['pat0'], - self.components['pat1'], - plabel='p_pat1', - qlabel='q_pat0') - self.connect_modules(self.components['pat1'], - self.components['pat2'], - plabel='p_pat2', - qlabel='q_pat1') - self.connect_modules(self.components['pat2'], - self.components['pat3'], - plabel='p_pat3', - qlabel='q_pat2') - self.connect_modules(self.components['pat3'], - self.components['pat4'], - plabel='p_pat4', - qlabel='q_pat3') - ############################################ - self.connect_modules(self.components['pat4'], - self.components['pvn'], - plabel='p_pvn', - qlabel='q_pat4') - ############################################ - self.connect_modules(self.components['pvn'], - self.components['la'], - plabel='p_la', - qlabel='q_pvn') - self.connect_modules(self.components['la'], - self.components['mi'], - plabel='p_la', - qlabel='q_mi') - self.connect_modules(self.components['mi'], - self.components['lv'], - plabel='p_lv', - qlabel='q_mi') - - for component in self.components.values(): - component.setup() - - # def set_phi_sv(self, comp_key:str) -> None: - # phi_key = 'phi_' + comp_key - # self._state_variable_dict[phi_key] = self.components[comp_key]._PHI - # self._state_variable_dict[phi_key].set_name(phi_key) - # self.all_sv_data[phi_key] = self.components[comp_key].PHI \ No newline at end of file diff --git a/src/ModularCirc/Models/KPat5MixedModel_parameters.py b/src/ModularCirc/Models/KPat5MixedModel_parameters.py deleted file mode 100644 index f72ad75..0000000 --- a/src/ModularCirc/Models/KPat5MixedModel_parameters.py +++ /dev/null @@ -1,108 +0,0 @@ -from ..HelperRoutines import activation_function_2, activation_function_3 -from .ParametersObject import ParametersObject -import pandas as pd - - -KKPat10_COMPONENTS = [ - 'la', # left atrium - 'mi', # mitral valve - 'lv', # left ventricle - 'ao', # aortic valve - 'sas', # systemic aortic sinus - 'sat', # systemic artery - 'svn', # systemic vein - 'ra', # right atrium - 'ti', # tricuspid vale - 'rv', # right ventricle - 'po', # pulmonary valve - 'pas', # pulmonary artery sinus - ############################### - 'pat0', # pulmonary artery - 'pat1', # pulmonary artery - 'pat2', # pulmonary artery - 'pat3', # pulmonary artery - 'pat4', # pulmonary artery - ############################### - 'pvn' # pulmonary vein - ] -VESSELS = ['sas', 'sat', 'svn', 'pas', 'pat0', 'pat1', 'pat2', 'pat3', 'pat4', 'pvn'] -VESSELS_PAR = ['r', 'c', 'l', 'v_ref', 'v', 'p'] - -VALVES = ['mi', 'ao', 'ti', 'po'] -VALVES_PAR = ['CQ', 'RRA'] - -CHAMBERS = ['la', 'lv', 'ra', 'rv'] -CHAMBERS_PAR = ['E_pas', 'E_act', 'v_ref', 'k_pas', 'af', 'v', 'p', 'tr', 'td', 'delay', 'tpww', 'tpwb'] - - -class KPat5MixedModel_parameters(ParametersObject): - """ - Intro - ----- - Model Parameters based on Korakianitis and Shi (2006) - """ - def __init__(self, name='Korakianitis 2006') -> None: - super().__init__(name=name) - self.components = {key : None for key in KKPat10_COMPONENTS} - for type_, type_var in [[VESSELS, VESSELS_PAR], [VALVES, VALVES_PAR], [CHAMBERS, CHAMBERS_PAR]]: - for key in type_: - self[key] = pd.Series(index=type_var, dtype=object) - - self._vessels = VESSELS - self._valves = VALVES - self._chambers= CHAMBERS - - self.set_chamber_comp('lv', E_pas= 0.1, k_pas=0.01, E_act= 2.5, v_ref=50.0, tr = 0.30, td = 0.450, v=100.) - self.set_chamber_comp('la', E_pas= 0.15, k_pas=0.01, E_act= 0.25, v_ref=10.0, tpwb = 0.0, tpww = 0.09, delay=0.08, v=0.0) - self.set_chamber_comp('rv', E_pas= 0.1, k_pas=0.01, E_act= 1.15, v_ref=50., tr=0.30, td=0.45, v=100.) - self.set_chamber_comp('ra', E_pas= 0.15, k_pas=0.01, E_act= 0.25, v_ref=10., tpwb=0.0, tpww=0.09, delay=0.08, v=0.0) - - - self.set_activation_function('lv', af=activation_function_2) - self.set_activation_function('rv', af=activation_function_2) - - self.set_activation_function('la', af=activation_function_3) - self.set_activation_function('ra', af=activation_function_3) - - - # systemic circulation - self.set_rlc_comp('sas', r=0.003, c=0.08, l=0.000062, v=0.0, v_ref=0.0) - self.set_rlc_comp('sat', r=(0.05 + 0.5 + 0.52), c=1.6 , l=0.0017 , v=550.0, v_ref=0.0) - self.set_rlc_comp('svn', r=0.075, c=20.5, v=0.0, v_ref=0.0) - - # pulmonary circulation - self.set_rlc_comp('pas', r=0.002 , c=0.18, l=0.000052, v=0.0, v_ref=0.0) - ############################################################################################# - self.set_rlc_comp('pat0', r=(0.01/5.), c=(3.8/5.) , l=(0.0017/5.) , v=0.0, v_ref=0.0) - self.set_rlc_comp('pat1', r=(0.01/5.), c=(3.8/5.) , l=(0.0017/5.) , v=0.0, v_ref=0.0) - self.set_rlc_comp('pat2', r=(0.01/5.), c=(3.8/5.) , l=(0.0017/5.) , v=0.0, v_ref=0.0) - self.set_rlc_comp('pat3', r=(0.01/5.), c=(3.8/5. ), l=(0.0017/5. ) , v=0.0, v_ref=0.0) - self.set_rlc_comp('pat4', r=(0.01/5.+0.05+0.25), c=(3.8/5.) , l=(0.0017/5.), v=0.0, v_ref=0.0) - ############################################################################################# - self.set_rlc_comp('pvn', r=0.006 , c=20.5 , v=0.0, v_ref=0.0) - - # valves - self.set_valve_comp('ao', CQ=350., RRA=0.0) - self.set_valve_comp('mi', CQ=400., RRA=0.0) - self.set_valve_comp('po', CQ=350., RRA=0.0) - self.set_valve_comp('ti', CQ=400., RRA=0.0) - - def set_chamber_comp(self, key, **kwargs): - self._set_comp(key=key, set=CHAMBERS, **kwargs) - - def set_activation_function(self, key, af): - self._set_comp(key, set=CHAMBERS, af=af) - - def set_rlc_comp(self, key, **kwargs): - self._set_comp(key=key, set=VESSELS, **kwargs) - - def set_valve_comp(self, key, **kwargs): - self._set_comp(key=key, set=VALVES, **kwargs) - - def set(self, key, **kwargs): - if key in CHAMBERS: - self._set_comp(key=key, set=CHAMBERS, **kwargs) - if key in VESSELS: - self._set_comp(key=key, set=VESSELS, **kwargs) - if key in VALVES: - self._set_comp(key=key, set=VALVES, **kwargs) diff --git a/src/ModularCirc/Models/KorakianitisMaynardModel.py b/src/ModularCirc/Models/KorakianitisMaynardModel.py deleted file mode 100644 index 7874e46..0000000 --- a/src/ModularCirc/Models/KorakianitisMaynardModel.py +++ /dev/null @@ -1,114 +0,0 @@ -from .OdeModel import OdeModel -from .KorakianitisModel_parameters import KorakianitisModel_parameters as k2006 -from .ParametersObject import ParametersObject as po -from ..Components import Rlc_component, Valve_maynard, HC_constant_elastance - -FULL_NAMES =[ - 'LeftA', - 'MiValve', - 'LeftV', - 'AoV', - 'SysAoSin', - 'SysArt', - 'SysVen', - 'RightA', - 'TriValve', - 'RightV', - 'PulV', - 'PulArtSin', - 'PulArt', - 'PulVen', -] - -class KorakianitisMaynardModel(OdeModel): - def __init__(self, time_setup_dict, parobj:po=k2006) -> None: - super().__init__(time_setup_dict) - self.name = 'KorakianitisModel' - - print(parobj) - - # The components... - for key, name in zip(parobj.components.keys(), FULL_NAMES): - if key in parobj._vessels: - class_ = Rlc_component - elif key in parobj._valves: - class_ = Valve_maynard - elif key in parobj._chambers: - class_ = HC_constant_elastance - else: - raise Exception(f'Component name {key} not in the model list.') - self.components[key] = class_(name=name, - time_object=self.time_object, - **parobj[key].to_dict()) - if key not in parobj._valves: - self.set_v_sv(key) - else: - self.set_phi_sv(key) - self.components[key].setup() - - self.connect_modules(self.components['lv'], - self.components['ao'], - plabel='p_lv', - qlabel='q_ao') - self.connect_modules(self.components['ao'], - self.components['sas'], - plabel='p_sas', - qlabel='q_ao') - self.connect_modules(self.components['sas'], - self.components['sat'], - plabel='p_sat', - qlabel='q_sas') - self.connect_modules(self.components['sat'], - self.components['svn'], - plabel='p_svn', - qlabel='q_sat') - self.connect_modules(self.components['svn'], - self.components['ra'], - plabel='p_ra', - qlabel='q_svn') - self.connect_modules(self.components['ra'], - self.components['ti'], - plabel='p_ra', - qlabel='q_ti') - self.connect_modules(self.components['ti'], - self.components['rv'], - plabel='p_rv', - qlabel='q_ti') - self.connect_modules(self.components['rv'], - self.components['po'], - plabel='p_rv', - qlabel='q_po') - self.connect_modules(self.components['po'], - self.components['pas'], - plabel='p_pas', - qlabel='q_po') - self.connect_modules(self.components['pas'], - self.components['pat'], - plabel='p_pat', - qlabel='q_pas') - self.connect_modules(self.components['pat'], - self.components['pvn'], - plabel='p_pvn', - qlabel='q_pat') - self.connect_modules(self.components['pvn'], - self.components['la'], - plabel='p_la', - qlabel='q_pvn') - self.connect_modules(self.components['la'], - self.components['mi'], - plabel='p_la', - qlabel='q_mi') - self.connect_modules(self.components['mi'], - self.components['lv'], - plabel='p_lv', - qlabel='q_mi') - - for component in self.components.values(): - component.setup() - - def set_phi_sv(self, comp_key:str) -> None: - phi_key = 'phi_' + comp_key - self._state_variable_dict[phi_key] = self.components[comp_key]._PHI - self._state_variable_dict[phi_key].set_name(phi_key) - self.all_sv_data[phi_key] = self.components[comp_key].PHI - self.components[comp_key]._PHI._u = self.all_sv_data[phi_key] \ No newline at end of file diff --git a/src/ModularCirc/Models/KorakianitisMaynardModel_parameters.py b/src/ModularCirc/Models/KorakianitisMaynardModel_parameters.py deleted file mode 100644 index a55bb8a..0000000 --- a/src/ModularCirc/Models/KorakianitisMaynardModel_parameters.py +++ /dev/null @@ -1,88 +0,0 @@ -from ..HelperRoutines import activation_function_2, activation_function_3 -from .ParametersObject import ParametersObject -import pandas as pd - - -KORAKIANITIS_2006_COMPONENTS = [ - 'la', # left atrium - 'mi', # mitral valve - 'lv', # left ventricle - 'ao', # aortic valve - 'sas', # systemic aortic sinus - 'sat', # systemic artery - 'svn', # systemic vein - 'ra', # right atrium - 'ti', # tricuspid vale - 'rv', # right ventricle - 'po', # pulmonary valve - 'pas', # pulmonary artery sinus - 'pat', # pulmonary artery - 'pvn' # pulmonary vein - ] -VESSELS = ['sas', 'sat', 'svn', 'pas', 'pat', 'pvn'] -VESSELS_PAR = ['r', 'c', 'l', 'v_ref', 'v', 'p'] - -VALVES = ['mi', 'ao', 'ti', 'po'] -VALVES_PAR = ['CQ', 'RRA', 'Ko', 'Kc', 'R', 'L'] - -CHAMBERS = ['la', 'lv', 'ra', 'rv'] -CHAMBERS_PAR = ['E_pas', 'E_act', 'v_ref', 'k_pas', 'af', 'v', 'p', 'tr', 'td', 'delay', 'tpww', 'tpwb'] - - -class KorakianitisMaynardModel_parameters(ParametersObject): - """ - Intro - ----- - Model Parameters based on Korakianitis and Shi (2006) with Maynard (2012) valves - """ - def __init__(self, name='Korakianitis 2006') -> None: - super().__init__(name=name) - self.components = {key : None for key in KORAKIANITIS_2006_COMPONENTS} - for type_, type_var in [[VESSELS, VESSELS_PAR], [VALVES, VALVES_PAR], [CHAMBERS, CHAMBERS_PAR]]: - for key in type_: - self[key] = pd.Series(index=type_var, dtype=object) - - self._vessels = VESSELS - self._valves = VALVES - self._chambers= CHAMBERS - - self.set_chamber_comp('lv', E_pas= 0.1, E_act= 2.5, v_ref=5.0, k_pas=0.1, tr = 0.30, td = 0.450, v=500.) - self.set_chamber_comp('la', E_pas= 0.15, E_act= 0.25, v_ref=4.0, k_pas=0.1, tpwb = 0.0, tpww = 0.09, delay=0.08, v=0.0) - self.set_chamber_comp('rv', E_pas= 0.1, E_act= 1.15, v_ref=10., k_pas=0.1, tr=0.30, td=0.45, v=400.) - self.set_chamber_comp('ra', E_pas= 0.15, E_act= 0.25, v_ref=4., k_pas=0.1, tpwb=0.0, tpww=0.09, delay=0.08, v=0.0) - - self.set_activation_function('lv', af=activation_function_2) - self.set_activation_function('rv', af=activation_function_2) - - self.set_activation_function('la', af=activation_function_3) - self.set_activation_function('ra', af=activation_function_3) - - - # systemic circulation - self.set_rlc_comp('sas', r=0.003, c=0.08, l=0.000062, v=0.0, v_ref=0.0) - self.set_rlc_comp('sat', r=(0.05 + 0.5 + 0.52), c=1.6 , l=0.0017 , v=0.0, v_ref=0.0) - self.set_rlc_comp('svn', r=0.075, c=20.5, v=0.0, v_ref=0.0) - - # pulmonary circulation - self.set_rlc_comp('pas', r=0.002 , c=0.18, l=0.000052, v=0.0, v_ref=0.0) - self.set_rlc_comp('pat', r=(0.01+0.05+0.25), c=3.8 , l=0.0017 , v=0.0, v_ref=0.0) - self.set_rlc_comp('pvn', r=0.006 , c=20.5 , v=0.0, v_ref=0.0) - - # valves - dyn = 1333.22 - self.set_valve_comp('ao', CQ=350., RRA=0.0, Ko = 0.012/dyn, Kc = 0.012/dyn, L=0.0, R=0.0) - self.set_valve_comp('mi', CQ=400., RRA=0.0, Ko = 0.03/dyn, Kc = 0.04/dyn, L=0.0, R=0.0 ) - self.set_valve_comp('po', CQ=350., RRA=0.0, Ko = 0.02/dyn, Kc = 0.02/dyn, L=0.0, R=0.0 ) - self.set_valve_comp('ti', CQ=400., RRA=0.0, Ko = 0.03/dyn, Kc = 0.04/dyn, L=0.0, R=0.0 ) - - def set_chamber_comp(self, key, **kwargs): - self._set_comp(key=key, set=CHAMBERS, **kwargs) - - def set_activation_function(self, key, af): - self._set_comp(key, set=CHAMBERS, af=af) - - def set_rlc_comp(self, key, **kwargs): - self._set_comp(key=key, set=VESSELS, **kwargs) - - def set_valve_comp(self, key, **kwargs): - self._set_comp(key=key, set=VALVES, **kwargs) diff --git a/src/ModularCirc/Models/KorakianitisMixedMaynardModel.py b/src/ModularCirc/Models/KorakianitisMixedMaynardModel.py deleted file mode 100644 index c8ab554..0000000 --- a/src/ModularCirc/Models/KorakianitisMixedMaynardModel.py +++ /dev/null @@ -1,113 +0,0 @@ -from .OdeModel import OdeModel -from .KorakianitisModel_parameters import KorakianitisModel_parameters as k2006 -from .ParametersObject import ParametersObject as po -from ..Components import Rlc_component, Valve_maynard, HC_mixed_elastance - -FULL_NAMES =[ - 'LeftA', - 'MiValve', - 'LeftV', - 'AoV', - 'SysAoSin', - 'SysArt', - 'SysVen', - 'RightA', - 'TriValve', - 'RightV', - 'PulV', - 'PulArtSin', - 'PulArt', - 'PulVen', -] - -class KorakianitisMixedMaynardModel(OdeModel): - def __init__(self, time_setup_dict, parobj:po=k2006) -> None: - super().__init__(time_setup_dict) - self.name = 'KorakianitisModel' - - print(parobj) - - # The components... - for key, name in zip(parobj.components.keys(), FULL_NAMES): - if key in parobj._vessels: - class_ = Rlc_component - elif key in parobj._valves: - class_ = Valve_maynard - elif key in parobj._chambers: - class_ = HC_mixed_elastance - else: - raise Exception(f'Component name {key} not in the model list.') - self.components[key] = class_(name=name, - time_object=self.time_object, - **parobj[key].to_dict()) - if key not in parobj._valves: - self.set_v_sv(key) - else: - self.set_phi_sv(key) - self.components[key].setup() - - self.connect_modules(self.components['lv'], - self.components['ao'], - plabel='p_lv', - qlabel='q_ao') - self.connect_modules(self.components['ao'], - self.components['sas'], - plabel='p_sas', - qlabel='q_ao') - self.connect_modules(self.components['sas'], - self.components['sat'], - plabel='p_sat', - qlabel='q_sas') - self.connect_modules(self.components['sat'], - self.components['svn'], - plabel='p_svn', - qlabel='q_sat') - self.connect_modules(self.components['svn'], - self.components['ra'], - plabel='p_ra', - qlabel='q_svn') - self.connect_modules(self.components['ra'], - self.components['ti'], - plabel='p_ra', - qlabel='q_ti') - self.connect_modules(self.components['ti'], - self.components['rv'], - plabel='p_rv', - qlabel='q_ti') - self.connect_modules(self.components['rv'], - self.components['po'], - plabel='p_rv', - qlabel='q_po') - self.connect_modules(self.components['po'], - self.components['pas'], - plabel='p_pas', - qlabel='q_po') - self.connect_modules(self.components['pas'], - self.components['pat'], - plabel='p_pat', - qlabel='q_pas') - self.connect_modules(self.components['pat'], - self.components['pvn'], - plabel='p_pvn', - qlabel='q_pat') - self.connect_modules(self.components['pvn'], - self.components['la'], - plabel='p_la', - qlabel='q_pvn') - self.connect_modules(self.components['la'], - self.components['mi'], - plabel='p_la', - qlabel='q_mi') - self.connect_modules(self.components['mi'], - self.components['lv'], - plabel='p_lv', - qlabel='q_mi') - - for component in self.components.values(): - component.setup() - - def set_phi_sv(self, comp_key:str) -> None: - phi_key = 'phi_' + comp_key - self._state_variable_dict[phi_key] = self.components[comp_key]._PHI - self._state_variable_dict[phi_key].set_name(phi_key) - self.all_sv_data[phi_key] = self.components[comp_key].PHI \ No newline at end of file diff --git a/src/ModularCirc/Models/KorakianitisMixedMaynardModel_parameters.py b/src/ModularCirc/Models/KorakianitisMixedMaynardModel_parameters.py deleted file mode 100644 index 6dc1d8f..0000000 --- a/src/ModularCirc/Models/KorakianitisMixedMaynardModel_parameters.py +++ /dev/null @@ -1,88 +0,0 @@ -from ..HelperRoutines import activation_function_2, activation_function_3 -from .ParametersObject import ParametersObject -import pandas as pd - - -KORAKIANITIS_2006_COMPONENTS = [ - 'la', # left atrium - 'mi', # mitral valve - 'lv', # left ventricle - 'ao', # aortic valve - 'sas', # systemic aortic sinus - 'sat', # systemic artery - 'svn', # systemic vein - 'ra', # right atrium - 'ti', # tricuspid vale - 'rv', # right ventricle - 'po', # pulmonary valve - 'pas', # pulmonary artery sinus - 'pat', # pulmonary artery - 'pvn' # pulmonary vein - ] -VESSELS = ['sas', 'sat', 'svn', 'pas', 'pat', 'pvn'] -VESSELS_PAR = ['r', 'c', 'l', 'v_ref', 'v', 'p'] - -VALVES = ['mi', 'ao', 'ti', 'po'] -VALVES_PAR = ['CQ', 'RRA', 'Ko', 'Kc', 'R', 'L'] - -CHAMBERS = ['la', 'lv', 'ra', 'rv'] -CHAMBERS_PAR = ['E_pas', 'E_act', 'v_ref', 'k_pas', 'af', 'v', 'p', 'tr', 'td', 'delay', 'tpww', 'tpwb'] - - -class KorakianitisMixedMaynardModel_parameters(ParametersObject): - """ - Intro - ----- - Model Parameters based on Korakianitis and Shi (2006) with Maynard (2012) valves - """ - def __init__(self, name='Korakianitis 2006') -> None: - super().__init__(name=name) - self.components = {key : None for key in KORAKIANITIS_2006_COMPONENTS} - for type_, type_var in [[VESSELS, VESSELS_PAR], [VALVES, VALVES_PAR], [CHAMBERS, CHAMBERS_PAR]]: - for key in type_: - self[key] = pd.Series(index=type_var, dtype=object) - - self._vessels = VESSELS - self._valves = VALVES - self._chambers= CHAMBERS - - self.set_chamber_comp('lv', E_pas= 0.1, E_act= 2.5, v_ref=5.0, k_pas=0.1, tr = 0.30, td = 0.450, v=50.) - self.set_chamber_comp('la', E_pas= 0.15, E_act= 0.25, v_ref=4.0, k_pas=0.1, tpwb = 0.0, tpww = 0.09, delay=0.08, v=0.0) - self.set_chamber_comp('rv', E_pas= 0.1, E_act= 1.15, v_ref=10., k_pas=0.1, tr=0.30, td=0.45, v=100.) - self.set_chamber_comp('ra', E_pas= 0.15, E_act= 0.25, v_ref=4., k_pas=0.1, tpwb=0.0, tpww=0.09, delay=0.08, v=0.0) - - self.set_activation_function('lv', af=activation_function_2) - self.set_activation_function('rv', af=activation_function_2) - - self.set_activation_function('la', af=activation_function_3) - self.set_activation_function('ra', af=activation_function_3) - - - # systemic circulation - self.set_rlc_comp('sas', r=0.003, c=0.08, l=0.000062, v=450.0, v_ref=0.0) - self.set_rlc_comp('sat', r=(0.05 + 0.5 + 0.52), c=1.6 , l=0.0017 , v=0.0, v_ref=0.0) - self.set_rlc_comp('svn', r=0.075, c=20.5, v=0.0, v_ref=0.0) - - # pulmonary circulation - self.set_rlc_comp('pas', r=0.002 , c=0.18, l=0.000052, v=200.0, v_ref=0.0) - self.set_rlc_comp('pat', r=(0.01+0.05+0.25), c=3.8 , l=0.0017 , v=0.0, v_ref=0.0) - self.set_rlc_comp('pvn', r=0.006 , c=20.5 , v=0.0, v_ref=0.0) - - # valves - dyn = 1333.22 - self.set_valve_comp('ao', CQ=350., RRA=0.0, Ko = 0.012/dyn, Kc = 0.012/dyn, L=0.0, R=0.0) - self.set_valve_comp('mi', CQ=400., RRA=0.0, Ko = 0.03/dyn, Kc = 0.04/dyn, L=0.0, R=0.0 ) - self.set_valve_comp('po', CQ=350., RRA=0.0, Ko = 0.02/dyn, Kc = 0.02/dyn, L=0.0, R=0.0 ) - self.set_valve_comp('ti', CQ=400., RRA=0.0, Ko = 0.03/dyn, Kc = 0.04/dyn, L=0.0, R=0.0 ) - - def set_chamber_comp(self, key, **kwargs): - self._set_comp(key=key, set=CHAMBERS, **kwargs) - - def set_activation_function(self, key, af): - self._set_comp(key, set=CHAMBERS, af=af) - - def set_rlc_comp(self, key, **kwargs): - self._set_comp(key=key, set=VESSELS, **kwargs) - - def set_valve_comp(self, key, **kwargs): - self._set_comp(key=key, set=VALVES, **kwargs) diff --git a/src/ModularCirc/Models/KorakianitisModel.py b/src/ModularCirc/Models/KorakianitisModel.py deleted file mode 100644 index 1592487..0000000 --- a/src/ModularCirc/Models/KorakianitisModel.py +++ /dev/null @@ -1,104 +0,0 @@ -from .OdeModel import OdeModel -from .KorakianitisModel_parameters import KorakianitisModel_parameters as k2006 -from .ParametersObject import ParametersObject as po -from ..Components import Rlc_component, Valve_simple_bernoulli, HC_constant_elastance - -FULL_NAMES =[ - 'LeftA', - 'MiValve', - 'LeftV', - 'AoV', - 'SysAoSin', - 'SysArt', - 'SysVen', - 'RightA', - 'TriValve', - 'RightV', - 'PulV', - 'PulArtSin', - 'PulArt', - 'PulVen', -] - -class KorakianitisModel(OdeModel): - def __init__(self, time_setup_dict, parobj:po=k2006, suppress_printing:bool=False) -> None: - super().__init__(time_setup_dict) - self.name = 'KorakianitisModel' - - if not suppress_printing: print(parobj) - - # The components... - for key, name in zip(parobj.components.keys(), FULL_NAMES): - if key in parobj._vessels: - class_ = Rlc_component - elif key in parobj._valves: - class_ = Valve_simple_bernoulli - elif key in parobj._chambers: - class_ = HC_constant_elastance - else: - raise Exception(f'Component name {key} not in the model list.') - self.components[key] = class_(name=name, - time_object=self.time_object, - **parobj[key].to_dict()) - if key not in parobj._valves: self.set_v_sv(key) - self.components[key].setup() - - self.connect_modules(self.components['lv'], - self.components['ao'], - plabel='p_lv', - qlabel='q_ao') - self.connect_modules(self.components['ao'], - self.components['sas'], - plabel='p_sas', - qlabel='q_ao') - self.connect_modules(self.components['sas'], - self.components['sat'], - plabel='p_sat', - qlabel='q_sas') - self.connect_modules(self.components['sat'], - self.components['svn'], - plabel='p_svn', - qlabel='q_sat') - self.connect_modules(self.components['svn'], - self.components['ra'], - plabel='p_ra', - qlabel='q_svn') - self.connect_modules(self.components['ra'], - self.components['ti'], - plabel='p_ra', - qlabel='q_ti') - self.connect_modules(self.components['ti'], - self.components['rv'], - plabel='p_rv', - qlabel='q_ti') - self.connect_modules(self.components['rv'], - self.components['po'], - plabel='p_rv', - qlabel='q_po') - self.connect_modules(self.components['po'], - self.components['pas'], - plabel='p_pas', - qlabel='q_po') - self.connect_modules(self.components['pas'], - self.components['pat'], - plabel='p_pat', - qlabel='q_pas') - self.connect_modules(self.components['pat'], - self.components['pvn'], - plabel='p_pvn', - qlabel='q_pat') - self.connect_modules(self.components['pvn'], - self.components['la'], - plabel='p_la', - qlabel='q_pvn') - self.connect_modules(self.components['la'], - self.components['mi'], - plabel='p_la', - qlabel='q_mi') - self.connect_modules(self.components['mi'], - self.components['lv'], - plabel='p_lv', - qlabel='q_mi') - - for component in self.components.values(): - component.setup() \ No newline at end of file diff --git a/src/ModularCirc/Models/KorakianitisModel_parameters.py b/src/ModularCirc/Models/KorakianitisModel_parameters.py deleted file mode 100644 index e4414f5..0000000 --- a/src/ModularCirc/Models/KorakianitisModel_parameters.py +++ /dev/null @@ -1,98 +0,0 @@ -from ..HelperRoutines import activation_function_2, activation_function_3 -from .ParametersObject import ParametersObject -import pandas as pd - - -KORAKIANITIS_2006_COMPONENTS = [ - 'la', # left atrium - 'mi', # mitral valve - 'lv', # left ventricle - 'ao', # aortic valve - 'sas', # systemic aortic sinus - 'sat', # systemic artery - 'svn', # systemic vein - 'ra', # right atrium - 'ti', # tricuspid vale - 'rv', # right ventricle - 'po', # pulmonary valve - 'pas', # pulmonary artery sinus - 'pat', # pulmonary artery - 'pvn' # pulmonary vein - ] -VESSELS = ['sas', 'sat', 'svn', 'pas', 'pat', 'pvn'] -VESSELS_PAR = ['r', 'c', 'l', 'v_ref', 'v', 'p'] - -VALVES = ['mi', 'ao', 'ti', 'po'] -VALVES_PAR = ['CQ', 'RRA'] - -CHAMBERS = ['la', 'lv', 'ra', 'rv'] -CHAMBERS_PAR = ['E_pas', 'E_act', 'v_ref', 'af', 'v', 'p', 'tr', 'td', 'delay', 'tpww', 'tpwb'] - -# TIMINGS = [] - -class KorakianitisModel_parameters(ParametersObject): - """ - Intro - ----- - Model Parameters based on Korakianitis and Shi (2006) - """ - def __init__(self, name='Korakianitis 2006') -> None: - super().__init__(name=name) - self.components = {key : None for key in KORAKIANITIS_2006_COMPONENTS} - for type_, type_var in [[VESSELS, VESSELS_PAR], [VALVES, VALVES_PAR], [CHAMBERS, CHAMBERS_PAR]]: - for key in type_: - self[key] = pd.Series(index=type_var, dtype=object) - - # self.timings = {key : pd.Series(index=TIMINGS) for key in CHAMBERS} - - self._vessels = VESSELS - self._valves = VALVES - self._chambers= CHAMBERS - - self.set_chamber_comp('lv', E_pas= 0.1, E_act= 2.5, v_ref=5.0, tr = 0.30, td = 0.450, v=500.) - self.set_chamber_comp('la', E_pas= 0.15, E_act= 0.25, v_ref=4.0, tpwb = 0.0, tpww = 0.09, delay=0.08, v=0.0) - self.set_chamber_comp('rv', E_pas= 0.1, E_act= 1.15, v_ref=10., tr=0.30, td=0.45, v=400.) - self.set_chamber_comp('ra', E_pas= 0.15, E_act= 0.25, v_ref=4., tpwb=0.0, tpww=0.09, delay=0.08, v=0.0) - - self.set_activation_function('lv', af=activation_function_2) - self.set_activation_function('rv', af=activation_function_2) - - self.set_activation_function('la', af=activation_function_3) - self.set_activation_function('ra', af=activation_function_3) - - - # systemic circulation - self.set_rlc_comp('sas', r=0.003, c=0.08, l=0.000062, v=0.0, v_ref=0.0) - self.set_rlc_comp('sat', r=(0.05 + 0.5 + 0.52), c=1.6 , l=0.0017 , v=0.0, v_ref=0.0) - self.set_rlc_comp('svn', r=0.075, c=20.5, v=0.0, v_ref=0.0) - - # pulmonary circulation - self.set_rlc_comp('pas', r=0.002 , c=0.18, l=0.000052, v=0.0, v_ref=0.0) - self.set_rlc_comp('pat', r=(0.01+0.05+0.25), c=3.8 , l=0.0017 , v=0.0, v_ref=0.0) - self.set_rlc_comp('pvn', r=0.006 , c=20.5 , v=0.0, v_ref=0.0) - - # valves - self.set_valve_comp('ao', CQ=350., RRA=0.0) - self.set_valve_comp('mi', CQ=400., RRA=0.0) - self.set_valve_comp('po', CQ=350., RRA=0.0) - self.set_valve_comp('ti', CQ=400., RRA=0.0) - - def set_chamber_comp(self, key, **kwargs): - self._set_comp(key=key, set=CHAMBERS, **kwargs) - - def set_activation_function(self, key, af): - self._set_comp(key, set=CHAMBERS, af=af) - - def set_rlc_comp(self, key, **kwargs): - self._set_comp(key=key, set=VESSELS, **kwargs) - - def set_valve_comp(self, key, **kwargs): - self._set_comp(key=key, set=VALVES, **kwargs) - - def set(self, key, **kwargs): - if key in CHAMBERS: - self._set_comp(key=key, set=CHAMBERS, **kwargs) - if key in VESSELS: - self._set_comp(key=key, set=VESSELS, **kwargs) - if key in VALVES: - self._set_comp(key=key, set=VALVES, **kwargs) diff --git a/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel.py b/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel.py deleted file mode 100644 index 49a1203..0000000 --- a/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel.py +++ /dev/null @@ -1,132 +0,0 @@ -from .OdeModel import OdeModel -from .MixedHeartMaynard4eWindkessel_parameters import MixedHeartMaynard4eWindkessel_parameters as MHM4W_parobj -from .ParametersObject import ParametersObject as po -from ..Components import Rlc_component, Valve_maynard, \ - HC_mixed_elastance, R_component, Valve_non_ideal, \ - HC_constant_elastance, Valve_simple_bernoulli - -FULL_NAMES =[ - 'LeftA', - 'MiValve', - 'LeftV', - 'AoV', - 'SysArtImp', - 'SysArt', - 'SysCap', - 'SysVen', - 'RightA', - 'TriValve', - 'RightV', - 'PulV', - 'PulArtImp', - 'PulArt', - 'PulCap', - 'PulVen', -] - -class MixedHeartMaynard4eWindkessel(OdeModel): - def __init__(self, time_setup_dict, parobj:po=MHM4W_parobj) -> None: - super().__init__(time_setup_dict) - self.name = 'MixedHeartMaynard4eWindkessel' - - print(parobj) - - # The components... - for key, name in zip(parobj.components.keys(), FULL_NAMES): - if key in parobj._vessels: - class_ = Rlc_component - elif key in parobj._imp or key in parobj._cap: - class_ = R_component - elif key in parobj._valves: - class_ = Valve_simple_bernoulli # Valve_non_ideal # Valve_maynard # Valve_simple_bernoulli - elif key in parobj._chambers: - class_ = HC_constant_elastance # HC_mixed_elastance HC_constant_elastance - else: - raise Exception(f'Component name {key} not in the model list.') - self.components[key] = class_(name=name, - time_object=self.time_object, - **parobj[key].to_dict()) - - if key not in parobj._valves + parobj._cap + parobj._imp: - self.set_v_sv(key) - # else: - # self.set_phi_sv(key) - self.components[key].setup() - - self.connect_modules(self.components['lv'], - self.components['ao'], - plabel='p_lv', - qlabel='q_ao', - ) - self.connect_modules(self.components['ao'], - self.components['sai'], - plabel='p_sa', - qlabel='q_ao') - self.connect_modules(self.components['sai'], - self.components['sa'], - plabel='pi_sa', - qlabel='q_ao', - qvariable=self.components['ao']._Q_o) - self.connect_modules(self.components['sa'], - self.components['sc'], - plabel='p_sc', - qlabel='q_sa') - self.connect_modules(self.components['sc'], - self.components['sv'], - plabel='p_sv', - qlabel='q_sa', - qvariable=self.components['sa']._Q_o) - self.connect_modules(self.components['sv'], - self.components['ra'], - plabel='p_ra', - qlabel='q_sv') - self.connect_modules(self.components['ra'], - self.components['ti'], - plabel='p_ra', - qlabel='q_ti') - self.connect_modules(self.components['ti'], - self.components['rv'], - plabel='p_rv', - qlabel='q_ti') - self.connect_modules(self.components['rv'], - self.components['po'], - plabel='p_rv', - qlabel='q_po') - self.connect_modules(self.components['po'], - self.components['pai'], - plabel='p_pa', - qlabel='q_po') - self.connect_modules(self.components['pai'], - self.components['pa'], - plabel='pi_pa', - qlabel='q_po', - qvariable=self.components['po']._Q_o) - self.connect_modules(self.components['pa'], - self.components['pc'], - plabel='p_pc', - qlabel='q_pa') - self.connect_modules(self.components['pc'], - self.components['pv'], - plabel='p_pv', - qlabel='q_pa', - qvariable=self.components['pa']._Q_o) - self.connect_modules(self.components['pv'], - self.components['la'], - plabel='p_la', - qlabel='q_pv') - self.connect_modules(self.components['la'], - self.components['mi'], - plabel='p_la', - qlabel='q_mi') - self.connect_modules(self.components['mi'], - self.components['lv'], - plabel='p_lv', - qlabel='q_mi') - for component in self.components.values(): - component.setup() - - def set_phi_sv(self, comp_key:str) -> None: - phi_key = 'phi_' + comp_key - self._state_variable_dict[phi_key] = self.components[comp_key]._PHI - self._state_variable_dict[phi_key].set_name(phi_key) - self.all_sv_data[phi_key] = self.components[comp_key].PHI \ No newline at end of file diff --git a/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel_parameters.py b/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel_parameters.py deleted file mode 100644 index 388363a..0000000 --- a/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel_parameters.py +++ /dev/null @@ -1,132 +0,0 @@ -from ..HelperRoutines import activation_function_2, activation_function_3, relu_max, softplus -from .ParametersObject import ParametersObject -import pandas as pd - - -MHM4WK_COMPONENTS = [ - 'la', # left atrium - 'mi', # mitral valve - 'lv', # left ventricle - 'ao', # aortic valve - 'sai', # systemic aortic impedance - 'sa', # systemic artery - 'sc', # systemic capilary bed - 'sv', # systemic vein - 'ra', # right atrium - 'ti', # tricuspid vale - 'rv', # right ventricle - 'po', # pulmonary valve - 'pai', # pulmonary artery impedance - 'pa', # pulmonary artery - 'pc', # pulmonary capilary - 'pv', # pulmonary vein - ] -VESSELS = ['sa', 'sv', 'pa', 'pv'] -VESSELS_PAR = ['r', 'c', 'l', 'v_ref', 'v', 'p'] - -VALVES = ['mi', 'ao', 'ti', 'po'] -# VALVES_PAR = ['CQ', 'RRA', 'Ko', 'Kc', 'R', 'L'] -# VALVES_PAR = ['r', 'max_func'] -VALVES_PAR = ['CQ', 'RRA'] - - -CHAMBERS = ['la', 'lv', 'ra', 'rv'] -CHAMBERS_PAR = ['E_pas', 'E_act', 'v_ref', 'k_pas', 'af', 'v', 'p', 'tr', 'td', 'delay', 'tpww', 'tpwb'] - -IMPEDANCES = ['sai', 'pai'] -IMPEDANCES_PAR = ['r'] - -CAPILARIES = ['sc', 'pc'] -CAPILARIES_PAR = ['r'] - -OBJ_PAR_PAIRS = [[VESSELS, VESSELS_PAR], - [VALVES, VALVES_PAR], - [CHAMBERS, CHAMBERS_PAR], - [IMPEDANCES, IMPEDANCES_PAR], - [CAPILARIES, CAPILARIES_PAR]] - -class MixedHeartMaynard4eWindkessel_parameters(ParametersObject): - """ - Intro - ----- - Model Parameters for MixedHeartMaynard4eWindkessel models - """ - def __init__(self, name='MixedHeartMaynard4eWindkessel_parameters') -> None: - super().__init__(name=name) - self.components = {key : None for key in MHM4WK_COMPONENTS} - for type_, type_var in OBJ_PAR_PAIRS: - for key in type_: - self[key] = pd.Series(index=type_var, dtype=object) - - self._vessels = VESSELS - self._valves = VALVES - self._chambers= CHAMBERS - self._imp = IMPEDANCES - self._cap = CAPILARIES - - self.set_chamber_comp('lv', E_pas= 0.1, E_act= 2.5, k_pas=0.03, v_ref=5.0, tr = 0.30, td = 0.450, v=50.) - self.set_chamber_comp('la', E_pas= 0.15, E_act= 0.25, k_pas=0.03, v_ref=4.0, tpwb = 0.0, tpww = 0.09, delay=0.08, v=0.0) - self.set_chamber_comp('rv', E_pas= 0.1, E_act= 1.15, k_pas=0.03, v_ref=10., tr =0.30, td=0.45, v=50.) - self.set_chamber_comp('ra', E_pas= 0.15, E_act= 0.25, k_pas=0.03, v_ref=4., tpwb=0.0, tpww=0.09, delay=0.08, v=0.0) - - self.set_activation_function('lv', af=activation_function_2) - self.set_activation_function('rv', af=activation_function_2) - - self.set_activation_function('la', af=activation_function_3) - self.set_activation_function('ra', af=activation_function_3) - - - # systemic circulation - self.set_rlc_comp('sa', r=0.05, c=1.6 , l=0.0017 , v=450.0, v_ref=0.0) - self.set_rlc_comp('sv', r=0.075, c=20.5, v=0.0, v_ref=0.0) - - # set impedances - self.set_resistance('sai', r = 0.003) - self.set_resistance('pai', r = 0.002) - - # pulmonary circulation - self.set_rlc_comp('pa', r=0.01, c=3.8 , l=0.0017 , v=250.0, v_ref=0.0) - self.set_rlc_comp('pv', r=0.006, c=20.5 , v=0.0, v_ref=0.0) - - # set capilary resistances - self.set_resistance('sc', r = 0.5 + 0.52) - self.set_resistance('pc', r = 0.05 + 0.25) - - # valves - ##################################################### - # self.set_valve_comp('ao', r=0.01, max_func=relu_max) - # self.set_valve_comp('mi', r=0.01, max_func=relu_max) - # self.set_valve_comp('po', r=0.01, max_func=relu_max) - # self.set_valve_comp('ti', r=0.01, max_func=relu_max) - ##################################################### - # self.set_valve_comp('ao', r=0.01, max_func=softplus) - # self.set_valve_comp('mi', r=0.01, max_func=softplus) - # self.set_valve_comp('po', r=0.01, max_func=softplus) - # self.set_valve_comp('ti', r=0.01, max_func=softplus) - ##################################################### - # self.set_valve_comp('ao', CQ=350., RRA=0.0, Ko = 26., Kc = 2e3, L=0.0, R=0.0) - # self.set_valve_comp('mi', CQ=400., RRA=0.0, Ko = 40., Kc = 2e3, L=0.0, R=0.0 ) - # self.set_valve_comp('po', CQ=350., RRA=0.0, Ko = 40., Kc = 18e3,L=0.0, R=0.0 ) - # self.set_valve_comp('ti', CQ=400., RRA=0.0, Ko = 40., Kc = 2e3, L=0.0, R=0.0 ) - ##################################################### - self.set_valve_comp('ao', CQ=350., RRA=0.0) - self.set_valve_comp('mi', CQ=400., RRA=0.0) - self.set_valve_comp('po', CQ=350., RRA=0.0) - self.set_valve_comp('ti', CQ=400., RRA=0.0) - ##################################################### - - - def set_chamber_comp(self, key, **kwargs): - self._set_comp(key=key, set=CHAMBERS, **kwargs) - - def set_activation_function(self, key, af): - self._set_comp(key, set=CHAMBERS, af=af) - - def set_rlc_comp(self, key, **kwargs): - self._set_comp(key=key, set=VESSELS, **kwargs) - - def set_valve_comp(self, key, **kwargs): - self._set_comp(key=key, set=VALVES, **kwargs) - - def set_resistance(self, key, **kwargs): - self._set_comp(key=key, set=IMPEDANCES + CAPILARIES, **kwargs) From 2ca42455e10c888d903ebe7ad3b1cf5e6f7b7cb9 Mon Sep 17 00:00:00 2001 From: Levan Bokeria Date: Mon, 14 Apr 2025 15:35:38 +0100 Subject: [PATCH 2/8] Update README.md deleting description of models that are not going to be published --- src/ModularCirc/Models/README.md | 54 ++++---------------------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/src/ModularCirc/Models/README.md b/src/ModularCirc/Models/README.md index 9c1b30d..fe9d514 100644 --- a/src/ModularCirc/Models/README.md +++ b/src/ModularCirc/Models/README.md @@ -1,5 +1,5 @@ # Models directory -This file contains the description of the model and model parameter classes defined in this module. +This folder contains the description of the model and model parameter classes defined in this module. The models presented here are made of three types of components: - *arteries*: RLC components (complex) and R components (simple) - *chamber*: linear elatic (simple) and mixed (complex, linear active and exponential passive behaviour) @@ -24,10 +24,12 @@ The model is comprised of the following components: []() -## 2. Korakianitis and Shi model (V1) +## 2. Korakianitis and Shi model Relevant files and classes: -- `ModularCirc/Models/KorakianitisModel.py`, where the `KorakianitisModel` class is defined -- `ModularCirc/Models/KorakianitisModel_parameters.py`, where the `KorakianitisModel_parameters` class is defined +- `ModularCirc/Models/KorakianitisMixedModel.py`, where the `KorakianitisModel` class is defined +- `ModularCirc/Models/KorakianitisMixedModel_parameters.py`, where the `KorakianitisModel_parameters` class is defined + +(TO BE EDITED BY MAX) A simplified CV model described in A concentrated parameter model for the human cardiovascular system including heart valve dynamics and atrioventricular interaction (https://www.sciencedirect.com/science/article/pii/S1350453305002195?via%3Dihub). @@ -66,47 +68,3 @@ This model is comprised of the following components: **Total set of parameters sums up to 55.** []() - - -## 3. Korakianitis and Shi model (V2) -Relevant files and classes: -- `ModularCirc/Models/KorakianitisMaynardModel.py`, where the `KorakianitisMaynardModel` class is defined -- `ModularCirc/Models/KorakianitisMaynardModel_parameters.py`, where the `KorakianitisMaynardModel_parameters` class is defined - -This model follow the same strucutre as **Korakianitis and Shi model (V1)**, however the valves are replaced with Maynard type valves which are more similar to the ones used in the original paper. -**This introduces 2 additional parameters per valve (one for the valve closing rate and one for the opening rate).** - -Components used: -- arteries: RLC with sinuses being represented as a separate RLC component. (3/4 components) -- valves: **Maynard** valves (4 parameters) -- chambers: **linear models** (5/6 parameters of ventricles/arteries) - -**Total set of parameters sums up to 60.** - - -## 4. Korakianitis and Shi model (V3) -Relevant files and classes: -- `ModularCirc/Models/KorakianitisMixedMaynardModel.py`, where the `KorakianitisMixedMaynardModel` class is defined -- `ModularCirc/Models/KorakianitisMixedMaynardModel_parameters.py`, where the `KorakianitisMixedMaynardModel_parameters` class is defined. - -This model is again based on the orinal structure of **Korakianitis and Shi model (V1)**. -Here, the following components were used: -- chambers: **mixed models** (6/7 parameters of ventricles/arteries) -- valves: **Maynard** valves (4 parameters) -- arteries: RLC with sinuses being represented as a separate RLC component. (3/4 parameters) - -**Total parameter count: 64** - - -## 5. Simplified Korakianitis and Shi model (V1) -Relevant files and classes: -- `ModularCirc/Models/MixedHeartMaynard4eWindkessel.py`, where the `MixedHeartMaynard4eWindkessel` class is defined -- `ModularCirc/Models/MixedHeartMaynard4eWindkessel_parameters.py`, where the `MixedHeartMaynard4eWindkessel` class is defined. - -This model is again based on the orinal structure of **Korakianitis and Shi model (V1)**. -Here, the following components were used: -- chambers: **mixed models** (6/7 parameters of ventricles/arteries) -- valves: **Maynard** valves (4 parameters) -- arteries: RLC with sinuses represented as a separate R component and capilaries similarly by R. This equivalent to the systemic and pulmonary arterial system being simulated as 2 4-component Windkessels in series with one another. (7/8 parameters systemic + 7/8 parameters pulmonary) - -**Total parameter count: 58 or 56 (if you choose to add the capilary resistance to the resistance of the previous component)** \ No newline at end of file From 2d13ce7f698641fd9a5fa3074e5f05344f4508ea Mon Sep 17 00:00:00 2001 From: Levan Bokeria Date: Mon, 14 Apr 2025 15:41:02 +0100 Subject: [PATCH 3/8] Update README.md updateing readme --- README.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 7468a87..ae30875 100644 --- a/README.md +++ b/README.md @@ -7,16 +7,13 @@ The scope of this package is to provide a framework for building **0D models** and **simulating cardiovascular flow** and **mechanics**. Conceptually, the models can be split into three types of components: 1. **Heart chambers** 2. **Valves** -3. **Vessels** +3. **Vessels** -## Clone the ModularCirc GitHub repo locally +The current version of the published package contains two models: +1. Naghavi model. +2. Korakianitis Mixed model. -Run: - -``` -git clone https://github.com/alan-turing-institute/ModularCirc -cd ModularCirc -``` +For other models currently under development, see the `dev` branch. ## Setup Conda or python virtual environment @@ -43,15 +40,24 @@ Activate the python environment: `source venv/bin/activate` Proceed to installing the ModularCirc package. -## Installation +## Installation through pip To install the pip package: ```bash -python -m pip install ModularCirc_LevanBokeria +python -m pip install ModularCirc ``` -From source: +## Installation from source: + +### Clone the ModularCirc GitHub repo locally + +Run: + +``` +git clone https://github.com/alan-turing-institute/ModularCirc +cd ModularCirc +``` After downloading the GitHub repository, from the repo directory run: From 54b25e8dc1aa834d1888d79a9eb10193a0d751e0 Mon Sep 17 00:00:00 2001 From: Levan Bokeria Date: Mon, 14 Apr 2025 15:43:20 +0100 Subject: [PATCH 4/8] Update README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ae30875..e2c1820 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,9 @@ Activate the python environment: `source venv/bin/activate` Proceed to installing the ModularCirc package. -## Installation through pip +## Installing ModularCirc + +### pip install To install the pip package: @@ -48,9 +50,9 @@ To install the pip package: python -m pip install ModularCirc ``` -## Installation from source: +### Installation from source: -### Clone the ModularCirc GitHub repo locally +Clone the ModularCirc GitHub repo locally. Run: From b224b8693e79e0849ba9b62d3a7445cbd798cee7 Mon Sep 17 00:00:00 2001 From: Maximilian Balmus Date: Mon, 14 Apr 2025 16:15:14 +0100 Subject: [PATCH 5/8] update src/ModularCirc/Models/README.md to contain more information about the KorakianitisMixedModel --- src/ModularCirc/Models/README.md | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/ModularCirc/Models/README.md b/src/ModularCirc/Models/README.md index fe9d514..653b91f 100644 --- a/src/ModularCirc/Models/README.md +++ b/src/ModularCirc/Models/README.md @@ -7,8 +7,8 @@ The models presented here are made of three types of components: ## 1. Naghavi et al. model Relevant files and classes: -- `ModularCirc/Models/NaghaviModel.py`, where the `NaghaviModel` class is defined -- `ModularCirc/Models/NaghaviModelParameters.py`, where the `NaghaviModelParameters` class is defined. +- `src/ModularCirc/Models/NaghaviModel.py`, where the `NaghaviModel` class is defined +- `src/ModularCirc/Models/NaghaviModelParameters.py`, where the `NaghaviModelParameters` class is defined. A CV model described in Rapid Estimation of Left Ventricular Contractility with a Physics-Informed Neural Network Inverse Modeling Approach (https://arxiv.org/html/2401.07331v1). The model is comprised of the following components: @@ -26,21 +26,19 @@ The model is comprised of the following components: ## 2. Korakianitis and Shi model Relevant files and classes: -- `ModularCirc/Models/KorakianitisMixedModel.py`, where the `KorakianitisModel` class is defined -- `ModularCirc/Models/KorakianitisMixedModel_parameters.py`, where the `KorakianitisModel_parameters` class is defined - -(TO BE EDITED BY MAX) +- `src/ModularCirc/Models/KorakianitisMixedModel.py`, where the `KorakianitisMixedModel` class is defined +- `src/ModularCirc/Models/KorakianitisMixedModel_parameters.py`, where the `KorakianitisMixedModel_parameters` class is defined A simplified CV model described in A concentrated parameter model for the human cardiovascular system including heart valve dynamics and atrioventricular interaction (https://www.sciencedirect.com/science/article/pii/S1350453305002195?via%3Dihub). -**Here, we simplified the model by eliminating (1) the motion of the annulus fibrosus and (2) the motion of the leaflets, replaced with a simple Bernoulli model.** +**In KorakianitisMixedModel, we simplified the model by eliminating (1) the motion of the annulus fibrosus, (2) the motion of the leaflets, replaced with a simple Bernoulli model and (3) the cardiac chamber laws are replaced with mixed law (exponential for the passive filling and linear for contraction).** This model is comprised of the following components: -- left atrium: linear time-varying elastance model - - **6 parameters** +- left atrium: time-varying elastance model, based on weighted sum of passive (exponential) and active (linear) laws + - **7 parameters** - mitral valve: simple Bernoulli model - **2 parameters** -- left ventricle: linear time-varying elastance model - - **5 parameters** +- left ventricle: time-varying elastance model, based on weighted sum of passive (exponential) and active (linear) laws + - **6 parameters** - aortic valve: simple Bernoulli model - **2 parameters** - aortic sinus (RLC 3 component windkessel) @@ -50,12 +48,12 @@ This model is comprised of the following components: - **4 parameters** - systemic venous system (RLC 3 component windkessel) - **3 parameters** (assume that venous impedance is zero) -- right atrium: linear time-varying elastance model - - **6 parameters** +- right atrium: time-varying elastance model, based on weighted sum of passive (exponential) and active (linear) laws + - **7 parameters** - tricuspid valve: simple Bernoulli model - **2 parameters** -- right ventricle: linear time-varying elastance model - - **5 parameters** +- right ventricle: time-varying elastance model, based on weighted sum of passive (exponential) and active (linear) laws + - **6 parameters** - pulmonary valve: simple Bernoulli model - **2 parameters** - pulmonary artery sinus (RLC 3 component windkessel) @@ -65,6 +63,6 @@ This model is comprised of the following components: - pulmonary venous system (RLC 3 component windessel) - **3 parameters** (assume that venous impedance is zero) -**Total set of parameters sums up to 55.** +**Total set of parameters sums up to 57.** []() From 6e8ccf1490bb7217f1314377d459a23e8394ec64 Mon Sep 17 00:00:00 2001 From: Levan Bokeria Date: Mon, 14 Apr 2025 17:34:03 +0100 Subject: [PATCH 6/8] Update README.md removing tests section from the main readme --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index e2c1820..47adf69 100644 --- a/README.md +++ b/README.md @@ -130,14 +130,6 @@ p_lv = solver.model.components['lv'].P_i.values ## Example values pv loops for all 4 chambers: ![Example PV loops!](Figures/PV_loops.png) -## Run tests - -You can run locally the tests by running the following command: -```bash - python -m unittest discover -s tests -``` -there is also a autamtated test pipeline that runs the tests on every push to the repository (see [here](.github/workflows/ci.yml)). - [actions-badge]: https://github.com/alan-turing-institute/ModularCirc/workflows/CI/badge.svg [actions-link]: https://github.com/alan-turing-institute/ModularCirc/actions From 1425d6350918b78bd178ed9546fbdba24b3e1a28 Mon Sep 17 00:00:00 2001 From: Levan Bokeria Date: Mon, 14 Apr 2025 17:43:56 +0100 Subject: [PATCH 7/8] updating the release version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 89b985f..2306df2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "ModularCirc" -version = "0.1.3" +version = "0.2.0" authors = [ {name = "Maximilian Balmus", email = "mbalmus@turing.ac.uk"} ] From 3bb428a2ec449e36f3e0ed64ceb549abc6040e34 Mon Sep 17 00:00:00 2001 From: Levan Bokeria Date: Thu, 17 Apr 2025 10:59:28 +0100 Subject: [PATCH 8/8] adding back models under development --- src/ModularCirc/Models/KPat5MixedModel.py | 136 ++++++++++++++++++ .../Models/KPat5MixedModel_parameters.py | 108 ++++++++++++++ .../Models/KorakianitisMaynardModel.py | 114 +++++++++++++++ .../KorakianitisMaynardModel_parameters.py | 88 ++++++++++++ .../Models/KorakianitisMixedMaynardModel.py | 113 +++++++++++++++ ...orakianitisMixedMaynardModel_parameters.py | 88 ++++++++++++ src/ModularCirc/Models/KorakianitisModel.py | 104 ++++++++++++++ .../Models/KorakianitisModel_parameters.py | 98 +++++++++++++ .../Models/MixedHeartMaynard4eWindkessel.py | 132 +++++++++++++++++ ...ixedHeartMaynard4eWindkessel_parameters.py | 132 +++++++++++++++++ 10 files changed, 1113 insertions(+) create mode 100644 src/ModularCirc/Models/KPat5MixedModel.py create mode 100644 src/ModularCirc/Models/KPat5MixedModel_parameters.py create mode 100644 src/ModularCirc/Models/KorakianitisMaynardModel.py create mode 100644 src/ModularCirc/Models/KorakianitisMaynardModel_parameters.py create mode 100644 src/ModularCirc/Models/KorakianitisMixedMaynardModel.py create mode 100644 src/ModularCirc/Models/KorakianitisMixedMaynardModel_parameters.py create mode 100644 src/ModularCirc/Models/KorakianitisModel.py create mode 100644 src/ModularCirc/Models/KorakianitisModel_parameters.py create mode 100644 src/ModularCirc/Models/MixedHeartMaynard4eWindkessel.py create mode 100644 src/ModularCirc/Models/MixedHeartMaynard4eWindkessel_parameters.py diff --git a/src/ModularCirc/Models/KPat5MixedModel.py b/src/ModularCirc/Models/KPat5MixedModel.py new file mode 100644 index 0000000..feb9644 --- /dev/null +++ b/src/ModularCirc/Models/KPat5MixedModel.py @@ -0,0 +1,136 @@ +from .OdeModel import OdeModel +from .KorakianitisModel_parameters import KorakianitisModel_parameters as k2006 +from .ParametersObject import ParametersObject as po +from ..Components import Rlc_component, Valve_simple_bernoulli, HC_mixed_elastance + +FULL_NAMES =[ + 'LeftA', + 'MiValve', + 'LeftV', + 'AoV', + 'SysAoSin', + 'SysArt', + 'SysVen', + 'RightA', + 'TriValve', + 'RightV', + 'PulV', + 'PulArtSin', + 'PulArt0', + 'PulArt1', + 'PulArt2', + 'PulArt3', + 'PulArt4', + 'PulVen', +] + +class KPat5MixedModel(OdeModel): + def __init__(self, time_setup_dict, parobj:po=k2006, suppress_printing:bool=False) -> None: + super().__init__(time_setup_dict) + self.name = 'KorakianitisModel' + + if not suppress_printing: print(parobj) + + # The components... + for key, name in zip(parobj.components.keys(), FULL_NAMES): + if key in parobj._vessels: + class_ = Rlc_component + elif key in parobj._valves: + class_ = Valve_simple_bernoulli + elif key in parobj._chambers: + class_ = HC_mixed_elastance + else: + raise Exception(f'Component name {key} not in the model list.') + self.components[key] = class_(name=name, + time_object=self.time_object, + **parobj[key].to_dict()) + if key not in parobj._valves: + self.set_v_sv(key) + # else: + # self.set_phi_sv(key) + self.components[key].setup() + + self.connect_modules(self.components['lv'], + self.components['ao'], + plabel='p_lv', + qlabel='q_ao') + self.connect_modules(self.components['ao'], + self.components['sas'], + plabel='p_sas', + qlabel='q_ao') + self.connect_modules(self.components['sas'], + self.components['sat'], + plabel='p_sat', + qlabel='q_sas') + self.connect_modules(self.components['sat'], + self.components['svn'], + plabel='p_svn', + qlabel='q_sat') + self.connect_modules(self.components['svn'], + self.components['ra'], + plabel='p_ra', + qlabel='q_svn') + self.connect_modules(self.components['ra'], + self.components['ti'], + plabel='p_ra', + qlabel='q_ti') + self.connect_modules(self.components['ti'], + self.components['rv'], + plabel='p_rv', + qlabel='q_ti') + self.connect_modules(self.components['rv'], + self.components['po'], + plabel='p_rv', + qlabel='q_po') + self.connect_modules(self.components['po'], + self.components['pas'], + plabel='p_pas', + qlabel='q_po') + ############################################ + self.connect_modules(self.components['pas'], + self.components['pat0'], + plabel='p_pat0', + qlabel='q_pas') + self.connect_modules(self.components['pat0'], + self.components['pat1'], + plabel='p_pat1', + qlabel='q_pat0') + self.connect_modules(self.components['pat1'], + self.components['pat2'], + plabel='p_pat2', + qlabel='q_pat1') + self.connect_modules(self.components['pat2'], + self.components['pat3'], + plabel='p_pat3', + qlabel='q_pat2') + self.connect_modules(self.components['pat3'], + self.components['pat4'], + plabel='p_pat4', + qlabel='q_pat3') + ############################################ + self.connect_modules(self.components['pat4'], + self.components['pvn'], + plabel='p_pvn', + qlabel='q_pat4') + ############################################ + self.connect_modules(self.components['pvn'], + self.components['la'], + plabel='p_la', + qlabel='q_pvn') + self.connect_modules(self.components['la'], + self.components['mi'], + plabel='p_la', + qlabel='q_mi') + self.connect_modules(self.components['mi'], + self.components['lv'], + plabel='p_lv', + qlabel='q_mi') + + for component in self.components.values(): + component.setup() + + # def set_phi_sv(self, comp_key:str) -> None: + # phi_key = 'phi_' + comp_key + # self._state_variable_dict[phi_key] = self.components[comp_key]._PHI + # self._state_variable_dict[phi_key].set_name(phi_key) + # self.all_sv_data[phi_key] = self.components[comp_key].PHI diff --git a/src/ModularCirc/Models/KPat5MixedModel_parameters.py b/src/ModularCirc/Models/KPat5MixedModel_parameters.py new file mode 100644 index 0000000..4a47578 --- /dev/null +++ b/src/ModularCirc/Models/KPat5MixedModel_parameters.py @@ -0,0 +1,108 @@ +from ..HelperRoutines import activation_function_2, activation_function_3 +from .ParametersObject import ParametersObject +import pandas as pd + + +KKPat10_COMPONENTS = [ + 'la', # left atrium + 'mi', # mitral valve + 'lv', # left ventricle + 'ao', # aortic valve + 'sas', # systemic aortic sinus + 'sat', # systemic artery + 'svn', # systemic vein + 'ra', # right atrium + 'ti', # tricuspid vale + 'rv', # right ventricle + 'po', # pulmonary valve + 'pas', # pulmonary artery sinus + ############################### + 'pat0', # pulmonary artery + 'pat1', # pulmonary artery + 'pat2', # pulmonary artery + 'pat3', # pulmonary artery + 'pat4', # pulmonary artery + ############################### + 'pvn' # pulmonary vein + ] +VESSELS = ['sas', 'sat', 'svn', 'pas', 'pat0', 'pat1', 'pat2', 'pat3', 'pat4', 'pvn'] +VESSELS_PAR = ['r', 'c', 'l', 'v_ref', 'v', 'p'] + +VALVES = ['mi', 'ao', 'ti', 'po'] +VALVES_PAR = ['CQ', 'RRA'] + +CHAMBERS = ['la', 'lv', 'ra', 'rv'] +CHAMBERS_PAR = ['E_pas', 'E_act', 'v_ref', 'k_pas', 'af', 'v', 'p', 'tr', 'td', 'delay', 'tpww', 'tpwb'] + + +class KPat5MixedModel_parameters(ParametersObject): + """ + Intro + ----- + Model Parameters based on Korakianitis and Shi (2006) + """ + def __init__(self, name='Korakianitis 2006') -> None: + super().__init__(name=name) + self.components = {key : None for key in KKPat10_COMPONENTS} + for type_, type_var in [[VESSELS, VESSELS_PAR], [VALVES, VALVES_PAR], [CHAMBERS, CHAMBERS_PAR]]: + for key in type_: + self[key] = pd.Series(index=type_var, dtype=object) + + self._vessels = VESSELS + self._valves = VALVES + self._chambers= CHAMBERS + + self.set_chamber_comp('lv', E_pas= 0.1, k_pas=0.01, E_act= 2.5, v_ref=50.0, tr = 0.30, td = 0.450, v=100.) + self.set_chamber_comp('la', E_pas= 0.15, k_pas=0.01, E_act= 0.25, v_ref=10.0, tpwb = 0.0, tpww = 0.09, delay=0.08, v=0.0) + self.set_chamber_comp('rv', E_pas= 0.1, k_pas=0.01, E_act= 1.15, v_ref=50., tr=0.30, td=0.45, v=100.) + self.set_chamber_comp('ra', E_pas= 0.15, k_pas=0.01, E_act= 0.25, v_ref=10., tpwb=0.0, tpww=0.09, delay=0.08, v=0.0) + + + self.set_activation_function('lv', af=activation_function_2) + self.set_activation_function('rv', af=activation_function_2) + + self.set_activation_function('la', af=activation_function_3) + self.set_activation_function('ra', af=activation_function_3) + + + # systemic circulation + self.set_rlc_comp('sas', r=0.003, c=0.08, l=0.000062, v=0.0, v_ref=0.0) + self.set_rlc_comp('sat', r=(0.05 + 0.5 + 0.52), c=1.6 , l=0.0017 , v=550.0, v_ref=0.0) + self.set_rlc_comp('svn', r=0.075, c=20.5, v=0.0, v_ref=0.0) + + # pulmonary circulation + self.set_rlc_comp('pas', r=0.002 , c=0.18, l=0.000052, v=0.0, v_ref=0.0) + ############################################################################################# + self.set_rlc_comp('pat0', r=(0.01/5.), c=(3.8/5.) , l=(0.0017/5.) , v=0.0, v_ref=0.0) + self.set_rlc_comp('pat1', r=(0.01/5.), c=(3.8/5.) , l=(0.0017/5.) , v=0.0, v_ref=0.0) + self.set_rlc_comp('pat2', r=(0.01/5.), c=(3.8/5.) , l=(0.0017/5.) , v=0.0, v_ref=0.0) + self.set_rlc_comp('pat3', r=(0.01/5.), c=(3.8/5. ), l=(0.0017/5. ) , v=0.0, v_ref=0.0) + self.set_rlc_comp('pat4', r=(0.01/5.+0.05+0.25), c=(3.8/5.) , l=(0.0017/5.), v=0.0, v_ref=0.0) + ############################################################################################# + self.set_rlc_comp('pvn', r=0.006 , c=20.5 , v=0.0, v_ref=0.0) + + # valves + self.set_valve_comp('ao', CQ=350., RRA=0.0) + self.set_valve_comp('mi', CQ=400., RRA=0.0) + self.set_valve_comp('po', CQ=350., RRA=0.0) + self.set_valve_comp('ti', CQ=400., RRA=0.0) + + def set_chamber_comp(self, key, **kwargs): + self._set_comp(key=key, set=CHAMBERS, **kwargs) + + def set_activation_function(self, key, af): + self._set_comp(key, set=CHAMBERS, af=af) + + def set_rlc_comp(self, key, **kwargs): + self._set_comp(key=key, set=VESSELS, **kwargs) + + def set_valve_comp(self, key, **kwargs): + self._set_comp(key=key, set=VALVES, **kwargs) + + def set(self, key, **kwargs): + if key in CHAMBERS: + self._set_comp(key=key, set=CHAMBERS, **kwargs) + if key in VESSELS: + self._set_comp(key=key, set=VESSELS, **kwargs) + if key in VALVES: + self._set_comp(key=key, set=VALVES, **kwargs) diff --git a/src/ModularCirc/Models/KorakianitisMaynardModel.py b/src/ModularCirc/Models/KorakianitisMaynardModel.py new file mode 100644 index 0000000..b923493 --- /dev/null +++ b/src/ModularCirc/Models/KorakianitisMaynardModel.py @@ -0,0 +1,114 @@ +from .OdeModel import OdeModel +from .KorakianitisModel_parameters import KorakianitisModel_parameters as k2006 +from .ParametersObject import ParametersObject as po +from ..Components import Rlc_component, Valve_maynard, HC_constant_elastance + +FULL_NAMES =[ + 'LeftA', + 'MiValve', + 'LeftV', + 'AoV', + 'SysAoSin', + 'SysArt', + 'SysVen', + 'RightA', + 'TriValve', + 'RightV', + 'PulV', + 'PulArtSin', + 'PulArt', + 'PulVen', +] + +class KorakianitisMaynardModel(OdeModel): + def __init__(self, time_setup_dict, parobj:po=k2006) -> None: + super().__init__(time_setup_dict) + self.name = 'KorakianitisModel' + + print(parobj) + + # The components... + for key, name in zip(parobj.components.keys(), FULL_NAMES): + if key in parobj._vessels: + class_ = Rlc_component + elif key in parobj._valves: + class_ = Valve_maynard + elif key in parobj._chambers: + class_ = HC_constant_elastance + else: + raise Exception(f'Component name {key} not in the model list.') + self.components[key] = class_(name=name, + time_object=self.time_object, + **parobj[key].to_dict()) + if key not in parobj._valves: + self.set_v_sv(key) + else: + self.set_phi_sv(key) + self.components[key].setup() + + self.connect_modules(self.components['lv'], + self.components['ao'], + plabel='p_lv', + qlabel='q_ao') + self.connect_modules(self.components['ao'], + self.components['sas'], + plabel='p_sas', + qlabel='q_ao') + self.connect_modules(self.components['sas'], + self.components['sat'], + plabel='p_sat', + qlabel='q_sas') + self.connect_modules(self.components['sat'], + self.components['svn'], + plabel='p_svn', + qlabel='q_sat') + self.connect_modules(self.components['svn'], + self.components['ra'], + plabel='p_ra', + qlabel='q_svn') + self.connect_modules(self.components['ra'], + self.components['ti'], + plabel='p_ra', + qlabel='q_ti') + self.connect_modules(self.components['ti'], + self.components['rv'], + plabel='p_rv', + qlabel='q_ti') + self.connect_modules(self.components['rv'], + self.components['po'], + plabel='p_rv', + qlabel='q_po') + self.connect_modules(self.components['po'], + self.components['pas'], + plabel='p_pas', + qlabel='q_po') + self.connect_modules(self.components['pas'], + self.components['pat'], + plabel='p_pat', + qlabel='q_pas') + self.connect_modules(self.components['pat'], + self.components['pvn'], + plabel='p_pvn', + qlabel='q_pat') + self.connect_modules(self.components['pvn'], + self.components['la'], + plabel='p_la', + qlabel='q_pvn') + self.connect_modules(self.components['la'], + self.components['mi'], + plabel='p_la', + qlabel='q_mi') + self.connect_modules(self.components['mi'], + self.components['lv'], + plabel='p_lv', + qlabel='q_mi') + + for component in self.components.values(): + component.setup() + + def set_phi_sv(self, comp_key:str) -> None: + phi_key = 'phi_' + comp_key + self._state_variable_dict[phi_key] = self.components[comp_key]._PHI + self._state_variable_dict[phi_key].set_name(phi_key) + self.all_sv_data[phi_key] = self.components[comp_key].PHI + self.components[comp_key]._PHI._u = self.all_sv_data[phi_key] diff --git a/src/ModularCirc/Models/KorakianitisMaynardModel_parameters.py b/src/ModularCirc/Models/KorakianitisMaynardModel_parameters.py new file mode 100644 index 0000000..6c9a840 --- /dev/null +++ b/src/ModularCirc/Models/KorakianitisMaynardModel_parameters.py @@ -0,0 +1,88 @@ +from ..HelperRoutines import activation_function_2, activation_function_3 +from .ParametersObject import ParametersObject +import pandas as pd + + +KORAKIANITIS_2006_COMPONENTS = [ + 'la', # left atrium + 'mi', # mitral valve + 'lv', # left ventricle + 'ao', # aortic valve + 'sas', # systemic aortic sinus + 'sat', # systemic artery + 'svn', # systemic vein + 'ra', # right atrium + 'ti', # tricuspid vale + 'rv', # right ventricle + 'po', # pulmonary valve + 'pas', # pulmonary artery sinus + 'pat', # pulmonary artery + 'pvn' # pulmonary vein + ] +VESSELS = ['sas', 'sat', 'svn', 'pas', 'pat', 'pvn'] +VESSELS_PAR = ['r', 'c', 'l', 'v_ref', 'v', 'p'] + +VALVES = ['mi', 'ao', 'ti', 'po'] +VALVES_PAR = ['CQ', 'RRA', 'Ko', 'Kc', 'R', 'L'] + +CHAMBERS = ['la', 'lv', 'ra', 'rv'] +CHAMBERS_PAR = ['E_pas', 'E_act', 'v_ref', 'k_pas', 'af', 'v', 'p', 'tr', 'td', 'delay', 'tpww', 'tpwb'] + + +class KorakianitisMaynardModel_parameters(ParametersObject): + """ + Intro + ----- + Model Parameters based on Korakianitis and Shi (2006) with Maynard (2012) valves + """ + def __init__(self, name='Korakianitis 2006') -> None: + super().__init__(name=name) + self.components = {key : None for key in KORAKIANITIS_2006_COMPONENTS} + for type_, type_var in [[VESSELS, VESSELS_PAR], [VALVES, VALVES_PAR], [CHAMBERS, CHAMBERS_PAR]]: + for key in type_: + self[key] = pd.Series(index=type_var, dtype=object) + + self._vessels = VESSELS + self._valves = VALVES + self._chambers= CHAMBERS + + self.set_chamber_comp('lv', E_pas= 0.1, E_act= 2.5, v_ref=5.0, k_pas=0.1, tr = 0.30, td = 0.450, v=500.) + self.set_chamber_comp('la', E_pas= 0.15, E_act= 0.25, v_ref=4.0, k_pas=0.1, tpwb = 0.0, tpww = 0.09, delay=0.08, v=0.0) + self.set_chamber_comp('rv', E_pas= 0.1, E_act= 1.15, v_ref=10., k_pas=0.1, tr=0.30, td=0.45, v=400.) + self.set_chamber_comp('ra', E_pas= 0.15, E_act= 0.25, v_ref=4., k_pas=0.1, tpwb=0.0, tpww=0.09, delay=0.08, v=0.0) + + self.set_activation_function('lv', af=activation_function_2) + self.set_activation_function('rv', af=activation_function_2) + + self.set_activation_function('la', af=activation_function_3) + self.set_activation_function('ra', af=activation_function_3) + + + # systemic circulation + self.set_rlc_comp('sas', r=0.003, c=0.08, l=0.000062, v=0.0, v_ref=0.0) + self.set_rlc_comp('sat', r=(0.05 + 0.5 + 0.52), c=1.6 , l=0.0017 , v=0.0, v_ref=0.0) + self.set_rlc_comp('svn', r=0.075, c=20.5, v=0.0, v_ref=0.0) + + # pulmonary circulation + self.set_rlc_comp('pas', r=0.002 , c=0.18, l=0.000052, v=0.0, v_ref=0.0) + self.set_rlc_comp('pat', r=(0.01+0.05+0.25), c=3.8 , l=0.0017 , v=0.0, v_ref=0.0) + self.set_rlc_comp('pvn', r=0.006 , c=20.5 , v=0.0, v_ref=0.0) + + # valves + dyn = 1333.22 + self.set_valve_comp('ao', CQ=350., RRA=0.0, Ko = 0.012/dyn, Kc = 0.012/dyn, L=0.0, R=0.0) + self.set_valve_comp('mi', CQ=400., RRA=0.0, Ko = 0.03/dyn, Kc = 0.04/dyn, L=0.0, R=0.0 ) + self.set_valve_comp('po', CQ=350., RRA=0.0, Ko = 0.02/dyn, Kc = 0.02/dyn, L=0.0, R=0.0 ) + self.set_valve_comp('ti', CQ=400., RRA=0.0, Ko = 0.03/dyn, Kc = 0.04/dyn, L=0.0, R=0.0 ) + + def set_chamber_comp(self, key, **kwargs): + self._set_comp(key=key, set=CHAMBERS, **kwargs) + + def set_activation_function(self, key, af): + self._set_comp(key, set=CHAMBERS, af=af) + + def set_rlc_comp(self, key, **kwargs): + self._set_comp(key=key, set=VESSELS, **kwargs) + + def set_valve_comp(self, key, **kwargs): + self._set_comp(key=key, set=VALVES, **kwargs) diff --git a/src/ModularCirc/Models/KorakianitisMixedMaynardModel.py b/src/ModularCirc/Models/KorakianitisMixedMaynardModel.py new file mode 100644 index 0000000..2e23339 --- /dev/null +++ b/src/ModularCirc/Models/KorakianitisMixedMaynardModel.py @@ -0,0 +1,113 @@ +from .OdeModel import OdeModel +from .KorakianitisModel_parameters import KorakianitisModel_parameters as k2006 +from .ParametersObject import ParametersObject as po +from ..Components import Rlc_component, Valve_maynard, HC_mixed_elastance + +FULL_NAMES =[ + 'LeftA', + 'MiValve', + 'LeftV', + 'AoV', + 'SysAoSin', + 'SysArt', + 'SysVen', + 'RightA', + 'TriValve', + 'RightV', + 'PulV', + 'PulArtSin', + 'PulArt', + 'PulVen', +] + +class KorakianitisMixedMaynardModel(OdeModel): + def __init__(self, time_setup_dict, parobj:po=k2006) -> None: + super().__init__(time_setup_dict) + self.name = 'KorakianitisModel' + + print(parobj) + + # The components... + for key, name in zip(parobj.components.keys(), FULL_NAMES): + if key in parobj._vessels: + class_ = Rlc_component + elif key in parobj._valves: + class_ = Valve_maynard + elif key in parobj._chambers: + class_ = HC_mixed_elastance + else: + raise Exception(f'Component name {key} not in the model list.') + self.components[key] = class_(name=name, + time_object=self.time_object, + **parobj[key].to_dict()) + if key not in parobj._valves: + self.set_v_sv(key) + else: + self.set_phi_sv(key) + self.components[key].setup() + + self.connect_modules(self.components['lv'], + self.components['ao'], + plabel='p_lv', + qlabel='q_ao') + self.connect_modules(self.components['ao'], + self.components['sas'], + plabel='p_sas', + qlabel='q_ao') + self.connect_modules(self.components['sas'], + self.components['sat'], + plabel='p_sat', + qlabel='q_sas') + self.connect_modules(self.components['sat'], + self.components['svn'], + plabel='p_svn', + qlabel='q_sat') + self.connect_modules(self.components['svn'], + self.components['ra'], + plabel='p_ra', + qlabel='q_svn') + self.connect_modules(self.components['ra'], + self.components['ti'], + plabel='p_ra', + qlabel='q_ti') + self.connect_modules(self.components['ti'], + self.components['rv'], + plabel='p_rv', + qlabel='q_ti') + self.connect_modules(self.components['rv'], + self.components['po'], + plabel='p_rv', + qlabel='q_po') + self.connect_modules(self.components['po'], + self.components['pas'], + plabel='p_pas', + qlabel='q_po') + self.connect_modules(self.components['pas'], + self.components['pat'], + plabel='p_pat', + qlabel='q_pas') + self.connect_modules(self.components['pat'], + self.components['pvn'], + plabel='p_pvn', + qlabel='q_pat') + self.connect_modules(self.components['pvn'], + self.components['la'], + plabel='p_la', + qlabel='q_pvn') + self.connect_modules(self.components['la'], + self.components['mi'], + plabel='p_la', + qlabel='q_mi') + self.connect_modules(self.components['mi'], + self.components['lv'], + plabel='p_lv', + qlabel='q_mi') + + for component in self.components.values(): + component.setup() + + def set_phi_sv(self, comp_key:str) -> None: + phi_key = 'phi_' + comp_key + self._state_variable_dict[phi_key] = self.components[comp_key]._PHI + self._state_variable_dict[phi_key].set_name(phi_key) + self.all_sv_data[phi_key] = self.components[comp_key].PHI diff --git a/src/ModularCirc/Models/KorakianitisMixedMaynardModel_parameters.py b/src/ModularCirc/Models/KorakianitisMixedMaynardModel_parameters.py new file mode 100644 index 0000000..1dd6299 --- /dev/null +++ b/src/ModularCirc/Models/KorakianitisMixedMaynardModel_parameters.py @@ -0,0 +1,88 @@ +from ..HelperRoutines import activation_function_2, activation_function_3 +from .ParametersObject import ParametersObject +import pandas as pd + + +KORAKIANITIS_2006_COMPONENTS = [ + 'la', # left atrium + 'mi', # mitral valve + 'lv', # left ventricle + 'ao', # aortic valve + 'sas', # systemic aortic sinus + 'sat', # systemic artery + 'svn', # systemic vein + 'ra', # right atrium + 'ti', # tricuspid vale + 'rv', # right ventricle + 'po', # pulmonary valve + 'pas', # pulmonary artery sinus + 'pat', # pulmonary artery + 'pvn' # pulmonary vein + ] +VESSELS = ['sas', 'sat', 'svn', 'pas', 'pat', 'pvn'] +VESSELS_PAR = ['r', 'c', 'l', 'v_ref', 'v', 'p'] + +VALVES = ['mi', 'ao', 'ti', 'po'] +VALVES_PAR = ['CQ', 'RRA', 'Ko', 'Kc', 'R', 'L'] + +CHAMBERS = ['la', 'lv', 'ra', 'rv'] +CHAMBERS_PAR = ['E_pas', 'E_act', 'v_ref', 'k_pas', 'af', 'v', 'p', 'tr', 'td', 'delay', 'tpww', 'tpwb'] + + +class KorakianitisMixedMaynardModel_parameters(ParametersObject): + """ + Intro + ----- + Model Parameters based on Korakianitis and Shi (2006) with Maynard (2012) valves + """ + def __init__(self, name='Korakianitis 2006') -> None: + super().__init__(name=name) + self.components = {key : None for key in KORAKIANITIS_2006_COMPONENTS} + for type_, type_var in [[VESSELS, VESSELS_PAR], [VALVES, VALVES_PAR], [CHAMBERS, CHAMBERS_PAR]]: + for key in type_: + self[key] = pd.Series(index=type_var, dtype=object) + + self._vessels = VESSELS + self._valves = VALVES + self._chambers= CHAMBERS + + self.set_chamber_comp('lv', E_pas= 0.1, E_act= 2.5, v_ref=5.0, k_pas=0.1, tr = 0.30, td = 0.450, v=50.) + self.set_chamber_comp('la', E_pas= 0.15, E_act= 0.25, v_ref=4.0, k_pas=0.1, tpwb = 0.0, tpww = 0.09, delay=0.08, v=0.0) + self.set_chamber_comp('rv', E_pas= 0.1, E_act= 1.15, v_ref=10., k_pas=0.1, tr=0.30, td=0.45, v=100.) + self.set_chamber_comp('ra', E_pas= 0.15, E_act= 0.25, v_ref=4., k_pas=0.1, tpwb=0.0, tpww=0.09, delay=0.08, v=0.0) + + self.set_activation_function('lv', af=activation_function_2) + self.set_activation_function('rv', af=activation_function_2) + + self.set_activation_function('la', af=activation_function_3) + self.set_activation_function('ra', af=activation_function_3) + + + # systemic circulation + self.set_rlc_comp('sas', r=0.003, c=0.08, l=0.000062, v=450.0, v_ref=0.0) + self.set_rlc_comp('sat', r=(0.05 + 0.5 + 0.52), c=1.6 , l=0.0017 , v=0.0, v_ref=0.0) + self.set_rlc_comp('svn', r=0.075, c=20.5, v=0.0, v_ref=0.0) + + # pulmonary circulation + self.set_rlc_comp('pas', r=0.002 , c=0.18, l=0.000052, v=200.0, v_ref=0.0) + self.set_rlc_comp('pat', r=(0.01+0.05+0.25), c=3.8 , l=0.0017 , v=0.0, v_ref=0.0) + self.set_rlc_comp('pvn', r=0.006 , c=20.5 , v=0.0, v_ref=0.0) + + # valves + dyn = 1333.22 + self.set_valve_comp('ao', CQ=350., RRA=0.0, Ko = 0.012/dyn, Kc = 0.012/dyn, L=0.0, R=0.0) + self.set_valve_comp('mi', CQ=400., RRA=0.0, Ko = 0.03/dyn, Kc = 0.04/dyn, L=0.0, R=0.0 ) + self.set_valve_comp('po', CQ=350., RRA=0.0, Ko = 0.02/dyn, Kc = 0.02/dyn, L=0.0, R=0.0 ) + self.set_valve_comp('ti', CQ=400., RRA=0.0, Ko = 0.03/dyn, Kc = 0.04/dyn, L=0.0, R=0.0 ) + + def set_chamber_comp(self, key, **kwargs): + self._set_comp(key=key, set=CHAMBERS, **kwargs) + + def set_activation_function(self, key, af): + self._set_comp(key, set=CHAMBERS, af=af) + + def set_rlc_comp(self, key, **kwargs): + self._set_comp(key=key, set=VESSELS, **kwargs) + + def set_valve_comp(self, key, **kwargs): + self._set_comp(key=key, set=VALVES, **kwargs) diff --git a/src/ModularCirc/Models/KorakianitisModel.py b/src/ModularCirc/Models/KorakianitisModel.py new file mode 100644 index 0000000..91db341 --- /dev/null +++ b/src/ModularCirc/Models/KorakianitisModel.py @@ -0,0 +1,104 @@ +from .OdeModel import OdeModel +from .KorakianitisModel_parameters import KorakianitisModel_parameters as k2006 +from .ParametersObject import ParametersObject as po +from ..Components import Rlc_component, Valve_simple_bernoulli, HC_constant_elastance + +FULL_NAMES =[ + 'LeftA', + 'MiValve', + 'LeftV', + 'AoV', + 'SysAoSin', + 'SysArt', + 'SysVen', + 'RightA', + 'TriValve', + 'RightV', + 'PulV', + 'PulArtSin', + 'PulArt', + 'PulVen', +] + +class KorakianitisModel(OdeModel): + def __init__(self, time_setup_dict, parobj:po=k2006, suppress_printing:bool=False) -> None: + super().__init__(time_setup_dict) + self.name = 'KorakianitisModel' + + if not suppress_printing: print(parobj) + + # The components... + for key, name in zip(parobj.components.keys(), FULL_NAMES): + if key in parobj._vessels: + class_ = Rlc_component + elif key in parobj._valves: + class_ = Valve_simple_bernoulli + elif key in parobj._chambers: + class_ = HC_constant_elastance + else: + raise Exception(f'Component name {key} not in the model list.') + self.components[key] = class_(name=name, + time_object=self.time_object, + **parobj[key].to_dict()) + if key not in parobj._valves: self.set_v_sv(key) + self.components[key].setup() + + self.connect_modules(self.components['lv'], + self.components['ao'], + plabel='p_lv', + qlabel='q_ao') + self.connect_modules(self.components['ao'], + self.components['sas'], + plabel='p_sas', + qlabel='q_ao') + self.connect_modules(self.components['sas'], + self.components['sat'], + plabel='p_sat', + qlabel='q_sas') + self.connect_modules(self.components['sat'], + self.components['svn'], + plabel='p_svn', + qlabel='q_sat') + self.connect_modules(self.components['svn'], + self.components['ra'], + plabel='p_ra', + qlabel='q_svn') + self.connect_modules(self.components['ra'], + self.components['ti'], + plabel='p_ra', + qlabel='q_ti') + self.connect_modules(self.components['ti'], + self.components['rv'], + plabel='p_rv', + qlabel='q_ti') + self.connect_modules(self.components['rv'], + self.components['po'], + plabel='p_rv', + qlabel='q_po') + self.connect_modules(self.components['po'], + self.components['pas'], + plabel='p_pas', + qlabel='q_po') + self.connect_modules(self.components['pas'], + self.components['pat'], + plabel='p_pat', + qlabel='q_pas') + self.connect_modules(self.components['pat'], + self.components['pvn'], + plabel='p_pvn', + qlabel='q_pat') + self.connect_modules(self.components['pvn'], + self.components['la'], + plabel='p_la', + qlabel='q_pvn') + self.connect_modules(self.components['la'], + self.components['mi'], + plabel='p_la', + qlabel='q_mi') + self.connect_modules(self.components['mi'], + self.components['lv'], + plabel='p_lv', + qlabel='q_mi') + + for component in self.components.values(): + component.setup() diff --git a/src/ModularCirc/Models/KorakianitisModel_parameters.py b/src/ModularCirc/Models/KorakianitisModel_parameters.py new file mode 100644 index 0000000..d40013a --- /dev/null +++ b/src/ModularCirc/Models/KorakianitisModel_parameters.py @@ -0,0 +1,98 @@ +from ..HelperRoutines import activation_function_2, activation_function_3 +from .ParametersObject import ParametersObject +import pandas as pd + + +KORAKIANITIS_2006_COMPONENTS = [ + 'la', # left atrium + 'mi', # mitral valve + 'lv', # left ventricle + 'ao', # aortic valve + 'sas', # systemic aortic sinus + 'sat', # systemic artery + 'svn', # systemic vein + 'ra', # right atrium + 'ti', # tricuspid vale + 'rv', # right ventricle + 'po', # pulmonary valve + 'pas', # pulmonary artery sinus + 'pat', # pulmonary artery + 'pvn' # pulmonary vein + ] +VESSELS = ['sas', 'sat', 'svn', 'pas', 'pat', 'pvn'] +VESSELS_PAR = ['r', 'c', 'l', 'v_ref', 'v', 'p'] + +VALVES = ['mi', 'ao', 'ti', 'po'] +VALVES_PAR = ['CQ', 'RRA'] + +CHAMBERS = ['la', 'lv', 'ra', 'rv'] +CHAMBERS_PAR = ['E_pas', 'E_act', 'v_ref', 'af', 'v', 'p', 'tr', 'td', 'delay', 'tpww', 'tpwb'] + +# TIMINGS = [] + +class KorakianitisModel_parameters(ParametersObject): + """ + Intro + ----- + Model Parameters based on Korakianitis and Shi (2006) + """ + def __init__(self, name='Korakianitis 2006') -> None: + super().__init__(name=name) + self.components = {key : None for key in KORAKIANITIS_2006_COMPONENTS} + for type_, type_var in [[VESSELS, VESSELS_PAR], [VALVES, VALVES_PAR], [CHAMBERS, CHAMBERS_PAR]]: + for key in type_: + self[key] = pd.Series(index=type_var, dtype=object) + + # self.timings = {key : pd.Series(index=TIMINGS) for key in CHAMBERS} + + self._vessels = VESSELS + self._valves = VALVES + self._chambers= CHAMBERS + + self.set_chamber_comp('lv', E_pas= 0.1, E_act= 2.5, v_ref=5.0, tr = 0.30, td = 0.450, v=500.) + self.set_chamber_comp('la', E_pas= 0.15, E_act= 0.25, v_ref=4.0, tpwb = 0.0, tpww = 0.09, delay=0.08, v=0.0) + self.set_chamber_comp('rv', E_pas= 0.1, E_act= 1.15, v_ref=10., tr=0.30, td=0.45, v=400.) + self.set_chamber_comp('ra', E_pas= 0.15, E_act= 0.25, v_ref=4., tpwb=0.0, tpww=0.09, delay=0.08, v=0.0) + + self.set_activation_function('lv', af=activation_function_2) + self.set_activation_function('rv', af=activation_function_2) + + self.set_activation_function('la', af=activation_function_3) + self.set_activation_function('ra', af=activation_function_3) + + + # systemic circulation + self.set_rlc_comp('sas', r=0.003, c=0.08, l=0.000062, v=0.0, v_ref=0.0) + self.set_rlc_comp('sat', r=(0.05 + 0.5 + 0.52), c=1.6 , l=0.0017 , v=0.0, v_ref=0.0) + self.set_rlc_comp('svn', r=0.075, c=20.5, v=0.0, v_ref=0.0) + + # pulmonary circulation + self.set_rlc_comp('pas', r=0.002 , c=0.18, l=0.000052, v=0.0, v_ref=0.0) + self.set_rlc_comp('pat', r=(0.01+0.05+0.25), c=3.8 , l=0.0017 , v=0.0, v_ref=0.0) + self.set_rlc_comp('pvn', r=0.006 , c=20.5 , v=0.0, v_ref=0.0) + + # valves + self.set_valve_comp('ao', CQ=350., RRA=0.0) + self.set_valve_comp('mi', CQ=400., RRA=0.0) + self.set_valve_comp('po', CQ=350., RRA=0.0) + self.set_valve_comp('ti', CQ=400., RRA=0.0) + + def set_chamber_comp(self, key, **kwargs): + self._set_comp(key=key, set=CHAMBERS, **kwargs) + + def set_activation_function(self, key, af): + self._set_comp(key, set=CHAMBERS, af=af) + + def set_rlc_comp(self, key, **kwargs): + self._set_comp(key=key, set=VESSELS, **kwargs) + + def set_valve_comp(self, key, **kwargs): + self._set_comp(key=key, set=VALVES, **kwargs) + + def set(self, key, **kwargs): + if key in CHAMBERS: + self._set_comp(key=key, set=CHAMBERS, **kwargs) + if key in VESSELS: + self._set_comp(key=key, set=VESSELS, **kwargs) + if key in VALVES: + self._set_comp(key=key, set=VALVES, **kwargs) diff --git a/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel.py b/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel.py new file mode 100644 index 0000000..d1fdbf3 --- /dev/null +++ b/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel.py @@ -0,0 +1,132 @@ +from .OdeModel import OdeModel +from .MixedHeartMaynard4eWindkessel_parameters import MixedHeartMaynard4eWindkessel_parameters as MHM4W_parobj +from .ParametersObject import ParametersObject as po +from ..Components import Rlc_component, Valve_maynard, \ + HC_mixed_elastance, R_component, Valve_non_ideal, \ + HC_constant_elastance, Valve_simple_bernoulli + +FULL_NAMES =[ + 'LeftA', + 'MiValve', + 'LeftV', + 'AoV', + 'SysArtImp', + 'SysArt', + 'SysCap', + 'SysVen', + 'RightA', + 'TriValve', + 'RightV', + 'PulV', + 'PulArtImp', + 'PulArt', + 'PulCap', + 'PulVen', +] + +class MixedHeartMaynard4eWindkessel(OdeModel): + def __init__(self, time_setup_dict, parobj:po=MHM4W_parobj) -> None: + super().__init__(time_setup_dict) + self.name = 'MixedHeartMaynard4eWindkessel' + + print(parobj) + + # The components... + for key, name in zip(parobj.components.keys(), FULL_NAMES): + if key in parobj._vessels: + class_ = Rlc_component + elif key in parobj._imp or key in parobj._cap: + class_ = R_component + elif key in parobj._valves: + class_ = Valve_simple_bernoulli # Valve_non_ideal # Valve_maynard # Valve_simple_bernoulli + elif key in parobj._chambers: + class_ = HC_constant_elastance # HC_mixed_elastance HC_constant_elastance + else: + raise Exception(f'Component name {key} not in the model list.') + self.components[key] = class_(name=name, + time_object=self.time_object, + **parobj[key].to_dict()) + + if key not in parobj._valves + parobj._cap + parobj._imp: + self.set_v_sv(key) + # else: + # self.set_phi_sv(key) + self.components[key].setup() + + self.connect_modules(self.components['lv'], + self.components['ao'], + plabel='p_lv', + qlabel='q_ao', + ) + self.connect_modules(self.components['ao'], + self.components['sai'], + plabel='p_sa', + qlabel='q_ao') + self.connect_modules(self.components['sai'], + self.components['sa'], + plabel='pi_sa', + qlabel='q_ao', + qvariable=self.components['ao']._Q_o) + self.connect_modules(self.components['sa'], + self.components['sc'], + plabel='p_sc', + qlabel='q_sa') + self.connect_modules(self.components['sc'], + self.components['sv'], + plabel='p_sv', + qlabel='q_sa', + qvariable=self.components['sa']._Q_o) + self.connect_modules(self.components['sv'], + self.components['ra'], + plabel='p_ra', + qlabel='q_sv') + self.connect_modules(self.components['ra'], + self.components['ti'], + plabel='p_ra', + qlabel='q_ti') + self.connect_modules(self.components['ti'], + self.components['rv'], + plabel='p_rv', + qlabel='q_ti') + self.connect_modules(self.components['rv'], + self.components['po'], + plabel='p_rv', + qlabel='q_po') + self.connect_modules(self.components['po'], + self.components['pai'], + plabel='p_pa', + qlabel='q_po') + self.connect_modules(self.components['pai'], + self.components['pa'], + plabel='pi_pa', + qlabel='q_po', + qvariable=self.components['po']._Q_o) + self.connect_modules(self.components['pa'], + self.components['pc'], + plabel='p_pc', + qlabel='q_pa') + self.connect_modules(self.components['pc'], + self.components['pv'], + plabel='p_pv', + qlabel='q_pa', + qvariable=self.components['pa']._Q_o) + self.connect_modules(self.components['pv'], + self.components['la'], + plabel='p_la', + qlabel='q_pv') + self.connect_modules(self.components['la'], + self.components['mi'], + plabel='p_la', + qlabel='q_mi') + self.connect_modules(self.components['mi'], + self.components['lv'], + plabel='p_lv', + qlabel='q_mi') + for component in self.components.values(): + component.setup() + + def set_phi_sv(self, comp_key:str) -> None: + phi_key = 'phi_' + comp_key + self._state_variable_dict[phi_key] = self.components[comp_key]._PHI + self._state_variable_dict[phi_key].set_name(phi_key) + self.all_sv_data[phi_key] = self.components[comp_key].PHI diff --git a/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel_parameters.py b/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel_parameters.py new file mode 100644 index 0000000..6a5c0e5 --- /dev/null +++ b/src/ModularCirc/Models/MixedHeartMaynard4eWindkessel_parameters.py @@ -0,0 +1,132 @@ +from ..HelperRoutines import activation_function_2, activation_function_3, relu_max, softplus +from .ParametersObject import ParametersObject +import pandas as pd + + +MHM4WK_COMPONENTS = [ + 'la', # left atrium + 'mi', # mitral valve + 'lv', # left ventricle + 'ao', # aortic valve + 'sai', # systemic aortic impedance + 'sa', # systemic artery + 'sc', # systemic capilary bed + 'sv', # systemic vein + 'ra', # right atrium + 'ti', # tricuspid vale + 'rv', # right ventricle + 'po', # pulmonary valve + 'pai', # pulmonary artery impedance + 'pa', # pulmonary artery + 'pc', # pulmonary capilary + 'pv', # pulmonary vein + ] +VESSELS = ['sa', 'sv', 'pa', 'pv'] +VESSELS_PAR = ['r', 'c', 'l', 'v_ref', 'v', 'p'] + +VALVES = ['mi', 'ao', 'ti', 'po'] +# VALVES_PAR = ['CQ', 'RRA', 'Ko', 'Kc', 'R', 'L'] +# VALVES_PAR = ['r', 'max_func'] +VALVES_PAR = ['CQ', 'RRA'] + + +CHAMBERS = ['la', 'lv', 'ra', 'rv'] +CHAMBERS_PAR = ['E_pas', 'E_act', 'v_ref', 'k_pas', 'af', 'v', 'p', 'tr', 'td', 'delay', 'tpww', 'tpwb'] + +IMPEDANCES = ['sai', 'pai'] +IMPEDANCES_PAR = ['r'] + +CAPILARIES = ['sc', 'pc'] +CAPILARIES_PAR = ['r'] + +OBJ_PAR_PAIRS = [[VESSELS, VESSELS_PAR], + [VALVES, VALVES_PAR], + [CHAMBERS, CHAMBERS_PAR], + [IMPEDANCES, IMPEDANCES_PAR], + [CAPILARIES, CAPILARIES_PAR]] + +class MixedHeartMaynard4eWindkessel_parameters(ParametersObject): + """ + Intro + ----- + Model Parameters for MixedHeartMaynard4eWindkessel models + """ + def __init__(self, name='MixedHeartMaynard4eWindkessel_parameters') -> None: + super().__init__(name=name) + self.components = {key : None for key in MHM4WK_COMPONENTS} + for type_, type_var in OBJ_PAR_PAIRS: + for key in type_: + self[key] = pd.Series(index=type_var, dtype=object) + + self._vessels = VESSELS + self._valves = VALVES + self._chambers= CHAMBERS + self._imp = IMPEDANCES + self._cap = CAPILARIES + + self.set_chamber_comp('lv', E_pas= 0.1, E_act= 2.5, k_pas=0.03, v_ref=5.0, tr = 0.30, td = 0.450, v=50.) + self.set_chamber_comp('la', E_pas= 0.15, E_act= 0.25, k_pas=0.03, v_ref=4.0, tpwb = 0.0, tpww = 0.09, delay=0.08, v=0.0) + self.set_chamber_comp('rv', E_pas= 0.1, E_act= 1.15, k_pas=0.03, v_ref=10., tr =0.30, td=0.45, v=50.) + self.set_chamber_comp('ra', E_pas= 0.15, E_act= 0.25, k_pas=0.03, v_ref=4., tpwb=0.0, tpww=0.09, delay=0.08, v=0.0) + + self.set_activation_function('lv', af=activation_function_2) + self.set_activation_function('rv', af=activation_function_2) + + self.set_activation_function('la', af=activation_function_3) + self.set_activation_function('ra', af=activation_function_3) + + + # systemic circulation + self.set_rlc_comp('sa', r=0.05, c=1.6 , l=0.0017 , v=450.0, v_ref=0.0) + self.set_rlc_comp('sv', r=0.075, c=20.5, v=0.0, v_ref=0.0) + + # set impedances + self.set_resistance('sai', r = 0.003) + self.set_resistance('pai', r = 0.002) + + # pulmonary circulation + self.set_rlc_comp('pa', r=0.01, c=3.8 , l=0.0017 , v=250.0, v_ref=0.0) + self.set_rlc_comp('pv', r=0.006, c=20.5 , v=0.0, v_ref=0.0) + + # set capilary resistances + self.set_resistance('sc', r = 0.5 + 0.52) + self.set_resistance('pc', r = 0.05 + 0.25) + + # valves + ##################################################### + # self.set_valve_comp('ao', r=0.01, max_func=relu_max) + # self.set_valve_comp('mi', r=0.01, max_func=relu_max) + # self.set_valve_comp('po', r=0.01, max_func=relu_max) + # self.set_valve_comp('ti', r=0.01, max_func=relu_max) + ##################################################### + # self.set_valve_comp('ao', r=0.01, max_func=softplus) + # self.set_valve_comp('mi', r=0.01, max_func=softplus) + # self.set_valve_comp('po', r=0.01, max_func=softplus) + # self.set_valve_comp('ti', r=0.01, max_func=softplus) + ##################################################### + # self.set_valve_comp('ao', CQ=350., RRA=0.0, Ko = 26., Kc = 2e3, L=0.0, R=0.0) + # self.set_valve_comp('mi', CQ=400., RRA=0.0, Ko = 40., Kc = 2e3, L=0.0, R=0.0 ) + # self.set_valve_comp('po', CQ=350., RRA=0.0, Ko = 40., Kc = 18e3,L=0.0, R=0.0 ) + # self.set_valve_comp('ti', CQ=400., RRA=0.0, Ko = 40., Kc = 2e3, L=0.0, R=0.0 ) + ##################################################### + self.set_valve_comp('ao', CQ=350., RRA=0.0) + self.set_valve_comp('mi', CQ=400., RRA=0.0) + self.set_valve_comp('po', CQ=350., RRA=0.0) + self.set_valve_comp('ti', CQ=400., RRA=0.0) + ##################################################### + + + def set_chamber_comp(self, key, **kwargs): + self._set_comp(key=key, set=CHAMBERS, **kwargs) + + def set_activation_function(self, key, af): + self._set_comp(key, set=CHAMBERS, af=af) + + def set_rlc_comp(self, key, **kwargs): + self._set_comp(key=key, set=VESSELS, **kwargs) + + def set_valve_comp(self, key, **kwargs): + self._set_comp(key=key, set=VALVES, **kwargs) + + def set_resistance(self, key, **kwargs): + self._set_comp(key=key, set=IMPEDANCES + CAPILARIES, **kwargs)