Skip to content

Commit

Permalink
refactoring parameter fitting
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiaskoenig committed Mar 12, 2021
1 parent cb39e92 commit 317dc9e
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 63 deletions.
64 changes: 32 additions & 32 deletions src/sbmlsim/fit/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ def __init__(
relative_tolerance: float = 1e-6,

) -> None:
"""Construct Optimization analysis."""
"""Construct Optimization analysis.
:param show_plots: boolean flag to display plots
"""
self.sid = opt_result.sid
self.opt_result: OptimizationResult = opt_result
# the results directory uses the hash of the OptimizationResult
Expand All @@ -49,32 +52,31 @@ def __init__(
results_dir.mkdir(parents=True, exist_ok=True)
self.results_dir = results_dir

self.fitting_strategy = fitting_strategy
self.residual_type = residual_type
self.weighting_points = weighting_points
self.variable_step_size = variable_step_size
self.absolute_tolerance = absolute_tolerance
self.relative_tolerance = relative_tolerance
self.show_plots=show_plots
# FIXME: remove
# self.fitting_strategy = fitting_strategy
# self.residual_type = residual_type
# self.weighting_points = weighting_points
# self.variable_step_size = variable_step_size
# self.absolute_tolerance = absolute_tolerance
# self.relative_tolerance = relative_tolerance

if op:
# FIXME: problem not initialized on multi-core and no simulator is assigned.
# This should happen automatically, to ensure correct behavior
op.initialize(
fitting_strategy=fitting_strategy,
weighting_points=weighting_points,
residual_type=residual_type,
variable_step_size=variable_step_size,
absolute_tolerance=absolute_tolerance,
relative_tolerance=relative_tolerance,
)
op.set_simulator(simulator=SimulatorSerial())
op.variable_step_size = variable_step_size
op.absolute_tolerance = absolute_tolerance
op.relative_tolerance = relative_tolerance

self.op = op

def analyse(self):
"""Perform complete analysis.
def run(self) -> None:
"""Execute complete analysis.
Creates all plots and reports.
This creates all plots and reports.
"""
problem_info: str = ""
if self.op:
Expand All @@ -91,8 +93,8 @@ def analyse(self):
with open(self.results_dir / "00_report.txt", "w") as f_report:
f_report.write(info)

self.opt_result.to_json(path=results_dir / "01_optimization_result.json")
self.opt_result.to_tsv(path=results_dir / "01_optimization_result.tsv")
self.opt_result.to_json(path=self.results_dir / "01_optimization_result.json")
self.opt_result.to_tsv(path=self.results_dir / "01_optimization_result.tsv")

if self.opt_result.size > 1:
self.plot_waterfall(
Expand All @@ -106,27 +108,25 @@ def analyse(self):

# plot top fit
if self.op:
xopt = opt_result.xopt
optimization_analyzer = OptimizationAnalysis(
optimization_problem=problem)
xopt = self.opt_result.xopt

df_costs = optimization_analyzer.plot_costs(
x=xopt, path=results_dir / "03_cost_improvement.svg",
show_plots=show_plots
df_costs = self.plot_costs(
x=xopt, path=self.results_dir / "03_cost_improvement.svg",
show_plots=self.show_plots
)
df_costs.to_csv(results_dir / "03_cost_improvement.tsv", sep="\t",
df_costs.to_csv(self.results_dir / "03_cost_improvement.tsv", sep="\t",
index=False)

optimization_analyzer.plot_fits(
x=xopt, path=results_dir / "05_fits.svg", show_plots=show_plots
self.plot_fits(
x=xopt, path=self.results_dir / "05_fits.svg", show_plots=self.show_plots
)
optimization_analyzer.plot_residuals(
x=xopt, output_path=results_dir, show_plots=show_plots
self.plot_residuals(
x=xopt, output_path=self.results_dir, show_plots=self.show_plots
)

if opt_result.size > 1:
opt_result.plot_correlation(
path=results_dir / "04_parameter_correlation", show_plots=show_plots
if self.opt_result.size > 1:
self.opt_result.plot_correlation(
path=self.results_dir / "04_parameter_correlation", show_plots=self.show_plots
)

@staticmethod
Expand Down
61 changes: 41 additions & 20 deletions src/sbmlsim/fit/optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,23 @@ def __init__(
self.weighting_points: Optional[WeightingPointsType] = None
self.residual_type: Optional[ResidualType] = None

self.experiment_keys = []
self.mapping_keys = []
self.xid_observable = []
self.yid_observable = []
self.x_references = []
self.y_references = []
self.y_errors = []
self.y_errors_type = []
self.weights = [] # total weights for points (data points and curve weights)
self.weights_points = [] # weights for data points based on errors
self.weights_curve = [] # user defined weights per mapping/curve

self.models = []
self.xmodel = np.empty(shape=(len(self.pids)))
self.simulations = []
self.selections = []

def __repr__(self) -> str:
"""Get representation."""
return f"<OptimizationProblem: {self.opid}>"
Expand Down Expand Up @@ -179,8 +196,22 @@ def initialize(
fitting_strategy: FittingStrategyType,
weighting_points: WeightingPointsType,
residual_type: ResidualType,
):
"""Initialize Optimization problem."""
variable_step_size: bool = True,
relative_tolerance: float = 1e-6,
absolute_tolerance: float = 1e-6,
) -> None:
"""Initialize Optimization problem.
Performs precalculations, resolving data, calculating weights.
Creates and attaches simulator for the given problem.
:param fitting_strategy: strategy for fitting (absolute or relative to baseline)
:param residual_type: handling of residuals
:param weighting_points: weighting of points
:param absolute_tolerance: absolute tolerance of simulator
:param relative_tolerance: relative tolerance of simulator
:param variable_step_size: use variable step size in solver
"""
# weighting in fitting and handling of residuals
if weighting_points is None:
raise ValueError("'weighting_local' is required.")
Expand Down Expand Up @@ -210,24 +241,6 @@ def initialize(
data_path=self.data_path,
)

# prepare reference data for all mappings (full length lists)
self.experiment_keys = []
self.mapping_keys = []
self.xid_observable = []
self.yid_observable = []
self.x_references = []
self.y_references = []
self.y_errors = []
self.y_errors_type = []
self.weights = [] # total weights for points (data points and curve weights combined)
self.weights_points = [] # weights for data points based on errors
self.weights_curve = [] # user defined weights per mapping/curve

self.models = []
self.xmodel = np.empty(shape=(len(self.pids)))
self.simulations = []
self.selections = []

# Collect information for simulations
fit_exp: Callable
for fit_experiment in self.fit_experiments:
Expand Down Expand Up @@ -488,6 +501,14 @@ def initialize(
# Print mappings with calculated weights
# print(fit_experiment)

# set simulator instance with arguments
simulator = SimulatorSerial(
absolute_tolerance=absolute_tolerance,
relative_tolerance=relative_tolerance,
variable_step_size=variable_step_size,
)
self.set_simulator(simulator)

def set_simulator(self, simulator):
"""Set the simulator on the runner and the experiments.
Expand Down
13 changes: 3 additions & 10 deletions src/sbmlsim/fit/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from sbmlsim.fit.options import (
FittingStrategyType, OptimizationAlgorithmType, WeightingPointsType, ResidualType
)
from sbmlsim.simulator import SimulatorSerial
from sbmlsim.utils import timeit


Expand Down Expand Up @@ -209,17 +208,11 @@ def _run_optimization_serial(
fitting_strategy=fitting_strategy,
weighting_points=weighting_points,
residual_type=residual_type,
absolute_tolerance=absolute_tolerance,
relative_tolerance=relative_tolerance,
variable_step_size=variable_step_size,
)

# set simulator instance with arguments
sim_kwargs = {
'absolute_tolerance': absolute_tolerance,
'relative_tolerance': relative_tolerance,
'variable_step_size': variable_step_size,
}
simulator = SimulatorSerial(**sim_kwargs) # sets tolerances
problem.set_simulator(simulator)

# optimize
fits, trajectories = problem.optimize(
size=size,
Expand Down
2 changes: 1 addition & 1 deletion src/sbmlsim/test/fit/test_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def test_optimization_analysis(tmp_path):
show_plots=False,
**fit_kwargs_default
)
op_analysis.analyse()
op_analysis.run()


def test_fit_lsq_serial() -> None:
Expand Down

0 comments on commit 317dc9e

Please sign in to comment.