-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
146 lines (127 loc) · 4.89 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import pandas as pd
import plotly.graph_objects as go
import plotly.io as pio
from dash import Dash, dcc, html, Input, Output, callback
import pandas as pd
import dash_bootstrap_components as dbc
# set plotly template
pio.templates.default = "plotly_white"
# Import data
results = pd.read_csv("data/model_results.csv")
app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
server = app.server
def create_figure(product_value=25, A_cost=1, B_cost=0.5):
# assume glucose concentration of 100 g/kg to calculate final product concentration
glucose_concentration = 100 # g/kg
# assume product value is in units of $/g
# assume additive concentrations in units of g/kg, and additive costs in units of $/g
results["Product Concentration"] = results["Yield"] * glucose_concentration # g/kg
results["Product Value"] = results["Product Concentration"] * product_value # $/kg
results["Additive A Cost"] = results["Concentration A"] * A_cost # $/g
results["Additive B Cost"] = results["Concentration B"] * B_cost # $/g
results["Estimated Profit"] = (
results["Product Value"]
- results["Additive A Cost"]
- results["Additive B Cost"]
)
fig = go.Figure(
data=[
go.Heatmap(
z=results["Estimated Profit"],
x=results["Concentration B"],
y=results["Concentration A"],
zmin=0,
zmax=5000,
colorbar={
"title": "Estimated Profit/kg broth",
"tickprefix": "US$",
# "dtick": 1.5,
# "tickformatstops": [{"dtickrange": [0, 60]}],
},
)
],
)
fig.update_yaxes(title_text="Concentration B")
fig.update_xaxes(title_text="Concentration A")
fig.update_layout(
title_text="How do Additive Concentrations Affect Potential Profit?",
height=500,
)
return fig
app.layout = dbc.Container(
children=[
dbc.Card(
children=[
html.H1(
children="Interactive Techno-Economic Analysis",
style={
"marginTop": 15,
"marginLeft": 15,
"marginRight": 15,
},
),
html.Div(
children="""
This is an interactive analysis that considers the impact of additive costs and product value on the potential for profit. Profit values appear binned because this is built on top of a random forest model fit to (dummy) experimental data. This model predicts yield given A and B concentrations during fermentation. Use the sliders to explore how product cost and additive concentration affects profit margin:
""",
style={
"marginTop": 15,
"marginLeft": 15,
"marginRight": 15,
},
),
],
style={"marginTop": 10, "marginBottom": 10},
),
dbc.Card(
children=[
dcc.Graph(id="results", figure=create_figure()),
html.Div(
children=[
"Product ($/g):",
dcc.Slider(0.5, 50, value=25, id="prod-val"),
],
id="prod-val-label",
style={
"marginLeft": 15,
"marginRight": 15,
},
),
html.Div(
children=[
"Additive A Cost ($/g):",
dcc.Slider(0.25, 25, value=2.5, id="add1-cost"),
],
id="add1-cost-label",
style={
"marginLeft": 15,
"marginRight": 15,
},
),
html.Div(
children=[
"Additive B Cost ($/g):",
dcc.Slider(0.25, 25, value=2.5, id="add2-cost"),
],
id="add2-cost-label",
style={
"marginLeft": 15,
"marginRight": 15,
},
),
],
style={"marginTop": 10, "marginBottom": 10},
),
]
)
@callback(
Output(component_id="results", component_property="figure"),
Input(component_id="prod-val", component_property="value"),
Input(component_id="add1-cost", component_property="value"),
Input(component_id="add2-cost", component_property="value"),
)
def remodel(prod_val, add1_cost, add2_cost):
fig = create_figure(product_value=prod_val, A_cost=add1_cost, B_cost=add2_cost)
return fig
if __name__ == "__main__":
app.run(debug=True)