Skip to content

Commit 6798381

Browse files
sensitivity cleanup
1 parent 8a52727 commit 6798381

File tree

2 files changed

+29
-30
lines changed

2 files changed

+29
-30
lines changed

src/sbmlsim/sensitivity/analysis.py

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
from sbmlsim.sensitivity.parameters import SensitivityParameter
2626
from sbmlsim.sensitivity.outputs import SensitivityOutput
27+
from sbmlsim.sensitivity.plots import heatmap
2728

2829

2930
class SensitivitySimulation:
@@ -112,9 +113,10 @@ def __init__(self,
112113
self.samples: Optional[xr.DataArray] = None
113114
# outputs for given samples; shape: (num_samples x num_outputs)
114115
self.results: Optional[xr.DataArray] = None
116+
117+
# multiple sensitivities are stored
115118
# sensitivity matrix; shape: (num_parameters x num_outputs); could be multiple
116-
self.sensitivity: Optional[xr.DataArray] = None
117-
self.sensitivity_normalized: Optional[xr.DataArray] = None
119+
self.sensitivity: dict[str, xr.DataArray] = {}
118120

119121

120122
@property
@@ -156,12 +158,19 @@ def simulate_samples(self) -> None:
156158
outputs = self.sensitivity_simulation.simulate(changes=changes)
157159
self.results[k, :] = list(outputs.values())
158160

159-
160161
def calculate_sensitivity(self):
161-
"""Calculate the sensitivity matrix."""
162+
"""Calculate the sensitivity matrices."""
162163

163164
raise NotImplemented
164165

166+
def sensitivity_df(self, key="normalized") -> pd.DataFrame:
167+
"""Convert sensitivity information to dataframe."""
168+
169+
return pd.DataFrame(
170+
self.sensitivity[key].values,
171+
columns=self.sensitivity[key].coords["output"],
172+
index=self.sensitivity[key].coords["parameter"]
173+
)
165174

166175

167176
class LocalSensitivityAnalysis(SensitivityAnalysis):
@@ -174,7 +183,7 @@ def __init__(self, sensitivity_simulation: SensitivitySimulation,
174183
parameters: list[SensitivityParameter], difference: float = 0.01):
175184

176185
super().__init__(sensitivity_simulation, parameters)
177-
self.sensitivity: np.ndarray = np.zeros(shape=(self.num_parameters, self.num_outputs))
186+
178187
self.difference: float = difference
179188
self.create_samples()
180189

@@ -224,24 +233,19 @@ def calculate_sensitivity(self):
224233
"""Calculate the two-sided local sensitivity matrix."""
225234

226235
# num_parameters x num_outputs
227-
# empty sensitivity
228-
self.sensitivity = xr.DataArray(
236+
for key in ["raw", "normalized"]:
237+
self.sensitivity[key] = xr.DataArray(
229238
np.full((self.num_parameters, self.num_outputs), np.nan),
230239
dims=["parameter", "output"],
231240
coords={"parameter": self.parameter_ids,
232241
"output": self.output_ids},
233-
name="sensitivity"
234-
)
235-
self.sensitivity_normalized = xr.DataArray(
236-
np.full((self.num_parameters, self.num_outputs), np.nan),
237-
dims=["parameter", "output"],
238-
coords={"parameter": self.parameter_ids,
239-
"output": self.output_ids},
240-
name="sensitivity"
242+
name=key
241243
)
242244

245+
sensitivity_raw = self.sensitivity["raw"]
246+
sensitivity_normalized = self.sensitivity["normalized"]
247+
243248
for kp, p in enumerate(self.parameters):
244-
pid = self.parameters[kp].uid
245249
p_ref = self.samples[-1, kp]
246250
p_up = self.samples[2*kp, kp]
247251
p_down = self.samples[2 * kp + 1, kp]
@@ -253,21 +257,13 @@ def calculate_sensitivity(self):
253257
q_down = self.results[2 * kp + 1, ko]
254258

255259
# two-sided sensitivity
256-
self.sensitivity[kp, ko] = (q_up - q_down) / (p_up - p_down)
260+
sensitivity_raw[kp, ko] = (q_up - q_down) / (p_up - p_down)
257261
# normalized: relative change in output per relative change in parameter
258-
self.sensitivity_normalized[kp, ko] = self.sensitivity[kp, ko] * p_ref/q_ref
262+
sensitivity_normalized[kp, ko] = sensitivity_raw[kp, ko] * p_ref/q_ref
259263

260-
@property
261-
def sensitivity_df(self) -> pd.DataFrame:
262-
"""Convert sensitivity information to dataframe."""
263-
return pd.DataFrame(
264-
self.sensitivity_normalized.values,
265-
columns=self.sensitivity.coords["output"],
266-
index=self.sensitivity.coords["parameter"]
267-
)
268264

269265
def plot_sensitivity(self, cutoff=0.1, cluster_rows: bool = True, title: Optional[str] = None):
270-
df = self.sensitivity_df
266+
df = self.sensitivity_df(key="normalized")
271267
self.plot_sensitivity_df(
272268
df=df,
273269
parameter_labels={p.uid: p.name for p in self.parameters},
@@ -285,7 +281,6 @@ def plot_sensitivity_df(
285281
cutoff=0.1, cluster_rows: bool = True,
286282
title: Optional[str] = None,
287283
):
288-
from sbmlsim.sensitivity.plots import heatmap
289284
console.print(df)
290285

291286
heatmap(
@@ -310,9 +305,13 @@ class SobolSensitivityAnalysis:
310305

311306
sensitivity_simulation: SensitivitySimulation
312307

313-
def __init__(self, sensitivity_simulation: SensitivitySimulation):
308+
def __init__(self,
309+
sensitivity_simulation: SensitivitySimulation,
310+
parameters: list[SensitivityParameter],
311+
):
314312
# assign simulation
315313
self.sensitivity_simulation = sensitivity_simulation
314+
self.parameters = parameters
316315

317316
self.sensitivity = np.zeros(shape=(self.num_parameters, self.num_outputs))
318317

src/sbmlsim/sensitivity/outputs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ class SensitivityOutput:
77
"""Output measurement for SensitivityAnalysis."""
88
uid: str
99
name: str
10-
unit: Optional[str]
10+
# unit: Optional[str]

0 commit comments

Comments
 (0)