Exemple #1
0
def plotObjectives(vars_set, interval, objectives):

    ax = fun_lib.getAxes(vars_set)

    ax.plot(vars_set['time'],
            vars_set['brachial_pressure'] / 133.32,
            label='Brachial pressure mmHg')
    # ax.plot(vars_set['time'], vars_set['V_LV']*1000*1000, label='V_LV ml')
    ax.plot(vars_set['time'], vars_set['CO'] / lpm2SI, label='CO')

    # ax.plot(vars_set['time'], vars_set['TEjection'], label='TEjection')
    # ax.plot(vars_set['time'], vars_set['TFilling'], label='TFilling')

    pack = (objectives, vars_set['time'], ax, interval)
    fun_lib.plotObjectiveTarget(pack, 'BPs', 1 / 133.32)
    # fun_lib.plotObjectiveTarget(pack, 'EDV', 1e6)
    fun_lib.plotObjectiveTarget(pack, 'ESV', 1e6)
    fun_lib.plotObjectiveTarget(pack, 'Ts', 1, verticalalignment='top')
    fun_lib.plotObjectiveTarget(pack, 'Td', 1)
    fun_lib.plotObjectiveTarget(pack, 'Ppa', 1 / 133.32)
    fun_lib.plotObjectiveTarget(pack, 'Ppa_s', 1 / 133.32)
    fun_lib.plotObjectiveTarget(pack, 'Ppa_d', 1 / 133.32)
    fun_lib.plotObjectiveTarget(pack, 'Ppv', 1 / 133.32)
    fun_lib.plotObjectiveLimit(pack, 'CO', 1 / lpm2SI, 'lower')

    total_costs = fun_lib.countTotalWeightedCost(objectives)
    ax.set_title('Exercise costs %.6f' % total_costs)
    ax.set_ylim([0, 165])
def logOutput(objectives):
    # log the output, if the log directory exists. exit otherwise
    writeLogHeader(objectives)

    filepath = getLogFilePath()
    run = fun_lib.getRunNumber()
    with open(filepath, 'a') as file:
        # prepare the line with value, cost value for this and percentage of total costs
        total_cost = fun_lib.countTotalSumCost(objectives)
        t = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        tail = "  ,%03d,%s, %.6e" % (run, t, total_cost)
        
        wc = fun_lib.countTotalWeightedCost(objectives)
        string_seq = map(lambda o: logLine(o, wc), objectives)

        file.write(',  '.join(string_seq) + tail + '\n')
Exemple #3
0
    def buildCostObjective(name, cost_func_folder, weight):
        """
        the name is prefix in the large model as well
        """
        nonlocal axes_num
        nonlocal ax

        # check if there are results for this particular use case
        if len([v for v in vars_set.keys() if v.startswith(name + '.')]) == 0:
            o = ObjectiveVar('IGNORING %s' % name,
                             value=0,
                             targetValue=0,
                             costFunctionType=CostFunctionType.Ignore)
            cost_objectives.append(o)
            all_objectives.append(o)
            return

        vars_set['__plot_axes'] = ax[axes_num]
        axes_num = axes_num + 1
        cf = importCostFunction(vars_set['__root_path'] + 'Identification\\' +
                                cost_func_folder)
        # mapped_vars = mapVarSet(vars_set, mapping)
        # filtering only vars relevant for that cost function, e.g. valsalva.brachial_pressure gives brachial_pressure

        mapped_vars = filterVarSet(vars_set, name + '.')
        objectives = cf.getObjectives(mapped_vars)

        # normalize to variance type cost function
        for o in objectives:
            fun_lib.unifyCostFunc(o)

        cost = fun_lib.countTotalWeightedCost(objectives)
        costObjective = ObjectiveVar(
            name,
            value=cost,
            costFunctionType=CostFunctionType.DistanceFromZero,
            weight=weight)
        # add it to the set
        cost_objectives.append(costObjective)

        # prepare to compare to all objectives in a log
        def sumObjectives(o: ObjectiveVar):
            o.name = name + '.' + o.name
            o.weight = weight * o.weight
            return o

        all_objectives.extend(map(sumObjectives, objectives))
def plotObjectives(vars_set, interval, objectives):
    ax = fun_lib.getAxes(vars_set)

    ax.plot(vars_set['time'], vars_set['brachial_pressure']/133.32, label='Brachial pressure mmHg')
    # ax.plot(vars_set['time'], vars_set['SV']*1e6, label='Stroke volume ml')    
    ax.plot(vars_set['time'], vars_set['CO']/lpm2SI, label='CO')   
    ax.plot(vars_set['time'], vars_set['HR']/bpm2SI, label='HR')    

    pack = (objectives, vars_set['time'], ax, interval)
    fun_lib.plotObjectiveTarget(pack, 'BPs', 1/133.32)
    fun_lib.plotObjectiveTarget(pack, 'BPd', 1/133.32)
    fun_lib.plotObjectiveTarget(pack, 'CO', 1/lpm2SI)
    fun_lib.plotObjectiveTarget(pack, 'HR', 1/bpm2SI)

    total_costs = fun_lib.countTotalWeightedCost(objectives)
    ax.set_title('Tilt costs %.6f' % total_costs)
    ax.set_ylim([0, 140])
