示例#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_UnperturbedRate(self):
     data = RungeKutta45IntegratorData(8, 0.0)
     iaf = IntegrateAndFire()
     fireNotifier = FiringTimesNotifier()
     iaf.Notify = fireNotifier.Notify
     npoints = 1000
     period = 1.0
     seriesNotifier = SeriesNotifier(8, npoints)
     allTimes = np.linspace(0.0, 10.0, npoints)
     for t in allTimes:
         data.t = t
         # this is to make the plot visually nicer :-)
         data.y[3] = 10.0 * np.cos(2 * np.pi * t / period)
         #data.y[0] = data.y[1] = data.y[2] = 0.0
         iaf.ApplyDrive(data)  # will open or not.
         logging.debug(data)
         seriesNotifier.Notify(data)
     #Print dots at firing times
     spikes = np.ones(len(fireNotifier.firingTimes))
     #print("Firing times: %s" % str(fireNotifier.firingTimes))
     fig = plt.figure()
     plt.subplot(2, 1, 1)
     #plt.ylim(-12.0,12.0)
     plt.plot(allTimes, seriesNotifier.GetVar(3))
     plt.subplot(2, 1, 2)
     plt.plot(allTimes, seriesNotifier.GetVar(4), "g")
     plt.plot(fireNotifier.firingTimes, spikes, "ro")
     fname = sys._getframe().f_code.co_name + ".png"
     print("Test result in %s" % fname)
     plt.savefig(fname)
 def test_FrequencyModulation(self):
     data = RungeKutta45IntegratorData(8, 0.0)
     iaf = IntegrateAndFire()
     fireNotifier = FiringTimesNotifier()
     iaf.Notify = fireNotifier.Notify
     npoints = 1000
     period = 20.0
     seriesNotifier = SeriesNotifier(8, npoints)
     allTimes = np.linspace(0.0, npoints * iaf.SamplingTime, npoints)
     for t in allTimes:
         data.t = t
         data.y[5] = 2.0 * iaf.r * (1.0 + np.cos(2 * np.pi * t / period))
         iaf.ApplyDrive(data)  # will open or not.
         logging.debug(data)
         seriesNotifier.Notify(data)
     #Print dots at firing times
     spikes = np.ones(len(fireNotifier.firingTimes))
     #print("Firing times: %s" % str(fireNotifier.firingTimes))
     fig = plt.figure()
     plt.subplot(2, 1, 1)
     #plt.ylim(-12.0,12.0)
     plt.plot(allTimes, seriesNotifier.GetVar(5))  #effective rate
     plt.subplot(2, 1, 2)
     plt.plot(allTimes, seriesNotifier.GetVar(4), "g")
     plt.plot(fireNotifier.firingTimes, spikes, "ro")
     fname = sys._getframe().f_code.co_name + ".png"
     print("Test result in %s" % fname)
     plt.savefig(fname)
示例#4
0
 def test_RectangularHeartActionForce(self):
     data = RungeKutta45IntegratorData(5, 0.0)
     force = RectangularHeartActionForce()
     fireNotifier = FiringTimesNotifier()
     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
         logging.debug(data)
         force.ApplyDrive(data)  # will open or not.
         seriesNotifier.Notify(data)
     allValues4 = seriesNotifier.GetVar(4)
     allValues3 = seriesNotifier.GetVar(3)
     logging.info("Firing times: %s" % str(fireNotifier.firingTimes))
     #fig = plt.figure()
     plt.subplot(2, 1, 1)
     #plt.ylim(-12.0,12.0)
     plt.plot(allTimes, allValues3)
     plt.subplot(2, 1, 2)
     plt.plot(allTimes, allValues4)
     fname = sys._getframe().f_code.co_name + ".png"
     logging.info("Test result in %s" % fname)
     plt.savefig(fname)
    def test_fiducial_points_collector_rect(self):
        settings = KickedWindkesselModel.KickedWindkesselModelSettings()
        settings.heartActionForce = RectangularHeartActionForce()
        model = KickedWindkesselModel(settings)
        model.param.Npoints = 10000

        collector = AbpmFiducialPointsCollector(
            0)  #ABPM = 0. Other compartments have different numbers.
        settings.heartActionForce.Notify = collector.HeartOpenNotifier
        mmNotifier = MinMaxNotifier(0)
        mmNotifier.MinNotifier = collector.AbpmMinNotifier
        mmNotifier.MaxNotifier = collector.AbpmMaxNotifier
        seriesNotifier = SeriesNotifier(model.param.dimension,
                                        model.param.Npoints)

        chain = NotifierChain((mmNotifier, collector, seriesNotifier))
        model.Notify = chain.Notify

        model.IterateToNotifiers()
        allValues = seriesNotifier.GetVar(0)
        allTimes = np.linspace(0.0, model.param.dT * model.param.Npoints,
                               model.param.Npoints)
        allItems = collector.GetFiducialPointsList()
        fig = plt.figure()
        #plt.ylim(-12.0,12.0)
        plt.plot(allTimes, allValues)
        #pdb.set_trace()
        plt.plot(allItems[:, 0], allItems[:, 1], "ro")  # systolic
        plt.plot(allItems[:, 0], allItems[:, 2], "go")  # diastolic
        plt.plot(allItems[:, 0], allItems[:, 3], "bo")  # mean
        plt.savefig("test_fiducial_points_collector_rect.png")
        logging.warning("Result in test_fiducial_points_collector_rect.png")
