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')
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])
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)
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