Skip to content

Commit

Permalink
Merge pull request #2406 from AMICI-dev/release_0.24.0
Browse files Browse the repository at this point in the history
Release 0.24.0
  • Loading branch information
dweindl committed Apr 22, 2024
2 parents 4d40911 + ca9d467 commit 29b7ee8
Show file tree
Hide file tree
Showing 29 changed files with 442 additions and 88 deletions.
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,48 @@

## v0.X Series

### v0.24.0 (2024-04-22)

This will be the last release supporting Python 3.9.
Future releases will require Python 3.10.

**Fixes**

* Fix cmake error `cannot create directory: /cmake/Amici`
during model import in cases where BLAS was not found via `FindBLAS`
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2389
* Added status code `AMICI_CONSTR_FAIL`
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2379
* Fixed certain initial state issues with PEtab
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2382
* Fixed Solver `operator==` and copyctor
(constraints were not copied correctly)
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2388
* Avoid confusing warnings about non-finite timepoints
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2395
* Fixed incorrect exception types / messages for `IDASolver`
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2398
* cmake: set SUNDIALS path hint for python package to help CMake find
the correct SUNDIALS installation
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2397

* **Features**

* Optionally include measurements in `plot_observable_trajectories`
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2381
* Improved type annotations in swig-wrappers
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2401
* Additional attributes are accessible directly via `ReturnDataView` and
`ExpDataView`, e.g. `ReturnDataView.ny`, `ReturnDataView.nx`
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2405
* Allow subselection of state variables for convergence check during
steady-state simulations via `Model.set_steadystate_mask([1, 0, ..., 1])`
(positive value: check; non-positive: don't check).
by @dweindl in https://github.com/AMICI-dev/AMICI/pull/2387

**Full Changelog**: https://github.com/AMICI-dev/AMICI/compare/v0.23.1...v0.24.0


### v0.23.1 (2024-03-11)

* Fixes installation issues related to building SuiteSparse on some systems
Expand Down
11 changes: 9 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,16 @@ elseif(AMICI_TRY_ENABLE_HDF5)
endif()

set(VENDORED_SUNDIALS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/sundials)
set(VENDORED_SUNDIALS_BUILD_DIR ${VENDORED_SUNDIALS_DIR}/build)
set(VENDORED_SUNDIALS_INSTALL_DIR ${VENDORED_SUNDIALS_BUILD_DIR})
set(SUNDIALS_PRIVATE_INCLUDE_DIRS "${VENDORED_SUNDIALS_DIR}/src")
# Handle different sundials build/install dirs, depending on whether we are
# building the Python extension only or the full C++ interface
if(AMICI_PYTHON_BUILD_EXT_ONLY)
set(VENDORED_SUNDIALS_BUILD_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(VENDORED_SUNDIALS_INSTALL_DIR ${VENDORED_SUNDIALS_BUILD_DIR})
else()
set(VENDORED_SUNDIALS_BUILD_DIR ${VENDORED_SUNDIALS_DIR}/build)
set(VENDORED_SUNDIALS_INSTALL_DIR ${VENDORED_SUNDIALS_BUILD_DIR})
endif()
find_package(
SUNDIALS REQUIRED PATHS
"${VENDORED_SUNDIALS_INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/sundials/")
Expand Down
15 changes: 8 additions & 7 deletions cmake/AmiciFindBLAS.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,14 @@ if(NOT TARGET BLAS::BLAS)
INTERFACE_INCLUDE_DIRECTORIES "${BLAS_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}")
add_library(BLAS::BLAS ALIAS BLAS)
install(TARGETS BLAS EXPORT BLAS)
export(EXPORT BLAS NAMESPACE BLAS::)
install(
EXPORT BLAS
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Amici"
NAMESPACE BLAS::)

if("${PROJECT_NAME}" STREQUAL "amici")
install(TARGETS BLAS EXPORT BLAS)
export(EXPORT BLAS NAMESPACE BLAS::)
install(
EXPORT BLAS
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Amici"
NAMESPACE BLAS::)
endif()

# legacy python package environment variables:
if(DEFINED ENV{BLAS_CFLAGS})
Expand Down
31 changes: 31 additions & 0 deletions documentation/amici_refs.bib
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,37 @@ @Article{SluijsZho2024
publisher = {Springer Science and Business Media LLC},
}
@Article{KissVen2024,
author = {Kiss, Anna E and Venkatasubramani, Anuroop V and Pathirana, Dilan and Krause, Silke and Sparr, Aline Campos and Hasenauer, Jan and Imhof, Axel and Müller, Marisa and Becker, Peter B},
journal = {Nucleic Acids Research},
title = {{Processivity and specificity of histone acetylation by the male-specific lethal complex}},
year = {2024},
issn = {0305-1048},
month = {02},
pages = {gkae123},
abstract = {{Acetylation of lysine 16 of histone H4 (H4K16ac) stands out among the histone modifications, because it decompacts the chromatin fiber. The metazoan acetyltransferase MOF (KAT8) regulates transcription through H4K16 acetylation. Antibody-based studies had yielded inconclusive results about the selectivity of MOF to acetylate the H4 N-terminus. We used targeted mass spectrometry to examine the activity of MOF in the male-specific lethal core (4-MSL) complex on nucleosome array substrates. This complex is part of the Dosage Compensation Complex (DCC) that activates X-chromosomal genes in male Drosophila. During short reaction times, MOF acetylated H4K16 efficiently and with excellent selectivity. Upon longer incubation, the enzyme progressively acetylated lysines 12, 8 and 5, leading to a mixture of oligo-acetylated H4. Mathematical modeling suggests that MOF recognizes and acetylates H4K16 with high selectivity, but remains substrate-bound and continues to acetylate more N-terminal H4 lysines in a processive manner. The 4-MSL complex lacks non-coding roX RNA, a critical component of the DCC. Remarkably, addition of RNA to the reaction non-specifically suppressed H4 oligo-acetylation in favor of specific H4K16 acetylation. Because RNA destabilizes the MSL-nucleosome interaction in vitro we speculate that RNA accelerates enzyme-substrate turn-over in vivo, thus limiting the processivity of MOF, thereby increasing specific H4K16 acetylation.}},
creationdate = {2024-02-28T18:25:06},
doi = {10.1093/nar/gkae123},
eprint = {https://academic.oup.com/nar/advance-article-pdf/doi/10.1093/nar/gkae123/56756494/gkae123.pdf},
modificationdate = {2024-02-28T18:25:06},
url = {https://doi.org/10.1093/nar/gkae123},
}
@Article{DoresicGre2024,
author = {Domagoj Dore{\v s}i{\'c} and Stephan Grein and Jan Hasenauer},
journal = {bioRxiv},
title = {Efficient parameter estimation for ODE models of cellular processes using semi-quantitative data},
year = {2024},
abstract = {Quantitative dynamical models facilitate the understanding of biological processes and the prediction of their dynamics. The parameters of these models are commonly estimated from experimental data. Yet, experimental data generated from different techniques do not provide direct information about the state of the system but a non-linear (monotonic) transformation of it. For such semi-quantitative data, when this transformation is unknown, it is not apparent how the model simulations and the experimental data can be compared. Here, we propose a versatile spline-based approach for the integration of a broad spectrum of semi-quantitative data into parameter estimation. We derive analytical formulas for the gradients of the hierarchical objective function and show that this substantially increases the estimation efficiency. Subsequently, we demonstrate that the method allows for the reliable discovery of unknown measurement transformations. Furthermore, we show that this approach can significantly improve the parameter inference based on semi-quantitative data in comparison to available methods. Modelers can easily apply our method by using our implementation in the open-source Python Parameter EStimation TOolbox (pyPESTO).Competing Interest StatementThe authors have declared no competing interest.},
creationdate = {2024-04-20T13:05:06},
doi = {10.1101/2024.01.26.577371},
elocation-id = {2024.01.26.577371},
eprint = {https://www.biorxiv.org/content/early/2024/01/30/2024.01.26.577371.full.pdf},
modificationdate = {2024-04-20T13:05:06},
publisher = {Cold Spring Harbor Laboratory},
url = {https://www.biorxiv.org/content/early/2024/01/30/2024.01.26.577371},
}
@Comment{jabref-meta: databaseType:bibtex;}
@Comment{jabref-meta: grouping:
Expand Down
28 changes: 21 additions & 7 deletions documentation/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,33 @@
import subprocess
import sys
from enum import EnumType

# need to import before setting typing.TYPE_CHECKING=True, fails otherwise
import amici
import exhale.deploy
import exhale_multiproject_monkeypatch
from unittest import mock
import pandas as pd
import sphinx
import sympy as sp
from exhale import configs as exhale_configs
from sphinx.transforms.post_transforms import ReferencesResolver

exhale_multiproject_monkeypatch, pd, sp # to avoid removal of unused import
try:
import exhale_multiproject_monkeypatch # noqa: F401
except ModuleNotFoundError:
# for unclear reasons, the import of exhale_multiproject_monkeypatch
# fails on some systems, because the the location of the editable install
# is not automatically added to sys.path ¯\_(ツ)_/¯
from importlib.metadata import Distribution
import json
from urllib.parse import unquote_plus, urlparse

dist = Distribution.from_name("sphinx-contrib-exhale-multiproject")
url = json.loads(dist.read_text("direct_url.json"))["url"]
package_dir = unquote_plus(urlparse(url).path)
sys.path.append(package_dir)
import exhale_multiproject_monkeypatch # noqa: F401

# need to import before setting typing.TYPE_CHECKING=True, fails otherwise
import amici
import pandas as pd # noqa: F401
import sympy as sp # noqa: F401


# BEGIN Monkeypatch exhale
from exhale.deploy import _generate_doxygen as exhale_generate_doxygen
Expand Down
17 changes: 16 additions & 1 deletion documentation/references.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# References

List of publications using AMICI. Total number is 83.
List of publications using AMICI. Total number is 85.

If you applied AMICI in your work and your publication is missing, please let us know via a new GitHub issue.

Expand All @@ -14,6 +14,21 @@ If you applied AMICI in your work and your publication is missing, please let us
<h1 class="unnumbered" id="section">2024</h1>
<div id="refs" class="references csl-bib-body hanging-indent"
role="list">
<div id="ref-DoresicGre2024" class="csl-entry" role="listitem">
Dorešić, Domagoj, Stephan Grein, and Jan Hasenauer. 2024.
<span>“Efficient Parameter Estimation for ODE Models of Cellular
Processes Using Semi-Quantitative Data.”</span> <em>bioRxiv</em>. <a
href="https://doi.org/10.1101/2024.01.26.577371">https://doi.org/10.1101/2024.01.26.577371</a>.
</div>
<div id="ref-KissVen2024" class="csl-entry" role="listitem">
Kiss, Anna E, Anuroop V Venkatasubramani, Dilan Pathirana, Silke Krause,
Aline Campos Sparr, Jan Hasenauer, Axel Imhof, Marisa Müller, and Peter
B Becker. 2024. <span>“<span class="nocase">Processivity and specificity
of histone acetylation by the male-specific lethal
complex</span>.”</span> <em>Nucleic Acids Research</em>, February,
gkae123. <a
href="https://doi.org/10.1093/nar/gkae123">https://doi.org/10.1093/nar/gkae123</a>.
</div>
<div id="ref-LangPen2024" class="csl-entry" role="listitem">
Lang, Paul F., David R. Penas, Julio R. Banga, Daniel Weindl, and Bela
Novak. 2024. <span>“Reusable Rule-Based Cell Cycle Model Explains
Expand Down
1 change: 1 addition & 0 deletions include/amici/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ constexpr int AMICI_CONV_FAILURE= -4;
constexpr int AMICI_LSETUP_FAIL= -6;
constexpr int AMICI_RHSFUNC_FAIL= -8;
constexpr int AMICI_FIRST_RHSFUNC_ERR= -9;
constexpr int AMICI_CONSTR_FAIL= -15;
constexpr int AMICI_ILL_INPUT= -22;
constexpr int AMICI_ERROR= -99;
constexpr int AMICI_NO_STEADY_STATE= -81;
Expand Down
43 changes: 43 additions & 0 deletions include/amici/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -1481,6 +1481,40 @@ class Model : public AbstractModel, public ModelDimensions {
*/
virtual std::vector<double> get_trigger_timepoints() const;

/**
* @brief Get steady-state mask as std::vector.
*
* See `set_steadystate_mask` for details.
*
* @return Steady-state mask
*/
std::vector<double> get_steadystate_mask() const {
return steadystate_mask_.getVector();
};

/**
* @brief Get steady-state mask as AmiVector.
*
* See `set_steadystate_mask` for details.
* @return Steady-state mask
*/
AmiVector const& get_steadystate_mask_av() const {
return steadystate_mask_;
};

/**
* @brief Set steady-state mask.
*
* The mask is used to exclude certain state variables from the steady-state
* convergence check. Positive values indicate that the corresponding state
* variable should be included in the convergence check, while non-positive
* values indicate that the corresponding state variable should be excluded.
* An empty mask is interpreted as including all state variables.
*
* @param mask Mask of length `nx_solver`.
*/
void set_steadystate_mask(std::vector<double> const& mask);

/**
* Flag indicating whether for
* `amici::Solver::sensi_` == `amici::SensitivityOrder::second`
Expand Down Expand Up @@ -2087,6 +2121,15 @@ class Model : public AbstractModel, public ModelDimensions {

/** Simulation parameters, initial state, etc. */
SimulationParameters simulation_parameters_;

/**
* Mask for state variables that should be checked for steady state
* during pre-/post-equilibration. Positive values indicate that the
* corresponding state variable should be checked for steady state.
* Negative values indicate that the corresponding state variable should
* be ignored.
*/
AmiVector steadystate_mask_;
};

bool operator==(Model const& a, Model const& b);
Expand Down
1 change: 1 addition & 0 deletions include/amici/serialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ void serialize(Archive& ar, amici::Model& m, unsigned int const /*version*/) {
ar & m.steadystate_computation_mode_;
ar & m.steadystate_sensitivity_mode_;
ar & m.state_independent_events_;
ar & m.steadystate_mask_;
}

/**
Expand Down
6 changes: 4 additions & 2 deletions include/amici/steadystateproblem.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,16 @@ class SteadystateProblem {
* w_i = 1 / ( rtol * x_i + atol )
* @param x current state (sx[ip] for sensitivities)
* @param xdot current rhs (sxdot[ip] for sensitivities)
* @param mask mask for state variables to include in WRMS norm.
* Positive value: include; non-positive value: exclude; empty: include all.
* @param atol absolute tolerance
* @param rtol relative tolerance
* @param ewt error weight vector
* @return root-mean-square norm
*/
realtype getWrmsNorm(
AmiVector const& x, AmiVector const& xdot, realtype atol, realtype rtol,
AmiVector& ewt
AmiVector const& x, AmiVector const& xdot, AmiVector const& mask,
realtype atol, realtype rtol, AmiVector& ewt
) const;

/**
Expand Down
4 changes: 2 additions & 2 deletions include/amici/vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,8 @@ inline span<realtype> make_span(N_Vector nv) {
}

/**
* @brief Create span from N_Vector
* @param nv
* @brief Create span from AmiVector
* @param av
*
*/
inline span<realtype const> make_span(amici::AmiVector const& av) {
Expand Down
17 changes: 10 additions & 7 deletions python/sdist/amici/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,18 @@ def __getitem__(self, item: str) -> Union[np.ndarray, float]:
if item in self._cache:
return self._cache[item]

if item == "id":
return getattr(self._swigptr, item)
if item in self._field_names:
value = _field_as_numpy(
self._field_dimensions, item, self._swigptr
)
self._cache[item] = value

if item not in self._field_names:
self.__missing__(item)
return value

if not item.startswith("_") and hasattr(self._swigptr, item):
return getattr(self._swigptr, item)

value = _field_as_numpy(self._field_dimensions, item, self._swigptr)
self._cache[item] = value
return value
self.__missing__(item)

def __missing__(self, key: str) -> None:
"""
Expand Down
15 changes: 9 additions & 6 deletions python/sdist/amici/petab/parameter_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,12 +486,11 @@ def create_parameter_mapping_for_condition(
condition_scale_map_preeq,
preeq_value,
)
else:
# need to set dummy value for preeq parameter anyways, as it
# is expected below (set to 0, not nan, because will be
# multiplied with indicator variable in initial assignment)
condition_map_sim[init_par_id] = 0.0
condition_scale_map_sim[init_par_id] = LIN
# need to set dummy value for preeq parameter anyways, as it
# is expected below (set to 0, not nan, because will be
# multiplied with indicator variable in initial assignment)
condition_map_sim[init_par_id] = 0.0
condition_scale_map_sim[init_par_id] = LIN

# for simulation
condition_id = condition[SIMULATION_CONDITION_ID]
Expand All @@ -505,6 +504,10 @@ def create_parameter_mapping_for_condition(
condition_scale_map_sim,
value,
)
# set dummy value as above
if condition_map_preeq:
condition_map_preeq[init_par_id] = 0.0
condition_scale_map_preeq[init_par_id] = LIN

##########################################################################
# separate fixed and variable AMICI parameters, because we may have
Expand Down
4 changes: 3 additions & 1 deletion python/sdist/amici/petab/sbml_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ def import_model_sbml(
init_par = sbml_model.createParameter()
init_par.setId(init_par_id)
init_par.setName(init_par_id)
# must be a fixed parameter in any case to allow reinitialization
fixed_parameters.append(init_par_id)
assignment = sbml_model.getInitialAssignment(assignee_id)
if assignment is None:
assignment = sbml_model.createInitialAssignment()
Expand Down Expand Up @@ -535,7 +537,7 @@ def _get_fixed_parameters_sbml(
ia.getMath(), parser_settings
)
)
if not sym_math.is_Number:
if not sym_math.evalf().is_Number:
fixed_parameters.remove(fixed_parameter)
continue

Expand Down
Loading

0 comments on commit 29b7ee8

Please sign in to comment.