def BasicProcessor():
    settings = KickedWindkesselModel.KickedWindkesselModelSettings()
    settings.heartActionForce = RectangularHeartActionForce()
    model = KickedWindkesselModel(settings)
    model.param.Npoints = 1000
    series = SeriesNotifier(model.param.dimension, model.param.Npoints + 1)
    model.Notify = series.Notify
    model.IterateToNotifiers()
    fname = "overview.png"
    series.PlotSeries((1, 2, 3, 4), fname)
    print("Plat data in %s" % fname)
 def test_UnperturbedRate(self):
     settings = KickedWindkesselModel.KickedWindkesselModelSettings()
     settings.heartActionForce = RectangularHeartActionForce()
     model = KickedWindkesselModel(settings)
     model.param.Npoints = 1000
     series = SeriesNotifier(model.param.dimension, model.param.Npoints + 1)
     model.Notify = series.Notify
     model.IterateToNotifiers()
     fname = sys._getframe().f_code.co_name + ".png"
     series.PlotSeries((1, 2, 3, 4), fname)
     print("Plot data in %s" % fname)
示例#8
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)
示例#9
0
    def test_min_max_notifier(self):
        data = RungeKutta45IntegratorData(2, 0.0)
        mmNotifier = MinMaxNotifier(0)  #first variable
        npoints = 1000
        seriesNotifier = SeriesNotifier(2, npoints)
        notifier = NotifierChain((mmNotifier, seriesNotifier))
        period = 1.0
        allTimes = np.linspace(0.0, 10.0, npoints)
        for t in allTimes:
            data.t = t
            data.y[0] = 10.0 * np.cos(2 * np.pi * t / period)
            data.y[1] = 10.0 * np.sin(2 * np.pi * t / period)

            notifier.Notify(data)
        maxTime, maxValue, maxIterator = mmNotifier.getMaxima()
        minTime, minValue, minIterator = mmNotifier.getMinima()
        allValues = seriesNotifier.GetVar(0)
        fig = plt.figure()
        plt.ylim(-12.0, 12.0)
        plt.plot(allTimes, allValues)
        plt.plot(minTime, minValue, "bo")
        plt.plot(maxTime, maxValue, "r*")
        plt.show()
