Example #1
0
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)
Example #4
0
    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)