def getObjectives(vars_set):

    fun_lib.checkSimulationLength(vars_set['time'][-1],110)

    # Pa = vars_set['Systemic#1.aortic_arch_C2.port_a.pressure']
    # Pa = vars_set['Pa']
    # interval = findInterval(380, 400, vars_set['time'])
    # Pa_avg = sum(Pa[interval]) / len(interval)

    # HR is system input (change in phi) from 70 to 89

    BPs_target = 113*mmHg2SI
    BPd_target = 90*mmHg2SI
    SV_target = 63*ml2SI
    HR_target = 81*bpm2SI
    CO_target = 5.1*lpm2SI
    phi_target = 0.3739
    t = vars_set['time'][-1]
    interval = fun_lib.findInterval(t-5, t, vars_set['time'])

    # build costs
    ov = [  ('BPs', max(vars_set['brachial_pressure'][interval]), 122.4*mmHg2SI, None, 1),
            ('BPd', min(vars_set['brachial_pressure'][interval]), 86.4*mmHg2SI, None, .1),
            ('CO', fun_lib.avg(vars_set['CO'], interval), 4.608*lpm2SI, None, 10),
            ('HR', fun_lib.avg(vars_set['HR'], interval), 78.12*bpm2SI, None, 10)]

    objectives=list(map(lambda o: fun_lib.ObjectiveVar(o[0], value = o[1], targetValue = o[2], limit=o[3], weight = o[4]), ov))

    # to have comparable cost function values one must have the stds ready
    map(fun_lib.unifyCostFunc, objectives)

    if '__draw_plots' in vars_set and vars_set['__draw_plots']:
        plotObjectives(vars_set, interval, objectives)

    return objectives
Exemple #2
0
def getObjectives(vars_set):

    endTime = vars_set['time'][-1]
    interval = fun_lib.findInterval(endTime - 10, endTime, vars_set['time'])
    BPs = max(vars_set['brachial_pressure'][interval])
    BPd = min(vars_set['brachial_pressure'][interval])

    # this shows quite a too low CO, probably due to sampling, sharp peaks and no interpolation
    # CO = sum(vars_set['heartComponent.aorticValve.q_in.q'][interval]) / len(interval)

    CO = sum(vars_set['CO'][interval]) / len(interval)

    objectives = list()

    def buildObjective(name, value, targetVal):
        o = fun_lib.ObjectiveVar(name, value, targetVal)
        objectives.append(o)

    buildObjective('BPs', BPs, 120 * 133.32)
    buildObjective('BPd', BPd, 80 * 133.32)
    buildObjective('CO', CO, (6.34 / 1000 / 60))

    # to have comparable cost function values one must have the stds ready
    map(fun_lib.unifyCostFunc, objectives)

    if '__draw_plots' in vars_set and vars_set['__draw_plots']:
        plotObjectives(vars_set, interval, objectives)

    return objectives
 def getInterval(phase, phase_offset):
     if phase_offset is None:
         offset = (0, 0)
     elif isinstance(phase_offset, int):
         offset = (phase_offset, phase_offset)
     else:
         offset = (phase_offset[0], phase_offset[1])
     
     return fun_lib.findInterval(phase[0] + offset[0], phase[1] + offset[1], time), offset
Exemple #4
0
def getCurrentValues(vars_set):

    interval = fun_lib.findInterval(25, 30, vars_set['time'])
    EDV = max(vars_set['V_LV'][interval])
    ESV = min(vars_set['V_LV'][interval])

    SV = EDV - ESV
    EF = fun_lib.calculateEF(vars_set['V_LV'][interval])

    return [EF]
Exemple #5
0
def getObjectives(vars_set):

    # Pa = vars_set['Systemic#1.aortic_arch_C2.port_a.pressure']
    # Pa = vars_set['Pa']
    # interval = findInterval(380, 400, vars_set['time'])
    # Pa_avg = sum(Pa[interval]) / len(interval)

    # HR is system input (change in phi) from 70 to 89
    mmHg2SI = 133.32
    ml2SI = 1e-6
    lpm2SI = 1e-3 / 60

    BPs_target = 160 * mmHg2SI
    EDV_target = 133 * ml2SI
    ESV_target = 27 * ml2SI

    t = vars_set['time'][-1]
    interval = fun_lib.findInterval(10, 15, vars_set['time'])
    interval2 = fun_lib.findInterval(10, 15, vars_set['time'])

    # build costs
    ov = [
        ('costs', max(vars_set['sum_cost'][interval]), -1, None, 1),
        ('fbr_aor',
         max(vars_set[
             'systemicMockPressure.baroreflex_system.baroreceptor_aortic.fbr']
             [interval2]), 35, None, 10),
        ('fbr_car',
         max(vars_set[
             'systemicMockPressure.baroreflex_system.baroreceptor_carotid.fbr']
             [interval2]), 35, None, 10),
    ]

    # make it a dict?
    objectives = list(
        map(
            lambda o: fun_lib.ObjectiveVar(
                o[0], value=o[1], targetValue=o[2], limit=o[3], weight=o[4]),
            ov))
    return objectives
