Spaces:
Runtime error
Runtime error
Weicheng HE
commited on
Commit
·
252c4ba
1
Parent(s):
66d38b8
init
Browse files
Pharmacokinetics_4_comportmental_model_PI_ref_FMU_base4_OAAS_lnx.fmu
ADDED
|
Binary file (711 kB). View file
|
|
|
app.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fmpy import *
|
| 2 |
+
from fmpy import read_model_description, extract
|
| 3 |
+
from fmpy.fmi2 import FMU2Slave
|
| 4 |
+
import numpy as np
|
| 5 |
+
import shutil
|
| 6 |
+
import pandas as pd
|
| 7 |
+
import random
|
| 8 |
+
import plotly.graph_objects as go
|
| 9 |
+
def add_noise(min, max, std, mean):
|
| 10 |
+
return np.clip(np.random.normal(mean, std), min, max)
|
| 11 |
+
|
| 12 |
+
def gen_pulsive_noise(count, min_val, max_val):
|
| 13 |
+
pulse = 0
|
| 14 |
+
n = count // 100 # Use integer division to get the floor of count / 100
|
| 15 |
+
start = 100 * n
|
| 16 |
+
end = start + 50
|
| 17 |
+
if (count > start and count < end and n % 15 == 0):
|
| 18 |
+
pulse = random.randint(min_val, max_val)
|
| 19 |
+
|
| 20 |
+
return pulse
|
| 21 |
+
def simulation(input_noise, output_noise, min_val, max_val, kp, ki):
|
| 22 |
+
vrs = {}
|
| 23 |
+
fmu = 'Pharmacokinetics_4_comportmental_model_PI_ref_FMU_base4_OAAS_lnx.fmu'
|
| 24 |
+
model_description = read_model_description(fmu)
|
| 25 |
+
for variable in model_description.modelVariables:
|
| 26 |
+
vrs[variable.name] = variable.valueReference
|
| 27 |
+
start_time = 0.0
|
| 28 |
+
stop_time = 7000
|
| 29 |
+
step_size = 1
|
| 30 |
+
unzipdir = extract(fmu)
|
| 31 |
+
|
| 32 |
+
fmu = FMU2Slave(guid=model_description.guid,
|
| 33 |
+
unzipDirectory=unzipdir,
|
| 34 |
+
modelIdentifier=model_description.coSimulation.modelIdentifier,
|
| 35 |
+
instanceName='instance1')
|
| 36 |
+
|
| 37 |
+
# initialize
|
| 38 |
+
fmu.instantiate()
|
| 39 |
+
fmu.setupExperiment(startTime=start_time)
|
| 40 |
+
fmu.enterInitializationMode()
|
| 41 |
+
fmu.exitInitializationMode()
|
| 42 |
+
|
| 43 |
+
fmu.setReal([vrs["amesim_interface.Age_year"]], [60])
|
| 44 |
+
fmu.setReal([vrs["amesim_interface.BIS0"]], [95.6])
|
| 45 |
+
fmu.setReal([vrs["amesim_interface.BISmin"]], [8.9])
|
| 46 |
+
fmu.setReal([vrs["amesim_interface.Drug_concentration_mgmL"]], [20])
|
| 47 |
+
fmu.setReal([vrs["amesim_interface.EC50"]], [2.23])
|
| 48 |
+
fmu.setReal([vrs["amesim_interface.Gamma"]], [1.58])
|
| 49 |
+
fmu.setReal([vrs["amesim_interface.Gender_0male_1female"]], [1])
|
| 50 |
+
fmu.setReal([vrs["amesim_interface.Height_cm"]], [168])
|
| 51 |
+
fmu.setReal([vrs["amesim_interface.Infusion_rate_mLh"]], [200])
|
| 52 |
+
fmu.setReal([vrs["amesim_interface.Weight_kg"]], [75])
|
| 53 |
+
vr_input = vrs["amesim_interface.Infusion_rate_mLh"]
|
| 54 |
+
vr_output = vrs["amesim_interface.BIS_Index"]
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
rows = [] # list to record the results
|
| 58 |
+
time = start_time
|
| 59 |
+
infusion_rate = 200
|
| 60 |
+
i = 0
|
| 61 |
+
target = 30
|
| 62 |
+
# simulation loop
|
| 63 |
+
while time < stop_time:
|
| 64 |
+
|
| 65 |
+
if time >= 2.4e3 and time < 4.5e3:
|
| 66 |
+
target = 70
|
| 67 |
+
p = 0
|
| 68 |
+
i = 0
|
| 69 |
+
if time >= 4.5e3:
|
| 70 |
+
target = 30
|
| 71 |
+
p = 0
|
| 72 |
+
i = 0
|
| 73 |
+
|
| 74 |
+
bis = fmu.getReal([int(vr_output)])[0] if time > step_size else 95.6
|
| 75 |
+
if input_noise:
|
| 76 |
+
bis += add_noise(5, 10, 2, 7)
|
| 77 |
+
p = bis - target
|
| 78 |
+
i = i + p
|
| 79 |
+
infusion_rate = np.clip(kp*p + ki*i, 0, 200)
|
| 80 |
+
# infusion_rate += gen_pulsive_noise(time, 50, 150)
|
| 81 |
+
if output_noise:
|
| 82 |
+
infusion_rate += gen_pulsive_noise(time, min_val, max_val)
|
| 83 |
+
|
| 84 |
+
fmu.setReal([vr_input], [int(infusion_rate)])
|
| 85 |
+
|
| 86 |
+
# perform one step
|
| 87 |
+
fmu.doStep(currentCommunicationPoint=time, communicationStepSize=step_size)
|
| 88 |
+
|
| 89 |
+
# advance the time
|
| 90 |
+
time += step_size
|
| 91 |
+
# get the values for 'inputs' and 'outputs[4]'
|
| 92 |
+
inputs, outputs = fmu.getReal([int(vr_input), int(vr_output)])
|
| 93 |
+
|
| 94 |
+
# append the results
|
| 95 |
+
rows.append((time, bis, inputs))
|
| 96 |
+
|
| 97 |
+
fmu.terminate()
|
| 98 |
+
fmu.freeInstance()
|
| 99 |
+
shutil.rmtree(unzipdir, ignore_errors=True)
|
| 100 |
+
result = np.array(rows, dtype=np.dtype([('time', np.float64), ('BIS', np.float64), ('Infusion', np.float64)]))
|
| 101 |
+
df = pd.DataFrame(result)
|
| 102 |
+
trace1 = go.Scatter(x=df.index, y=df['BIS'], mode='lines', name='BIS')
|
| 103 |
+
fig1 = go.Figure(data=trace1)
|
| 104 |
+
fig1.update_layout(height=300, width=900, title_text="BIS evolution")
|
| 105 |
+
|
| 106 |
+
# Add a line trace for column_2 in the second subplot
|
| 107 |
+
trace2 = go.Scatter(x=df.index, y=df['Infusion'], mode='lines', name='Infusion')
|
| 108 |
+
fig2 = go.Figure(data=trace2)
|
| 109 |
+
fig2.update_layout(height=300, width=900, title_text="Infusion evolution")
|
| 110 |
+
|
| 111 |
+
return fig1, fig2
|
| 112 |
+
import gradio as gr
|
| 113 |
+
with gr.Blocks() as demo:
|
| 114 |
+
with gr.Row():
|
| 115 |
+
with gr.Column(scale=1):
|
| 116 |
+
gr.Markdown("**BIS noise**")
|
| 117 |
+
input_noise = gr.inputs.Checkbox(label="Add noise")
|
| 118 |
+
gr.Markdown("**Infusion noise**")
|
| 119 |
+
with gr.Blocks():
|
| 120 |
+
output_noise = gr.inputs.Checkbox(label="Add noise")
|
| 121 |
+
with gr.Accordion("noise range"):
|
| 122 |
+
min_slider = gr.inputs.Slider(minimum=0, maximum=50, step=1, default=50, label="noise min")
|
| 123 |
+
max_slider = gr.inputs.Slider(minimum=0, maximum=150, step=1, default=150, label="noise max")
|
| 124 |
+
gr.Markdown("**PI controller paramters**")
|
| 125 |
+
with gr.Blocks():
|
| 126 |
+
kp_slider = gr.inputs.Slider(minimum=0, maximum=19, default=4, label="kp")
|
| 127 |
+
ki_slider = gr.inputs.Slider(minimum=0, maximum=1, default=0.01, label="ki")
|
| 128 |
+
button = gr.Button("Simulate")
|
| 129 |
+
with gr.Column(scale=5):
|
| 130 |
+
plot1 = gr.Plot(label="BIS evolution")
|
| 131 |
+
plot2 = gr.Plot(label="Infusion evolution")
|
| 132 |
+
button.click(simulation, inputs=[input_noise, output_noise, min_slider, max_slider, kp_slider, ki_slider], outputs=[plot1, plot2])
|
| 133 |
+
demo.launch()
|