Fröhlich, Fabian, and Peter K. Sorger. 2021. “Fides: Reliable Trust-Region Optimization for Parameter Estimation of Ordinary Differential Equation Models.” bioRxiv. https://doi.org/10.1101/2021.05.20.445065.
+Gaspari, Erika. 2021. “Model-Driven Design of Mycoplasma as a Vaccine Chassis.” PhD thesis, Wageningen: Wageningen University. https://doi.org/10.18174/539593.
+Raimúndez, Elba, Erika Dudkin, Jakob Vanhoefer, Emad Alamoudi, Simon Merkt, Lara Fuhrmann, Fan Bai, and Jan Hasenauer. 2021. “COVID-19 Outbreak in Wuhan Demonstrates the Limitations of Publicly Available Case Numbers for Epidemiological Modeling.” Epidemics 34: 100439. https://doi.org/https://doi.org/10.1016/j.epidem.2021.100439.
Städter, Philipp, Yannik Schälte, Leonard Schmiester, Jan Hasenauer, and Paul L. Stapor. 2021. “Benchmarking of Numerical Integration Methods for Ode Models of Biological Systems.” Scientific Reports 11 (1): 2696. https://doi.org/10.1038/s41598-021-82196-2.
Sten, Sebastian, Henrik Podéus, Nicolas Sundqvist, Fredrik Elinder, Maria Engström, and Gunnar Cedersund. 2021. “A Multi-Data Based Quantitative Model for the Neurovascular Coupling in the Brain.” bioRxiv. https://doi.org/10.1101/2021.03.25.437053.
+Vanhoefer, Jakob, Marta R. a. Matos, Dilan Pathirana, Yannik Schälte, and Jan Hasenauer. 2021. “Yaml2sbml: Human-Readable and -Writable Specification of Ode Models and Their Conversion to Sbml.” Journal of Open Source Software 6 (61): 3215. https://doi.org/10.21105/joss.03215.
+van Rosmalen, R. P., R. W. Smith, V. A. P. Martins dos Santos, C. Fleck, and M. Suarez-Diez. 2021. “Model Reduction of Genome-Scale Metabolic Models as a Basis for Targeted Kinetic Models.” Metabolic Engineering 64: 74–84. https://doi.org/https://doi.org/10.1016/j.ymben.2021.01.008.
+Villaverde, Alejandro F., Dilan Pathirana, Fabian Fröhlich, Jan Hasenauer, and Julio R. Banga. 2021. “A Protocol for Dynamic Model Calibration.” http://arxiv.org/abs/2105.12008.
+Alabert, Constance, Carolin Loos, Moritz Voelker-Albert, Simona Graziano, Ignasi Forné, Nazaret Reveron-Gomez, Lea Schuh, et al. 2020. “Domain Model Explains Propagation Dynamics and Stability of Histone H3k27 and H3k36 Methylation Landscapes.” Cell Reports 30 (4): 1223–1234.e8. https://doi.org/10.1016/j.celrep.2019.12.060.
Erdem, Cemal, Ethan M. Bensman, Arnab Mutsuddy, Michael M. Saint-Antoine, Mehdi Bouhaddou, Robert C. Blake, Will Dodd, et al. 2020. “A Simple and Efficient Pipeline for Construction, Merging, Expansion, and Simulation of Large-Scale, Single-Cell Mechanistic Models.” bioRxiv. https://doi.org/10.1101/2020.11.09.373407.
Adlung, Lorenz, Paul Stapor, Christian Tönsing, Leonard Schmiester, Luisa E. Schwarzmüller, Dantong Wang, Jens Timmer, Ursula Klingmüller, Jan Hasenauer, and Marcel Schilling. 2019. “Cell-to-Cell Variability in Jak2/Stat5 Pathway Components and Cytoplasmic Volumes Define Survival Threshold in Erythroid Progenitor Cells.” bioRxiv. https://doi.org/10.1101/866871.
Terje Lines, Glenn, Łukasz Paszkowski, Leonard Schmiester, Daniel Weindl, Paul Stapor, and Jan Hasenauer. 2019. “Efficient Computation of Steady States in Large-Scale Ode Models of Biochemical Reaction Networks.” IFAC-PapersOnLine 52 (26): 32–37. https://doi.org/10.1016/j.ifacol.2019.12.232.
Villaverde, Alejandro F., Elba Raimúndez, Jan Hasenauer, and Julio R. Banga. 2019. “A Comparison of Methods for Quantifying Prediction Uncertainty in Systems Biology⁎⁎This Research Has Received Funding from the European Unions Horizon 2020 Research and Innovation Program Under Grant Agreement No 686282 (Canpathpro) and the German Ministry of Education and Research (Bmbf) Under the Grant Agreement No 01ZX1310B (Sys-Stomach) and No 01ZX1705A (Income).” IFAC-PapersOnLine 52 (26): 45–51. https://doi.org/10.1016/j.ifacol.2019.12.234.
+Villaverde, Alejandro F., Elba Raimúndez, Jan Hasenauer, and Julio R. Banga. 2019. “A Comparison of Methods for Quantifying Prediction Uncertainty in Systems Biology.” IFAC-PapersOnLine 52 (26): 45–51. https://doi.org/10.1016/j.ifacol.2019.12.234.
Wang, Dantong, Paul Stapor, and Jan Hasenauer. 2019. “Dirac Mixture Distributions for the Approximation of Mixed Effects Models.” IFAC-PapersOnLine 52 (26): 200–206. https://doi.org/10.1016/j.ifacol.2019.12.258.
@@ -120,8 +138,8 @@ If you applied AMICI in your work and your publication is missing, please let usLoos, Carolin, Katharina Moeller, Fabian Fröhlich, Tim Hucho, and Jan Hasenauer. 2018. “A Hierarchical, Data-Driven Approach to Modeling Single-Cell Populations Predicts Latent Causes of Cell-to-Cell Variability.” Cell Systems 6 (5): 593–603. https://doi.org/10.1016/j.cels.2018.04.008.
Pitt, Jake Alan, Lucian Gomoescu, Constantinos C. Pantelides, Benoît Chachuat, and Julio R. Banga. 2018. “Critical Assessment of Parameter Estimation Methods in Models of Biological Oscillators⁎⁎This Project Has Received Funding from the European Unions Horizon 2020 Research and Innovation Program Under Grant Agreement 675585 (Marie Sklodowska-Curie Itn Symbiosys). The Authors Jap and Lg Are Marie Sklodowska-Curie Early Stage Researchers at Iim-Csic (Spain) and Pse Ltd (Uk) Respectively.” IFAC-PapersOnLine 51 (19): 72–75. https://doi.org/https://doi.org/10.1016/j.ifacol.2018.09.040.
+Pitt, Jake Alan, Lucian Gomoescu, Constantinos C. Pantelides, Benoît Chachuat, and Julio R. Banga. 2018. “Critical Assessment of Parameter Estimation Methods in Models of Biological Oscillators.” IFAC-PapersOnLine 51 (19): 72–75. https://doi.org/https://doi.org/10.1016/j.ifacol.2018.09.040.
Schälte, Y., P. Stapor, and J. Hasenauer. 2018. “Evaluation of Derivative-Free Optimizers for Parameter Estimation in Systems Biology.” FAC-PapersOnLine 51 (19): 98–101. https://doi.org/10.1016/j.ifacol.2018.09.025.
diff --git a/include/amici/serialization.h b/include/amici/serialization.h index 0e2e6e0902..ebb2ec87dc 100644 --- a/include/amici/serialization.h +++ b/include/amici/serialization.h @@ -116,6 +116,8 @@ void serialize(Archive &ar, amici::Model &m, const unsigned int /*version*/) { ar &m.nmaxevent_; ar &m.state_is_non_negative_; ar &m.pythonGenerated; + ar &m.min_sigma_; + ar &m.sigma_res_; } diff --git a/python/amici/__main__.py b/python/amici/__main__.py new file mode 100644 index 0000000000..dac5230270 --- /dev/null +++ b/python/amici/__main__.py @@ -0,0 +1,25 @@ +"""Package-level entrypoint""" + +from . import __version__, compiledWithOpenMP, has_clibs, hdf5_enabled +import os +import sys + +def print_info(): + """Displays information on the current AMICI installation. + + Useful for verifying package installation of submitting bug reports""" + features = [] + + if has_clibs: + features.append("extensions") + + if compiledWithOpenMP(): + features.append("OpenMP") + + if hdf5_enabled: + features.append("HDF5") + + print(f"AMICI ({sys.platform}) version {__version__} ({','.join(features)})") + +if __name__ == '__main__': + print_info() diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 713ecf468f..b5ec800af4 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -1215,17 +1215,6 @@ def transform_dxdt_to_concentration(species_id, dxdt): # fill in 'self._sym' based on prototypes and components in ode_model self.generate_basic_variables(from_sbml=True) - # substitute 'w' expressions into event expressions now, to avoid - # rewriting '{model_name}_root.cpp' headers to include 'w.h' - w_sorted = toposort_symbols(dict(zip(self._syms['w'], self._eqs['w']))) - for index, event in enumerate(self._events): - self._events[index] = Event( - identifier=event.get_id(), - name=event.get_name(), - value=event.get_val().subs(w_sorted), - state_update=event._state_update, - event_observable=event._observable, - ) self._has_quadratic_nllh = all( llh['dist'] in ['normal', 'lin-normal'] for llh in si.symbols[SymbolId.LLHY].values() @@ -1631,21 +1620,15 @@ def generate_basic_variables(self, *, from_sbml: bool = False) -> None: """ Generates the symbolic identifiers for all variables in ODEModel.variable_prototype - """ - # Workaround to generate `'w'` before events, such that `'w'` can be - # replaced in events, to avoid adding `w` to the header of - # "{model_name}_stau.cpp". - if 'w' not in self._syms: - self._generate_symbol('w', from_sbml=from_sbml) + :param from_sbml: + whether the model is generated from SBML + """ # We need to process events and Heaviside functions in the ODE Model, # before adding it to ODEExporter self.parse_events() for var in self._variable_prototype: - # Part of the workaround described earlier in this method. - if var == 'w': - continue if var not in self._syms: self._generate_symbol(var, from_sbml=from_sbml) @@ -1658,7 +1641,6 @@ def parse_events(self) -> None: and replaces the formulae of the found roots by identifiers of AMICI's Heaviside function implementation in the right hand side """ - # Track all roots functions in the right hand side roots = copy.deepcopy(self._events) for state in self._states: @@ -1667,6 +1649,11 @@ def parse_events(self) -> None: for expr in self._expressions: expr.set_val(self._process_heavisides(expr.get_val(), roots)) + # remove all possible Heavisides from roots, which may arise from + # the substitution of `'w'` in `_collect_heaviside_roots` + for root in roots: + root.set_val(self._process_heavisides(root.get_val(), roots)) + # Now add the found roots to the model components for root in roots: # skip roots of SBML events, as these have already been added @@ -1877,7 +1864,7 @@ def _compute_equation(self, name: str) -> None: # following lines are only evaluated if a model has events w_sorted = \ toposort_symbols(dict(zip(self._syms['w'], self._eqs['w']))) - tmp_xdot = self._eqs['xdot'].subs(w_sorted) + tmp_xdot = smart_subs_dict(self._eqs['xdot'], w_sorted) self._eqs[name] = ( smart_multiply(self.eq('drootdx'), tmp_xdot) + self.eq('drootdt') @@ -2411,7 +2398,7 @@ def _get_unique_root( def _collect_heaviside_roots( self, - args: Sequence[sp.Expr] + args: Sequence[sp.Expr], ) -> List[sp.Expr]: """ Recursively checks an expression for the occurrence of Heaviside @@ -2432,8 +2419,12 @@ def _collect_heaviside_roots( root_funs.extend(self._collect_heaviside_roots(arg.args)) # substitute 'w' expressions into root expressions now, to avoid - # rewriting '{model_name}_stau.cpp' headers to include 'w.h' - w_sorted = toposort_symbols(dict(zip(self._syms['w'], self.eq('w')))) + # rewriting '{model_name}_root.cpp' and '{model_name}_stau.cpp' headers + # to include 'w.h' + w_sorted = toposort_symbols(dict(zip( + [expr.get_id() for expr in self._expressions], + [expr.get_val() for expr in self._expressions], + ))) root_funs = [ r.subs(w_sorted) for r in root_funs diff --git a/python/amici/petab_objective.py b/python/amici/petab_objective.py index 2039d68033..6ae8ab0ca1 100644 --- a/python/amici/petab_objective.py +++ b/python/amici/petab_objective.py @@ -139,9 +139,6 @@ def simulate_petab( # Compute total llh llh = sum(rdata['llh'] for rdata in rdatas) - # Compute total sllh - sllh = aggregate_sllh(amici_model=amici_model, rdatas=rdatas, - parameter_mapping=parameter_mapping) # Log results sim_cond = petab_problem.get_simulation_conditions_from_measurement_df() @@ -151,7 +148,6 @@ def simulate_petab( return { LLH: llh, - SLLH: sllh, RDATAS: rdatas } @@ -732,45 +728,4 @@ def rdatas_to_simulation_df( df = rdatas_to_measurement_df(rdatas=rdatas, model=model, measurement_df=measurement_df) - return df.rename(columns={MEASUREMENT: SIMULATION}) - - -def aggregate_sllh( - amici_model: AmiciModel, - rdatas: Sequence[amici.ReturnDataView], - parameter_mapping: Optional[ParameterMapping], -) -> Union[None, Dict[str, float]]: - """ - Aggregate likelihood gradient for all conditions, according to PEtab - parameter mapping. - - :param amici_model: - AMICI model from which ``rdatas`` were obtained. - :param rdatas: - Simulation results. - :param parameter_mapping: - PEtab parameter mapping to condition-specific - simulation parameters - - :return: - aggregated sllh - """ - sllh = {} - model_par_ids = amici_model.getParameterIds() - for condition_par_map, rdata in \ - zip(parameter_mapping, rdatas): - par_map_sim_var = condition_par_map.map_sim_var - if rdata['status'] != amici.AMICI_SUCCESS \ - or 'sllh' not in rdata \ - or rdata['sllh'] is None: - return None - - for model_par_id, problem_par_id in par_map_sim_var.items(): - if isinstance(problem_par_id, str): - model_par_idx = model_par_ids.index(model_par_id) - cur_par_sllh = rdata['sllh'][model_par_idx] - try: - sllh[problem_par_id] += cur_par_sllh - except KeyError: - sllh[problem_par_id] = cur_par_sllh - return sllh + return df.rename(columns={MEASUREMENT: SIMULATION}) \ No newline at end of file diff --git a/python/sdist/amici/__main__.py b/python/sdist/amici/__main__.py new file mode 120000 index 0000000000..cfa13d34da --- /dev/null +++ b/python/sdist/amici/__main__.py @@ -0,0 +1 @@ +../../amici/__main__.py \ No newline at end of file diff --git a/scripts/installAmiciArchive.sh b/scripts/installAmiciArchive.sh index 20f4251ee1..25de4f9f93 100755 --- a/scripts/installAmiciArchive.sh +++ b/scripts/installAmiciArchive.sh @@ -33,4 +33,8 @@ else fi pip install $(ls -t ${AMICI_PATH}/build/python/amici-*.tar.gz | head -1) + +# verify import succeeds +python -m amici + deactivate diff --git a/src/hdf5.cpp b/src/hdf5.cpp index 2dc974bb8d..b548e4d54f 100644 --- a/src/hdf5.cpp +++ b/src/hdf5.cpp @@ -960,6 +960,17 @@ void readModelDataFromHDF5(const H5::H5File &file, Model &model, model.setUnscaledInitialStateSensitivities(sx0); } } + + if(attributeExists(file, datasetPath, "sigma_res")) { + auto sigma_res = getIntScalarAttribute(file, datasetPath, "sigma_res"); + model.setAddSigmaResiduals(static_cast