Exemple #6
0
def calculateCosts(vars_set):

    # Pa = vars_set['Systemic#1.aortic_arch_C2.port_a.pressure']
    # Pa = vars_set['Pa']
    # interval = findInterval(380, 400, vars_set['time'])
    # Pa_avg = sum(Pa[interval]) / len(interval)

    # cost = (Pa_avg - 100*133.32)**2

    # HR is system input (change in phi) from 70 to 89
    mmHg2Pa = 133.32
    ml2m3 = 1e-6

    BPs_target = 157
    BPd_target = 87
    BPm_target = 114
    BPk_target = 20

    interval = fun_lib.findInterval(25, 30, vars_set['time'])

    BPs = max(vars_set['brachial_pressure'][interval])
    BPd = min(vars_set['brachial_pressure'][interval])

    # using true mean
    BPm = sum(vars_set['brachial_pressure_mean'][interval]) / len(interval)

    # using simpler mean
    BPk = sum(vars_set['renal_capillary'][interval]) / len(interval)

    print('BPs %s mmHg (%s)' %
          tuple(map(lambda x: str(round(x)), (BPs / mmHg2Pa, BPs_target))))
    print('BPd %s mmHg (%s)' % tuple(map(round, (BPd / mmHg2Pa, BPd_target))))
    print('SV %s  ml (%s)' % tuple(map(round, (BPm / mmHg2Pa, BPm_target))))

    cost = lambda measured, target: (measured / target - 1)**2
    costs = list(
        map(cost, (BPs, BPd, BPm, BPk),
            (BPs_target * mmHg2Pa, BPd_target * mmHg2Pa, BPm_target * mmHg2Pa,
             BPk_target * mmHg2Pa)))

    # costs = [(BPs / (BPs_target*mmHg2Pa) - 1)**2,  (BPd / (80*133.32) - 1)**2, (CO / (6.34/1000/60) - 1)**2]

    return costs
def getObjectives(vars_set):

    # Pa = vars_set['Systemic#1.aortic_arch_C2.port_a.pressure']
    # Pa = vars_set['Pa']
    # interval = findInterval(380, 400, vars_set['time'])
    # Pa_avg = sum(Pa[interval]) / len(interval)

    # HR is system input (change in phi) from 70 to 89
    mmHg2SI = 133.32
    ml2SI = 1e-6
    lpm2SI = 1e-3 / 60

    BPs_target = 120 * mmHg2SI
    BPd_target = 80 * mmHg2SI
    EDV_target = 175 * ml2SI
    ESV_target = 70 * ml2SI

    t = vars_set['time'][-1]
    interval = fun_lib.findInterval(t - 3, t, vars_set['time'])

    # build costs
    ov = [
        ('BPs', max(vars_set['brachial_pressure'][interval]), BPs_target, None,
         1),
        ('BPd', min(vars_set['brachial_pressure'][interval]), BPd_target, None,
         1),
        ('EDV', max(vars_set['V_LV'][interval]), EDV_target, None, 1),
        ('ESV', min(vars_set['V_LV'][interval]), ESV_target, None, 1),
        ('Ts', max(vars_set['TEjection'][interval]), 0.25, None, 1e-4),
    ]

    # make it a dict?
    objectives = list(
        map(
            lambda o: fun_lib.ObjectiveVar(
                o[0], value=o[1], targetValue=o[2], limit=o[3], weight=o[4]),
            ov))

    objectives[-1].costFunctionType = fun_lib.CostFunctionType.Linear
    return objectives
Exemple #8
0
def getObjectives(vars_set):

    fun_lib.checkSimulationLength(vars_set['time'][-1], 60, penalty=1000)

    # Pa = vars_set['Systemic#1.aortic_arch_C2.port_a.pressure']
    # Pa = vars_set['Pa']
    # interval = findInterval(380, 400, vars_set['time'])
    # Pa_avg = sum(Pa[interval]) / len(interval)

    # HR is system input (change in phi) from 70 to 89

    # t = vars_set['time'][-1]
    t = 30
    interval = fun_lib.findInterval(t - 3, t, vars_set['time'])

    BPs_target = 194.4 * mmHg2SI
    BPd_target = 88 * mmHg2SI
    EDV_target = 133 * ml2SI
    ESV_target = 30 * ml2SI
    CO_min = 15.5 * lpm2SI
    # Ppa_target = 34*mmHg2SI # (Kovacs Eur Respir J 2009)
    Ppv_target = 12 * mmHg2SI  # (Kovacs Eur Respir J 2009)
    co = fun_lib.calculateAlternativeCO(vars_set, interval)
    Ppv_target = co * 60 * 1e3 * 1.2  # Eisman 2018 (PMID 29695381) shows a relation CO to PCWP of 1.2 mmHg/(L/min) in healthy control
    Ppas_target = 34 * mmHg2SI  # (Kovacs Eur Respir J 2009)

    Ppad_target = 15 * mmHg2SI  # (Kovacs Eur Respir J 2009)

    tm = 60
    intervalm = fun_lib.findInterval(tm - 3, tm, vars_set['time'])
    co_max = fun_lib.calculateAlternativeCO(vars_set, intervalm)
    # build costs
    ov = [
        ('BPs', max(vars_set['brachial_pressure'][interval]) / mmHg2SI, 194.4,
         None, 3),
        ('BPd', min(vars_set['brachial_pressure'][interval]) / mmHg2SI, 81.16,
         None, 10),
        # ('EDV', max(vars_set['V_LV'][interval]), EDV_target, None, 1),
        # ('ESV', min(vars_set['V_LV'][interval]), ESV_target, None, 1e-3),
        ('CO', co / lpm2SI, 16.17, None, 0.1),
        ('CO_max', co_max / lpm2SI, 20.6, None, 1),
        ('Ts', max(vars_set['TEjection'][interval]), 0.196, None, .05),
        # ('Td', max(vars_set['TFilling'][interval]), 0.18, [0.18*0.5, 0.18*1.5], 1e-4),
        ('EF', fun_lib.calculateEF(vars_set['V_LV'][interval]), 0.78, None, .1
         ),
        # ('HR', numpy.mean(vars_set['HR'][interval])*60, 154, None, 0, 60),
        # ('Ppa', numpy.mean(vars_set['P_pa'][interval]), Ppa_targ)et, None, .1),
        # ('Ppv', numpy.mean(vars_set['P_pv'][interval]), Ppv_target, None, .1),
        ('Ppa_s', numpy.max(vars_set['P_pa'][interval]), Ppas_target, None, 10
         ),
        # ('Ppa_d', numpy.min(vars_set['P_pa'][interval]), Ppad_target, None, 0.1, 1/mmHg2SI),
        ('Ppv', numpy.mean(vars_set['P_pv'][interval]) / mmHg2SI, Ppv_target,
         None, 2),
        ('Pcap',
         numpy.mean(vars_set['exercised_capillary'][interval]) / mmHg2SI, None,
         [10, 40], 10),
    ]

    # make it a dict?
    objectives = list(
        map(
            lambda o: fun_lib.ObjectiveVar(o[0],
                                           value=o[1],
                                           targetValue=o[2],
                                           limit=o[3],
                                           tolerance=o[4],
                                           k_p=1), ov))

    # objectives[-1].costFunctionType = fun_lib.CostFunctionType.Linear
    # objectives[-2].costFunctionType = fun_lib.CostFunctionType.Linear

    # to have comparable cost function values one must have the stds ready
    map(fun_lib.unifyCostFunc, objectives)

    if '__draw_plots' in vars_set and vars_set['__draw_plots']:
        plotObjectives(vars_set, interval, objectives)

    return objectives
