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_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)