def StandardModelSetup(dimension, npoints): settings = KickedWindkesselModel.KickedWindkesselModelSettings() fireNotifier = FiringTimesNotifier() force = RespiratoryDelayedSmearedHeartActionForce() force.CoordinateNumber = 9 #Coordinate number, to which the state will be written force.CoordinateNumberForInput = 6 force.KickAmplitude = 1.0 #Kick amplitude force.DelayTau = 0.3 #Time from firing order to actual kick force.SamplingTime = 0.01 # required to normalize delay time. force.DecayTau = 0.3 # Time by which the drive decays force.Notify = fireNotifier.Notify iafResp = IntegrateAndFire() iafResp.SamplingTime = 0.01 iafResp.SetPhaseVelocityFromBPM(20) iafResp.SetInitialPhase(0.0) iafResp.KickAmplitude = 0.1 iafResp.CoordinateNumberForRate = -1 iafResp.CoordinateNumberForPhase = 5 iafResp.CoordinateNumberForForceInput = -1 #not used # Coordinate number, to which the state will be written #this variable will be used for coupling. iafResp.CoordinateNumberForOutput = 6 fireNotifierResp = FiringTimesNotifier() iafResp.Notify = fireNotifierResp.Notify iafHeart = IntegrateAndFire() iafHeart.SamplingTime = 0.01 iafHeart.SetPhaseVelocityFromBPM(66) #45 worked OK iafHeart.phaseEfectivenessCurve = phaseEfectivenessCurveSH iafHeart.CoordinateNumberForRate = 8 iafHeart.CoordinateNumberForPhase = 7 iafHeart.CoordinateNumberForForceInput = force.CoordinateNumber # Coordinate number, to which the state will be written iafHeart.CoordinateNumberForOutput = 4 fireNotifierHeart = FiringTimesNotifier() #iafHeart.Notify = fireNotifierHeart.Notify collector = AbpmFiducialPointsCollector(0) #ABPM = 0 iafHeart.NotifyFunctions = [ fireNotifierHeart.Notify, collector.HeartOpenNotifier ] mmNotifier = MinMaxNotifier(0) mmNotifier.MinNotifier = collector.AbpmMinNotifier mmNotifier.MaxNotifier = collector.AbpmMaxNotifier seriesNotifier = SeriesNotifier(dimension, npoints) settings.heartActionForce = HeartActionForceChain( [iafResp, force, iafHeart]) settings.CoordinateNumberForRespPhase = iafResp.CoordinateNumberForPhase model = KickedWindkesselModel(settings, dimension) model.param.Npoints = npoints chain = NotifierChain((mmNotifier, collector, seriesNotifier)) model.Notify = chain.Notify return settings, model, force, iafResp, iafHeart, collector, seriesNotifier, fireNotifierResp, fireNotifierHeart, fireNotifier
def test_DoubleKickViaSmearedForceWithPRC(self): """ This test handles the majority of physiological control of heart rate. Respiratory IAF periodically forces the heart via the RespiratoryDelayedSmearedHeartActionForce. The force is applied to heart drive. Initially the heart is in phase with respiration, as both periods are commensurate (3:1) and initial phase of both is 0. """ npoints = 120 data = RungeKutta45IntegratorData(10, 0.0) iafResp = IntegrateAndFire() iafResp.SetPhaseVelocityFromBPM(20) iafResp.phaseEfectivenessCurve = phaseEfectivenessCurveSH iafResp.SamplingTime = 0.1 iafResp.SetInitialPhase(0.0) iafResp.KickAmplitude = 0.1 iafResp.SamplingTime = 0.1 iafResp.CoordinateNumberForRate = 7 iafResp.CoordinateNumberForPhase = 6 iafResp.CoordinateNumberForForceInput = 8 #coupling in opposite direction. # Coordinate number, to which the state will be written #this variable will be used for coupling. iafResp.CoordinateNumberForOutput = 4 fireNotifierResp = FiringTimesNotifier() iafResp.Notify = fireNotifierResp.Notify forceCoordinateNumber = 5 iafHeart = IntegrateAndFire() iafHeart.SamplingTime = 0.1 iafHeart.SetPhaseVelocityFromBPM(67) iafHeart.phaseEfectivenessCurve = phaseEfectivenessCurveSH iafHeart.CoordinateNumberForRate = 0 iafHeart.CoordinateNumberForPhase = 1 iafHeart.CoordinateNumberForForceInput = forceCoordinateNumber # Coordinate number, to which the state will be written iafHeart.CoordinateNumberForOutput = 2 fireNotifierHeart = FiringTimesNotifier() iafHeart.Notify = fireNotifierHeart.Notify fireNotifier = FiringTimesNotifier() force = RespiratoryDelayedSmearedHeartActionForce() force.CoordinateNumber = forceCoordinateNumber #Coordinate number, to which the state will be written force.CoordinateNumberForInput = iafResp.CoordinateNumberForOutput force.KickAmplitude = -1.0 #Kick amplitude force.DelayTau = 0.1 #Time from firing order to actual kick force.SamplingTime = 0.1 # required to normalize delay time. force.DecayTau = 0.9 # Time by which the drive decays force.Notify = fireNotifier.Notify fireNotifierR = FiringTimesNotifier() forceR = RespiratoryDelayedSmearedHeartActionForce() forceR.CoordinateNumber = 8 #Coordinate number, to which the state will be written forceR.KickAmplitude = 1.0 #Kick amplitude forceR.DelayTau = 0.1 #Time from firing order to actual kick forceR.SamplingTime = 0.1 # required to normalize delay time. forceR.DecayTau = 0.9 # Time by which the drive decays forceR.CoordinateNumberForInput = iafHeart.CoordinateNumberForOutput forceR.Notify = fireNotifierR.Notify seriesNotifier = SeriesNotifier(data.dimension, npoints) allTimes = np.linspace(0.0, npoints * force.SamplingTime, npoints) for t in allTimes: data.t = t data.y[0] = 0.0 # reset only the variable which gets set manually # to prevent constant firing iafResp.ApplyDrive(data) #if data[iafResp.CoordinateNumberForOutput] > 0.0: # data.y[0] = 1.0 # force.FireOrderTime = t logging.debug(data) forceR.ApplyDrive(data) force.ApplyDrive(data) iafHeart.ApplyDrive(data) seriesNotifier.Notify(data) #print("Firing times: %s" % str(fireNotifier.firingTimes)) fig = plt.figure() plt.subplot(5, 1, 1) plt.plot(allTimes, seriesNotifier.GetVar(6), "b") plt.plot(fireNotifierResp.firingTimes, fireNotifierResp.firingTimesSpikes(), "bo") plt.ylabel(r"$\Phi(t)$") plt.yticks([]) plt.xticks([]) plt.ylim(0.0, 1.2) plt.subplot(5, 1, 2) plt.plot(allTimes, seriesNotifier.GetVar(iafResp.CoordinateNumberForOutput), "g", linewidth=2) plt.plot(fireNotifier.firingTimes, fireNotifier.firingTimesSpikes(), "go") plt.plot(allTimes, seriesNotifier.GetVar(force.CoordinateNumber), "g", linewidth=2) plt.yticks([]) plt.xticks([]) plt.ylabel("Force") #plt.ylim(0.0,5.0 * iafResp.KickAmplitude) plt.subplot(5, 1, 3) plt.ylabel(r"$d\varphi(t)/dt$") plt.plot(allTimes, seriesNotifier.GetVar(iafHeart.CoordinateNumberForRate), "v") plt.yticks([]) plt.xticks([]) plt.subplot(5, 1, 4) plt.plot(allTimes, seriesNotifier.GetVar(iafHeart.CoordinateNumberForPhase), "r") #plt.plot(allTimes,seriesNotifier.GetVar(2),"r") plt.plot(fireNotifierHeart.firingTimes, fireNotifierHeart.firingTimesSpikes(), "ro") plt.ylim(0.0, 1.2) plt.yticks([]) plt.xticks([]) plt.ylabel(r"$\varphi(t)$") #plt.ylim(0.0,5.0 * iafResp.KickAmplitude) plt.subplot(5, 1, 5) plt.ylabel("RR") plt.yticks([]) plt.plot(fireNotifierHeart.firingTimes[1:], fireNotifierHeart.ISI()[1:], "b+-") plt.xlabel("Time [s]") fname = sys._getframe().f_code.co_name + ".png" print("Test result in %s" % fname) plt.savefig(fname)
def test_RespiratoryDelayedSmearedHeartActionForceForcedByResp(self): """ This test handles the majority of physiological control of heart rate. Respiratory IAF periodically forces the heart via the RespiratoryDelayedSmearedHeartActionForce. The test shows how respiratory kick is converted to delayed smeared kick. """ npoints = 240 data = RungeKutta45IntegratorData(10, 0.0) iafResp = IntegrateAndFire() iafResp.SetPhaseVelocityFromBPM(20) iafResp.SamplingTime = 0.1 iafResp.SetInitialPhase(0.0) iafResp.KickAmplitude = 0.1 iafResp.SamplingTime = 0.1 iafResp.CoordinateNumberForRate = 7 iafResp.CoordinateNumberForPhase = 6 iafResp.CoordinateNumberForForceInput = -1 #not used # Coordinate number, to which the state will be written #this variable will be used for coupling. iafResp.CoordinateNumberForOutput = 4 fireNotifierResp = FiringTimesNotifier() iafResp.Notify = fireNotifierResp.Notify fireNotifier = FiringTimesNotifier() force = RespiratoryDelayedSmearedHeartActionForce() force.Drive = 0.0 #Current value of heart drive. force.CoordinateNumber = 5 #Coordinate number, to which the state will be written force.KickAmplitude = 1.0 #Kick amplitude force.DelayTau = 1.53 #Time from firing order to actual kick force.SamplingTime = 0.1 # required to normalize delay time. force.StepPeriod = 1.0 #Heart period #force.FireOrderTime = None #Time of last beat [s] force.DecayTau = 15.0 # Time by which the drive decays force.Notify = fireNotifier.Notify seriesNotifier = SeriesNotifier(data.dimension, npoints) allTimes = np.linspace(0.0, npoints * force.SamplingTime, npoints) for t in allTimes: data.t = t data.y[0] = 0.0 # reset only the variable which gets set manually # to prevent constant firing iafResp.ApplyDrive(data) if data[iafResp.CoordinateNumberForOutput] > 0.0: data.y[0] = 1.0 force.FireOrderTime = t logging.debug(data) force.ApplyDrive(data) # will open or not. seriesNotifier.Notify(data) spikes = np.ones(len(fireNotifier.firingTimes)) spikesResp = np.ones(len(fireNotifierResp.firingTimes)) #print("Firing times: %s" % str(fireNotifier.firingTimes)) fig = plt.figure() plt.subplot(3, 1, 1) plt.plot(allTimes, seriesNotifier.GetVar(6), "b") plt.plot(fireNotifierResp.firingTimes, spikesResp, "bo") plt.ylabel("Resp. phase [1/rad]") plt.xlabel("Time [s]") plt.ylim(0.0, 1.2) plt.subplot(3, 1, 2) plt.plot(allTimes, seriesNotifier.GetVar(iafResp.CoordinateNumberForOutput), "g", linewidth=2) plt.xlabel("Time [s]") plt.ylabel("Force") plt.ylim(0.0, 5.0 * iafResp.KickAmplitude) plt.subplot(3, 1, 3) plt.plot(fireNotifier.firingTimes, spikes, "bo") plt.plot(allTimes, seriesNotifier.GetVar(force.CoordinateNumber), "g", linewidth=2) plt.xlabel("Time [s]") plt.ylabel("Delayed Force") #plt.ylim(0.0,5.0 * iafResp.KickAmplitude) fname = sys._getframe().f_code.co_name + ".png" print("Test result in %s" % fname) plt.savefig(fname)
def test_RespiratoryDelayedSmearedHeartActionForce(self): data = RungeKutta45IntegratorData(5, 0.0) period = 0.5 lastFire = -period #force fire at 0.0 fireNotifier = FiringTimesNotifier() force = RespiratoryDelayedSmearedHeartActionForce() force.Drive = 0.0 #Current value of heart drive. force.CoordinateNumber = 4 #Coordinate number, to which the state will be written force.CoordinateNumberForInput = 0 force.KickAmplitude = 1.0 #Kick amplitude force.DelayTau = 0.13 #Time from firing order to actual kick force.SamplingTime = 0.1 # required to normalize delay time. force.DecayTau = 15.0 # Time by which the drive decays force.Notify = fireNotifier.Notify npoints = 1000 period = 1.0 seriesNotifier = SeriesNotifier(5, npoints) allTimes = np.linspace(0.0, 10.0, npoints) for t in allTimes: data.t = t data.y[3] = 10.0 * np.cos(2 * np.pi * t / period) data.y[0] = data.y[1] = data.y[2] = 0.0 if t >= lastFire + period: data.y[0] = 1.0 lastFire = t logging.debug(data) force.ApplyDrive(data) # will open or not. seriesNotifier.Notify(data) #print("Firing times: %s" % str(fireNotifier.firingTimes)) fig = plt.figure() plt.subplot(2, 1, 1) plt.plot(allTimes, seriesNotifier.GetVar(3)) plt.subplot(2, 1, 2) plt.plot(allTimes, seriesNotifier.GetVar(0), "r") plt.plot(allTimes, seriesNotifier.GetVar(4)) fname = sys._getframe().f_code.co_name + ".png" logging.info("Test result in %s" % fname) plt.savefig(fname)
def test_FullCoupling(self): """ This test handles the majority of physiological control of heart rate. Respiratory IAF periodically forces the heart via the RespiratoryDelayedSmearedHeartActionForce. The force is applied to heart drive. Initially the heart is in phase with respiration, as both periods are commensurate (3:1) and initial phase of both is 0. """ dimension = 10 npoints = 1800 settings = KickedWindkesselModel.KickedWindkesselModelSettings() fireNotifier = FiringTimesNotifier() force = RespiratoryDelayedSmearedHeartActionForce() force.CoordinateNumber = 9 #Coordinate number, to which the state will be written force.CoordinateNumberForInput = 6 force.KickAmplitude = 1.0 #Kick amplitude force.DelayTau = 0.1 #Time from firing order to actual kick force.SamplingTime = 0.01 # required to normalize delay time. force.DecayTau = 0.9 # Time by which the drive decays force.Notify = fireNotifier.Notify iafResp = IntegrateAndFire() iafResp.SamplingTime = 0.01 iafResp.SetPhaseVelocityFromBPM(20) iafResp.SetInitialPhase(0.0) iafResp.KickAmplitude = 0.1 iafResp.CoordinateNumberForRate = -1 iafResp.CoordinateNumberForPhase = 5 iafResp.CoordinateNumberForForceInput = -1 #not used # Coordinate number, to which the state will be written #this variable will be used for coupling. iafResp.CoordinateNumberForOutput = 6 fireNotifierResp = FiringTimesNotifier() iafResp.Notify = fireNotifierResp.Notify iafHeart = IntegrateAndFire() iafHeart.SamplingTime = 0.01 iafHeart.SetPhaseVelocityFromBPM(67) iafHeart.phaseEfectivenessCurve = phaseEfectivenessCurveSH iafHeart.CoordinateNumberForRate = 8 iafHeart.CoordinateNumberForPhase = 7 iafHeart.CoordinateNumberForForceInput = force.CoordinateNumber # Coordinate number, to which the state will be written iafHeart.CoordinateNumberForOutput = 4 fireNotifierHeart = FiringTimesNotifier() iafHeart.Notify = fireNotifierHeart.Notify collector = AbpmFiducialPointsCollector(0) #ABPM = 0 seriesNotifier = SeriesNotifier(dimension, npoints) allTimes = np.linspace(0.0, npoints * force.SamplingTime, npoints) settings.heartActionForce = HeartActionForceChain( [iafResp, force, iafHeart]) model = KickedWindkesselModel(settings, dimension) model.param.Npoints = npoints chain = NotifierChain((collector, seriesNotifier)) model.Notify = chain.Notify model.IterateToNotifiers() #print("Firing times: %s" % str(fireNotifier.firingTimes)) fig = plt.figure() gs = gridspec.GridSpec(6, 1, height_ratios=[1, 2, 2, 2, 2, 4]) ax = plt.subplot(gs[0]) plt.plot(allTimes, seriesNotifier.GetVar(iafResp.CoordinateNumberForPhase), "b") plt.plot(fireNotifierResp.firingTimes, fireNotifierResp.firingTimesSpikes(), "bo") plt.yticks([0.0, 1.0]) plt.ylabel(r"$\Phi(t)$") #plt.xlabel("Time [s]") plt.ylim(0.0, 1.2) plt.setp(ax.get_xticklabels(), visible=False) ax = plt.subplot(gs[1]) #todo: the guy below is all flat. #plt.plot(allTimes,seriesNotifier.GetVar(iafResp.CoordinateNumberForOutput),"g",linewidth=2) plt.plot(fireNotifier.firingTimes, fireNotifier.firingTimesSpikes(), "go") plt.plot(allTimes, seriesNotifier.GetVar(force.CoordinateNumber), "g", linewidth=2) plt.yticks([]) plt.setp(ax.get_xticklabels(), visible=False) #plt.xlabel("Time [s]") plt.ylabel(r"$r_{n}(t)$") #plt.ylim(0.0,5.0 * iafResp.KickAmplitude) ax = plt.subplot(gs[2]) plt.yticks([]) plt.ylabel(r"$r(t)$") plt.plot(allTimes, seriesNotifier.GetVar(iafHeart.CoordinateNumberForRate), "v") plt.setp(ax.get_xticklabels(), visible=False) ax = plt.subplot(gs[3]) plt.plot(allTimes, seriesNotifier.GetVar(iafHeart.CoordinateNumberForPhase), "r") #plt.plot(allTimes,seriesNotifier.GetVar(2),"r") plt.plot(fireNotifierHeart.firingTimes, fireNotifierHeart.firingTimesSpikes(), "ro") plt.ylim(0.0, 1.2) plt.yticks([0.0, 1.0]) #plt.xlabel("Time [s]") plt.ylabel(r"$\varphi(t)$") #plt.ylim(0.0,5.0 * iafResp.KickAmplitude) plt.setp(ax.get_xticklabels(), visible=False) ax = plt.subplot(gs[4]) plt.ylabel("ISI") plt.plot(fireNotifierHeart.firingTimes[1:], fireNotifierHeart.ISI()[1:], "b+-") plt.setp(ax.get_xticklabels(), visible=False) plt.subplot(gs[5]) for varNumber in (0, 1, 2, 3): plt.plot(allTimes, seriesNotifier.GetVar(varNumber)) plt.ylim(0.0, 300.0) plt.xlabel("Time [s]") plt.ylabel("BP [mmHg]") fname = sys._getframe().f_code.co_name + ".png" print("Test result in %s" % fname) plt.savefig(fname) plt.close(fig)
def test_HighAmplitude(self): """ Is the influence of high intrathoracic pressure amplitude visible at disabled heart control """ dimension = 10 npoints = 2400 settings = KickedWindkesselModel.KickedWindkesselModelSettings() fireNotifier = FiringTimesNotifier() force = RespiratoryDelayedSmearedHeartActionForce() force.CoordinateNumber = 9 #Coordinate number, to which the state will be written force.CoordinateNumberForInput = 6 force.KickAmplitude = 0.0 #Kick amplitude force.DelayTau = 0.3 #Time from firing order to actual kick force.SamplingTime = 0.01 # required to normalize delay time. force.DecayTau = 0.3 # Time by which the drive decays force.Notify = fireNotifier.Notify iafResp = IntegrateAndFire() iafResp.SamplingTime = 0.01 iafResp.SetPhaseVelocityFromBPM(6) iafResp.SetInitialPhase(0.0) iafResp.KickAmplitude = 0.1 iafResp.CoordinateNumberForRate = -1 iafResp.CoordinateNumberForPhase = 5 iafResp.CoordinateNumberForForceInput = -1 #not used # Coordinate number, to which the state will be written #this variable will be used for coupling. iafResp.CoordinateNumberForOutput = 6 fireNotifierResp = FiringTimesNotifier() iafResp.Notify = fireNotifierResp.Notify iafHeart = IntegrateAndFire() iafHeart.SamplingTime = 0.01 iafHeart.SetPhaseVelocityFromBPM(67) iafHeart.phaseEfectivenessCurve = phaseEfectivenessCurveSH iafHeart.CoordinateNumberForRate = 8 iafHeart.CoordinateNumberForPhase = 7 iafHeart.CoordinateNumberForForceInput = force.CoordinateNumber # Coordinate number, to which the state will be written iafHeart.CoordinateNumberForOutput = 4 fireNotifierHeart = FiringTimesNotifier() #iafHeart.Notify = fireNotifierHeart.Notify collector = AbpmFiducialPointsCollector(0) #ABPM = 0 iafHeart.NotifyFunctions = [ fireNotifierHeart.Notify, collector.HeartOpenNotifier ] mmNotifier = MinMaxNotifier(0) mmNotifier.MinNotifier = collector.AbpmMinNotifier mmNotifier.MaxNotifier = collector.AbpmMaxNotifier seriesNotifier = SeriesNotifier(dimension, npoints) allTimes = np.linspace(0.0, npoints * force.SamplingTime, npoints) settings.heartActionForce = HeartActionForceChain( [iafResp, force, iafHeart]) settings.CoordinateNumberForRespPhase = iafResp.CoordinateNumberForPhase settings.p_I1 = 3.0 # default is 0.1 model = KickedWindkesselModel(settings, dimension) model.param.Npoints = npoints chain = NotifierChain((mmNotifier, collector, seriesNotifier)) model.Notify = chain.Notify model.IterateToNotifiers() allItems = collector.GetFiducialPointsList() series = {} series["systolicABP"] = np.array(allItems[:, 1]) series["diastolicABP"] = np.array(allItems[:, 2]) series["meanABP"] = np.array(allItems[:, 3]) for key in series.keys(): av = np.average(series[key]) sd = np.std(series[key]) logging.info("%s: av: %.2lf sd: %.2lf, npoints: %d" % (key, av, sd, len(series[key]))) print(allItems) fname = sys._getframe().f_code.co_name + ".png" KickedWindkesselModelVisualization( fname, allTimes, allItems, seriesNotifier, fireNotifierResp, fireNotifier, fireNotifierHeart, iafResp.CoordinateNumberForPhase, force.CoordinateNumber, iafHeart.CoordinateNumberForRate, iafHeart.CoordinateNumberForPhase)