Exemple #9
0
def getObjectives(vars_set):

    fun_lib.checkSimulationLength(vars_set['time'][-1], 10, penalty=1000)

    # def 'johan'

    # Pa = vars_set['Systemic#1.aortic_arch_C2.port_a.pressure']
    # Pa = vars_set['Pa']
    # interval = findInterval(380, 400, vars_set['time'])
    # Pa_avg = sum(Pa[interval]) / len(interval)

    # HR is system input (change in phi) from 70 to 89
    mmHg2SI = 133.32
    ml2SI = 1e-6
    lpm2SI = 1e-3 / 60
    bpm2SI = 1 / 60

    # BPs_target = 120*mmHg2SI
    # BPd_target = 80*mmHg2SI
    # BPk_target = 20*mmHg2SI
    # CO_target = 5.76*lpm2SI
    # EF_target = 0.6
    # HR_target = 60*bpm2SI
    # Ppa_target = 14*mmHg2SI # (Kovacs Eur Respir J 2009)
    # Ppv_target = 8*mmHg2SI # (Kovacs Eur Respir J 2009)
    # Ppas_target = 20.8*mmHg2SI # (Kovacs Eur Respir J 2009)
    # Ppad_target = 8.8*mmHg2SI # (Kovacs Eur Respir J 2009)
    # pwv_bounds = [5, 10]

    time = vars_set['time']

    # interval = fun_lib.findInterval(time[0] + 43, time[0] + 48, time)

    # interval for averaging
    interval = fun_lib.findInterval(time[-1] - 2, time[-1], time)
    # to observe how much the baseline fluctuates
    steady_interval = fun_lib.findInterval(time[-1] - 30, time[-1] - 5, time)

    # mitral valve flow ratio spontaneous:atrial contraction is about 2:1
    # vla_1st_Peak_i = fun_lib.findInterval(39.8, 40, time)
    # vla_2nd_Peak_i = fun_lib.findInterval(39.2, 39.4, time)
    # vla_peak_frac = numpy.max(vars_set['q_mv'][vla_1st_Peak_i])/numpy.max(vars_set['q_mv'][vla_2nd_Peak_i])

    # interval for Q MV - must be a bit shorter to find further saddle after the peak
    intervalQMV = fun_lib.findInterval(time[-1] - 2, time[-1] - 1, time)
    # (q_mv_Ppassive, q_mv_Patrial) = fun_lib.calculateQ_MV(vars_set['q_mv'], time, intervalQMV)
    # (q_mv_Ppassive, q_mv_Patrial) = fun_lib.calculateQ_MV(vars_set['q_mv'], time, intervalQMV)
    (E_A, A_s) = fun_lib.calculateEA(vars_set['q_mv'],
                                     vars_set['cardiac_cycle'], time,
                                     intervalQMV)
    # vla_peak_frac = q_mv_Ppassive/q_mv_Patrial
    # (atrial_kick, q_mv_saddle) = fun_lib.calculateQdot_mv(vars_set['V_LV'], vars_set['q_mv'], time, intervalQMV)
    # peak pressure drop on aortic valve
    dp_av = numpy.max(vars_set['ascending_aorta'][interval]) - numpy.max(
        vars_set['P_LV'][interval])

    # Van Bortel 2012 siggest using 80 % of carotid to femoral distance
    # distance = vars_set['speedSegmentLength'][1]*0.8
    distance = 0.677 * 0.8
    pwv = fun_lib.calculatePWV(vars_set['time'], vars_set['carotid_pressure'],
                               vars_set['femoral_pressure'], distance)

    # build costs
    ov = [
        ('BPs', max(vars_set['brachial_pressure'][interval]) / mmHg2SI, 120,
         None, 1),
        ('BPd', min(vars_set['brachial_pressure'][interval]) / mmHg2SI, 80,
         None, 1),
        ('EDV', numpy.max(vars_set['V_LV'][interval]) / ml2SI, 150, None, 5),
        ('ESV', numpy.min(vars_set['V_LV'][interval]) / ml2SI, 60, None, 3),
        ('ESV_la', numpy.min(vars_set['V_la'][interval]) / ml2SI, 12, None, 5),
        ('EDV_la', numpy.max(vars_set['V_la'][interval]) / ml2SI, 41, None, 5),
        ('dp_av', dp_av / mmHg2SI, None, [-5, 5], 0.1),
        ('E/A', E_A, 1.7, None, 0.5),
        ('E/S', A_s, 2, None, 1.5),
        # ('Q_MV_f', vla_peak_frac*1, None, [1.5, 2], 0),
        # ('Qdot_mv', atrial_kick*1, None, [0.2, 0.3], 0),
        # ('q_mv_sad', q_mv_saddle*100, None, [0, q_mv_Patrial*20], 0),
        # ('SL_max', max(vars_set['SLo_max'][interval]), 2.2, None, 0, 1),
        # ('SL_min', min(vars_set['SLo_min'][interval]), 1.75, None, 0, 1),
        # ('HR', numpy.mean(vars_set['HR'][interval]) , 64*bpm2SI, None, 1, 1/bpm2SI),
        # set by assumption and loop closed
        #            ('HR', numpy.mean(vars_set['HR'][interval]), HR_target, None, 1),
        # set by EDV and ESV
        #            ('EF', fun_lib.calculateEF(vars_set['V_LV'][interval]), EF_target, None, 1),
        # set by HR and EDV AND ESV, just emphasized here
        ('CO', sum(vars_set['CO'][interval]) / len(interval) / lpm2SI, 5.76,
         None, 0.1),
        # ('BPk', sum(vars_set['renal_capillary'][interval]) / len(interval)/mmHg2SI, 20, None, 1, 1/mmHg2SI),
        ('Ppas', numpy.max(vars_set['P_pa'][interval]) / mmHg2SI, 20.5, None, 5
         ),
        ('Ppad', numpy.min(vars_set['P_pa'][interval]) / mmHg2SI, 8.8, None,
         5),
        ('Ppv', numpy.mean(vars_set['P_pv'][interval]) / mmHg2SI, 8, None, 2),
        # ('EDP', numpy.min(vars_set['P_LV'][interval]), None, [6*mmHg2SI, 12*mmHg2SI], 1e-3),
        # ('P_MV_o', numpy.mean(vars_set['P_MV_o'][interval])/mmHg2SI, 4.5*mmHg2SI, None, 0, 1/mmHg2SI),
        # ('P_MV_c', numpy.mean(vars_set['P_MV_c'][interval])/mmHg2SI, 6*mmHg2SI, None, 0, 1/mmHg2SI),
        # ('BPMeanStd', numpy.std(vars_set['brachial_pressure_mean'][steady_interval]), None, [0, 4*mmHg2SI], 0, 1/mmHg2SI),
        ('Ts', max(vars_set['TEjection'][interval]), 0.292, None, 0.04),
        ('PWV', pwv, None, [5, 10], 1)
    ]

    objectives = list(
        map(
            lambda o: fun_lib.ObjectiveVar(o[0],
                                           value=o[1],
                                           targetValue=o[2],
                                           limit=o[3],
                                           tolerance=o[4],
                                           k_p=1), ov))

    # to have comparable cost function values one must have the stds ready
    map(fun_lib.unifyCostFunc, objectives)

    if '__draw_plots' in vars_set and vars_set['__draw_plots']:
        plotObjectives(vars_set, interval, objectives)

    return objectives