示例#10
0
def PhaseShiftProcessorOld():
    logging.basicConfig(level=logging.ERROR)
    stepShiftLinspace = np.linspace(0, 1.25, 10)
    stepShiftLinspace = np.linspace(0, 2.0 * np.pi, 100)
    Sav = []
    Ssd = []
    Dav = []
    Dsd = []
    Mav = []
    Msd = []

    for stepShift in stepShiftLinspace:
        settings = KickedWindkesselModel.KickedWindkesselModelSettings()
        settings.breathingPhi0 = stepShift
        settings.heartActionForce = RectangularHeartActionForce()
        settings.heartActionForce.StepShift = stepShift
        model = KickedWindkesselModel(settings)
        model.param.Npoints = 1000
        collector = AbpmFiducialPointsCollector(
            0)  #ABPM = 0. Other compartments have different numbers.
        settings.heartActionForce.Notify = collector.HeartOpenNotifier
        mmNotifier = MinMaxNotifier(0)
        mmNotifier.MinNotifier = collector.AbpmMinNotifier
        mmNotifier.MaxNotifier = collector.AbpmMaxNotifier
        seriesNotifier = SeriesNotifier(model.param.dimension,
                                        model.param.Npoints)

        chain = NotifierChain((mmNotifier, collector, seriesNotifier))
        model.Notify = chain.Notify

        model.IterateToNotifiers()

        allItems = collector.GetFiducialPointsList()
        averages = []
        standard_deviations = []

        for channel in [1, 2, 3]:  # 1-systloic 2-diastolic 3-mean
            averages.append(np.mean(allItems[:, channel]))
            standard_deviations.append(np.std(allItems[:, channel]))

        Sav.append(averages[0])
        Ssd.append(standard_deviations[0])
        Dav.append(averages[1])
        Dsd.append(standard_deviations[1])
        Mav.append(averages[2])
        Msd.append(standard_deviations[2])
        print("%f\t%f\t%f\t%f\t%f\t%f\t%f" %
              (settings.heartActionForce.StepShift, averages[0],
               standard_deviations[0], averages[1], standard_deviations[1],
               averages[2], standard_deviations[2]))

    #normalize values
    basalValue = Ssd[0]
    for i, v in enumerate(Ssd):
        Ssd[i] = 100.0 * (v / basalValue)
    basalValue = Dsd[0]
    for i, v in enumerate(Dsd):
        Dsd[i] = 100.0 * (v / basalValue)
    basalValue = Msd[0]
    for i, v in enumerate(Msd):
        Msd[i] = 100.0 * (v / basalValue)

    #pdb.set_trace()
    fig, ax = plt.subplots()
    ax.ticklabel_format(useOffset=False)
    #plt.subplot(3,1,1)
    ax.plot(stepShiftLinspace, Ssd, "r", linestyle="-",
            linewidth=1)  # SAP thin curve
    #plt.subplot(3,1,2)
    ax.plot(stepShiftLinspace, Dsd, "g", linestyle="--",
            linewidth=3)  # DAP thick dashed
    #plt.subplot(3,1,3)
    ax.plot(stepShiftLinspace, Msd, "b", linestyle="-",
            linewidth=3)  # MAP thick solid
    for y in (100.0, ):  # 80.0,100.0,120.0):
        plt.axhline(y=y, color='k', linestyle='-')
    #ax.fill(30, 30, fill=False, hatch='\\')
    #pdb.set_trace()
    ylim = copy.deepcopy(ax.get_ylim())  # keep original limits.\
    xlim = copy.deepcopy(ax.get_xlim())  # keep original limits.\

    ax.set_ylim([ylim[0], ylim[1]])
    ax.set_xlim([xlim[0], xlim[1]])
    plt.savefig("phaseShiftFunction100.png")
    plt.show()
    return (Sav, Ssd, Dav, Dsd, Mav,
            Msd), (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_TwoIAFOneWayCoupledInSeconds(self):
        """
        This test is a comparison of two IAFs: one with PRC and one without.
        """
        npoints = 240

        data = RungeKutta45IntegratorData(10, 0.0)

        iafResp = IntegrateAndFire()
        iafResp.SetPhaseVelocityFromBPM(20)
        iafResp.SetInitialPhase(1.0 / 7.0)
        iafResp.KickAmplitude = 0.1
        iafResp.SamplingTime = 0.01
        iafResp.CoordinateNumberForRate = 7
        iafResp.CoordinateNumberForPhase = 6
        iafResp.CoordinateNumberForForceInput = 5  #not used
        # Coordinate number, to  which the state will be written
        #this variable will be used for coupling.
        iafResp.CoordinateNumberForOutput = 4
        fireNotifier = FiringTimesNotifier()
        iafResp.Notify = fireNotifier.Notify
        seriesNotifier = SeriesNotifier(10, npoints)

        iafHeart = IntegrateAndFire()
        iafHeart.SamplingTime = 0.01
        iafHeart.SetPhaseVelocityFromBPM(67)
        iafHeart.CoordinateNumberForRate = 0
        iafHeart.CoordinateNumberForPhase = 1
        iafHeart.CoordinateNumberForForceInput = 4  #essential
        #iafHeart.CoordinateNumberForForceInput = 9 # void  #essential
        # Coordinate number, to  which the state will be written
        #this variable will be used for coupling.
        iafHeart.CoordinateNumberForOutput = 2
        fireNotifierHeart = FiringTimesNotifier()
        iafHeart.Notify = fireNotifierHeart.Notify

        allTimes = np.linspace(0.0, npoints * iafHeart.SamplingTime, npoints)
        for t in allTimes:
            data.t = t

            iafResp.ApplyDrive(data)  # will open or not.
            iafHeart.ApplyDrive(data)
            #print("%lf\t%lf" % (iaf.Phase,data.y[6]))
            logging.debug(data)
            seriesNotifier.Notify(data)
        #Print dots at firing times
        spikes = np.ones(len(fireNotifier.firingTimes))
        spikes2 = np.ones(len(fireNotifierHeart.firingTimes))
        #print("Firing times: %s" % str(fireNotifier.firingTimes))
        fig = plt.figure()
        plt.subplot(3, 1, 1)
        #plt.ylim(-12.0,12.0)
        #plt.plot(allTimes,seriesNotifier.GetVar(5))#effective rate
        plt.plot(allTimes, seriesNotifier.GetVar(4), "g", linewidth=2)
        plt.xlabel("Time [s]")
        plt.ylabel("Force")
        plt.ylim(0.0, 0.1)
        plt.subplot(3, 1, 2)
        #pdb.set_trace()

        plt.plot(allTimes, seriesNotifier.GetVar(6), "b")
        plt.plot(fireNotifier.firingTimes, spikes, "bo")
        plt.xlabel("Time [s]")
        plt.ylim(0.0, 1.2)
        plt.subplot(3, 1, 3)
        plt.plot(allTimes, seriesNotifier.GetVar(1), "r")
        #plt.plot(allTimes,seriesNotifier.GetVar(2),"r")
        plt.plot(fireNotifierHeart.firingTimes, spikes2, "ro")
        plt.ylim(0.0, 1.2)
        plt.xlabel("Time [s]")
        fname = sys._getframe().f_code.co_name + ".png"
        print("Test result in %s" % fname)
        plt.savefig(fname)
    def test_FrequencyModulationWithPRCandKick(self):
        """
        This test is a comparison of two IAFs: one with PRC and one without.
        """
        npoints = 1000
        period = 20.0

        data = RungeKutta45IntegratorData(8, 0.0)

        iaf = IntegrateAndFire()
        iaf.phaseEfectivenessCurve = phaseEfectivenessCurveSH
        fireNotifier = FiringTimesNotifier()
        iaf.Notify = fireNotifier.Notify
        seriesNotifier = SeriesNotifier(8, npoints)

        data2 = RungeKutta45IntegratorData(8, 0.0)
        iaf2 = IntegrateAndFire()
        fireNotifier2 = FiringTimesNotifier()
        iaf2.Notify = fireNotifier2.Notify
        seriesNotifier2 = SeriesNotifier(8, npoints)

        allTimes = np.linspace(0.0, npoints * iaf.SamplingTime, npoints)
        binaryKick = np.zeros(npoints)
        for i in range(npoints):
            if random.randint(0, 10) == 1:
                binaryKick[i] = 0.2

        for i, t in enumerate(allTimes):
            data.t = t
            data[5] = binaryKick[i]
            data2.t = t
            data2[5] = binaryKick[i]

            #data.y[5] = 2.0 * iaf.r * (1.0 + np.cos(2 * np.pi * t / period))

            #data.y[6] = iaf.Phase+phaseEfectivenessCurveSH(iaf.Phase)
            iaf.ApplyDrive(data)  # will open or not.
            iaf2.ApplyDrive(data2)
            #print("%lf\t%lf" % (iaf.Phase,data.y[6]))
            logging.debug(data)
            seriesNotifier.Notify(data)
            seriesNotifier2.Notify(data2)
        #Print dots at firing times
        spikes = np.ones(len(fireNotifier.firingTimes))
        spikes2 = np.ones(len(fireNotifier2.firingTimes))
        #print("Firing times: %s" % str(fireNotifier.firingTimes))
        fig = plt.figure()
        plt.subplot(3, 1, 1)
        #plt.ylim(-12.0,12.0)
        plt.plot(allTimes, seriesNotifier.GetVar(5))  #effective rate
        plt.subplot(3, 1, 2)
        plt.plot(allTimes, seriesNotifier.GetVar(4), "g")
        plt.plot(allTimes, seriesNotifier.GetVar(6), "r")
        plt.plot(fireNotifier.firingTimes, spikes, "ro")
        plt.subplot(3, 1, 3)
        plt.plot(allTimes, seriesNotifier2.GetVar(4), "g")
        plt.plot(allTimes, seriesNotifier2.GetVar(6), "r")
        plt.plot(fireNotifier2.firingTimes, spikes2, "ro")

        fname = sys._getframe().f_code.co_name + ".png"
        print("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)