Spaces:
Runtime error
Runtime error
| from fmpy import * | |
| from fmpy import read_model_description, extract | |
| from fmpy.fmi2 import FMU2Slave | |
| import numpy as np | |
| import shutil | |
| import pandas as pd | |
| import random | |
| import plotly.graph_objects as go | |
| def add_noise(min, max, std, mean): | |
| return np.clip(np.random.normal(mean, std), min, max) | |
| def gen_pulsive_noise(count, min_val, max_val): | |
| pulse = 0 | |
| n = count // 100 # Use integer division to get the floor of count / 100 | |
| start = 100 * n | |
| end = start + 50 | |
| if (count > start and count < end and n % 15 == 0): | |
| pulse = random.randint(min_val, max_val) | |
| return pulse | |
| def simulation(input_noise, output_noise, min_val, max_val, kp, ki): | |
| vrs = {} | |
| fmu = 'Pharmacokinetics_4_comportmental_model_PI_ref_FMU_base4_OAAS_lnx.fmu' | |
| model_description = read_model_description(fmu) | |
| for variable in model_description.modelVariables: | |
| vrs[variable.name] = variable.valueReference | |
| start_time = 0.0 | |
| stop_time = 7000 | |
| step_size = 1 | |
| unzipdir = extract(fmu) | |
| fmu = FMU2Slave(guid=model_description.guid, | |
| unzipDirectory=unzipdir, | |
| modelIdentifier=model_description.coSimulation.modelIdentifier, | |
| instanceName='instance1') | |
| # initialize | |
| fmu.instantiate() | |
| fmu.setupExperiment(startTime=start_time) | |
| fmu.enterInitializationMode() | |
| fmu.exitInitializationMode() | |
| fmu.setReal([vrs["amesim_interface.Age_year"]], [60]) | |
| fmu.setReal([vrs["amesim_interface.BIS0"]], [95.6]) | |
| fmu.setReal([vrs["amesim_interface.BISmin"]], [8.9]) | |
| fmu.setReal([vrs["amesim_interface.Drug_concentration_mgmL"]], [20]) | |
| fmu.setReal([vrs["amesim_interface.EC50"]], [2.23]) | |
| fmu.setReal([vrs["amesim_interface.Gamma"]], [1.58]) | |
| fmu.setReal([vrs["amesim_interface.Gender_0male_1female"]], [1]) | |
| fmu.setReal([vrs["amesim_interface.Height_cm"]], [168]) | |
| fmu.setReal([vrs["amesim_interface.Infusion_rate_mLh"]], [200]) | |
| fmu.setReal([vrs["amesim_interface.Weight_kg"]], [75]) | |
| vr_input = vrs["amesim_interface.Infusion_rate_mLh"] | |
| vr_output = vrs["amesim_interface.BIS_Index"] | |
| rows = [] # list to record the results | |
| time = start_time | |
| infusion_rate = 200 | |
| i = 0 | |
| target = 30 | |
| # simulation loop | |
| while time < stop_time: | |
| if time >= 2.4e3 and time < 4.5e3: | |
| target = 70 | |
| p = 0 | |
| i = 0 | |
| if time >= 4.5e3: | |
| target = 30 | |
| p = 0 | |
| i = 0 | |
| bis = fmu.getReal([int(vr_output)])[0] if time > step_size else 95.6 | |
| if input_noise: | |
| bis += add_noise(5, 10, 2, 7) | |
| p = bis - target | |
| i = i + p | |
| infusion_rate = np.clip(kp*p + ki*i, 0, 200) | |
| # infusion_rate += gen_pulsive_noise(time, 50, 150) | |
| if output_noise: | |
| infusion_rate += gen_pulsive_noise(time, min_val, max_val) | |
| fmu.setReal([vr_input], [int(infusion_rate)]) | |
| # perform one step | |
| fmu.doStep(currentCommunicationPoint=time, communicationStepSize=step_size) | |
| # advance the time | |
| time += step_size | |
| # get the values for 'inputs' and 'outputs[4]' | |
| inputs, outputs = fmu.getReal([int(vr_input), int(vr_output)]) | |
| # append the results | |
| rows.append((time, bis, inputs)) | |
| fmu.terminate() | |
| fmu.freeInstance() | |
| shutil.rmtree(unzipdir, ignore_errors=True) | |
| result = np.array(rows, dtype=np.dtype([('time', np.float64), ('BIS', np.float64), ('Infusion', np.float64)])) | |
| df = pd.DataFrame(result) | |
| trace1 = go.Scatter(x=df.index, y=df['BIS'], mode='lines', name='BIS') | |
| fig1 = go.Figure(data=trace1) | |
| fig1.update_layout(height=300, width=900, title_text="BIS evolution") | |
| # Add a line trace for column_2 in the second subplot | |
| trace2 = go.Scatter(x=df.index, y=df['Infusion'], mode='lines', name='Infusion') | |
| fig2 = go.Figure(data=trace2) | |
| fig2.update_layout(height=300, width=900, title_text="Infusion evolution") | |
| return fig1, fig2 | |
| import gradio as gr | |
| with gr.Blocks() as demo: | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| gr.Markdown("**BIS noise**") | |
| input_noise = gr.inputs.Checkbox(label="Add noise") | |
| gr.Markdown("**Infusion noise**") | |
| with gr.Blocks(): | |
| output_noise = gr.inputs.Checkbox(label="Add noise") | |
| with gr.Accordion("noise range"): | |
| min_slider = gr.inputs.Slider(minimum=0, maximum=50, step=1, default=50, label="noise min") | |
| max_slider = gr.inputs.Slider(minimum=0, maximum=150, step=1, default=150, label="noise max") | |
| gr.Markdown("**PI controller paramters**") | |
| with gr.Blocks(): | |
| kp_slider = gr.inputs.Slider(minimum=0, maximum=19, default=4, label="kp") | |
| ki_slider = gr.inputs.Slider(minimum=0, maximum=1, default=0.01, label="ki") | |
| button = gr.Button("Simulate") | |
| with gr.Column(scale=5): | |
| plot1 = gr.Plot(label="BIS evolution") | |
| plot2 = gr.Plot(label="Infusion evolution") | |
| button.click(simulation, inputs=[input_noise, output_noise, min_slider, max_slider, kp_slider, ki_slider], outputs=[plot1, plot2]) | |
| demo.launch() |