def getObjectives(vars_set):

    fun_lib.checkSimulationLength(vars_set['time'][-1], 40)

    # Pa = vars_set['Systemic#1.aortic_arch_C2.port_a.pressure']
    # Pa = vars_set['Pa']
    # interval = findInterval(380, 400, vars_set['time'])
    # Pa_avg = sum(Pa[interval]) / len(interval)

    # HR is system input (change in phi) from 70 to 89

    BPs_target = 194.4 * mmHg2SI
    EDV_target = 133 * ml2SI
    ESV_target = 30 * ml2SI
    CO_min = 17.5 * lpm2SI
    # Ppa_target = 34*mmHg2SI # (Kovacs Eur Respir J 2009)
    Ppv_target = 12 * mmHg2SI  # (Kovacs Eur Respir J 2009)
    Ppas_target = 34 * mmHg2SI  # (Kovacs Eur Respir J 2009)
    Ppad_target = 15 * mmHg2SI  # (Kovacs Eur Respir J 2009)

    t = vars_set['time'][-1]
    interval = fun_lib.findInterval(t - 5, t, vars_set['time'])

    # build costs
    ov = [
        ('BPs', max(vars_set['brachial_pressure'][interval]), BPs_target, None,
         10, 1 / mmHg2SI),
        # ('EDV', max(vars_set['V_LV'][interval]), EDV_target, None, 1),
        # ('ESV', min(vars_set['V_LV'][interval]), ESV_target, None, 1e-3),
        ('CO', numpy.mean(vars_set['CO'][interval]), None,
         [CO_min, 60 * lpm2SI], 100e-3, 1 / lpm2SI),
        # ('Ts', max(vars_set['TEjection'][interval]), 0.18, [0.18*0.5, 0.18*1.5], 1e-4),
        # ('Td', max(vars_set['TFilling'][interval]), 0.18, [0.18*0.5, 0.18*1.5], 1e-4),
        ('EF', fun_lib.calculateEF(vars_set['V_LV'][interval]), 0.8, None, 1,
         100),
        ('HR', numpy.mean(vars_set['HR'][interval]), 154 * (1 / 60), None, 0,
         60),
        # ('Ppa', numpy.mean(vars_set['P_pa'][interval]), Ppa_targ)et, None, .1),
        # ('Ppv', numpy.mean(vars_set['P_pv'][interval]), Ppv_target, None, .1),
        ('Ppa_s', numpy.max(vars_set['P_pa'][interval]), Ppas_target, None,
         0.1, 1 / mmHg2SI),
        ('Ppa_d', numpy.min(vars_set['P_pa'][interval]), Ppad_target, None,
         0.1, 1 / mmHg2SI),
        ('Ppv', numpy.min(vars_set['P_pv'][interval]), Ppv_target, None, 1,
         1 / mmHg2SI),
    ]

    # make it a dict?
    objectives = list(
        map(
            lambda o: fun_lib.ObjectiveVar(o[0],
                                           value=o[1],
                                           targetValue=o[2],
                                           limit=o[3],
                                           weight=o[4],
                                           base=o[5],
                                           k_p=1e3), ov))

    # objectives[-1].costFunctionType = fun_lib.CostFunctionType.Linear
    # objectives[-2].costFunctionType = fun_lib.CostFunctionType.Linear

    # to have comparable cost function values one must have the stds ready
    map(fun_lib.unifyCostFunc, objectives)

    if '__draw_plots' in vars_set and vars_set['__draw_plots']:
        plotObjectives(vars_set, interval, objectives)

    return objectives