Exemple #5
0
def plotObjectives(vars_set, interval, objectives):
    if '__plot_axes' in vars_set:
        ax = vars_set['__plot_axes']
    else:
        fig = plt.figure()
        ax = fig.subplots()

    ax.plot(vars_set['time'],
            vars_set['brachial_pressure'] / 133.32,
            label='Brachial pressure mmHg')
    ax.plot(vars_set['time'], vars_set['CO'] * 1000 * 60, label='CO l/min')

    # bounds
    pack = (objectives, vars_set['time'], ax, interval)
    fun_lib.plotObjectiveTarget(pack, 'BPs', 1 / 133.32)
    fun_lib.plotObjectiveTarget(pack, 'BPd', 1 / 133.32)
    fun_lib.plotObjectiveTarget(pack, 'CO', 1000 * 60, fmt='r')

    total_costs = fun_lib.countTotalWeightedCost(objectives)
    ax.set_title('Baseline costs %.6f' % total_costs)
Exemple #6
0
def plotObjectives(vars_set, interval, objectives):
    if '__plot_axes' in vars_set:
        ax = vars_set['__plot_axes']
    else:
        fig = plt.figure()
        ax = fig.subplots()

    ax.plot(vars_set['time'],
            vars_set['brachial_pressure'] / 133.32,
            label='Brachial pressure mmHg')
    ax.plot(vars_set['time'], vars_set['CO'] * 1000 * 60, label='CO l/min')
    ax.plot(vars_set['time'],
            vars_set['renal_capillary'] / 133.32,
            label='Capillary pressure')
    # ax.plot([vars_set['time'][interval[0]], vars_set['time'][interval[-1]]], [fun_lib.getObjectiveByName(objectives, 'EF').value*100]*2, label='EF')
    ax.plot([vars_set['time'][interval[0]], vars_set['time'][interval[-1]]],
            [fun_lib.getObjectiveByName(objectives, 'PWV').value * 1] * 2,
            label='PWV')

    # bounds
    pack = (objectives, vars_set['time'], ax, interval)
    fun_lib.plotObjectiveTarget(pack, 'BPs', 1 / 133.32)
    fun_lib.plotObjectiveTarget(pack, 'BPd', 1 / 133.32)
    # fun_lib.plotObjectiveTarget(pack,'CO', 1000*60)
    fun_lib.plotObjectiveTarget(pack, 'BPk', 1 / 133.32)
    # fun_lib.plotObjectiveTarget(pack,'EF', 100)
    fun_lib.plotObjectiveTarget(pack, 'HR', 60, verticalalignment='top')
    # fun_lib.plotObjectiveTarget(pack,'Ppa', 1/133.32)
    fun_lib.plotObjectiveTarget(pack, 'Ppas', 1 / 133.32)
    fun_lib.plotObjectiveTarget(pack, 'Ppad', 1 / 133.32)
    fun_lib.plotObjectiveTarget(pack, 'Ppv', 1 / 133.32)
    fun_lib.plotObjectiveLimit(pack,
                               'PWV',
                               1,
                               'lower',
                               verticalalignment='top')

    total_costs = fun_lib.countTotalWeightedCost(objectives)
    ax.set_title('Baseline costs %.6f' % total_costs)
    ax.set_ylim([0, 140])
    

    objectives = cf.getObjectives(var_set)
    logOutput(objectives)

    for objective in objectives:
        if subject not in objectiveMetrics:
            objectiveMetrics[subject] = dict()
        if objective.name not in objectiveMetrics[subject]:
            objectiveMetrics[subject][objective.name] = list()

        objectiveMetrics[subject][objective.name].append(objective.value)
    
    if subject not in costMetrics:
        costMetrics[subject] = list()
    costMetrics[subject].append(fun_lib.countTotalWeightedCost(objectives))

    # writeCost(objectives)
(targetVals, targetStds) = processObjectiveMetrics(objectiveMetrics)
processCostMetrics(costMetrics)
writeTargetValues(targetVals, targetStds, file_set)

plt.figure()
plotTargetValues(targetVals, targetStds)
plt.savefig(getTargetFileName(file_set).replace('.txt', '.png') , dpi = 150)


pass

# compare sitting and supine targetvalues
def getAndPlotTargetVals(file_set, style):
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