Source code for cardioemulator._emulator

from scipy import interpolate
import json

[docs]class Emulator: """ 0D emulator of a cardiac chamber. """ def __init__(self, emulator_data): """ Parameters ---------- emulator_data : dict or str Dictionary encoding the emulator. This input can be provided as a dictionary or as the path to json file containing the dictionary. """ if isinstance(emulator_data, str): with open(emulator_data) as json_file: emulator_data = json.load(json_file) self.data = emulator_data if self.data['EDPV']['klotz']: self.EDPV = lambda V: self.data['EDPV']['An'] * ((V - self.data['EDPV']['V0']) / (self.data['EDPV']['V30'] - self.data['EDPV']['V0']))**self.data['EDPV']['Bn'] else: self.EDPV = interpolate.interp1d(self.data['EDPV']['V'], self.data['EDPV']['P'], fill_value = 'extrapolate') self.activation_base = interpolate.interp1d(self.data['activation']['t'], self.data['activation']['v'])
[docs] def ESPV(self, V): """ End-systolic pressure-volume relationship. Parameters ---------- V : float [mL] Chamber volume. Returns ------- p : float [mmHg] Chamber pressure. """ return self.data['ESPV']['E'] * ( V - self.data['ESPV']['V_0'] )
[docs] def EDPV(self, V): """ End-distolic pressure-volume relationship. Parameters ---------- V : float [mL] Chamber volume. Returns ------- p : float [mmHg] Chamber pressure. """ raise Exception('EDPV function should be overwritten in the class constructor!')
[docs] def activation(self, t): """ Time-dependent activation function. Parameters ---------- t : float [s] time. Returns ------- act : float [-] Activation (0 = fully relaxed, 1 = fully activated). """ return self.activation_base(t % self.data['period'])
[docs] def PV(self, V, t): """ Time-dependent pressure-volume relationship. Parameters ---------- V : float [mL] Chamber volume. t : float [s] time. Returns ------- p : float [mmHg] Chamber pressure. """ return (1 - self.activation(t)) * self.EDPV(V) + self.activation(t) * self.ESPV(V)
[docs]class Emulator_parametric: """ Parametric 0D emulator of a cardiac chamber. """ def __init__(self, emulator_data): """ Parameters ---------- emulator_data : dict or str Dictionary encoding the parametric emulator. This input can be provided as a dictionary or as the path to json file containing the dictionary. """ if isinstance(emulator_data, str): with open(emulator_data) as json_file: emulator_data = json.load(json_file) self.data = emulator_data self.emulatorA = Emulator(emulator_data['emulatorA']) self.emulatorB = Emulator(emulator_data['emulatorB']) self.paramA = emulator_data['paramA'] self.paramB = emulator_data['paramB']
[docs] def PV(self, V, t, param): """ Time-dependent pressure-volume relationship. Parameters ---------- V : float [mL] Chamber volume. t : float [s] time. param : float Emulator parameter. Returns ------- p : float [mmHg] Chamber pressure. """ return (param - self.paramA) / (self.paramB - self.paramA) * self.emulatorB.PV(V,t) \ + (param - self.paramB) / (self.paramA - self.paramB) * self.emulatorA.PV(V,t)
[docs]def get_PV_relationship(emulator_data, emulator_param = None): """ Get the time-dependent pressure-volume relationship associated with an emulator. Parameters ---------- emulator_data : dict or str Dictionary encoding the emulator or parametric emulator. This input can be provided as a dictionary or as the path to json file containing the dictionary. emulator_param : float, optional In case the ``emulator_data`` encodes a parametric emulator, this input represents the parameter associated with the concrete emulator. Returns ------- fun : callable Time-dependent pressure-volume relationship ``fun(volume, time) -> pressure`` with input volume [mL], time [s] and output pressure [mmHg]. """ if isinstance(emulator_data, str): with open(emulator_data) as json_file: emulator_data = json.load(json_file) if emulator_data.get('parametric', False): return lambda V, t: Emulator_parametric(emulator_data).PV(V, t, emulator_param) else: return Emulator(emulator_data).PV