Exemple #11
0
def getObjectives(vars_set, targetsFileName = r'../../../data/Valsalva/targetValues_' + DEFAULT_TARGETVARS_TAG + '.txt'):
    """ Returns dict of objectives
    control variables:
    __targetValuesFilename
    __plot_title
    __saveFig_path
    __draw_plots"""
    
    
    fun_lib.checkSimulationLength(vars_set['time'][-1],50)
    
    # some control variables are not present in case of identification
    if '__targetValuesFilename' not in vars_set or vars_set['__targetValuesFilename'] is None:
        vars_set['__targetValuesFilename'] = targetsFileName

    # if '__draw_plots' not in vars_set:
    #     vars_set['__draw_plots'] = True
    

    # Pa = vars_set['Systemic#1.aortic_arch_C2.port_a.pressure']
    # Pa = vars_set['Pa']
    # interval = findInterval(380, 400, vars_set['time'])
    # Pa_avg = sum(Pa[interval]) / len(interval)

    # HR is system input (change in phi) from 70 to 89
    mmHg2SI = 133.32
    ml2SI = 1e-6
    # lpm2SI = 1e-3/60
    BPM2SI = 1/60

    # simulation starts when the BP gets over 10 Pa
    sim_start_i = fun_lib.findLowestIndex(10, vars_set['brachial_pressure'])
    sim_start_t = vars_set['time'][sim_start_i]
    print('Valsalva simulation starts at %0.0fs' % sim_start_t)

    BP = vars_set['brachial_pressure'][sim_start_i:]
    # HR = vars_set['heartRate.HR']
    TP = vars_set['thoracic_pressure'][sim_start_i:]
    SV = vars_set['SV'][sim_start_i:] if 'SV' in vars_set else None
    time = vars_set['time'][sim_start_i:] - sim_start_t

    # make sure its in non-SI units
    if numpy.mean(BP) > 200:
        # convert to SI units
        BP = BP/mmHg2SI
        # HR = HR/BPM2SI
        TP = TP/mmHg2SI
        SV = SV/ml2SI if SV is not None else None

    dt = time[2] - time[1]
    assert dt > 0, "The simulation must not store values at events."

    
    peaks  = fun_lib.getPeaks(BP, dt)
    HR = fun_lib.getHR(BP, peaks, dt)/BPM2SI
    bp_mean = fun_lib.getMeanRR(BP, peaks)
    ppulse = fun_lib.getPPulseRR(BP,peaks)

    # find valsalva start and end
    valsalva_start = fun_lib.getValsalvaStart(time, TP, threshold=10)
    valsalva_end = fun_lib.getValsalvaEnd(valsalva_start, time, TP, threshold=10)
    valsalva = (valsalva_start, valsalva_end)
    
    # divide valsalva phases    
    # pre-valsalva
    phase0 = (2, valsalva_start)
    # overshoot phase at start of the valsalva
    phase1 = (valsalva_start, valsalva_start + 5)
    # min mean pressure during valsalva
    phase2 = (valsalva_start, valsalva_end)
    # drop and overshoot after valsalva release
    phase4 = (valsalva_end, valsalva_end + 7)
    # recovery - all is getting to normal
    phase5 = (time[-1] - 5, time[-1])


    # baseline is start to just before Valsalva
    baseline_interval = fun_lib.findInterval(phase0[0], phase0[1], time)
    baseline_bp = bp_mean[baseline_interval].mean()
    baseline_hr = HR[baseline_interval].mean()
    baseline_pp = ppulse[baseline_interval].mean()

    IGNORE = fun_lib.CostFunctionType.Ignore
    COUNT = fun_lib.CostFunctionType.Quadratic
    # construct objectives
    objectives = list()
    objectives.append(fun_lib.ObjectiveVar('baseline_bp', baseline_bp, costFunctionType=IGNORE))
    objectives.append(fun_lib.ObjectiveVar('baseline_hr', baseline_hr, costFunctionType=IGNORE))
    objectives.append(fun_lib.ObjectiveVar('baseline_pp', baseline_pp, costFunctionType=IGNORE))

    def getInterval(phase, phase_offset):
        if phase_offset is None:
            offset = (0, 0)
        elif isinstance(phase_offset, int):
            offset = (phase_offset, phase_offset)
        else:
            offset = (phase_offset[0], phase_offset[1])
        
        return fun_lib.findInterval(phase[0] + offset[0], phase[1] + offset[1], time), offset

    def buildValueObjective(o):
        (sig, phase, phase_offset, fun, baseline, name, include_in_cost) = o
        interval, _ = getInterval(phase, phase_offset)
        value = fun(sig[interval])/baseline
        return fun_lib.ObjectiveVar(name, value=value, costFunctionType=include_in_cost, base = baseline, tolerance = 1/baseline)

    def buildTimeObjective(to):
        (sig, phase, phase_offset, fun, name, include_in_cost) = to
        interval, offset = getInterval(phase, phase_offset)        
        value = time[fun(sig[interval])] + offset[0]
        return fun_lib.ObjectiveVar(name, value=value, costFunctionType=include_in_cost, tolerance=1)        

    def buildPPObjective(po):
        (name, timeObjName, phase, tolerance, include_in_cost) = po
        o = fun_lib.getObjectiveByName(objectives, timeObjName).value + phase[0]
        i = fun_lib.findLowestIndex(o, time)
        value = ppulse[i]/baseline_pp
        return fun_lib.ObjectiveVar(name, value=value, costFunctionType=include_in_cost, base=baseline_pp, tolerance=1/baseline_pp)

    def buildSVObjective(svo):
        (phase, phase_offset, name, limit, tolerance, include_in_cost) = svo
        phase_interval, _ = getInterval(phase, phase_offset)
        sv_val_valsalva = numpy.min(SV[phase_interval])
        return fun_lib.ObjectiveVar(name, sv_val_valsalva, limit=limit, std = limit[0]*0.1, k_p=1, tolerance = tolerance, costFunctionType=include_in_cost)

    phase_values = [(bp_mean, phase1, (-1, 0), numpy.max  , baseline_bp, 'ph1_peak'    , IGNORE),
                    (bp_mean, phase2, (2, -2), numpy.min  , baseline_bp, 'ph2_mean_min', IGNORE),
                    (bp_mean, phase4,(-7, -7), numpy.max  , baseline_bp, 'ph2_max'     , IGNORE),
                    (bp_mean, phase4,(-2, -3), numpy.min  , baseline_bp, 'ph4_drop'    , IGNORE),
                    (bp_mean, phase4, (2, 5) , numpy.max  , baseline_bp, 'ph4_ovrshoot', IGNORE),
                    (bp_mean, phase5, 0      , numpy.mean , baseline_bp, 'ph5_recovery', IGNORE),
                    (HR     , phase1, 0      , numpy.min  , baseline_hr, 'ph1_hr_min' , COUNT),
                    (HR     , phase4, (0, 0) , numpy.max  , baseline_hr, 'ph4_hr_max' , COUNT),
                    (HR     , phase4, (0, 3) , numpy.min  , baseline_hr, 'ph4_hr_drop', COUNT),
                    (HR     , phase5, 0      , numpy.mean , baseline_hr, 'ph5_hr_recovery', COUNT)]

    time_values = [ (bp_mean, phase1, (-1, 0), numpy.argmax, 't_ph1_peak'    , IGNORE),
                    (bp_mean, phase2, (2, -2), numpy.argmin, 't_ph2_mean_min', IGNORE),
                    (bp_mean, phase4,(-7, -7), numpy.argmax, 't_ph2_max'     , IGNORE),# relative to phase 4 !!!
                    (bp_mean, phase4, (-2, -3), numpy.argmin, 't_ph4_drop'   , IGNORE),
                    (bp_mean, phase4, (2, 5) , numpy.argmax, 't_ph4_ovrshoot', IGNORE),
                    (HR     , phase1, 0      , numpy.argmin, 't_ph1_hr_min'  , IGNORE),
                    (HR     , phase4, (0, 0) , numpy.argmax, 't_ph4_hr_max'  , IGNORE),
                    (HR     , phase4, (0, 3) , numpy.argmin, 't_ph4_hr_drop' , IGNORE)    ]

    # Get pulse pressures
    pp_values = [('pp_ph2_mean_min', 't_ph2_mean_min', phase2, 1, COUNT),
                 ('pp_ph2_max'     , 't_ph2_max'     , phase4, 1, COUNT), # realtive to phase 4
                 ('pp_ph4_drop'    , 't_ph4_drop'    , phase4, 1, IGNORE)]

    sv_values = [(phase2, (2, -1), 'SV_min_valsalva', [25, 40], 10, COUNT),
                 (phase1, (0,  5), 'SV_min_midValsalva', [55, 150], 10, COUNT),
                 (phase4, (3, 4), 'SV_min_recovery', [60, 200], 5, COUNT),                ]

    # map the inputs to ObjectiveVar
    objectives.extend(map(buildValueObjective, phase_values))
    objectives.extend(map(buildTimeObjective, time_values))
    objectives.extend(map(buildPPObjective, pp_values))
    if SV is not None:
        objectives.extend(map(buildSVObjective, sv_values))
    
 

    # INCLUDE_SV = IGNORE

    # # penalize by too low SV in wide area - SV should not go below also in phase 4
    # if SV is not None:
    #     # during valsalva SV should not go below 25ml
    #     phase2_interval, _ = getInterval(phase2, (2, -1))
    #     sv_val_valsalva = numpy.min(SV[phase2_interval])
    #     sv_objective = fun_lib.ObjectiveVar(
    #             'SV_min_valsalva', 
    #             sv_val_valsalva, limit=[25, 150], std = 25*0.1, k_p=1, costFunctionType=INCLUDE_SV)
    #     objectives.append(sv_objective)

    #     # The decrease should be slower
    #     phase1_interval, _ = getInterval(phase1, None)
    #     sv_val_midValsalva = numpy.min(SV[phase1_interval])
    #     sv_objective = fun_lib.ObjectiveVar(
    #             'SV_min_midValsalva', 
    #             sv_val_valsalva, limit=[60, 150], std = 50*0.1, k_p=1, costFunctionType=INCLUDE_SV)
    #     objectives.append(sv_objective)

    #     # interval spans from valsalva release to complete recovery - we should not go below 90% of normal SV, but lets say 60%
    #     recovery_interval, _ = getInterval(phase4, [3, 4])
    #     sv_val_recovery = numpy.min(SV[recovery_interval])
    #     sv_objective = fun_lib.ObjectiveVar(
    #             'SV_min_recovery', 
    #             sv_val_recovery, limit=[60, 200], std = 60*0.1, k_p=1, costFunctionType=INCLUDE_SV)
    #     objectives.append(sv_objective)            

    

    if '__targetValuesFilename' in vars_set and vars_set['__targetValuesFilename'] is not None:
        fun_lib.updateObjectivesByValuesFromFile(vars_set['__targetValuesFilename'], objectives)
      
    # # to have comparable cost function values one must have the stds ready
    # map(fun_lib.unifyCostFunc, objectives)

    if '__draw_plots' in vars_set and vars_set['__draw_plots']:
        ax = fun_lib.getAxes(vars_set)

        total_costs = fun_lib.countTotalWeightedCost(objectives)
        if '__plot_title' in vars_set:
            ax.set_title('%s costs %.6f' % (vars_set['__plot_title'], total_costs))
        else:
            ax.set_title('Valsalva costs %.6f' % total_costs)

        # limit the initial BP to leave some place to show the costs
        start_at_i = fun_lib.findLowestIndex(15, time)
        ax.plot(time[start_at_i:], BP[start_at_i:], 'b')
        ax.plot(time, bp_mean, 'm')
        ax.plot(time, ppulse, 'c')
        if SV is not None:
            ax.plot(time, SV, 'y')
        # ax.plot(time, TP, 'g')
        ax.plot(time, HR)
        # ax.plot(time, vars_set['heartRate.HR'], '--')


        # get objective by name shortcuts
        def getObj(name):
            if fun_lib.getObjectiveByName(objectives, name).costFunctionType == fun_lib.CostFunctionType.Ignore:
                return -100
            return fun_lib.getObjectiveByName(objectives, name).value
        
        # ax.plot(phase0, [baseline_bp]*2, 'k')
        # ax.plot(phase5, [getObj('ph5_recovery')*baseline_bp]*2, 'k')

        # ax.plot(phase1, [getObj('ph1_peak'    )*baseline_bp]*2, 'k')
        # ax.plot(phase2, [getObj('ph2_mean_min')*baseline_bp]*2, 'k')
        # ax.plot(phase4, [getObj('ph4_drop'    )*baseline_bp]*2, 'k')

        ax.plot(getObj('t_ph1_peak'    ) + phase1[0], getObj('ph1_peak'    )*baseline_bp, '*r')
        ax.plot(getObj('t_ph2_mean_min') + phase2[0], getObj('ph2_mean_min')*baseline_bp, '*r')
        ax.plot(getObj('t_ph2_max'     ) + phase4[0], getObj('ph2_max'     )*baseline_bp, '*r')        
        ax.plot(getObj('t_ph4_drop'    ) + phase4[0], getObj('ph4_drop'    )*baseline_bp, '*r')
        ax.plot(getObj('t_ph4_ovrshoot') + phase4[0], getObj('ph4_ovrshoot')*baseline_bp, '*r')

        ax.plot(phase0, [baseline_hr]*2, 'c')
        ax.plot(getObj('t_ph1_hr_min' ) + phase1[0], getObj('ph1_hr_min' )*baseline_hr, '*m')
        ax.plot(getObj('t_ph4_hr_max' ) + phase4[0], getObj('ph4_hr_max' )*baseline_hr, '*m')
        ax.plot(getObj('t_ph4_hr_drop') + phase4[0], getObj('ph4_hr_drop')*baseline_hr, '*m')
        ax.plot(phase5, [getObj('ph5_hr_recovery')*baseline_hr]*2, 'c')

        ax.plot(getObj('t_ph2_mean_min') + phase2[0], getObj('pp_ph2_mean_min')*baseline_pp, '*y')
        ax.plot(getObj('t_ph2_max') + phase4[0], getObj('pp_ph2_max')*baseline_pp, '*y')
        ax.plot(getObj('t_ph4_drop') + phase4[0], getObj('pp_ph4_drop')*baseline_pp, '*y')

        plotTargetValues(ax, objectives, valsalva_start, valsalva_end, time)
        ax.set_ylim([0, 165])
        ax.set_xlim(0, 60)
        # ax.show(block = False)

        if '__saveFig_path' in vars_set and vars_set['__saveFig_path'] is not None:
            plt.savefig(vars_set['__saveFig_path'], dpi = 300)
        

    return objectives
Exemple #12
0
def plotTargetValues(ax, objectives, valsalva_start, valsalva_end, time):
    # plot merged timecourse
    # valsalva_start = 20
    # valsalva_end = 35
    # signal_end = 55
    signal_end = time[-1]
    
    # All targets are relative to baseline, so we have to have that set first
    baseline_bp = fun_lib.getObjectiveByName(objectives, 'baseline_bp').value
    baseline_hr = fun_lib.getObjectiveByName(objectives, 'baseline_hr').value
    baseline_pp = fun_lib.getObjectiveByName(objectives, 'baseline_pp').value

    # just a shortcuts
    def getTrgtVal(name):
        return fun_lib.getObjectiveByName(objectives, name).targetValue
    
    def getTrgtVar(name):
        return fun_lib.getObjectiveByName(objectives, name).std
    
    def getCost(name):
        return fun_lib.getObjectiveByName(objectives, name).cost()

    # color for BP and HR
    c_BP = 'g'
    c_HR = 'c'
    c_PP = 'm'

    # baselines
    ax.errorbar((valsalva_start/2), getTrgtVal('baseline_bp'), yerr=getTrgtVar('baseline_bp'), fmt = c_BP, barsabove = True, zorder=3)
    ax.errorbar((valsalva_start/2), getTrgtVal('baseline_hr'), yerr=getTrgtVar('baseline_hr'), fmt = c_HR, barsabove = True, zorder=3)
    ax.errorbar((valsalva_start/2), getTrgtVal('baseline_pp'), yerr=getTrgtVar('baseline_pp'), fmt = c_PP, barsabove = True, zorder=3)    
    
    # recoveries
    ax.errorbar((signal_end - 2.5), getTrgtVal('ph5_recovery')*baseline_bp, yerr=getTrgtVar('ph5_recovery')*baseline_bp, fmt = c_BP, barsabove = True, zorder=3)
    ax.errorbar((signal_end - 2.5), getTrgtVal('ph5_hr_recovery')*baseline_hr, yerr=getTrgtVar('ph5_hr_recovery')*baseline_hr, fmt = c_HR, barsabove = True, zorder=3)

    # sv lower limit
    if len([o for o in objectives if o.name == 'SV_min_valsalva']) > 0:
        pack = (objectives, time, ax, fun_lib.findInterval(valsalva_start, valsalva_end, time))
        fun_lib.plotObjectiveLimit(pack, 'SV_min_valsalva', 1, 'lower')
        fun_lib.plotObjectiveLimit(pack, 'SV_min_recovery', 1, 'lower')

    costs_legend = []
    def plotMetric(t_val, t_offset, val, baseline, color, showYerr = True, showXerr = True):
        if fun_lib.getObjectiveByName(objectives, val).costFunctionType == fun_lib.CostFunctionType.Ignore:
            return
        val_mean = getTrgtVal(val)*baseline
        val_std = getTrgtVar(val)*baseline if showYerr else None
        t_mean = getTrgtVal(t_val) + t_offset
        t_std = getTrgtVar(t_val) if showXerr else None
        costs_legend.append('%s %.4f\n%s %.4f' % (val, getCost(val), t_val, getCost(t_val)))
        # zorder 3 is a workaround to show errorbars above the plots
        ax.errorbar(t_mean, val_mean, yerr= val_std, xerr=t_std, fmt = color, barsabove = True, zorder=3, linewidth = 2)

    def plotBPMetric(t_val, t_offset, val, color = c_BP):
        plotMetric(t_val, t_offset, val, baseline_bp, color)

    def plotHRMetric(t_val, t_offset, val, color = c_HR):
        plotMetric(t_val, t_offset, val, baseline_hr, color)    

    def plotPPMetric(t_val, t_offset, val, color = c_PP):
        plotMetric(t_val, t_offset, val, baseline_pp, color, showXerr=False)    

    plotBPMetric('t_ph1_peak', valsalva_start, 'ph1_peak')
    plotBPMetric('t_ph2_mean_min', valsalva_start, 'ph2_mean_min')
    plotBPMetric('t_ph2_max', valsalva_end, 'ph2_max')
    plotBPMetric('t_ph4_drop', valsalva_end, 'ph4_drop')
    plotBPMetric('t_ph4_ovrshoot', valsalva_end, 'ph4_ovrshoot')

    plotHRMetric('t_ph1_hr_min', valsalva_start, 'ph1_hr_min')
    plotHRMetric('t_ph4_hr_max', valsalva_end, 'ph4_hr_max')
    plotHRMetric('t_ph4_hr_drop', valsalva_end, 'ph4_hr_drop')

    plotPPMetric('t_ph2_mean_min', valsalva_start, 'pp_ph2_mean_min')
    plotPPMetric('t_ph2_max', valsalva_end, 'pp_ph2_max')
    plotPPMetric('t_ph4_drop', valsalva_end, 'pp_ph4_drop')

    ax.text(0, 60, '\n'.join(costs_legend), 
            horizontalalignment='left', 
            verticalalignment='bottom', fontsize = 8)

    pass