diff --git a/.github/workflows/parpe_tests.yml b/.github/workflows/parpe_tests.yml index 855c45d1c..11f66db27 100644 --- a/.github/workflows/parpe_tests.yml +++ b/.github/workflows/parpe_tests.yml @@ -53,13 +53,14 @@ jobs: -DBUILD_TESTS=OFF \ && cmake --build "${AMICI_PATH}/build" --parallel -- VERBOSE=1 - - name: Install google test - run: ThirdParty/installGoogleTest.sh - - name: Install parPE Python deps run: | pip install -r ${PARPE_BASE}/python/requirements.txt + - name: "Install parPE deps: fides" + run: | + sudo apt install libspdlog-dev && ${PARPE_BASE}/ThirdParty/installFides.sh + - name: Configure parPE run: | cmake \ @@ -69,7 +70,8 @@ jobs: -DIPOPT_INCLUDE_DIRS=/usr/include/coin/ \ -DIPOPT_LIBRARIES=/usr/lib/libipopt.so \ -DGCOV_REPORT=TRUE \ - -DBUILD_TESTING=TRUE + -DBUILD_TESTING=TRUE \ + -DPARPE_ENABLE_FIDES=TRUE - name: Build parPE # with sonar build wrapper diff --git a/CMakeLists.txt b/CMakeLists.txt index bcacf6cc4..aea9f82ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 3.10) # for GoogleTest -cmake_policy(VERSION 3.10) +cmake_minimum_required(VERSION 3.13) # pkg_search_module GLOBAL +cmake_policy(VERSION 3.13) if(POLICY CMP0074) # Use package_ROOT environment variables @@ -51,6 +51,7 @@ set(BUILD_PYTHON_MODULE FALSE CACHE BOOL "Build Python module?") set(BLAS "CBLAS" CACHE STRING "BLAS library to use") set_property(CACHE BLAS PROPERTY STRINGS "CBLAS" "MKL") set(PARPE_ENABLE_MPI TRUE CACHE BOOL "Use MPI?") +set(PARPE_ENABLE_FIDES FALSE CACHE BOOL "Enable fides optimizer?") set(PARPE_ENABLE_IPOPT TRUE CACHE BOOL "Enable ipopt optimizer?") set(PARPE_ENABLE_CERES TRUE CACHE BOOL "Enable ceres optimizer?") set(PARPE_ENABLE_DLIB FALSE CACHE BOOL "Enable dlib optimizers?") @@ -68,13 +69,17 @@ if(${PARPE_ENABLE_MPI}) endif(${PARPE_ENABLE_MPI}) # +if(${PARPE_ENABLE_FIDES}) + find_package(Fides REQUIRED) +endif(${PARPE_ENABLE_FIDES}) + find_package(PkgConfig) pkg_search_module(IPOPT REQUIRED IMPORTED_TARGET GLOBAL ipopt>=3.11.0 ) -if(${ENABLE_DLIB}) +if(${PARPE_ENABLE_DLIB}) set(DLIB_DIR "${CMAKE_CURRENT_LIST_DIR}/ThirdParty/dlib-19.7" CACHE FILEPATH "DLIB base directory") -endif(${ENABLE_DLIB}) +endif(${PARPE_ENABLE_DLIB}) # PThreads set(THREADS_PREFER_PTHREAD_FLAG ON) @@ -101,25 +106,6 @@ if(${BUILD_TESTING}) set(TESTS_MPIEXEC_COMMAND mpiexec --allow-run-as-root --oversubscribe -n 4 CACHE STRING "") - # googletest - add_definitions(-DGTEST_LANGUAGE_CXX11) - find_package(Threads REQUIRED) - if ($ENV{GOOGLETEST_DIR}) - set(GOOGLETEST_DIR $ENV{GOOGLETEST_DIR}) - else() - set(GOOGLETEST_DIR "${CMAKE_CURRENT_LIST_DIR}/ThirdParty/googletest") - endif() - if (EXISTS ${GOOGLETEST_DIR}) - set(GTestSrc ${GOOGLETEST_DIR}/googletest) - set(GMockSrc ${GOOGLETEST_DIR}/googlemock) - else () - message(FATAL_ERROR "No googletest src dir found - set GOOGLETEST_DIR " - "or run ../ThirdParty/installGoogleTest.sh to enable!" - " (Or disable building tests with BUILD_TESTING=OFF)") - endif () - include_directories(${GTestSrc} "${GTestSrc}/include" - ${GMockSrc} "${GMockSrc}/include") - # # Create test coverage reports? set(GCOV_REPORT FALSE CACHE BOOL "Create GCOV report?") diff --git a/CMakeModules/ParPEConfig.cmake.in b/CMakeModules/ParPEConfig.cmake.in index ebb66791e..015538f64 100644 --- a/CMakeModules/ParPEConfig.cmake.in +++ b/CMakeModules/ParPEConfig.cmake.in @@ -5,6 +5,7 @@ include(CMakeFindDependencyMacro) set(PARPE_ENABLE_MPI @PARPE_ENABLE_MPI@) set(PARPE_ENABLE_IPOPT @PARPE_ENABLE_IPOPT@) set(PARPE_ENABLE_CERES @PARPE_ENABLE_CERES@) +set(PARPE_ENABLE_FIDES @PARPE_ENABLE_FIDES@) if(${PARPE_ENABLE_MPI}) find_dependency(MPI REQUIRED) @@ -12,7 +13,8 @@ endif() if(${PARPE_ENABLE_IPOPT}) find_dependency(PkgConfig REQUIRED) -pkg_search_module(IPOPT REQUIRED IMPORTED_TARGET GLOBAL ipopt>=3.11.0) +pkg_search_module(IPOPT REQUIRED IMPORTED_TARGET GLOBAL ipopt=@IPOPT_VERSION@) +message("-- Found Ipopt version: ${IPOPT_VERSION}") endif() if(${PARPE_ENABLE_CERES}) @@ -21,6 +23,11 @@ find_dependency(Ceres COMPONENTS find_dependency(Eigen3 REQUIRED) endif() +if(${PARPE_ENABLE_FIDES}) +find_dependency(Fides + HINTS "${CMAKE_SOURCE_DIR}/ThirdParty/fides-cpp/build/") +endif() + find_dependency(Amici REQUIRED) find_dependency(OpenMP) find_dependency(HDF5 COMPONENTS C CXX HL REQUIRED) diff --git a/ThirdParty/installDeps.sh b/ThirdParty/installDeps.sh index 3c0b910bb..bc587a86a 100755 --- a/ThirdParty/installDeps.sh +++ b/ThirdParty/installDeps.sh @@ -15,5 +15,3 @@ cd "$script_dir" ./installCeres.sh ./installIpopt.sh - -./installGoogleTest.sh diff --git a/ThirdParty/installDlib.sh b/ThirdParty/installDlib.sh index f02d822d0..3c8085685 100755 --- a/ThirdParty/installDlib.sh +++ b/ThirdParty/installDlib.sh @@ -1,24 +1,32 @@ #!/usr/bin/env bash -# build DLIB +# Download and build DLIB set -euo pipefail +script_dir=$(dirname "$0") +script_dir=$(cd "${script_dir}" && pwd) +cd "${script_dir}" + +make_opts=${MAKEOPTS-} dlib_archive="dlib-19.7.tar.bz2" -if [ ! -d "dlib-19.7" ]; then +dlib_dir=${script_dir}/dlib-19.7 + +if [ ! -d "${dlib_dir}" ]; then if [ ! -f "${dlib_archive}" ]; then - wget "http://dlib.net/files/${dlib_archive}" -o "${dlib_archive}" + wget "http://dlib.net/files/${dlib_archive}" -O "${dlib_archive}" fi tar -xjf "${dlib_archive}" fi -cd "dlib-19.7/" +cd "${dlib_dir}" mkdir -p build && cd build/ - cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install" \ - -DDLIB_NO_GUI_SUPPORT=ON \ - -DDLIB_GIF_SUPPORT=OFF \ - -DDLIB_JPEG_SUPPORT=OFF \ - -DDLIB_PNG_SUPPORT=OFF \ - -DDLIB_LINK_WITH_SQLITE3=OFF \ - .. +cmake -S .. \ + -DCMAKE_INSTALL_PREFIX="$(pwd)/install" \ + -DDLIB_NO_GUI_SUPPORT=ON \ + -DDLIB_GIF_SUPPORT=OFF \ + -DDLIB_JPEG_SUPPORT=OFF \ + -DDLIB_PNG_SUPPORT=OFF \ + -DDLIB_LINK_WITH_SQLITE3=OFF \ + .. -make -j12 && make install +make ${make_opts} && make install diff --git a/ThirdParty/installFides.sh b/ThirdParty/installFides.sh new file mode 100755 index 000000000..39bb9e362 --- /dev/null +++ b/ThirdParty/installFides.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Download and build fides-cpp + +build_blaze() { + cd "${script_dir}" + + if [[ ! -d "${blaze_dir}" ]]; then + if [[ ! -f "blaze-3.8.tar.gz" ]]; then + wget https://bitbucket.org/blaze-lib/blaze/downloads/blaze-3.8.tar.gz + fi + tar -xzf blaze-3.8.tar.gz + cd blaze-3.8 + cmake -S . -B build/ -DCMAKE_INSTALL_PREFIX="$(pwd)/build/install" + cd build + make -j2 install + fi +} + +build_fides() { + if [ ! -d "${fides_dir}" ]; then + cd "${script_dir}" + git clone https://github.com/dweindl/fides-cpp.git + cd "${fides_dir}" + git checkout 9906bdac6a1966ddd4b37b96f98ad8f89770c128 + fi + + cd "${fides_dir}" + cmake -S . -B build -DBUILD_TESTING=OFF + cd build + make ${make_opts} +} + +set -euo pipefail +script_dir=$(dirname "$0") +script_dir=$(cd "${script_dir}" && pwd) +cd "${script_dir}" + +make_opts=${MAKEOPTS-} + +fides_dir=${script_dir}/fides-cpp +blaze_dir=${script_dir}/blaze-3.8 + +build_blaze +build_fides diff --git a/ThirdParty/installGoogleTest.sh b/ThirdParty/installGoogleTest.sh deleted file mode 100755 index 270a99363..000000000 --- a/ThirdParty/installGoogleTest.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash -# Download and build googletest - -set -euo pipefail - -script_path="$(dirname "$0")" -script_path="$(cd "${script_path}" && pwd)" - -cd "${script_path}" - -if [[ ! -d "googletest" ]]; then - echo "googletest/ does not exist" - if [[ ! -f "googletest.zip" ]]; then - echo "Downloading googletest..." - wget "https://github.com/google/googletest/archive/master.zip" -O "googletest.zip" - fi - - echo "Unpacking and building googletest..." - unzip "googletest" - mv "googletest-master" "googletest" - cd "googletest" - mkdir -p build - cd build - cmake .. - make -j 4 -else - echo "googletest/ exists. nothing to do." -fi diff --git a/ThirdParty/installIpopt.sh b/ThirdParty/installIpopt.sh index 1c8792114..c7369cbe8 100755 --- a/ThirdParty/installIpopt.sh +++ b/ThirdParty/installIpopt.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# build Ipopt +# Download and build Ipopt and HSL set -euo pipefail script_dir=$(dirname "$0") @@ -16,6 +16,7 @@ hsl_install_dir="${ipopt_dir}/ThirdParty-HSL/install" if [[ ! -d "${ipopt_dir}" ]]; then if [[ ! -f "${ipopt_archive}" ]]; then + echo "Downloading IpOpt source archive ..." wget -O "${ipopt_archive}" "${ipopt_url}" else echo "Skipping download step." @@ -26,50 +27,63 @@ if [[ ! -d "${ipopt_dir}" ]]; then # Handle HSL solvers cd "${ipopt_dir}" if [[ ! -d "ThirdParty-HSL" ]]; then + echo "Cloning ThirdParty-HSL ..." git clone https://github.com/coin-or-tools/ThirdParty-HSL.git fi cd ThirdParty-HSL + # Need some coinhsl library. if [[ ! -d "coinhsl" ]]; then - # Need some coinhsl library. Check for common ones: - if [[ -f "${script_dir}/coinhsl-2015.06.23.tar.gz" ]]; then - tar -xzf "${script_dir}/coinhsl-2015.06.23.tar.gz" - mv coinhsl-2015.06.23 coinhsl - elif [[ -f "${script_dir}/coinhsl-2014.01.10.tar.gz" ]]; then - tar -xzf "${script_dir}/coinhsl-2014.01.10.tar.gz" - mv coinhsl-2014.01.10 coinhsl - elif [[ -f "${script_dir}/coinhsl-2019.05.21.tar.gz" ]]; then - tar -xzf "${script_dir}/coinhsl-2019.05.21.tar.gz" - mv coinhsl-2019.05.21 coinhsl + # ThirdParty/coinhsl ? + if [[ -d "${script_dir}/coinhsl" ]]; then + echo "Using coinhsl from ${script_dir}/coinhsl" + cp -aR "${script_dir}/coinhsl" coinhsl else - echo "Did not find coinhsl/ or a known coinhsl archive." - echo "Name your coinhsl version." - read version - if [[ -f "${script_dir}/coinhsl-${version}.tar.gz" ]]; then - tar -xzf "${script_dir}/coinhsl-${version}.tar.gz" - mv coinhsl-${version} coinhsl - else - echo "Press any key to continue" - read -n 1 -s -r - fi + # Check for common ones: + coinhsl_archive_names=" + coinhsl-2014.01.10 + coinhsl-2015.06.23 + coinhsl-2019.05.21 + " + for coinhsl_archive in $coinhsl_archive_names; do + if [[ -f "${script_dir}/${coinhsl_archive}.tar.gz" ]]; then + echo "Unpacking ${script_dir}/${coinhsl_archive}.tar.gz ..." + tar -xzf "${script_dir}/${coinhsl_archive}.tar.gz" + mv "${coinhsl_archive}" coinhsl + fi + done fi + + if [[ ! -d "coinhsl" ]]; then + echo "Did not find coinhsl/ or a known coinhsl archive." \ + "IpOpt will probably not work." + fi + fi + + # Use Intel MKL for lapack? + lapack_lflags="" + if [[ -v MKL_SHLIB ]]; then + # Will require F77=ifort when using intel compilers. + lapack_lflags="--with-lapack-lflags=${MKL_SHLIB}" fi - ./configure --prefix="${hsl_install_dir}" - make + ./configure --prefix="${hsl_install_dir}" \ + --with-lapack "${lapack_lflags}" \ + --disable-static --enable-shared + make $make_opts make install - (cd ${hsl_install_dir}/lib && test ! -e libhsl.so && ln -s libcoinhsl.so libhsl.so || true) cd "${ipopt_dir}" + + PKG_CONFIG_PATH=${PKG_CONFIG_PATH-}:${hsl_install_dir}/lib/pkgconfig/ \ ./configure --prefix="${ipopt_install_dir}" \ - --enable-static \ - --disable-shared \ + --disable-static \ + --enable-shared \ --with-pic \ --with-hsl \ - --with-hsl-cflags=-I${hsl_install_dir}/include/coin-or/hsl \ - --with-hsl-lflags="-L${hsl_install_dir}/lib/ -lcoinhsl" \ - --disable-linear-solver-loader + --disable-linear-solver-loader \ + --with-lapack "${lapack_lflags}" make $make_opts make $make_opts install else diff --git a/benchmark_collection/all.sh b/benchmark_collection/all.sh index 5bc854c58..d0737d046 100755 --- a/benchmark_collection/all.sh +++ b/benchmark_collection/all.sh @@ -1,28 +1,60 @@ #!/usr/bin/env bash # Import, build, and run benchmark models -set -e +set -eou pipefail +# Path to benchmark collection model directory [[ -n "${BENCHMARK_COLLECTION}" ]] && model_dir="${BENCHMARK_COLLECTION}" # all_models=$(ls -1d ${model_dir}/*/) - expected_to_work=" Boehm_JProteomeRes2014 Borghans_BiophysChem1997 +Crauste_CellSystems2017 Elowitz_Nature2000 Fujita_SciSignal2010 +Schwen_PONE2014 Sneyd_PNAS2002 -Zheng_PNAS2012" -#Schwen_PONE2014 Chen_MSB2009 +Weber_BMC2015 +Zheng_PNAS2012 +" +# Timepoint-specific parameter overrides currently unsupported.: +# +# Chen_MSB2009 +# +# missing ref: +# +# Alkan_SciSignal2018 +# Blasi_CellSystems2016 +# Bruno_JExpBio2016 +# Giordano_Nature2020 +# Okuonghae_ChaosSolitonsFractals2020 +# Perelson_Science1996 +# Rahman_MBS2016 +# Raimundez_PCB2020 +# SalazarCavazos_MBoC2020 +# Zhao_QuantBiol2020 +# +# integration trouble: +# +# Beer_MolBioSystems2014 +# Bertozzi_PNAS2020 +# Borghans_BiophysChem1997 +# Isensee_JCB2018 +# +# Mismatch: +# Bachmann_MSB2011: Expected llh -478.459689232875, got nllh -418.409381 +# Brannmark_JBC2010 FAILED: Expected llh 283.778227541074, got nllh 141.889034 +# Lucarelli_CellSystems2018 +# Fiedler_BMC2016 FAILED: Expected llh -117.16780323362, got nllh 109391.496205 -for MODEL in $expected_to_work; do +for model_name in $expected_to_work; do printf '=%.0s' {1..20} - printf %s "${MODEL}" + printf %s "${model_name}" printf '=%.0s' {1..20} echo - echo ./import_and_run.sh "${model_dir}"/"${MODEL}" - ./import_and_run.sh "${model_dir}"/"${MODEL}" + echo ./import_and_run.sh "${model_dir}"/"${model_name}" + ./import_and_run.sh "${model_dir}"/"${model_name}" printf '=%.0s' {1..100} echo done diff --git a/benchmark_collection/import_and_run.sh b/benchmark_collection/import_and_run.sh index 6a8b13d08..fecc2fcfd 100755 --- a/benchmark_collection/import_and_run.sh +++ b/benchmark_collection/import_and_run.sh @@ -1,89 +1,94 @@ #!/usr/bin/env bash # Import, build, and run model from the benchmark collection -set -e +set -eou pipefail get_abs_filename() { # $1 : relative filename echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")" } +check_output() { + # Check output + local nllh=$(grep Likelihood "${output_file}" | tr -cd '[:print:]' | sed -r 's/.*Likelihood: (.*)\[.*/\1/') + rm "${output_file}" + local reference_file="${amici_root}/tests/benchmark-models/benchmark_models.yaml" + local ref=$(shyaml get-value "${model_name}".llh <"$reference_file") + local abs="define abs(i) {\\nif (i < 0) return (-i) \nreturn (i)\n}\n" + + # Do we match within tolerance? + # LLH VS nllh! + if (($(echo -e "${abs}\nabs($nllh + $ref) < 0.001 * abs($ref)" | bc))); then + echo "OKAY: Expected llh $ref, got nllh $nllh" + else + echo "FAILED: Expected llh $ref, got nllh $nllh" + exit 1 + fi +} + if [[ $# -lt 1 ]] || [[ $# -gt 1 ]]; then - echo "Import, build, and run model from the benchmark collection" - echo "USAGE: $(basename "$0") /path/to/model/dir" - exit 1; + echo "Import, build, and run model from the benchmark collection" + echo "USAGE: $(basename "$0") /path/to/model/dir" + exit 1 fi -PETAB_MODEL_DIR=$1 -SCRIPT_PATH=$(get_abs_filename "$(dirname "$BASH_SOURCE")") -PARPE_DIR=${SCRIPT_PATH}/.. -MODEL_NAME=$(basename "${PETAB_MODEL_DIR}") -AMICI_MODEL_DIR=${SCRIPT_PATH}/${MODEL_NAME} -petab_yaml=${MODEL_NAME}.yaml -if [[ -z "${AMICI_ROOT}" ]] - then AMICI_ROOT=${PARPE_DIR}/deps/AMICI/ -fi +petab_model_dir=$1 +script_path=$(get_abs_filename "$(dirname "$BASH_SOURCE")") +parpe_dir=${script_path}/.. +model_name=$(basename "${petab_model_dir}") +amici_model_dir=${script_path}/${model_name} +petab_yaml=${model_name}.yaml +output_file=tmp.out +hdf5_infile="parpe_${model_name}/${model_name}.h5" +estimate_exe="parpe_${model_name}/build/estimate_${model_name}" +amici_root="${AMICI_ROOT:-${parpe_dir}/deps/AMICI/}" -cd "${PETAB_MODEL_DIR}" +cd "${petab_model_dir}" echo "Running petablint on ${petab_yaml}..." -petablint -v -y "${MODEL_NAME}".yaml +petablint -v -y "${model_name}".yaml # import AMICI model -if [[ ! -d ${AMICI_MODEL_DIR} ]]; then - echo "Importing model..." - CMD="amici_import_petab.py --verbose -y ${MODEL_NAME}.yaml -o ${AMICI_MODEL_DIR}" - echo "${CMD}" - ${CMD} +if [[ ! -d ${amici_model_dir} ]]; then + echo "Importing model..." + cmd="amici_import_petab.py --verbose -y ${model_name}.yaml -n ${model_name} -o ${amici_model_dir}" + echo "${cmd}" + ${cmd} fi -cd "${SCRIPT_PATH}" +cd "${script_path}" # parPE build -if [[ ! -d parpe_${MODEL_NAME} ]]; then - echo "Setting up parPE..." - "${PARPE_DIR}"/misc/setup_amici_model.sh "${AMICI_MODEL_DIR}" parpe_"${MODEL_NAME}" +if [[ ! -d parpe_${model_name} ]]; then + echo "Setting up parPE..." + "${parpe_dir}"/misc/setup_amici_model.sh "${amici_model_dir}" parpe_"${model_name}" else - (cd parpe_"${MODEL_NAME}"/build && cmake -DAmici_DIR="${AMICI_ROOT}"/build .. && make) + (cd parpe_"${model_name}"/build && cmake -DAmici_DIR="${amici_root}"/build .. && make) fi # generate data file echo "Importing data..." -CMD="parpe_petab_to_hdf5 \ - -o parpe_${MODEL_NAME}/${MODEL_NAME}.h5 \ - -d ${AMICI_MODEL_DIR} \ - -y ${PETAB_MODEL_DIR}/${MODEL_NAME}.yaml \ - -n ${MODEL_NAME}" -echo "$CMD" -$CMD +cmd="parpe_petab_to_hdf5 \ + -o ${hdf5_infile} \ + -d ${amici_model_dir} \ + -y ${petab_model_dir}/${model_name}.yaml \ + -n ${model_name}" +echo "$cmd" +$cmd echo "" echo "Start parameter estimation by:" -echo "parpe_${MODEL_NAME}/build/estimate_${MODEL_NAME} -o parpe_${MODEL_NAME}_results/ parpe_${MODEL_NAME}/${MODEL_NAME}.h5" +echo "${estimate_exe} -o parpe_${model_name}_results/ ${hdf5_infile}" echo "" echo "Running simulation with nominal parameters..." -cmd="parpe_${MODEL_NAME}/build/simulateNominal_${MODEL_NAME} parpe_${MODEL_NAME}/${MODEL_NAME}.h5" +cmd="parpe_${model_name}/build/simulateNominal_${model_name} ${hdf5_infile}" echo "$cmd" -$cmd |& tee tmp.out - -# Check output -NLLH=$(grep Likelihood tmp.out | tr -cd '[:print:]' | sed -r 's/.*Likelihood: (.*)\[.*/\1/') -rm tmp.out -REFERENCE_FILE="${AMICI_ROOT}/tests/benchmark-models/benchmark_models.yaml" -REF=$(shyaml get-value "${MODEL_NAME}".llh < "$REFERENCE_FILE") -ABS="define abs(i) {\\nif (i < 0) return (-i) \nreturn (i)\n}\n" - -# Do we match within tolerance? -# LLH VS NLLH! -if (( $(echo -e "${ABS}\nabs($NLLH + $REF) < 0.001 * abs($REF)" | bc) )); then - echo "OKAY: Expected llh $REF, got nllh $NLLH" -else - echo "FAILED: Expected llh $REF, got nllh $NLLH" - exit 1 -fi +$cmd |& tee "${output_file}" + +check_output echo "Checking gradient..." -echo PARPE_NO_DEBUG=1 "parpe_${MODEL_NAME}/build/estimate_${MODEL_NAME}" -t gradient_check -o "parpe_${MODEL_NAME}_results/gradient_check" "parpe_${MODEL_NAME}/${MODEL_NAME}.h5" -PARPE_NO_DEBUG=1 "parpe_${MODEL_NAME}/build/estimate_${MODEL_NAME}" -t gradient_check -o "parpe_${MODEL_NAME}_results/gradient_check" "parpe_${MODEL_NAME}/${MODEL_NAME}.h5" +echo PARPE_NO_DEBUG=1 "${estimate_exe}" -t gradient_check -o "parpe_${model_name}_results/gradient_check" "${hdf5_infile}" +PARPE_NO_DEBUG=1 "${estimate_exe}" -t gradient_check -o "parpe_${model_name}_results/gradient_check" "${hdf5_infile}" diff --git a/buildAll.sh b/buildAll.sh index 171f58944..377770a8f 100755 --- a/buildAll.sh +++ b/buildAll.sh @@ -5,6 +5,8 @@ set -euo pipefail parpe_root=$(dirname "$0") parpe_root=$(cd "${parpe_root}" && pwd) +make_opts=${MAKEOPTS--j12} + # Build amici amici_dir="${parpe_root}/deps/AMICI/" cd "${amici_dir}" @@ -16,12 +18,13 @@ cd "${amici_dir}" "${parpe_root}/ThirdParty/installIpopt.sh" # build parpe -export PKG_CONFIG_PATH=${parpe_root}/ThirdParty/Ipopt-releases-3.13.3/:${PKG_CONFIG_PATH:-} +ipopt_root=${parpe_root}/ThirdParty/Ipopt-releases-3.13.3/ +export PKG_CONFIG_PATH=${PKG_CONFIG_PATH:-}:${ipopt_root}/install/lib/pkgconfig/:${ipopt_root}/ThirdParty-HSL/install/lib/pkgconfig/ parpe_build_dir="${parpe_root}/build" mkdir -p "${parpe_build_dir}" cd "${parpe_build_dir}" cmake "${parpe_root}" -make -j12 +make ${make_opts} # run tests make test diff --git a/buildSuperMUC.sh b/buildSuperMUC.sh index cd4119311..5e683726f 100755 --- a/buildSuperMUC.sh +++ b/buildSuperMUC.sh @@ -1,61 +1,114 @@ #!/bin/bash -set -e -PARPE_ROOT="`dirname \"$BASH_SOURCE\"`" -PARPE_ROOT="`( cd \"${PARPE_ROOT}\" && pwd )`" - -MAKE_OPTS=-j12 -# load modules - -# build AMICI -AMICI_PATH=${PARPE_ROOT}/deps/AMICI - -#cpputest -#CPPUTEST_PATH=${AMICI_PATH}/ThirdParty/cpputest-master -#cd ${CPPUTEST_PATH} -# -DC++11=ON breaks compilation of some `_override` for no obvious reason -#cmake -DC++11=OFF -DCMAKE_INSTALL_PREFIX=`pwd` -#make ${MAKE_OPTS} -#make install - -deps/AMICI/scripts/buildSuiteSparse.sh -deps/AMICI/scripts/buildSundials.sh - -export PYTHON_EXECUTABLE=$(which python3) -mkdir -p ${AMICI_PATH}/build -cd ${AMICI_PATH}/build -cmake -DCMAKE_BUILD_TYPE=Release \ - -DBLAS=MKL \ - -DBLAS_LIBRARIES="${MKL_LIB}" \ - -DBLAS_INCLUDE_DIRS="${MKL_INCDIR}" \ - -DBUILD_TESTING=OFF \ - .. -make ${MAKE_OPTS} amici - -# build dependencies -cd ${PARPE_ROOT}/ThirdParty -#./installCeres.sh -#./installCpputest.sh -# requires download of additional packages ./installIpopt.sh - -CERES_BASE=${PARPE_ROOT}/ThirdParty/ceres-solver-1.13.0/ -CERES_INSTALL_DIR=${CERES_BASE}/build/install/ -if [[ -d ${CERES_BASE} ]]; then - echo "Found CERES. Building..." - mkdir -p ${CERES_BASE}/build - cd ${CERES_BASE}/build - make ${MAKE_OPTS} -else - echo "CERES sources not found. Skipping..." -fi - -echo -echo "Building parPE..." -cd $PARPE_ROOT -mkdir -p build && cd build -CC=mpicc CXX=mpiCC HDF5_ROOT=${HDF5_BASE} BOOST_ROOT=${BOOST_BASE} MPI_HOME=${MPI_BASE} cmake \ - -DBoost_USE_STATIC_LIBS=TRUE \ - -DIPOPT_DIR=`pwd`/../ThirdParty/Ipopt-3.12.9/install \ - -DCERES_LIBRARIES="${CERES_INSTALL_DIR}/lib64/libceres.a;${MKL_LIB}" \ - -DCERES_INCLUDE_DIRS="${CERES_INSTALL_DIR}/include/;${CERES_INSTALL_DIR}/include/ceres/internal/miniglog/;`pwd`/../ThirdParty/eigen-eigen-67e894c6cd8f/build/install/include/eigen3/" \ - .. -make ${MAKE_OPTS} +# Build parPE on SuperMUC +# +# Assumes all relevant modules are loaded with compatible versions. +# Assumes there is Python>=3.7 available on $PATH. +# +# Known issues: +# * With CMake<3.16, linking IpOpt compiled with MKL via pkg-config info may +# result in "ld: cannot find -lpkgcfg_lib_IPOPT_iomp5-NOTFOUND" +# -> use newer CMake + +build_cpputest() { + #cpputest + #CPPUTEST_PATH=${amici_path}/ThirdParty/cpputest-master + #cd ${CPPUTEST_PATH} + # -DC++11=ON breaks compilation of some `_override` for no obvious reason + #cmake -DC++11=OFF -DCMAKE_INSTALL_PREFIX=`pwd` + #make ${make_opts} + #make install + : +} + +build_amici() { + amici_path=${parpe_root}/deps/AMICI + + "${amici_path}/scripts/buildSuiteSparse.sh" + "${amici_path}/scripts/buildSundials.sh" + + python_exec=$(which python3) + export PYTHON_EXECUTABLE=${python_exec} + mkdir -p "${amici_path}/build" + cd "${amici_path}/build" + cmake -S .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DBLAS=MKL \ + -DBLAS_LIBRARIES="${MKL_LIB}" \ + -DBLAS_INCLUDE_DIRS="${MKL_INCDIR}" \ + -DBUILD_TESTS=OFF + make ${make_opts} amici +} + +build_boost() { + # Build custom boost (with CXX11 ABI!) + cd "${parpe_root}/ThirdParty" + # NOTE 1.70.0 has broken CMake config + local archive_name=boost_1_71_0.tar.gz + local boost_dir=${parpe_root}/ThirdParty/boost_1_71_0 + local url="https://dl.bintray.com/boostorg/release/1.71.0/source/${archive_name}" + boost_install_dir=${boost_dir}/install + + if [[ ! -d ${boost_dir} ]]; then + if [[ ! -f ${archive_name} ]]; + then wget $url -O "${archive_name}" + fi + + tar -xzf $archive_name + cd "${boost_dir}" + ./bootstrap.sh \ + --prefix="${boost_install_dir}" \ + --with-libraries=filesystem,program_options,regex,serialization,system + ./b2 install -j 20 + else + echo "Skipping boost - ${boost_dir} already exists" + fi +} + +build_3rd_party_deps() { + # build dependencies + build_boost + "${parpe_root}/ThirdParty/installIpopt.sh" + #./installCeres.sh + #./installCpputest.sh + # ceres_base=${parpe_root}/ThirdParty/ceres-solver-1.13.0/ + # ceres_install_dir=${ceres_base}/build/install/ + # if [[ -d ${ceres_base} ]]; then + # echo "Found CERES. Building..." + # mkdir -p "${ceres_base}/build" + # cd "${ceres_base}/build" + # make ${make_opts} + # else + # echo "CERES sources not found. Skipping..." + # fi +} + +build_parpe() { + echo + echo "Building parPE..." + cd "${parpe_root}" + mkdir -p build && cd build + ipopt_root=${parpe_root}/ThirdParty/Ipopt-releases-3.13.3/ + + HDF5_ROOT=${HDF5_BASE} \ + BOOST_ROOT=${boost_install_dir} \ + MPI_HOME=${MPI_BASE} \ + PKG_CONFIG_PATH=${PKG_CONFIG_PATH:-}:${ipopt_root}/install/lib/pkgconfig/:${ipopt_root}/ThirdParty-HSL/install/lib/pkgconfig/ \ + cmake -S .. \ + -DPARPE_ENABLE_CERES=OFF \ + -DBoost_USE_STATIC_LIBS=TRUE \ + -DBUILD_TESTING=OFF + make ${make_opts} +} + +set -eou pipefail + +# absolute path to parpe repository base directory +parpe_root=$(dirname "$BASH_SOURCE") +parpe_root=$(cd "${parpe_root}" && pwd) + +make_opts=${MAKEOPTS--j12} + +build_cpputest +build_3rd_party_deps +build_amici +build_parpe diff --git a/container/charliecloud/parpe_base/install_parpe.sh b/container/charliecloud/parpe_base/install_parpe.sh index 8fab7b578..1a46ef8c0 100755 --- a/container/charliecloud/parpe_base/install_parpe.sh +++ b/container/charliecloud/parpe_base/install_parpe.sh @@ -30,9 +30,6 @@ cmake \ #- cd $PARPE_BASE/ThirdParty && ./installCeres.sh -# For google-test for parPE tests -cd "${PARPE_BASE}" && ThirdParty/installGoogleTest.sh - # install parPE python requirements pip install -r "${PARPE_BASE}"/python/requirements.txt diff --git a/deps/AMICI/.github/ISSUE_TEMPLATE/feature_request.md b/deps/AMICI/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..a5cd274b4 --- /dev/null +++ b/deps/AMICI/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,14 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement, new +assignees: '' + +--- + +**Feature description** +[A clear and concise description of what you would like to have.] + +**Motivation/Application** +[Why is this feature useful?] diff --git a/deps/AMICI/.github/workflows/release_biosimulators.yml b/deps/AMICI/.github/workflows/release_biosimulators.yml new file mode 100644 index 000000000..53d5a5559 --- /dev/null +++ b/deps/AMICI/.github/workflows/release_biosimulators.yml @@ -0,0 +1,32 @@ +name: Release to BioSimulators + +on: + release: + types: + - published + +jobs: + updateCliAndDockerImage: + name: Build and release downstream command-line interface and Docker image + runs-on: ubuntu-latest + env: + # Owner/repository-id for the GitHub repository for the downstream command-line interface and Docker image + DOWNSTREAM_REPOSITORY: biosimulators/Biosimulators_AMICI + + # Username/token to use the GitHub API to trigger an action on the GitHub repository for the downstream + # command-line interface and Docker image. Tokens can be generated at https://github.com/settings/tokens. + # The token should have the scope `repo` + GH_ISSUE_USERNAME: ${{ secrets.BIOSIMULATORS_USERNAME }} + GH_ISSUE_TOKEN: ${{ secrets.BIOSIMULATORS_TOKEN }} + steps: + - name: Trigger GitHub action that will build and release the downstream command-line interface and Docker image + run: | + PACKAGE_VERSION="${GITHUB_REF/refs\/tags\/v/}" + WORKFLOW_FILE=ci.yml + + curl \ + -X POST \ + -u ${GH_ISSUE_USERNAME}:${GH_ISSUE_TOKEN} \ + -H "Accept: application/vnd.github.v3+json" \ + https://api.github.com/repos/${DOWNSTREAM_REPOSITORY}/actions/workflows/${WORKFLOW_FILE}/dispatches \ + -d "{\"ref\": \"dev\", \"inputs\": {\"simulatorVersion\": \"${PACKAGE_VERSION}\", \"simulatorVersionLatest\": \"true\"}}" diff --git a/deps/AMICI/.github/workflows/test_install.yml b/deps/AMICI/.github/workflows/test_install.yml index 82ef251f4..b075d8d6f 100644 --- a/deps/AMICI/.github/workflows/test_install.yml +++ b/deps/AMICI/.github/workflows/test_install.yml @@ -75,4 +75,6 @@ jobs: run: | pip3 install -v --user $(ls -t python/sdist/dist/amici-*.tar.gz | head -1) - + - name: Test import + run: | + python -m amici diff --git a/deps/AMICI/.github/workflows/test_matlab.yml b/deps/AMICI/.github/workflows/test_matlab.yml new file mode 100644 index 000000000..d14c0012b --- /dev/null +++ b/deps/AMICI/.github/workflows/test_matlab.yml @@ -0,0 +1,21 @@ +name: Matlab +on: [push, pull_request, workflow_dispatch] + +jobs: + matlab: + name: Matlab + + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@master + - run: git fetch --prune --unshallow + + - run: echo "AMICI_DIR=$(pwd)" >> $GITHUB_ENV + + - name: Install MATLAB + uses: matlab-actions/setup-matlab@v0 + - name: Run script + uses: matlab-actions/run-command@v0 + with: + command: cd matlab; installAMICI; addpath tests; testModels diff --git a/deps/AMICI/.github/workflows/test_performance.yml b/deps/AMICI/.github/workflows/test_performance.yml index 4e78e6ede..a2f463b2f 100644 --- a/deps/AMICI/.github/workflows/test_performance.yml +++ b/deps/AMICI/.github/workflows/test_performance.yml @@ -4,7 +4,7 @@ on: branches: - develop - master - - speedup_reaction_ids + - compile_without_optimization pull_request: branches: @@ -50,12 +50,7 @@ jobs: # import test model - name: Import test model run: | - cd CS_Signalling_ERBB_RAS_AKT \ - && check_time.sh \ - petab_import amici_import_petab -v \ - -n 'CS_Signalling_ERBB_RAS_AKT_petab' \ - -y 'FroehlichKes2018/PEtab/FroehlichKes2018.yaml' \ - --no-compile + check_time.sh petab_import python tests/performance/test.py import - name: "Upload artifact: CS_Signalling_ERBB_RAS_AKT_petab" uses: actions/upload-artifact@v1 @@ -65,29 +60,60 @@ jobs: # install model package - name: Install test model - run: | - check_time.sh install_model \ - python3 CS_Signalling_ERBB_RAS_AKT/CS_Signalling_ERBB_RAS_AKT_petab/setup.py install --user + run: > + check_time.sh install_model tests/performance/test.py compile; + for opt in O0 O1 O2; + do + check_time.sh install_model_${opt} tests/performance/test.py compile_${opt}; + done # run simulations - name: forward_simulation - run: | - check_time.sh forward_simulation tests/performance/test.py forward_simulation + run: > + check_time.sh forward_simulation tests/performance/test.py forward_simulation; + for opt in O0 O1 O2; + do + check_time.sh forward_simulation tests/performance/test.py forward_simulation_${opt}; + done - name: forward_sensitivities - run: | - check_time.sh forward_sensitivities tests/performance/test.py forward_sensitivities + run: > + check_time.sh forward_sensitivities tests/performance/test.py forward_sensitivities; + for opt in O0 O1 O2; + do + check_time.sh forward_sensitivities tests/performance/test.py forward_sensitivities_${opt}; + done - name: adjoint_sensitivities - run: | - check_time.sh adjoint_sensitivities tests/performance/test.py adjoint_sensitivities + run: > + check_time.sh adjoint_sensitivities tests/performance/test.py adjoint_sensitivities; + for opt in O0 O1 O2; + do + check_time.sh adjoint_sensitivities tests/performance/test.py adjoint_sensitivities_${opt}; + done - name: forward_simulation_non_optimal_parameters run: | - check_time.sh forward_simulation_non_optimal_parameters tests/performance/test.py forward_simulation_non_optimal_parameters + check_time.sh forward_simulation_non_optimal_parameters tests/performance/test.py forward_simulation_non_optimal_parameters; + for opt in O0 O1 O2; + do + check_time.sh forward_simulation_non_optimal_parameters tests/performance/test.py forward_simulation_non_optimal_parameters_${opt}; + done - name: adjoint_sensitivities_non_optimal_parameters run: | - check_time.sh adjoint_sensitivities_non_optimal_parameters tests/performance/test.py adjoint_sensitivities_non_optimal_parameters + check_time.sh adjoint_sensitivities_non_optimal_parameters tests/performance/test.py adjoint_sensitivities_non_optimal_parameters; + for opt in O0 O1 O2; + do + check_time.sh adjoint_sensitivities_non_optimal_parameters tests/performance/test.py adjoint_sensitivities_non_optimal_parameters_${opt}; + done - name: forward_steadystate_sensitivities_non_optimal_parameters run: | - check_time.sh forward_steadystate_sensitivities_non_optimal_parameters tests/performance/test.py forward_steadystate_sensitivities_non_optimal_parameters + check_time.sh forward_steadystate_sensitivities_non_optimal_parameters tests/performance/test.py forward_steadystate_sensitivities_non_optimal_parameters; + for opt in O0 O1 O2; + do + check_time.sh forward_steadystate_sensitivities_non_optimal_parameters tests/performance/test.py forward_steadystate_sensitivities_non_optimal_parameters_${opt}; + done - name: adjoint_steadystate_sensitivities_non_optimal_parameters run: | - check_time.sh adjoint_steadystate_sensitivities_non_optimal_parameters tests/performance/test.py adjoint_steadystate_sensitivities_non_optimal_parameters + check_time.sh adjoint_steadystate_sensitivities_non_optimal_parameters tests/performance/test.py adjoint_steadystate_sensitivities_non_optimal_parameters; + for opt in O0 O1 O2; + do + check_time.sh adjoint_steadystate_sensitivities_non_optimal_parameters tests/performance/test.py adjoint_steadystate_sensitivities_non_optimal_parameters_${opt}; + done diff --git a/deps/AMICI/.github/workflows/test_pypi.yml b/deps/AMICI/.github/workflows/test_pypi.yml new file mode 100644 index 000000000..138a93395 --- /dev/null +++ b/deps/AMICI/.github/workflows/test_pypi.yml @@ -0,0 +1,45 @@ +name: PyPI installation +on: + workflow_dispatch: + schedule: + - cron: '48 4 * * *' + +jobs: + pypi: + name: PyPI installation + + strategy: + fail-fast: false + matrix: + python-version: [3.7, 3.8, 3.9] + os: [ubuntu-20.04, macos-latest] + + runs-on: ${{ matrix.os }} + + steps: + - name: apt + run: | + if [[ ${{ matrix.os }} == ubuntu* ]] ; then \ + sudo apt-get update \ + && sudo apt-get install -y \ + g++ \ + libatlas-base-dev \ + libhdf5-serial-dev \ + swig + fi + + - name: homebrew + run: | + if [[ ${{ matrix.os }} == macos* ]] ; then \ + brew install hdf5 swig gcc libomp + fi + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - run: pip install --upgrade pip + - run: pip install -v amici + - run: python -c "from amici import _amici; print(_amici)" + - run: python -m amici diff --git a/deps/AMICI/.github/workflows/test_sbml_semantic_test_suite.yml b/deps/AMICI/.github/workflows/test_sbml_semantic_test_suite.yml index 602683e7a..7dad35396 100644 --- a/deps/AMICI/.github/workflows/test_sbml_semantic_test_suite.yml +++ b/deps/AMICI/.github/workflows/test_sbml_semantic_test_suite.yml @@ -4,6 +4,7 @@ on: branches: - develop - master + - release** pull_request: paths: - .github/workflows/test_sbml_semantic_test_suite.yml @@ -19,9 +20,14 @@ on: jobs: build: name: SBML Semantic Test Suite - runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + cases: ["1 - 250", "251 - 500", "501 - 750", "751 - 1000", + "1000-1250", "1251-1780"] + steps: - uses: actions/checkout@v1 with: @@ -31,7 +37,7 @@ jobs: sudo apt-get update \ && sudo apt-get install -y swig4.0 libatlas-base-dev - run: AMICI_PARALLEL_COMPILE=2 ./scripts/installAmiciSource.sh - - run: AMICI_PARALLEL_COMPILE=2 ./scripts/run-SBMLTestsuite.sh + - run: AMICI_PARALLEL_COMPILE=2 ./scripts/run-SBMLTestsuite.sh ${{ matrix.cases }} - name: "Upload artifact: SBML semantic test suite results" uses: actions/upload-artifact@v1 diff --git a/deps/AMICI/.gitignore b/deps/AMICI/.gitignore index 6871f4448..44053581e 100644 --- a/deps/AMICI/.gitignore +++ b/deps/AMICI/.gitignore @@ -193,3 +193,4 @@ coverage_SBMLSuite.xml Benchmark-Models-PEtab/ +CS_Signalling_ERBB_RAS_AKT/ diff --git a/deps/AMICI/.gitrepo b/deps/AMICI/.gitrepo index 886e9bae5..20b7889ce 100644 --- a/deps/AMICI/.gitrepo +++ b/deps/AMICI/.gitrepo @@ -5,8 +5,8 @@ ; [subrepo] remote = git@github.com:ICB-DCM/AMICI.git - branch = v0.11.13 - commit = b090fbb34ee64e65522cef0a2c0d639e70cfbcfe - parent = 6a39edf26417c415f4c3fc701b33a61be3c08a93 + branch = v0.11.17 + commit = c0377065207b68c881143d203de1f56fd52878b9 + parent = d0bd8c19b9bb5426affdcd8386d893eee7940e80 cmdver = 0.4.1 method = merge diff --git a/deps/AMICI/CHANGELOG.md b/deps/AMICI/CHANGELOG.md new file mode 100644 index 000000000..e39c780db --- /dev/null +++ b/deps/AMICI/CHANGELOG.md @@ -0,0 +1,957 @@ +# Changelog + +## v0.X Series + +### v0.11.17 (2021-05-30) + +Fixes: +* Fix "maybe-uninitialized" compiler warning (#1495) +* Fix substitution of expressions in `drootdt_total (#1512) +* C++: Fix serialization and == operator (#1493) +* C++: Avoid `w` in `root` and `stau` headers (refactor) (#1503) + +Documentation: +* Updated OpenBLAS Windows installation instructions (#1496) +* Updated how-to-cite to Bioinformatics paper (#1499) +* Updated list of papers using AMICI (#1509) + +Other: +* Remove sllh computation from `petab_objective.simulate_petab` (#1498) +* Add __main__.py to Python package to provide info on AMICI installation + via `python -m amici` (#1500) + +### v0.11.16 (2021-04-13) + +Fixes: +* Fixed serialization bug (#1490) + +New: +* Construction of condition specific plist for parameter mappings (#1487, #1488) +* **Add support for error residuals** (#1489) + +### v0.11.15 (2021-03-31) + +Fixes: +* Fixed initial state sensitivities in adjoint preequilibration (#1468) +* Fixed various model import / parameter mapping issues (#1469, #1473, #1475) + +New: +* New AMICI releases will automatically trigger releases at + https://biosimulators.org/simulators/amici/latest +* Transparent logo + +### v0.11.14 (2021-03-16) + +New features: +* **Python import now supports SBML Events** (#1443) +* Implement support for compilation without sensitivities (#1454) + +Fixes: + * Issue #1446: Check whether constant parameters are valid targets (#1450) + * Issue #1422: Fix Steadystate solver failing if preequilibration starts in + steadystate (#1461) + * Issue #1401: Ensure diagnostics variables in ReturnData are always of + expected length (#1438, #1447) + * Fix FIM approximation for parameter dependent sigma (#1441) + * Fix invalid SBML in PEtab/PySB import (#1433) + * Fix: No context for inspect.getouterframes (#1432) + +Documentation: +* Added this CHANGELOG +* Added feature request issue template (#1437) +* Updated reference list (#1430) +* Overhauled experimental conditions notebook (#1460) + +CI: +* Test Matlab interface on GHA (#1451) +* Include componentTags in SBML test suite output (#1462) +* Split SBML semantic test suite into multiple jobs (#1452) +* Fix Crauste ref val, fixes #1458 (#1459) + +Misc: +* Various cleanup (#1465, #1448, #1455) +* Micro-optimize SUNMatrixWrapper::transpose (#1439) +* Remove constant triggers from roots in Heaviside (#1440) + +### v0.11.13 (2021-02-20) + +Breaking changes: +* AMICI requires Python>=3.7 +* Updated package installation (PEP517/518): + Creating source distributions requires https://github.com/pypa/build (#1384) + (but now handles all package building dependencies properly) + +Features: +* More flexible state reinitialization (#1417) + +Updated dependencies: +* Upgrade to sundials 5.7.0 (#1392) + +Fixes: +* Python: account for heaviside functions in expressions (#1382) +* Python: allow loading of existing models in import_petab_problem (#1383) +* Python: Don't override user-provided compiler/linker flags (#1389) +* Python: PEtab import reinitialization fixes (#1417) +* Python: Fix PEtab observables for pysb models (#1390) +* Python: Substitute expressions in event condition expressions (#1404) +* Python: Unspecified initial states in PEtab conditions table default to SBML initial value (#1397) +* C++: Fix timepoint out of bounds access (#1402) +* C++: Fix exported CMake config (#1388) +* Fixed Dockerfile: add python3-venv (#1398, #1408) + +Other: +* Slim exported swig interface (#1425) +* Updated documentation + * Getting started tutorial (#1423) + * List supported SBML test tags (#1428) + * Add AMICI C++/Python/Matlab feature comparison (#1409) + * ... +* Various minor CI improvements +* ... + +### v0.11.12 (2021-01-26) + +Features: +* Add expression IDs and names to generated models (#1374) + +Fixes: +* Raise minimum sympy version to 1.7.1 (Closes #1367) +* Fix species assignment rules in reactions (#1372) +* Fix id vector for DAEs (#1376) + +Docs: +* Update how-to-cite (#1378) + + +### v0.11.11 (2020-12-15) + +#### Python +* Restore support for species references (#1358) +* Add support for noise models in pysb (#1360) +* Proper handling of discontinuities in the ODE rhs (#1352) +* Fix directly calling AMICI from snakemake (#1348 ) +* Extend mathml function support, particularly for numerical arguments (#1357) +* Restore support for sympy 1.6 (#1356) + +#### C++ +* Fix some compiler related warnings (#1349, #1362 ) +* Fix a rare segfault for adjoint sensitivities (#1351) + +#### CI +* Move windows tests to GHA (#1354) +* Pin breathe to 4.24.1 + +#### Docker +* Update ubuntu to 20.04 + +### v0.11.10 (2020-11-30) + +Bugfix release that restores compatibility with sympy 1.7 + +### v0.11.9 (2020-11-29) + +#### Python +* General improvements to SBML import (#1312, #1316, #1315, #1322 , #1324 #1333, #1329) +* Small bugfixes and improvements (#1321 ) +* Improve derivative computation for instances of `power` (#1320 ) + +#### C++ +* Fix FIM and residual computation for models with parameter dependent sigma. (#1338) +* Disable chi2/residual/FIM computation for non-gaussian objective functions. (#1338) +* Bugfix for integration failure during adjoint solve (#1327) + +#### Doc +* Update references (#1331, #1336) + +#### CI +* Update OpenBLAS for windows (#1334) + +### v0.11.8 (2020-10-21) + +#### Python +* Fix pysb-petab support (#1288) +* Fix ExpData constructor overloading (#1299) +* Fix support for positivity enforcement (#1306) +* **Refactor SBML import, adds support for parameter rate rules and initial assignments** (#1284, #1296, #1304) +* Improve model generation for models with many parameters (#1300) +* Add support for PEtab based synthetic data generation (#1283) + +#### C++ +* Make HDF5 an optional dependency (#1285) + +#### Doc +* General Improvements to Documentation (#1289, #1291, #1292, #1293, #1294, #1286, #1277, #1281) + +#### CI +* Add python 3.9 support test (#1282) +* Allow manual triggering of GitHub actions (#1287) +* Remove appveyor config (#1295) +* Update GHA env and path management (#1302) + +### v0.11.7 (2020-09-22) + +#### Python +* Improve and extend available objective functions (#1235) +* Fix processing of compartment definitions (#1223) +* Fix replacement of reserved symbols (#1265) +* Use Hierarchical Derivatives for Expressions (#1224, #1246) +* Fix duplicate running of swig (#1216) +* Overload python interface functions for amici.{Model,Solver,ExpData} and amici.{Model,Solver,ExpData}Ptr (#1271) + +#### C++ +* Fix and extend use of sparse matrix operations (#1230, #1240, #1244, #1247, #1271) +* **Fix application of maximal number of steps**, MaxNumStep parameter now limit total number of steps, not number of steps between output times. (#1267) + +#### Doc +* Move all Documentation to RTD (#1229, #1241) +* General Improvements to Documentation (#1225, #1227, #1219, #1228, #1232, #1233, #1234, #1237, #1238, #1239, #1243, #1253, #1255, #1262) + +#### CI +* Better check for doc building (#1226) +* Add more gradient checks (#1213) +* Update GHA to Ubuntu 20.04 (#1268) + +### v0.11.6 (2020-08-20) + +#### Python +* Bugfix for piecewise functions (#1199) +* Refactor swigging - generate one single wrapper (#1213) + +#### C++ +* Fix warnings: account for zero indexing in nan/inf error (#1112) + +#### Doc +* Update Windows build instructions (#1200, #1202) +* Update README: Projects using AMICI (#1209) +* Add CODE_OF_CONDUCT.md (#1210) +* Update documentation for Python interface (#1208) + +#### CI +* Create sdist on GHA using swig4.0.1 (#1204) (Fixing broken pypi package) +* Fix links after repository move +* Speed-up swig build: disable all languages except python (#1211) +* Fix doc generation on readthedocs (#1196) + + +### v0.11.5 (2020-08-07) + +#### General +* Move repo to new organization (#1193) +* Update Bibliography + +#### Python +* Fix bug for energyPySB models (#1191) + +#### CI +* Fix release deployment (#1189) + +### v0.11.4 (2020-08-06) + +#### Python +* Skip unnecessary expressions in pysb models (#1185) +* MSVC compiler support (this time for real... #1152) + +#### CI +* Implement MSVC tests (#1152) +* Rename and group GitHub actions (#1186) +* Fix release deployment (#1186) + +### v0.11.3 (2020-08-06) + +#### Python +* Fix simplification for pysb models (#1168) +* Pass verbosity flags to pysb network generation (#1173) +* Enable experimental pysb-petab support (#1175) +* Add installation instructions for Fedora (#1177) +* Implement support for SBML rate-references (#1180) + +#### C++ +* Refactoring (#1162, #1163) + +#### CI +* Move majority of tests to Github Actions (#1166, #1160) +* Improve reporting of skipped tests in SBML testsuite (#1183) + +### v0.11.2 (2020-07-17) + +#### Python +* Speed up model import, compilation (#1123, #1112) +* Improve/Add steady-state solver documentation (#1102) +* Improve extension import (#1141) +* Bugfixes SBML import (#1135, #1134, #1145, #1154) +* Fixed issue that prevented simplification (#1158) + +#### C++ +* Bugfixes (#1121, #1125, #1131, #1132, #1136) +* Enable openMP by default (#1118) +* Improve memoy footprint for simulations with replicates (#1153) +* Improve steady-state solver and add option to to adjoint-steadystate hybrid (#1143, #1099, #1129, #1146) + +#### CI +* Store build artifacts from github actions (#1138) + +### v0.11.1 (2020-06-05) + +#### Python +* Upgrade to sympy 1.6.0, which is now required minimum version (#1098, #1103) +* Speed up model import + * Speed-up computation of sx0, reduce file size (#1109) + * Replace terribly slow sympy.MutableDenseMatrix.is_zero_matrix by custom implementation (#1104) +* speedup dataframe creation in `get*AsDataFrame` (#1088) +* Allow caching edatas for simulate_petab (#1106) +* Fix wrong deprecation warning (Fixes #1093) +* Fix segmentation faults in NewtonSolver under certain conditions (#1089, #1090, #1097) +* fix wrong power function call in `unscale_parameter` (#1094) +* Fix MathML conversion (#1086) +* Fix deepcopy of SymPy objects (#1091) + +#### Matlab +* handle empty rdata->{pre|post}eq_numlinsteps (Closes #1113), which previously made the matlab interface unusable +* Fix generation of compileMexFile.m for matlab compilation of python code (#1115) + +#### C++ +* Reduce memory requirements and speedup compilation of large models (#1105) +* Place generated code into own namespace (#937) (#1112) +* Fix several msvc compiler warnings (#1116) (Note that MSVC support is still experimental) **breaking change for users of C++ interface** +* Fix swig warning: ensure base class ContextManager is known before use (Fixes #1092) (#1101) + +#### CI +* Don't install/run valgrind on travis CI (done with github actions… (#1111) + + +### v0.11.0 (2020-05-10) + +Python: + +- **Implement support for variable compartments (#1036)** +- Better handling of constant species (#1047) +- **Better handling of C++ enums, this makes `amici.SensitivityMethod_forward` available as `amici.SensitivityMethod.forward` (#1042)** +- Improve installation routines (#1055, #1056, #1058, #1076) +- Add option to reduce memory usage (#1044) +- **Fix handling of symbolic expressions in nested rules (#1081, 1069)** + +Library: + +- Update Sundials to 5.2.0 (#1039) +- Update SuiteSparse to 5.4.0 (#1040) +- Refactor use of ReturnData, now completely created post-hoc (#1002) +- **Fix propagation of reinitialization in ExpData constructor (#1041)** +- **Fix issue where InternalSensitivityParameter was sometimes not set (#1075)** +- **Fix or disable certain combinations of equilibraition, presimulation and adjoint sensitivity analysis** + +CI: + +- Move from Codacy to Sonarcloud (#1065) +- Run SBML Testsuite when appropriate (#1058) + +### v0.10.21 (2020-04-04) + +Library: +* Fix: Handle paths with blanks in build scripts +* Feature: Add function to write amici::Solver settings to HDF5 (#1023) +* Fix: typehints (#1018, #1022) +* Refactor: Move creation of parameter mapping for objective<->simulation to classes (#1020) + +CI: +* Refactor: Cleanup and reorganize tests (#1026) +* Fix: benchmark problem test should fail on missing files (Closes #1015) + + +### v0.10.20 (2020-03-18) + +* Fixed (re)initialization of sensitivities if ExpData::fixedParametersPreequilibration is set (#994) +* Fixed sensitivities for parameters in sigma expressions for Python/SBML in case provided expression was not just a single parameter ID +* Enable parallel compilation of model files from Python (#997) based on AMICI_PARALLEL_COMPILE enviroment variable +* Fixed computation of log-likelihood for log10-normal distributed noise +* Added `reinitializeFixedParameterInitialStates` to ExpData (#1000) (**breaking change**: overrides settings in `amici::Model`) +* Python model import now verifies that chosen model name is a valid identifier (Closes #928) +* Made w available in ReturnData (Closes #990) (#992) +* Fixed setting of log level when passing boolean values to verbose (#991) +* Documentation now on ReadTheDocs https://amici.readthedocs.io/en/ +* Use proper state/observable names in plotting functions (#979) +* PEtab support: + * Adapt to most recent PEtab (0.1.5) + * Extended support for import of PEtab models + * Added support for computing cost function based on PEtab problem + * Implemented handling of species in condition table + * petab_import.import_model now provides reproducible parameter list (Closes #976) + * Fix python import error in import_petab_problem: Add absolute paths to python path, invalidate caches and reload (#970) + * Added example notebook +* CI: PEtab test suite integrated in CI workflow +* Added AMICI dockerfile and image deployment to dockerhub (#948) +* Removed mention of 'mex' in warning/error ids (#968) +* More informative errors on SWIG interface import failures (#959) + +### v0.10.19 (2020-02-13) + +Python: +* Fix logo display on pypi +* Fix deadlocks in multithreaded python environments when using openMP parallelization + +Matlab: +* Fix compilation errors due to switch to C++14 + +### v0.10.18 (2020-02-11) + +General: +* AMICI now comes with a logo +* implement getName function for models +* Updated documentation / examples + +Python: +* Enable MSVC compilation of Python extensions (#847) +* Always recompile clibs and extensions (Closes #700) +* Extended PEtab support (Running +* enable multithreading in swig (#938) +* Fixes pysb (#902) (#907) + +C++ +* Build optimized AMICI and sundials by default (Closes #934) + +Matlab: +* Fix(matlab) Compile CalcMD5 on demand (Fixes #914) +* Don't pass empty include strings to mex +* Fix Matlab compilation error if AMICI or model path contains blanks + +CI: +* Running additional test models + +... and various minor fixes/updates + +### v0.10.17 (2020-01-15) + +- **added python 3.8 support, dropped python 3.6 support** (#898) +- Added logging functionality (#900) +- Fixes PySB import (#879, #902) +- Fixes symbolic processing (#899) +- Improved build scripts (#894, +- Improved petab support (#886, #888, #891) +- CI related fixes (#865, #896) + +### v0.10.16 (2019-12-11) + +* **Sparsify dwdp to reduce computation time for adjoints (#858)** +* Fix(matlab) update example name example_dae_events->example_calvetti (Closes #866) +* Fix nullptr deferencing for simulations with events when no measurements are provided (Fixes #866) +* Fix accessing empty vector during adjoint state event update (Closes #866) +* Fix pysb_import (fixes #878) + + +### v0.10.15 (2019-12-03) + +Bugfix release due to incorrect sensitivities w.r.t. sigmas introduced in 0.10.14. + +No other changes. + +### v0.10.14 (2019-12-02) + +**NOTE: For Python-imported SBML-models this release may compute incorrect sensitivities w.r.t. sigma. Bug introduced in 0.10.14, fixed in 0.10.15.** + +Python: + +* Don't require use of ModelPtr.get to call ExpData(Model) +* Fix import in generated model Python package +* Setup AMICI standalone scripts as setuptools entrypoints +* Simplify symbolic sensitivity expressions during Python SBML import + Fixes Infs in the Jacobian when using Hill-functions with states of 0.0. +* Extended Newton solver #848 + The changes that allow performing Newton tests from the paper: + G. T. Lines, Ł. Paszkowski, L. Schmiester, D. Weindl, P. Stapor, and J. Hasenauer. Efficient computation of steady states in large-scale ODE models of biochemical reaction networks. accepted for Proceedings of the 8th IFAC Conference on Foundations of Systems Biology in Engineering (FOSBE), Valencia, Spain, October 2019. +* Use SWIG>=4.0 on travis to include PyDoc in sdist / pypi package (#841) +* **Fix choice of likelihood formula; failed if observable names were not equal to observable IDs** +* Fix(sbml-import) Compartment IDs in right-hand side of Rules are not replaced and lead to undefined identifiers in c++ files +* Fix invalid logging level +* Speed up sympy simplification (#871) + +C++: + +* Performance: Avoid unnecessary repeated function calls for SUNMatrixWrapper dimensions +* Add AmiciApplication class as context for handling so far global settings. + This allows for example setting custom logging functions for concurrent AMICI + runs, e.g. in multi-thread applications (Closes #576). + +Misc: + +* Setup performance test on github actions (#853) +* Update documentation and FAQ for CBLAS requirement and others +* Update reference list + +### v0.10.13 (2019-10-09) + +* BREAKING CHANGE: Renaming {get|set}tNewtonPreequilibration to {get|set}Preequilibration (Closes #720) +* Make wurlitzer non-optional requirement for AMICI python package (Fixes missing AMICI errors when running from jupyter notebooks) +* Compute initial state for Model::getInitialStates if not already set (Fixes #818) +* Make swig generate pydoc comments from doxygen comments #830 (Closes #745) to provide Python docstrings for C++ wrapper functions +* feature(cmake) Add option to disable compiler optimizations for wrapfunctions.cpp (Fixes #828) (#829) +* Change SBML test suite to pytest to allow for parallel test execution… (#824) +* Fix(cmake): -E option is not available in all sed versions. Neither is the equivalent -r. Use --regexp-extended instead (Closes #826) +* Refactor(python) Move PEtab import code from command line script… (#825) +* Fix(core) Fix regular expressions for intel compiler (Closes #754) (#822) +* Update workflow figure to include PySB (Closes #799) +* Fix compiler warnings + +### v0.10.12 (2019-09-28) + +* Fix handling of species specified in PEtab condition table (#813) +* Fix some Visual C++ issues, update cppcheck handling, cleanup (VisualC++ still not fully supported) +* Minor fixups (#801) +* Create SBML test suite result files for upload to http://sbml.org/Facilities/Database/ (#798) + + +### v0.10.11 (2019-08-31) + +* Fixed setting initial conditions for preequilibration (#784) +* Fixed species->parameter conversion during PEtab import (#782) +* Set correct Matlab include directories in CMake (#793) +* Extended and updated documentation (#785, #787) +* Fix various SBML import issues +* Run SBML test suite using github actions instead of travisCI (#789) + +### v0.10.10 (2019-08-07) + +* Simplify/fix AMICI installation + * If available use environment modules to detect dependencies + + * Add SWIG installation script + +* Update list of publication +* Update documentation + * Update doc for SWIG build and custom SWIG location. + * Add AMICI interface overview / workflow figure and show in README + * Document environment variables for model/core compilation (Closes #737) + +* Added handling of abs function, since there seem to be problems with case sensitivity (#713) Closes #770 + +Detaills: + * cmake: Use package_ROOT environment variables + * fix(cmake) Fix finding version.txt + * cmake: Auto-detect loaded MKL environment module + * cmake: Use new FindPython3 modules where possible + * fix(python) Restore python3.6 compatibility + * Inside venv, use pip instead of pip3 which should point to the correct version + * fix(python) Workaround for missing ensurepip during venv creation [ci skip] + * feature(python) Use MKL from environment modules to provide cblas + * fix(python) Fix define_macros not being passed to setuptools for Extension + * fix(python) Fix define_macros not being passed to setuptools for clibs + * Do not always add 'cblas' library since users may want to override that by a cblas-compatible library with a different name (closes #736) + * Update HDF5 path hints; use shared library if static is not available. + * Check for HDF5_BASE from environment module + * Fix system-dependent sundials library directory (Fixes #749) (#750) + * Handle OSTYPE==linux in scripts/buildBNGL.sh (Fixes #751) + * Add SWIG download and build script + * Improve finding swig executable and allow user override via SWIG environment variable + * Provide installation hints if no SWIG found (Closes #724) + * Allow overriding cmake executable with environment variables in build scripts (Closes #738) + + +### v0.10.9 (2019-07-24) + +Fixup for missing version bump in v0.10.8 release. No code changes compared to v0.10.8. + +### v0.10.8 (2019-07-24) + +Changes in this release: + +All: +- Updated / extended documentation +- Fix reuse of `Solver` instances (#541) + +C++: +- Check for correct AMICI version for model in CMake +- Add reporting of computation times (#699) + +Python: +- Fix manifest file (#698) +- Fix initial amounts/concentrations in SBML import + +... and various other minor fixes/improvements + +### v0.10.7 (2019-05-01) + +Python +* fix unset noise distribution when automatically generating observables in case None are passed (#691) + +### v0.10.6 (2019-04-19) + +C++ +- Add SuperLUMT support (#681) +- Sparsified dJydy (#686) +- Enabled support of impulse-free events for DAE models (#687) - thanks to Sebastien Sten for providing a testcase for this + +Python +- Enabled support for piecewise functions in SBML import (#662) +- Fix numeric type when constructing ExpData from Dataframes (#690) +- Fix dynamic override in PETab + + +### v0.10.5 (2019-04-08) + +Bugfix release + +Doc +- Update documentation of Windows installation + +C++ +- Fix missing source files in CMakeLists.txt (#658) +- Set CMake policies to prevent warnings (Closes #676) (#677) +- Start using gsl::span instead of raw pointers (#393) (#678) + +Python +- PySB parsing fix (#669) +- Fix failure to propagate BLAS_LIBS contents (#665) +- Require setuptools at setup (#673) +- Updated PEtab import to allow for different noise models + + +### v0.10.4 (2019-03-21) + +Features / improvements: + +* Implement ReturnData and ExpData wrappers as more efficient views (#657) +* Add list of references using AMICI (#659) +* Custom llh (normal/laplace, lin/log/log10) (#656) + +Bugfixes: + ++ Speedup and fix travis build + +### v0.10.3 (2019-03-13) + +Features / improvements: + +- adds the option for early termination on integration failures for runAmiciSimulations +- improve runtime of `SUNMatrixWrapper::mutliply` +- expose finite difference routines in public API +- enable parallel compilation of clib source files + +Bugfixes: + +- fixed symbolic processing for unreleased pysb features + +### v0.10.2 (2019-03-07) + +Features / improvements: + +- extended `ExpData` interface to allow for condition specific parameters, parameter scales, parameter lists, initial conditions and initial condition sensitivities. + +Bugfixes: + +- fixed output values of `ReturnData::x_ss` and `ReturnData::sx_ss` + +### v0.10.1 (2019-03-04) + +* travis-ci.com migration +* fix problem with has{variable} functions +* allow to import sbml model from string, not only file + +### v0.10.0 (2019-03-01) + +Features / improvements: + +- updated sundials to 4.1.0 +- updated SuiteSparse to 5.4.0 +- added generic implementations for symbolic expressions that were sparse matrix vector products + +Bugfixes: + +- fixed return value of `rz` when no data is provided. + +### v0.9.5 (2019-02-26) + +Features / improvements: + +- allow python installations without compilation of c++ extension +- improvements to ExpData <-> pandas.DataFrame interface +- allow generation of matlab models from python +- implement CLI interface for PEtab +- improve computation time for conservation laws from pysb import + +Bugfixes: + +- Fix sign in undamped Newton step. + +Maintenance: + +- use newer CI images + +### v0.9.4 (2019-02-11) + +Minor fixes only: +- fix(core) Get solver diagnostics for first(last) timepoint (#588) (Closes #586) +- fix(ci) Fix autodeploy (Closes #589) + +### v0.9.3 (2019-02-07) + +**CRITICAL FIXES** +- **fix(python) fix symbolic computations for adjoint (#583)** + +**Features** +- feature(python) Check for matching AMICI versions when importing model (Closes #556). Set exact AMICI version as model package requirement. +- feature(core) Add option to rethrow AMICI exception (Closes #552) +- feature(python) Redirect C/C++ output in stdout is redirected (e.g. in ipython notebooks) (Closes #456) + +**Minor fixes** +- fix(python) Fix doc and rename sys_pipes to something more meaningful +- fix(ci) Fix premature exit of scripts/runNotebook.sh +- fix(deploy) Update pyenv shims to find twine + + + +### v0.9.2 (2019-01-30) + +Bugfixes: + +- fixes a critical bug in the newton solver +- fixes multiple bugs in sbml import for degenerate models, empty stoichiometry assignments and conversion factors +- improved error messages for sbml import +- #560 +- #557 +- #559 + + +### v0.9.1 (2019-01-21) + +Features / improvements: + +- make pure steadystate results available as `rdata['x_ss']` and `rdata['sx_ss'] ` +- add option to specify integration tolerances for the adjoint problem via `atolB` and `rtolB` + +Bugfixes: + +- improved conservation law identification to also account for constant species. +- fixed a bug where simulation results were written into results of the second newton solver attempt +- fixed an openMP related warning + +Maintenance: + +- attempt to fix automatic deploy to pypi via travis + +### v0.9.0 (2019-01-18) + +Features / improvements: + +- Allow computation and application of conservation laws for pysb importet models. This enables use of NewtonSolver for preequilibration for models where it was previously not possible. +- Use `klu_refactor` in the sparse Newton solver instead of always using `klu_factor` and only perform symbolic factorization once (#421) +- Allow more detailed finiteness checks (#514) + +Bugfixes: + - #491 + +Maintenance: +- Several improvements to travis log sizes and folding +- Use default copy constructor for Model by implementing class wrappers for sundials matrix types (#516) +- Reenable run of SBML testsuite + + +### v0.8.2 (2019-01-07) + +Features / improvements: +* Speedup symbolic processing for ODE generation in python + +Bugfixes: +* Fix(python) Add missing deepcopy (introduced in 6847ba675f2088854db583199b8754aaa6e01576) +* Fix(core) Prevent parameter scaling length mismatch (#488) +* Fix(python) Set distutils dependency to current version to fix +* fix(python) add symlink to version.txt to be included in package + +Backwards-compatibility: +* Replace 'newline' by literal to restore Please use v0.7.0 + +### v0.5.0 (2018-03-15) + +Main new features are: + +- Reimplemented support for DAE equations +- Added newton solver for steady state calculation and preequilibration +- Better caching for recompilation of models +- Blas support to allow compilation of large models with many observables +- Improved SBML support +- Added c++ interface +- Added support for second order adjoint computation + +- Rewrote large parts of the code as proper c++11 code to allow easier code maintanance +- Substantially extended testing in continuous integration to assure code quality + +### v0.4.0 (2017-05-15) + +* First citable version of AMICI (via zenodo integration). +* Better support for standalone compilation +* Improved SBML import scripts +* General Code Cleanup + +### v0.3.0 (2016-09-05) + +This update comes with many improvements, bug fixes and several new features. Most notably: + +1) AMICI should now run on older versions of MATLAB (back to R2014a) +2) AMICI now compiles using older versions of Visual Studio +3) AMICI now also supports second order adjoint sensitivities (full (via the o2flag = 1 and as a vector product via o2flag = 2) +4) AMICI now supports more SBML, SBML v2 and rate rules + + +### 0.2.1 (2016-05-09) + +Bugfix release. This release also includes some changes that should improve the performance on the new R2016a release of MATLAB. + + +### v0.2 (2016-03-17) + +This update comes with many improvements to the computation time for both compilation and simulation. Moreover several new features were included: + +1) Hessian Vector products for second order forward sensitivities +2) Correct treatment of parameter/state dependent discontinuities for both forward and adjoint sensitivities + + +### v0.1 (2015-11-05) + +This is the initial release of the toolbox diff --git a/deps/AMICI/INSTALL.md b/deps/AMICI/INSTALL.md index 2d4153502..61140d2e2 100755 --- a/deps/AMICI/INSTALL.md +++ b/deps/AMICI/INSTALL.md @@ -231,14 +231,14 @@ This will download openBLAS and compile it, creating You will also need to define two environment variables: BLAS_LIBS="/LIBPATH:C:/BLAS/lib openblas.lib" - BLAS_CFLAGS="/IC:/BLAS/OpenBLAS-v0.3.12/OpenBLAS-0.3.12" + BLAS_CFLAGS="/IC:/BLAS/OpenBLAS-0.3.12/OpenBLAS-0.3.12" One way to do that is to run a PowerShell script with the following commands: - [System.Environment]::SetEnvironmentVariable("BLAS_LIBS", "/LIBPATH:C:\BLAS\lib openblas.lib", [System.EnvironmentVariableTarget]::User) - [System.Environment]::SetEnvironmentVariable("BLAS_LIBS", "/LIBPATH:C:\BLAS\lib openblas.lib", [System.EnvironmentVariableTarget]::Process) - [System.Environment]::SetEnvironmentVariable("BLAS_CFLAGS", "-IC:\BLAS\OpenBLAS-v0.3.12\OpenBLAS-0.3.12", [System.EnvironmentVariableTarget]::User) - [System.Environment]::SetEnvironmentVariable("BLAS_CFLAGS", "-IC:\BLAS\OpenBLAS-v0.3.12\OpenBLAS-0.3.12", [System.EnvironmentVariableTarget]::Process) + [System.Environment]::SetEnvironmentVariable("BLAS_LIBS", "/LIBPATH:C:/BLAS/lib openblas.lib", [System.EnvironmentVariableTarget]::User) + [System.Environment]::SetEnvironmentVariable("BLAS_LIBS", "/LIBPATH:C:/BLAS/lib openblas.lib", [System.EnvironmentVariableTarget]::Process) + [System.Environment]::SetEnvironmentVariable("BLAS_CFLAGS", "-IC:/BLAS/OpenBLAS-0.3.12/OpenBLAS-0.3.12", [System.EnvironmentVariableTarget]::User) + [System.Environment]::SetEnvironmentVariable("BLAS_CFLAGS", "-IC:/BLAS/OpenBLAS-0.3.12/OpenBLAS-0.3.12", [System.EnvironmentVariableTarget]::Process) The call ending in `Process` sets the environment variable in the current process, and it is no longer in effect in the next process. The call ending in `User` is permanent, and takes effect the next time the user logs on. diff --git a/deps/AMICI/README.md b/deps/AMICI/README.md index 4f37d0680..1b05c7050 100644 --- a/deps/AMICI/README.md +++ b/deps/AMICI/README.md @@ -33,6 +33,8 @@ constrained optimization problems. PyPI version + + PyPI installation Build Status @@ -127,14 +129,20 @@ If you used AMICI in your work, we are happy to include your project, please let us know via a Github issue. When using AMICI in your project, please cite -* Fröhlich, F., Weindl, D., Schälte, Y., Pathirana, D., Paszkowski, Ł., Lines, G.T., Stapor, P. and Hasenauer, J., 2020. - AMICI: High-Performance Sensitivity Analysis for Large Ordinary Differential Equation Models. arXiv preprint [arXiv:2012.09122](https://arxiv.org/abs/2012.09122). +* Fröhlich, F., Weindl, D., Schälte, Y., Pathirana, D., Paszkowski, Ł., Lines, G.T., Stapor, P. and Hasenauer, J., 2021. + AMICI: High-Performance Sensitivity Analysis for Large Ordinary Differential Equation Models. Bioinformatics, btab227, + [DOI:10.1093/bioinformatics/btab227](https://doi.org/10.1093/bioinformatics/btab227). ``` @article{frohlich2020amici, title={AMICI: High-Performance Sensitivity Analysis for Large Ordinary Differential Equation Models}, author={Fr{\"o}hlich, Fabian and Weindl, Daniel and Sch{\"a}lte, Yannik and Pathirana, Dilan and Paszkowski, {\L}ukasz and Lines, Glenn Terje and Stapor, Paul and Hasenauer, Jan}, - journal={arXiv preprint arXiv:2012.09122}, - year={2020} + journal = {Bioinformatics}, + year = {2021}, + month = {04}, + issn = {1367-4803}, + doi = {10.1093/bioinformatics/btab227}, + note = {btab227}, + eprint = {https://academic.oup.com/bioinformatics/advance-article-pdf/doi/10.1093/bioinformatics/btab227/36866220/btab227.pdf}, } ``` diff --git a/deps/AMICI/docker/README.md b/deps/AMICI/docker/README.md index ec7ecc677..97c072254 100644 --- a/deps/AMICI/docker/README.md +++ b/deps/AMICI/docker/README.md @@ -12,4 +12,4 @@ cd docker && docker build -t $USER/amici:latest . ## Published images AMICI docker images are regularly published to -https://hub.docker.com/layers/dweindl/amici/. +https://hub.docker.com/r/dweindl/amici. diff --git a/deps/AMICI/documentation/CI.md b/deps/AMICI/documentation/CI.md index de86b0bfb..93fd106dc 100644 --- a/deps/AMICI/documentation/CI.md +++ b/deps/AMICI/documentation/CI.md @@ -1,6 +1,7 @@ # Continuous integration (CI) and tests -AMICI uses a continuous integration pipeline running on https://travis-ci.org/. +AMICI uses a continuous integration pipeline running via +https://github.com/features/actions. This includes the following steps: - Checking existence and format of documentation @@ -67,7 +68,7 @@ This code is to be updated whenever `amici::Model` changes. ### Regenerating C++ code of the test models -Regeneration of the model code must done whenever `amici::Model` or +Regeneration of the model code has to be done whenever `amici::Model` or the Matlab model import routines change. This is done with @@ -89,7 +90,7 @@ replace `tests/cpputest/expectedResults.h5` by Before replacing the test results, confirm that only expected datasets have changed, e.g. using - h5diff -v -r 1e-8 tests/cpputest/expectedResults.h5 tests/cpputest/writeResults.h5.bak | less + h5diff -v --relative 1e-8 tests/cpputest/expectedResults.h5 tests/cpputest/writeResults.h5.bak | less ## Adding/Updating tests diff --git a/deps/AMICI/documentation/ExampleExperimentalConditions.ipynb b/deps/AMICI/documentation/ExampleExperimentalConditions.ipynb new file mode 120000 index 000000000..269610ab4 --- /dev/null +++ b/deps/AMICI/documentation/ExampleExperimentalConditions.ipynb @@ -0,0 +1 @@ +../python/examples/example_presimulation/ExampleExperimentalConditions.ipynb \ No newline at end of file diff --git a/deps/AMICI/documentation/GettingStarted.ipynb b/deps/AMICI/documentation/GettingStarted.ipynb index a4036aba8..c1bc4df6b 100644 --- a/deps/AMICI/documentation/GettingStarted.ipynb +++ b/deps/AMICI/documentation/GettingStarted.ipynb @@ -185,7 +185,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This notebook only explains the basics of AMICI simulations. In general, AMICI simulations are highly customizable and can also be used to simulate sensitivities. The [ExampleSteadystate](https://amici.readthedocs.io/en/latest/ExampleSteadystate.html) notebook in this folder gives more detail about the model employed here and goes into the basics of sensitivity analysis. The [ExampleEquilibrationLogic](https://amici.readthedocs.io/en/latest/ExampleEquilibrationLogic.html) notebook, builds on this by using a modified version of this model to give detailed insights into the methods and options to compute steady states before and after simulations, as well as respective sensitivities. The [Presimulation example](https://amici.readthedocs.io/en/latest/model_presimulation.html) notebook, goes into the details of how even more complex experimental setups, such as addition of drugs at predefined timepoints, can be simulated in AMICI. Finally, the [petab](https://amici.readthedocs.io/en/latest/petab.html) notebook explains how standardized definitions of experimental data and conditions in the [PEtab](https://github.com/PEtab-dev/PEtab) format can be imported in AMICI." + "This notebook only explains the basics of AMICI simulations. In general, AMICI simulations are highly customizable and can also be used to simulate sensitivities. The [ExampleSteadystate](https://amici.readthedocs.io/en/latest/ExampleSteadystate.html) notebook in this folder gives more detail about the model employed here and goes into the basics of sensitivity analysis. The [ExampleEquilibrationLogic](https://amici.readthedocs.io/en/latest/ExampleEquilibrationLogic.html) notebook, builds on this by using a modified version of this model to give detailed insights into the methods and options to compute steady states before and after simulations, as well as respective sensitivities. The [ExampleExperimentalConditions example](https://amici.readthedocs.io/en/latest/ExampleExperimentalConditions.html) notebook, goes into the details of how even more complex experimental setups, such as addition of drugs at predefined timepoints, can be simulated in AMICI. Finally, the [petab](https://amici.readthedocs.io/en/latest/petab.html) notebook explains how standardized definitions of experimental data and conditions in the [PEtab](https://github.com/PEtab-dev/PEtab) format can be imported in AMICI." ] } ], diff --git a/deps/AMICI/documentation/about.rst b/deps/AMICI/documentation/about.rst index 3533b31f7..468c98c8a 100644 --- a/deps/AMICI/documentation/about.rst +++ b/deps/AMICI/documentation/about.rst @@ -42,7 +42,6 @@ Features * Pre-equilibration and pre-simulation conditions * Support for `discrete events and logical operations `_ - (Matlab-only) Interfaces & workflow ====================== @@ -57,7 +56,8 @@ simulation. .. image:: gfx/amici_workflow.png :alt: AMICI workflow -The functionality of the Python, Matlab and C++ interfaces slightly differ, as shown in the following table: +The functionality of the Python, Matlab and C++ interfaces slightly differ, +as shown in the following table: .. list-table:: :header-rows: 1 @@ -96,8 +96,8 @@ The functionality of the Python, Matlab and C++ interfaces slightly differ, as s - no - yes * - Events - - no - - no + - yes + - yes - yes * - :term:`preequilibration` - yes diff --git a/deps/AMICI/documentation/amici_refs.bib b/deps/AMICI/documentation/amici_refs.bib index 8bcdbb634..6803ee7e6 100644 --- a/deps/AMICI/documentation/amici_refs.bib +++ b/deps/AMICI/documentation/amici_refs.bib @@ -549,7 +549,7 @@ @Article{LinesPas2019 @Article{VillaverdeRai2019, author = {Alejandro F. Villaverde and Elba Raimúndez and Jan Hasenauer and Julio R. Banga}, journal = {IFAC-PapersOnLine}, - title = {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).}, + title = {A Comparison of Methods for Quantifying Prediction Uncertainty in Systems Biology}, year = {2019}, issn = {2405-8963}, note = {8th Conference on Foundations of Systems Biology in Engineering FOSBE 2019}, @@ -594,34 +594,6 @@ @Article{WangSta2019 url = {http://www.sciencedirect.com/science/article/pii/S2405896319321433}, } -@Article{Staedter2020.09.03.268276, - author = {St{\"a}dter, Philipp and Sch{\"a}lte, Yannik and Schmiester, Leonard and Hasenauer, Jan and Stapor, Paul L.}, - journal = {bioRxiv}, - title = {Benchmarking of numerical integration methods for ODE models of biological systems}, - year = {2020}, - abstract = {Ordinary differential equation (ODE) models are a key tool to understand complex mechanisms in systems biology. These models are studied using various approaches, including stability and bifurcation analysis, but most frequently by numerical simulations. The number of required simulations is often large, e.g., when unknown parameters need to be inferred. This renders efficient and reliable numerical integration methods essential. However, these methods depend on various hyperparameters, which strongly impact the ODE solution. Despite this, and although hundreds of published ODE models are freely available in public databases, a thorough study that quantifies the impact of hyperparameters on the ODE solver in terms of accuracy and computation time is still missing. In this manuscript, we investigate which choices of algorithms and hyperparameters are generally favorable when dealing with ODE models arising from biological processes. To ensure a representative evaluation, we considered 167 published models. Our study provides evidence that most ODEs in computational biology are stiff, and we give guidelines for the choice of algorithms and hyperparameters. We anticipate that our results will help researchers in systems biology to choose appropriate numerical methods when dealing with ODE models.Competing Interest StatementThe authors have declared no competing interest.}, - doi = {10.1101/2020.09.03.268276}, - elocation-id = {2020.09.03.268276}, - eprint = {https://www.biorxiv.org/content/early/2020/09/04/2020.09.03.268276.full.pdf}, - publisher = {Cold Spring Harbor Laboratory}, - timestamp = {2020-09-30}, - url = {https://www.biorxiv.org/content/early/2020/09/04/2020.09.03.268276}, -} - -@Article{RaimundezDud2020, - author = {Raim{\'u}ndez, Elba and Dudkin, Erika and Vanhoefer, Jakob and Alamoudi, Emad and Merkt, Simon and Fuhrmann, Lara and Bai, Fan and Hasenauer, Jan}, - journal = {medRxiv}, - title = {COVID-19 outbreak in Wuhan demonstrates the limitations of publicly available case numbers for epidemiological modelling.}, - year = {2020}, - abstract = {Epidemiological models are widely used to analyse the spread of diseases such as the global COVID-19 pandemic caused by SARS-CoV-2. However, all models are based on simplifying assumptions and on sparse data. This limits the reliability of parameter estimates and predictions. In this manuscript, we demonstrate the relevance of these limitations by performing a study of the COVID-19 outbreak in Wuhan, China. We perform parameter estimation, uncertainty analysis and model selection for a range of established epidemiological models. Amongst others, we employ Markov chain Monte Carlo sampling, parameter and prediction profile calculation algorithms. Our results show that parameter estimates and predictions obtained for several established models on the basis of reported case numbers can be subject to substantial uncertainty. More importantly, estimates were often unrealistic and the confidence / credibility intervals did not cover plausible values of critical parameters obtained using different approaches. These findings suggest, amongst others, that several models are over-simplistic and that the reported case numbers provide often insufficient information.Competing Interest StatementThe authors have declared no competing interest.Funding StatementThis work was supported by the European Union{\textquoteright}s Horizon 2020 research and innovation program (CanPathPro; Grant no. 686282; E.D., J.H., S.M.), the Federal Ministry of Education and Research of Germany (Grant no. 031L0159C; E.A. \& Grant no. 01ZX1705; J.H.), the Federal Ministry of Economic Affairs and Energy (Grant no. 16KN074236; J.V.), and the German Research Foundation (Clusters of Excellence EXC 2047 \& EXC 2151; E.R., F.B., J.H.).Author DeclarationsAll relevant ethical guidelines have been followed; any necessary IRB and/or ethics committee approvals have been obtained and details of the IRB/oversight body are included in the manuscript.YesAll necessary patient/participant consent has been obtained and the appropriate institutional forms have been archived.YesI understand that all clinical trials and any other prospective interventional studies must be registered with an ICMJE-approved registry, such as ClinicalTrials.gov. I confirm that any such study reported in the manuscript has been registered and the trial registration ID is provided (note: if posting a prospective study registered retrospectively, please provide a statement in the trial ID field explaining why the study was not registered in advance).Yes I have followed all appropriate research reporting guidelines and uploaded the relevant EQUATOR Network research reporting checklist(s) and other pertinent material as supplementary files, if applicable.YesThe complete implementation (including the respective version of the used toolboxes) and data are available on ZENODO (https://doi.org/10.5281/zenodo.3757227). This includes the MATLAB code as well as the the specification of the parameter estimation problems as PEtab files (with the model in SBML format).https://doi.org/10.5281/zenodo.3757227}, - doi = {10.1101/2020.04.19.20071597}, - elocation-id = {2020.04.19.20071597}, - eprint = {https://www.medrxiv.org/content/early/2020/04/22/2020.04.19.20071597.full.pdf}, - publisher = {Cold Spring Harbor Laboratory Press}, - timestamp = {2020-11-09}, - url = {https://www.medrxiv.org/content/early/2020/04/22/2020.04.19.20071597}, -} - @Article{GerosaChi2020, author = {Luca Gerosa and Christopher Chidley and Fabian Fröhlich and Gabriela Sanchez and Sang Kyun Lim and Jeremy Muhlich and Jia-Yun Chen and Sreeram Vallabhaneni and Gregory J. Baker and Denis Schapiro and Mariya I. Atanasova and Lily A. Chylek and Tujin Shi and Lian Yi and Carrie D. Nicora and Allison Claas and Thomas S.C. Ng and Rainer H. Kohler and Douglas A. Lauffenburger and Ralph Weissleder and Miles A. Miller and Wei-Jun Qian and H. Steven Wiley and Peter K. Sorger}, journal = {Cell Systems}, @@ -739,7 +711,7 @@ @Article{Schaelte2020.01.30.927004 url = {https://www.biorxiv.org/content/early/2020/01/31/2020.01.30.927004}, } -@Article{Adlung866871, +@Article{AdlungSta2019, author = {Adlung, Lorenz and Stapor, Paul and T{\"o}nsing, Christian and Schmiester, Leonard and Schwarzm{\"u}ller, Luisa E. and Wang, Dantong and Timmer, Jens and Klingm{\"u}ller, Ursula and Hasenauer, Jan and Schilling, Marcel}, journal = {bioRxiv}, title = {Cell-to-cell variability in JAK2/STAT5 pathway components and cytoplasmic volumes define survival threshold in erythroid progenitor cells}, @@ -753,10 +725,10 @@ @Article{Adlung866871 url = {https://www.biorxiv.org/content/early/2019/12/07/866871}, } -@Article{PITT201872, +@Article{PittGom2018, author = {Jake Alan Pitt and Lucian Gomoescu and Constantinos C. Pantelides and Benoît Chachuat and Julio R. Banga}, journal = {IFAC-PapersOnLine}, - title = {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.}, + title = {Critical Assessment of Parameter Estimation Methods in Models of Biological Oscillators}, year = {2018}, issn = {2405-8963}, note = {7th Conference on Foundation of Systems Biology in Engineering FOSBE 2018}, @@ -780,7 +752,7 @@ @MastersThesis{Watanabe2019 url = {https://hdl.handle.net/20.500.12380/256855}, } -@Article{Erdem2020.11.09.373407, +@Article{ErdemBen2020, author = {Erdem, Cemal and Bensman, Ethan M. and Mutsuddy, Arnab and Saint-Antoine, Michael M. and Bouhaddou, Mehdi and Blake, Robert C. and Dodd, Will and Gross, Sean M. and Heiser, Laura M. and Feltus, F. Alex and Birtwistle, Marc R.}, journal = {bioRxiv}, title = {A Simple and Efficient Pipeline for Construction, Merging, Expansion, and Simulation of Large-Scale, Single-Cell Mechanistic Models}, @@ -794,6 +766,125 @@ @Article{Erdem2020.11.09.373407 url = {https://www.biorxiv.org/content/early/2020/11/10/2020.11.09.373407}, } +@Article{StaedterSch2021, + author = {Städter, Philipp and Schälte, Yannik and Schmiester, Leonard and Hasenauer, Jan and Stapor, Paul L.}, + journal = {Scientific Reports}, + title = {Benchmarking of numerical integration methods for ODE models of biological systems}, + year = {2021}, + issn = {2045-2322}, + number = {1}, + pages = {2696}, + volume = {11}, + abstract = {Ordinary differential equation (ODE) models are a key tool to understand complex mechanisms in systems biology. These models are studied using various approaches, including stability and bifurcation analysis, but most frequently by numerical simulations. The number of required simulations is often large, e.g., when unknown parameters need to be inferred. This renders efficient and reliable numerical integration methods essential. However, these methods depend on various hyperparameters, which strongly impact the ODE solution. Despite this, and although hundreds of published ODE models are freely available in public databases, a thorough study that quantifies the impact of hyperparameters on the ODE solver in terms of accuracy and computation time is still missing. In this manuscript, we investigate which choices of algorithms and hyperparameters are generally favorable when dealing with ODE models arising from biological processes. To ensure a representative evaluation, we considered 142 published models. Our study provides evidence that most ODEs in computational biology are stiff, and we give guidelines for the choice of algorithms and hyperparameters. We anticipate that our results will help researchers in systems biology to choose appropriate numerical methods when dealing with ODE models.}, + doi = {10.1038/s41598-021-82196-2}, + refid = {Städter2021}, + timestamp = {2021-02-19}, + url = {https://doi.org/10.1038/s41598-021-82196-2}, +} + +@Article{Schmiester2021.02.06.430039, + author = {Schmiester, Leonard and Weindl, Daniel and Hasenauer, Jan}, + journal = {bioRxiv}, + title = {Efficient gradient-based parameter estimation for dynamic models using qualitative data}, + year = {2021}, + abstract = {Motivation Unknown parameters of dynamical models are commonly estimated from experimental data. However, while various efficient optimization and uncertainty analysis methods have been proposed for quantitative data, methods for qualitative data are rare and suffer from bad scaling and convergence.Results Here, we propose an efficient and reliable framework for estimating the parameters of ordinary differential equation models from qualitative data. In this framework, we derive a semi-analytical algorithm for gradient calculation of the optimal scaling method developed for qualitative data. This enables the use of efficient gradient-based optimization algorithms. We demonstrate that the use of gradient information improves performance of optimization and uncertainty quantification on several application examples. On average, we achieve a speedup of more than one order of magnitude compared to gradient-free optimization. Additionally, in some examples, the gradient-based approach yields substantially improved objective function values and quality of the fits. Accordingly, the proposed framework substantially improves the parameterization of models from qualitative data.Availability The proposed approach is implemented in the open-source Python Parameter EStimation TOolbox (pyPESTO). All application examples and code to reproduce this study are available at https://doi.org/10.5281/zenodo.4507613.Competing Interest StatementThe authors have declared no competing interest.}, + doi = {10.1101/2021.02.06.430039}, + elocation-id = {2021.02.06.430039}, + eprint = {https://www.biorxiv.org/content/early/2021/02/08/2021.02.06.430039.full.pdf}, + publisher = {Cold Spring Harbor Laboratory}, + timestamp = {2021-02-19}, + url = {https://www.biorxiv.org/content/early/2021/02/08/2021.02.06.430039}, +} + +@Article{RaimundezDud2021, + author = {Elba Raimúndez and Erika Dudkin and Jakob Vanhoefer and Emad Alamoudi and Simon Merkt and Lara Fuhrmann and Fan Bai and Jan Hasenauer}, + journal = {Epidemics}, + title = {COVID-19 outbreak in Wuhan demonstrates the limitations of publicly available case numbers for epidemiological modeling}, + year = {2021}, + issn = {1755-4365}, + pages = {100439}, + volume = {34}, + abstract = {Epidemiological models are widely used to analyze the spread of diseases such as the global COVID-19 pandemic caused by SARS-CoV-2. However, all models are based on simplifying assumptions and often on sparse data. This limits the reliability of parameter estimates and predictions. In this manuscript, we demonstrate the relevance of these limitations and the pitfalls associated with the use of overly simplistic models. We considered the data for the early phase of the COVID-19 outbreak in Wuhan, China, as an example, and perform parameter estimation, uncertainty analysis and model selection for a range of established epidemiological models. Amongst others, we employ Markov chain Monte Carlo sampling, parameter and prediction profile calculation algorithms. Our results show that parameter estimates and predictions obtained for several established models on the basis of reported case numbers can be subject to substantial uncertainty. More importantly, estimates were often unrealistic and the confidence/credibility intervals did not cover plausible values of critical parameters obtained using different approaches. These findings suggest, amongst others, that standard compartmental models can be overly simplistic and that the reported case numbers provide often insufficient information for obtaining reliable and realistic parameter values, and for forecasting the evolution of epidemics.}, + doi = {https://doi.org/10.1016/j.epidem.2021.100439}, + keywords = {Compartment model, SEIRD, Parameter estimation, Model selection, Uncertainty analysis}, + timestamp = {2021-02-19}, + url = {https://www.sciencedirect.com/science/article/pii/S1755436521000037}, +} + +@Article{vanRosmalenSmi2021, + author = {R.P. {van Rosmalen} and R.W. Smith and V.A.P. {Martins dos Santos} and C. Fleck and M. Suarez-Diez}, + journal = {Metabolic Engineering}, + title = {Model reduction of genome-scale metabolic models as a basis for targeted kinetic models}, + year = {2021}, + issn = {1096-7176}, + pages = {74-84}, + volume = {64}, + abstract = {Constraint-based, genome-scale metabolic models are an essential tool to guide metabolic engineering. However, they lack the detail and time dimension that kinetic models with enzyme dynamics offer. Model reduction can be used to bridge the gap between the two methods and allow for the integration of kinetic models into the Design-Built-Test-Learn cycle. Here we show that these reduced size models can be representative of the dynamics of the original model and demonstrate the automated generation and parameterisation of such models. Using these minimal models of metabolism could allow for further exploration of dynamic responses in metabolic networks.}, + doi = {https://doi.org/10.1016/j.ymben.2021.01.008}, + keywords = {Metabolic engineering, DBTL cycle, Model reduction, Model optimisation, Model-driven design, Synthetic biology}, + url = {https://www.sciencedirect.com/science/article/pii/S1096717621000161}, +} + +@Article{StenPod2021, + author = {Sten, Sebastian and Pod{\'e}us, Henrik and Sundqvist, Nicolas and Elinder, Fredrik and Engstr{\"o}m, Maria and Cedersund, Gunnar}, + journal = {bioRxiv}, + title = {A multi-data based quantitative model for the neurovascular coupling in the brain}, + year = {2021}, + abstract = {The neurovascular coupling (NVC) forms the foundation for functional imaging techniques of the brain, since NVC connects neural activity with observable hemodynamic changes. Many aspects of the NVC have been studied both experimentally and with mathematical models: various combinations of blood volume and flow, electrical activity, oxygen saturation measures, blood oxygenation level-dependent (BOLD) response, and optogenetics have been measured and modeled in rodents, primates, or humans. We now present a first inter-connected mathematical model that describes all such data types simultaneously. The model can predict independent validation data not used for training. Using simulations, we show for example how complex bimodal behaviors appear upon stimulation. These simulations thus demonstrate how our new quantitative model, incorporating most of the core aspects of the NVC, can be used to mechanistically explain each of its constituent datasets.Competing Interest StatementThe authors have declared no competing interest.}, + doi = {10.1101/2021.03.25.437053}, + elocation-id = {2021.03.25.437053}, + eprint = {https://www.biorxiv.org/content/early/2021/03/26/2021.03.25.437053.full.pdf}, + publisher = {Cold Spring Harbor Laboratory}, + url = {https://www.biorxiv.org/content/early/2021/03/26/2021.03.25.437053}, +} + +@PhdThesis{Gaspari2021, + author = {Gaspari, Erika}, + school = {Wageningen University}, + title = {Model-driven design of Mycoplasma as a vaccine chassis}, + year = {2021}, + address = {Wageningen}, + comment = {WU thesis 7758 Includes bibliographical references. - With summaries in English, Italian and Spanish +10.18174/539593}, + doi = {10.18174/539593}, + issn = {9789463956864}, + url = {https://edepot.wur.nl/539593}, +} + +@Article{VanhoeferMat2021, + author = {Jakob Vanhoefer and Marta R. A. Matos and Dilan Pathirana and Yannik Schälte and Jan Hasenauer}, + journal = {Journal of Open Source Software}, + title = {yaml2sbml: Human-readable and -writable specification of ODE models and their conversion to SBML}, + year = {2021}, + number = {61}, + pages = {3215}, + volume = {6}, + doi = {10.21105/joss.03215}, + publisher = {The Open Journal}, + url = {https://doi.org/10.21105/joss.03215}, +} + +@Misc{VillaverdePat2021, + author = {Alejandro F. Villaverde and Dilan Pathirana and Fabian Fröhlich and Jan Hasenauer and Julio R. Banga}, + title = {A protocol for dynamic model calibration}, + year = {2021}, + archiveprefix = {arXiv}, + eprint = {2105.12008}, + primaryclass = {q-bio.QM}, +} +@article {Froehlich2021.05.20.445065, + author = {Fr{\"o}hlich, Fabian and Sorger, Peter K.}, + title = {Fides: Reliable Trust-Region Optimization for Parameter Estimation of Ordinary Differential Equation Models}, + elocation-id = {2021.05.20.445065}, + year = {2021}, + doi = {10.1101/2021.05.20.445065}, + publisher = {Cold Spring Harbor Laboratory}, + abstract = {Motivation Because they effectively represent mass action kinetics, ordinary differential equation models are widely used to describe biochemical processes. Optimization-based calibration of these models on experimental data can be challenging, even for low-dimensional problems. However, reliable model calibration is a prerequisite for many subsequent analysis steps, including uncertainty analysis, model selection and biological interpretation. Although multiple hypothesis have been advanced to explain why optimization based calibration of biochemical models is challenging, there are few comprehensive studies that test these hypothesis and tools for performing such studies are also lacking.Results We implemented an established trust-region method as a modular python framework (fides) to enable structured comparison of different approaches to ODE model calibration involving Hessian approximation schemes and trust-region subproblem solvers. We evaluate fides on a set of benchmark problems that include experimental data. We find a high variability in optimizer performance among different implementations of the same algorithm, with fides performing more reliably that other implementations investigated. Our investigation of possible sources of poor optimizer performance identify shortcomings in the widely used Gauss-Newton approximation. We address these shortcomings by proposing a novel hybrid Hessian approximation scheme that enhances optimizer performance.Availability Fides is published under the permissive BSD-3-Clause license with source code publicly available at https://github.com/fides-dev/fides. Citeable releases are archived on Zenodo.Contact fabian_froehlich{at}hms.harvard.edu and peter_sorger{at}hms.harvard.eduSupplementary information Supplementary data are available at Bioinformatics online and at https://github.com/fides-dev/fides-benchmark.Competing Interest StatementPKS is a member of the SAB or BOD member of Applied Biomath, RareCyte Inc., and Glencoe Software, which distributes a commercial version of the OMERO database; PKS is also a member of the NanoString SAB. In the last five years the Sorger lab has received research funding from Novartis and Merck. Sorger declares that none of these relationships have related to the content of this manuscript.}, + URL = {https://www.biorxiv.org/content/early/2021/05/22/2021.05.20.445065}, + eprint = {https://www.biorxiv.org/content/early/2021/05/22/2021.05.20.445065.full.pdf}, + journal = {bioRxiv} +} + @Comment{jabref-meta: databaseType:bibtex;} @Comment{jabref-meta: grouping: diff --git a/deps/AMICI/documentation/changelog.md b/deps/AMICI/documentation/changelog.md new file mode 120000 index 000000000..04c99a55c --- /dev/null +++ b/deps/AMICI/documentation/changelog.md @@ -0,0 +1 @@ +../CHANGELOG.md \ No newline at end of file diff --git a/deps/AMICI/documentation/gfx/banner.png b/deps/AMICI/documentation/gfx/banner.png index a88c2da48..40016b4da 100644 Binary files a/deps/AMICI/documentation/gfx/banner.png and b/deps/AMICI/documentation/gfx/banner.png differ diff --git a/deps/AMICI/documentation/gfx/logo.png b/deps/AMICI/documentation/gfx/logo.png index 3f22c92a8..7810c1e7c 100644 Binary files a/deps/AMICI/documentation/gfx/logo.png and b/deps/AMICI/documentation/gfx/logo.png differ diff --git a/deps/AMICI/documentation/gfx/logo_text.png b/deps/AMICI/documentation/gfx/logo_text.png index 22354e62b..c72388e94 100644 Binary files a/deps/AMICI/documentation/gfx/logo_text.png and b/deps/AMICI/documentation/gfx/logo_text.png differ diff --git a/deps/AMICI/documentation/how_to_cite.rst b/deps/AMICI/documentation/how_to_cite.rst index b94673e0b..5439a8e04 100644 --- a/deps/AMICI/documentation/how_to_cite.rst +++ b/deps/AMICI/documentation/how_to_cite.rst @@ -13,17 +13,23 @@ your project, please let us know via a Github issue. When using AMICI in your project, please cite -* Fröhlich, F., Weindl, D., Schälte, Y., Pathirana, D., Paszkowski, Ł., Lines, G.T., Stapor, P. and Hasenauer, J., 2020. - AMICI: High-Performance Sensitivity Analysis for Large Ordinary Differential Equation Models. arXiv preprint `arXiv:2012.09122 `_. +* Fröhlich, F., Weindl, D., Schälte, Y., Pathirana, D., Paszkowski, Ł., Lines, G.T., Stapor, P. and Hasenauer, J., 2021. + AMICI: High-Performance Sensitivity Analysis for Large Ordinary Differential Equation Models. Bioinformatics, btab227, + `DOI:10.1093/bioinformatics/btab227 `_. .. code-block:: bibtex @article{frohlich2020amici, title={AMICI: High-Performance Sensitivity Analysis for Large Ordinary Differential Equation Models}, author={Fr{\"o}hlich, Fabian and Weindl, Daniel and Sch{\"a}lte, Yannik and Pathirana, Dilan and Paszkowski, {\L}ukasz and Lines, Glenn Terje and Stapor, Paul and Hasenauer, Jan}, - journal={arXiv preprint arXiv:2012.09122}, - year={2020} - } + journal = {Bioinformatics}, + year = {2021}, + month = {04}, + issn = {1367-4803}, + doi = {10.1093/bioinformatics/btab227}, + note = {btab227}, + eprint = {https://academic.oup.com/bioinformatics/advance-article-pdf/doi/10.1093/bioinformatics/btab227/36866220/btab227.pdf}, + } When presenting work that employs AMICI, feel free to use one of the icons in `documentation/gfx/ `_, diff --git a/deps/AMICI/documentation/index.rst b/deps/AMICI/documentation/index.rst index d230451a3..39a6b4b7e 100644 --- a/deps/AMICI/documentation/index.rst +++ b/deps/AMICI/documentation/index.rst @@ -29,6 +29,7 @@ Welcome to AMICI's documentation! how_to_cite references background + changelog glossary contributing diff --git a/deps/AMICI/documentation/model_presimulation.ipynb b/deps/AMICI/documentation/model_presimulation.ipynb deleted file mode 120000 index 7b73d05c7..000000000 --- a/deps/AMICI/documentation/model_presimulation.ipynb +++ /dev/null @@ -1 +0,0 @@ -../python/examples/example_presimulation/model_presimulation.ipynb \ No newline at end of file diff --git a/deps/AMICI/documentation/python_interface.rst b/deps/AMICI/documentation/python_interface.rst index c605c71d6..9db3a06c7 100644 --- a/deps/AMICI/documentation/python_interface.rst +++ b/deps/AMICI/documentation/python_interface.rst @@ -26,15 +26,31 @@ AMICI can import :term:`SBML` models via the Status of SBML support in Python-AMICI ++++++++++++++++++++++++++++++++++++++ -Python-AMICI currently **passes 862 out of the 1780 (~48%) test cases** from +Python-AMICI currently **passes 996 out of the 1780 (~56%) test cases** from the semantic `SBML Test Suite `_ (`current status `_). -The following SBML test tags are supported +The following SBML test suite tags are currently supported (i.e., at least one test case with the respective test passes; `tag descriptions `_): +**Component tags:** + +* AssignmentRule +* Compartment +* CSymbolAvogadro +* CSymbolTime +* EventNoDelay +* FunctionDefinition +* InitialAssignment +* Parameter +* RateRule +* Reaction +* Species + +**Test tags:** + * 0D-Compartment * Amount * AssignedConstantStoichiometry @@ -44,6 +60,7 @@ The following SBML test tags are supported * Concentration * ConstantSpecies * ConversionFactors +* EventT0Firing * HasOnlySubstanceUnits * InitialValueReassigned * L3v2MathML @@ -63,17 +80,15 @@ In addition, we currently plan to add support for the following features (see corresponding `issues `_ for details and progress): -- Events (currently Matlab-only) (`#757 `_) - Algebraic rules (`#760 `_) -contributions are welcome. - However, the following features are unlikely to be supported: - any SBML extensions - `factorial()`, `ceil()`, `floor()`, due to incompatibility with symbolic sensitivity computations - `delay()` due to missing :term:`SUNDIALS` solver support +- events with delays, events with non-persistent triggers Tutorials +++++++++ @@ -105,7 +120,7 @@ Importing plain ODEs The AMICI Python interface does not currently support direct import of ODEs. However, it is straightforward to encode them as RateRules in an SBML model. -The `yaml2sbml `_ package may come in +The `yaml2sbml `_ package may come in handy, as it facilitates generating SBML models from a YAML-based specification of an ODE model. Besides the SBML model it can also create `PEtab `_ files. @@ -125,7 +140,7 @@ Examples GettingStarted.ipynb ExampleSteadystate.ipynb petab.ipynb - model_presimulation.ipynb + ExampleExperimentalConditions.ipynb ExampleEquilibrationLogic.ipynb @@ -140,21 +155,27 @@ OpenMP support for parallelized simulation for multiple experimental conditions AMICI can be built with OpenMP support, which allows to parallelize model simulations for multiple experimental conditions. -On Linux and OSX this is enabled by default. This can be verified using:: +On Linux and OSX this is enabled by default. This can be verified using: - import amici - amici.compiledWithOpenMP() +.. code-block:: python + + import amici + amici.compiledWithOpenMP() If not already enabled by default, you can enable OpenMP support by setting the environment variables ``AMICI_CXXFLAGS`` and ``AMICI_LDFLAGS`` to the correct OpenMP flags of your compiler and linker, respectively. This has to be done for both AMICI package installation *and* model compilation. When using -``gcc`` on Linux, this would be:: +``gcc`` on Linux, this would be: + +.. code-block:: bash + + # on your shell: + AMICI_CXXFLAGS=-fopenmp AMICI_LDFLAGS=-fopenmp pip3 install amici - # on your shell: - AMICI_CXXFLAGS=-fopenmp AMICI_LDFLAGS=-fopenmp pip3 install amici +.. code-block:: python - # in python, before model compilation: - import os - os.environ['AMICI_CXXFLAGS'] = '-fopenmp' - os.environ['AMICI_LDFLAGS'] = '-fopenmp' + # in python, before model compilation: + import os + os.environ['AMICI_CXXFLAGS'] = '-fopenmp' + os.environ['AMICI_LDFLAGS'] = '-fopenmp' diff --git a/deps/AMICI/documentation/references.md b/deps/AMICI/documentation/references.md index 848f63271..3f624bdac 100644 --- a/deps/AMICI/documentation/references.md +++ b/deps/AMICI/documentation/references.md @@ -1,15 +1,45 @@ # References -List of publications using AMICI. Total number is 50. +List of publications using AMICI. Total number is 57. If you applied AMICI in your work and your publication is missing, please let us know via a new Github issue. -

2020

-
+

2021

+
+ +
+

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.

+
+
+

Schmiester, Leonard, Daniel Weindl, and Jan Hasenauer. 2021. “Efficient Gradient-Based Parameter Estimation for Dynamic Models Using Qualitative Data.” bioRxiv. https://doi.org/10.1101/2021.02.06.430039.

+
+
+

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.

+
+
+

2020

+

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.

@@ -18,9 +48,6 @@ If you applied AMICI in your work and your publication is missing, please let us

Kuritz, Karsten, Alain R Bonny, João Pedro Fonseca, and Frank Allgöwer. 2020. “PDE-Constrained Optimization for Estimating Population Dynamics over Cell Cycle from Static Single Cell Measurements.” bioRxiv. https://doi.org/10.1101/2020.03.30.015909.

-
-

Raimúndez, Elba, Erika Dudkin, Jakob Vanhoefer, Emad Alamoudi, Simon Merkt, Lara Fuhrmann, Fan Bai, and Jan Hasenauer. 2020. “COVID-19 Outbreak in Wuhan Demonstrates the Limitations of Publicly Available Case Numbers for Epidemiological Modelling.” medRxiv. https://doi.org/10.1101/2020.04.19.20071597.

-

Schälte, Yannik, and Jan Hasenauer. 2020. “Efficient Exact Inference for Dynamical Systems with Noisy Measurements Using Sequential Approximate Bayesian Computation.” bioRxiv. https://doi.org/10.1101/2020.01.30.927004.

@@ -33,9 +60,6 @@ If you applied AMICI in your work and your publication is missing, please let us

Schuh, Lea, Carolin Loos, Daniil Pokrovsky, Axel Imhof, Ralph Rupp, and Carsten Marr. 2020. “Computational Modeling Reveals Cell-Cycle Dependent Kinetics of H4k20 Methylation States During Xenopus Embryogenesis.” bioRxiv. https://doi.org/10.1101/2020.05.28.110684.

-
-

Städter, Philipp, Yannik Schälte, Leonard Schmiester, Jan Hasenauer, and Paul L. Stapor. 2020. “Benchmarking of Numerical Integration Methods for Ode Models of Biological Systems.” bioRxiv. https://doi.org/10.1101/2020.09.03.268276.

-

Sten, Sebastian. 2020. “Mathematical Modeling of Neurovascular Coupling.” Linköping University Medical Dissertations. PhD thesis, Linköping UniversityLinköping UniversityLinköping University, Division of Diagnostics; Specialist Medicine, Faculty of Medicine; Health Sciences, Center for Medical Image Science; Visualization (CMIV); Linköping University, Division of Diagnostics; Specialist Medicine. https://doi.org/10.3384/diss.diva-167806.

@@ -46,9 +70,9 @@ If you applied AMICI in your work and your publication is missing, please let us

Tsipa, Argyro, Jake Alan Pitt, Julio R. Banga, and Athanasios Mantalaris. 2020. “A Dual-Parameter Identification Approach for Data-Based Predictive Modeling of Hybrid Gene Regulatory Network-Growth Kinetics in Pseudomonas Putida Mt-2.” Bioprocess and Biosystems Engineering 43 (9): 1671–88. https://doi.org/10.1007/s00449-020-02360-2.

-

2019

-
-
+

2019

+
+

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.

@@ -82,7 +106,7 @@ If you applied AMICI in your work and your publication is missing, please let us

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.

@@ -91,8 +115,8 @@ If you applied AMICI in your work and your publication is missing, please let us

Watanabe, Simon Berglund. 2019. “Identifiability of Parameters in Pbpk Models.” Master’s thesis, Chalmers University of Technology / Department of Mathematical Sciences. https://hdl.handle.net/20.500.12380/256855.

-

2018

-
+

2018

+

Ballnus, Benjamin, Steffen Schaper, Fabian J Theis, and Jan Hasenauer. 2018. “Bayesian Parameter Estimation for Biochemical Reaction Networks Using Region-Based Adaptive Parallel Tempering.” Bioinformatics 34 (13): i494–i501. https://doi.org/10.1093/bioinformatics/bty229.

@@ -114,8 +138,8 @@ If you applied AMICI in your work and your publication is missing, please let us

Loos, 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.

@@ -127,8 +151,8 @@ If you applied AMICI in your work and your publication is missing, please let us

Villaverde, Alejandro F, Fabian Fröhlich, Daniel Weindl, Jan Hasenauer, and Julio R Banga. 2018. “Benchmarking optimization methods for parameter estimation in large kinetic models.” Bioinformatics 35 (5): 830–38. https://doi.org/10.1093/bioinformatics/bty736.

-

2017

-
+

2017

+

Ballnus, B., S. Hug, K. Hatz, L. Görlitz, J. Hasenauer, and F. J. Theis. 2017. “Comprehensive Benchmarking of Markov Chain Monte Carlo Methods for Dynamical Systems.” BMC Syst. Biol. 11 (63). https://doi.org/10.1186/s12918-017-0433-1.

@@ -145,8 +169,8 @@ If you applied AMICI in your work and your publication is missing, please let us

Maier, C., C. Loos, and J. Hasenauer. 2017. “Robust Parameter Estimation for Dynamical Systems from Outlier-Corrupted Data.” Bioinformatics 33 (5): 718–25. https://doi.org/10.1093/bioinformatics/btw703.

-

2016

-
+

2016

+

Boiger, R., J. Hasenauer, S. Hross, and B. Kaltenbacher. 2016. “Integration Based Profile Likelihood Calculation for PDE Constrained Parameter Estimation Problems.” Inverse Prob. 32 (12): 125009. https://doi.org/10.1088/0266-5611/32/12/125009.

@@ -166,8 +190,8 @@ If you applied AMICI in your work and your publication is missing, please let us

Loos, C., A. Fiedler, and J. Hasenauer. 2016. “Parameter Estimation for Reaction Rate Equation Constrained Mixture Models.” In Proc. 13th Int. Conf. Comp. Meth. Syst. Biol., edited by E. Bartocci, P. Lio, and N. Paoletti, 186–200. Lecture Notes in Bioinformatics. Springer International Publishing. https://doi.org/10.1007/978-3-319-45177-0.

-

2015

-
+

2015

+

Loos, C., C. Marr, F. J. Theis, and J. Hasenauer. 2015. “Computational Methods in Systems Biology.” In, edited by O. Roux and J. Bourdon, 9308:52–63. Lecture Notes in Computer Science. Springer International Publishing. https://doi.org/10.1007/978-3-319-23401-4_6.

diff --git a/deps/AMICI/documentation/rtd_requirements.txt b/deps/AMICI/documentation/rtd_requirements.txt index 58ccbff6d..154f12a9d 100644 --- a/deps/AMICI/documentation/rtd_requirements.txt +++ b/deps/AMICI/documentation/rtd_requirements.txt @@ -21,4 +21,4 @@ git+https://github.com/dweindl/exhale@ea77a313777c1382a7830ce9ee6c405ce47f5f3b#e -e git+https://github.com/mithro/sphinx-contrib-mithro#egg=sphinx-contrib-exhale-multiproject&subdirectory=sphinx-contrib-exhale-multiproject sphinxcontrib-matlabdomain sphinxcontrib-napoleon -pygments==2.4.1 +pygments==2.7.4 diff --git a/deps/AMICI/include/amici/abstract_model.h b/deps/AMICI/include/amici/abstract_model.h index c74bc9f95..dc11b13e9 100644 --- a/deps/AMICI/include/amici/abstract_model.h +++ b/deps/AMICI/include/amici/abstract_model.h @@ -171,7 +171,7 @@ class AbstractModel { const AmiVector &x, const AmiVector &dx) = 0; /** - * @brief Model specific sparse implementation of explicit parameter + * @brief Model-specific sparse implementation of explicit parameter * derivative of right hand side * @param t time * @param x state @@ -195,19 +195,19 @@ class AbstractModel { realtype cj) = 0; /** - * @brief Returns the amici version that was used to generate the model - * @return ver amici version string + * @brief Returns the AMICI version that was used to generate the model + * @return AMICI version string */ - virtual const std::string getAmiciVersion() const; + virtual std::string getAmiciVersion() const; /** - * @brief Returns the amici commit that was used to generate the model - * @return ver amici commit string + * @brief Returns the AMICI commit that was used to generate the model + * @return AMICI commit string */ - virtual const std::string getAmiciCommit() const; + virtual std::string getAmiciCommit() const; /** - * @brief Model specific implementation of fx0 + * @brief Model-specific implementation of fx0 * @param x0 initial state * @param t initial time * @param p parameter vector @@ -225,7 +225,7 @@ class AbstractModel { virtual bool isFixedParameterStateReinitializationAllowed() const; /** - * @brief Model specific implementation of fx0_fixedParameters + * @brief Model-specific implementation of fx0_fixedParameters * @param x0 initial state * @param t initial time * @param p parameter vector @@ -238,7 +238,7 @@ class AbstractModel { gsl::span reinitialization_state_idxs); /** - * @brief Model specific implementation of fsx0_fixedParameters + * @brief Model-specific implementation of fsx0_fixedParameters * @param sx0 initial state sensitivities * @param t initial time * @param x0 initial state @@ -254,7 +254,7 @@ class AbstractModel { gsl::span reinitialization_state_idxs); /** - * @brief Model specific implementation of fsx0 + * @brief Model-specific implementation of fsx0 * @param sx0 initial state sensitivities * @param t initial time * @param x0 initial state @@ -275,7 +275,7 @@ class AbstractModel { virtual void fdx0(AmiVector &x0, AmiVector &dx0); /** - * @brief Model specific implementation of fstau + * @brief Model-specific implementation of fstau * @param stau total derivative of event timepoint * @param t current time * @param x current state @@ -291,7 +291,7 @@ class AbstractModel { const realtype *sx, int ip, int ie); /** - * @brief Model specific implementation of fy + * @brief Model-specific implementation of fy * @param y model output at current timepoint * @param t current time * @param x current state @@ -305,7 +305,7 @@ class AbstractModel { const realtype *w); /** - * @brief Model specific implementation of fdydp + * @brief Model-specific implementation of fdydp * @param dydp partial derivative of observables y w.r.t. model parameters p * @param t current time * @param x current state @@ -321,7 +321,7 @@ class AbstractModel { int ip, const realtype *w, const realtype *dwdp); /** - * @brief Model specific implementation of fdydx + * @brief Model-specific implementation of fdydx * @param dydx partial derivative of observables y w.r.t. model states x * @param t current time * @param x current state @@ -336,7 +336,7 @@ class AbstractModel { const realtype *w, const realtype *dwdx); /** - * @brief Model specific implementation of fz + * @brief Model-specific implementation of fz * @param z value of event output * @param ie event index * @param t current time @@ -349,7 +349,7 @@ class AbstractModel { const realtype *p, const realtype *k, const realtype *h); /** - * @brief Model specific implementation of fsz + * @brief Model-specific implementation of fsz * @param sz Sensitivity of rz, total derivative * @param ie event index * @param t current time @@ -365,7 +365,7 @@ class AbstractModel { const realtype *sx, int ip); /** - * @brief Model specific implementation of frz + * @brief Model-specific implementation of frz * @param rz value of root function at current timepoint (non-output events * not included) * @param ie event index @@ -379,7 +379,7 @@ class AbstractModel { const realtype *p, const realtype *k, const realtype *h); /** - * @brief Model specific implementation of fsrz + * @brief Model-specific implementation of fsrz * @param srz Sensitivity of rz, total derivative * @param ie event index * @param t current time @@ -395,7 +395,7 @@ class AbstractModel { const realtype *h, const realtype *sx, int ip); /** - * @brief Model specific implementation of fdzdp + * @brief Model-specific implementation of fdzdp * @param dzdp partial derivative of event-resolved output z w.r.t. model * parameters p * @param ie event index @@ -411,7 +411,7 @@ class AbstractModel { const realtype *h, int ip); /** - * @brief Model specific implementation of fdzdx + * @brief Model-specific implementation of fdzdx * @param dzdx partial derivative of event-resolved output z w.r.t. model * states x * @param ie event index @@ -426,7 +426,7 @@ class AbstractModel { const realtype *h); /** - * @brief Model specific implementation of fdrzdp + * @brief Model-specific implementation of fdrzdp * @param drzdp partial derivative of root output rz w.r.t. model parameters * p * @param ie event index @@ -442,7 +442,7 @@ class AbstractModel { const realtype *h, int ip); /** - * @brief Model specific implementation of fdrzdx + * @brief Model-specific implementation of fdrzdx * @param drzdx partial derivative of root output rz w.r.t. model states x * @param ie event index * @param t current time @@ -456,7 +456,7 @@ class AbstractModel { const realtype *h); /** - * @brief Model specific implementation of fdeltax + * @brief Model-specific implementation of fdeltax * @param deltax state update * @param t current time * @param x current state @@ -473,7 +473,7 @@ class AbstractModel { const realtype *xdot_old); /** - * @brief Model specific implementation of fdeltasx + * @brief Model-specific implementation of fdeltasx * @param deltasx sensitivity update * @param t current time * @param x current state @@ -496,7 +496,7 @@ class AbstractModel { const realtype *sx, const realtype *stau); /** - * @brief Model specific implementation of fdeltaxB + * @brief Model-specific implementation of fdeltaxB * @param deltaxB adjoint state update * @param t current time * @param x current state @@ -515,7 +515,7 @@ class AbstractModel { const realtype *xB); /** - * @brief Model specific implementation of fdeltaqB + * @brief Model-specific implementation of fdeltaqB * @param deltaqB sensitivity update * @param t current time * @param x current state @@ -535,7 +535,7 @@ class AbstractModel { const realtype *xB); /** - * @brief Model specific implementation of fsigmay + * @brief Model-specific implementation of fsigmay * @param sigmay standard deviation of measurements * @param t current time * @param p parameter vector @@ -545,7 +545,7 @@ class AbstractModel { const realtype *k); /** - * @brief Model specific implementation of fsigmay + * @brief Model-specific implementation of fsigmay * @param dsigmaydp partial derivative of standard deviation of measurements * @param t current time * @param p parameter vector @@ -556,7 +556,7 @@ class AbstractModel { const realtype *p, const realtype *k, int ip); /** - * @brief Model specific implementation of fsigmaz + * @brief Model-specific implementation of fsigmaz * @param sigmaz standard deviation of event measurements * @param t current time * @param p parameter vector @@ -566,7 +566,7 @@ class AbstractModel { const realtype *k); /** - * @brief Model specific implementation of fsigmaz + * @brief Model-specific implementation of fsigmaz * @param dsigmazdp partial derivative of standard deviation of event * measurements * @param t current time @@ -578,7 +578,7 @@ class AbstractModel { const realtype *p, const realtype *k, int ip); /** - * @brief Model specific implementation of fJy + * @brief Model-specific implementation of fJy * @param nllh negative log-likelihood for measurements y * @param iy output index * @param p parameter vector @@ -592,7 +592,7 @@ class AbstractModel { const realtype *sigmay, const realtype *my); /** - * @brief Model specific implementation of fJz + * @brief Model-specific implementation of fJz * @param nllh negative log-likelihood for event measurements z * @param iz event output index * @param p parameter vector @@ -606,7 +606,7 @@ class AbstractModel { const realtype *sigmaz, const realtype *mz); /** - * @brief Model specific implementation of fJrz + * @brief Model-specific implementation of fJrz * @param nllh regularization for event measurements z * @param iz event output index * @param p parameter vector @@ -619,7 +619,7 @@ class AbstractModel { const realtype *sigmaz); /** - * @brief Model specific implementation of fdJydy + * @brief Model-specific implementation of fdJydy * @param dJydy partial derivative of time-resolved measurement negative * log-likelihood Jy * @param iy output index @@ -648,7 +648,7 @@ class AbstractModel { virtual void fdJydy_rowvals(SUNMatrixWrapper &dJydy, int index); /** - * @brief Model specific implementation of fdJydsigma + * @brief Model-specific implementation of fdJydsigma * @param dJydsigma Sensitivity of time-resolved measurement negative * log-likelihood Jy w.r.t. standard deviation sigmay * @param iy output index @@ -663,7 +663,7 @@ class AbstractModel { const realtype *sigmay, const realtype *my); /** - * @brief Model specific implementation of fdJzdz + * @brief Model-specific implementation of fdJzdz * @param dJzdz partial derivative of event measurement negative * log-likelihood Jz * @param iz event output index @@ -678,7 +678,7 @@ class AbstractModel { const realtype *sigmaz, const realtype *mz); /** - * @brief Model specific implementation of fdJzdsigma + * @brief Model-specific implementation of fdJzdsigma * @param dJzdsigma Sensitivity of event measurement negative log-likelihood * Jz w.r.t. standard deviation sigmaz * @param iz event output index @@ -693,7 +693,7 @@ class AbstractModel { const realtype *sigmaz, const realtype *mz); /** - * @brief Model specific implementation of fdJrzdz + * @brief Model-specific implementation of fdJrzdz * @param dJrzdz partial derivative of event penalization Jrz * @param iz event output index * @param p parameter vector @@ -706,7 +706,7 @@ class AbstractModel { const realtype *sigmaz); /** - * @brief Model specific implementation of fdJrzdsigma + * @brief Model-specific implementation of fdJrzdsigma * @param dJrzdsigma Sensitivity of event penalization Jrz w.r.t. standard * deviation sigmaz * @param iz event output index @@ -720,7 +720,7 @@ class AbstractModel { const realtype *sigmaz); /** - * @brief Model specific implementation of fw + * @brief Model-specific implementation of fw * @param w Recurring terms in xdot * @param t timepoint * @param x vector with the states @@ -734,7 +734,7 @@ class AbstractModel { const realtype *tcl); /** - * @brief Model specific sparse implementation of dwdp + * @brief Model-specific sparse implementation of dwdp * @param dwdp Recurring terms in xdot, parameter derivative * @param t timepoint * @param x vector with the states @@ -751,19 +751,19 @@ class AbstractModel { const realtype *stcl); /** - * @brief Model specific implementation for dwdp, column pointers + * @brief Model-specific implementation for dwdp, column pointers * @param dwdp sparse matrix to which colptrs will be written */ virtual void fdwdp_colptrs(SUNMatrixWrapper &dwdp); /** - * @brief Model specific implementation for dwdp, row values + * @brief Model-specific implementation for dwdp, row values * @param dwdp sparse matrix to which rowvals will be written */ virtual void fdwdp_rowvals(SUNMatrixWrapper &dwdp); /** - * @brief Model specific sensitivity implementation of dwdp + * @brief Model-specific sensitivity implementation of dwdp * @param dwdp Recurring terms in xdot, parameter derivative * @param t timepoint * @param x vector with the states @@ -781,7 +781,7 @@ class AbstractModel { const realtype *stcl, int ip); /** - * @brief Model specific implementation of dwdx, data part + * @brief Model-specific implementation of dwdx, data part * @param dwdx Recurring terms in xdot, state derivative * @param t timepoint * @param x vector with the states @@ -796,19 +796,19 @@ class AbstractModel { const realtype *w, const realtype *tcl); /** - * @brief Model specific implementation for dwdx, column pointers + * @brief Model-specific implementation for dwdx, column pointers * @param dwdx sparse matrix to which colptrs will be written */ virtual void fdwdx_colptrs(SUNMatrixWrapper &dwdx); /** - * @brief Model specific implementation for dwdx, row values + * @brief Model-specific implementation for dwdx, row values * @param dwdx sparse matrix to which rowvals will be written */ virtual void fdwdx_rowvals(SUNMatrixWrapper &dwdx); /** - * @brief Model specific implementation of fdwdw, no w chainrule (Py) + * @brief Model-specific implementation of fdwdw, no w chainrule (Py) * @param dwdw partial derivative w wrt w * @param t timepoint * @param x Vector with the states @@ -823,13 +823,13 @@ class AbstractModel { const realtype *w, const realtype *tcl); /** - * @brief Model specific implementation of fdwdw, colptrs part + * @brief Model-specific implementation of fdwdw, colptrs part * @param dwdw sparse matrix to which colptrs will be written */ virtual void fdwdw_colptrs(SUNMatrixWrapper &dwdw); /** - * @brief Model specific implementation of fdwdw, rowvals part + * @brief Model-specific implementation of fdwdw, rowvals part * @param dwdw sparse matrix to which rowvals will be written */ virtual void fdwdw_rowvals(SUNMatrixWrapper &dwdw); diff --git a/deps/AMICI/include/amici/edata.h b/deps/AMICI/include/amici/edata.h index d43d0a91e..1ed10896d 100644 --- a/deps/AMICI/include/amici/edata.h +++ b/deps/AMICI/include/amici/edata.h @@ -34,19 +34,19 @@ class ExpData : public SimulationParameters { /** * @brief constructor that only initializes dimensions * - * @param nytrue - * @param nztrue - * @param nmaxevent + * @param nytrue Number of observables + * @param nztrue Number of event outputs + * @param nmaxevent Maximal number of events to track */ ExpData(int nytrue, int nztrue, int nmaxevent); /** * @brief constructor that initializes timepoints from vectors * - * @param nytrue (dimension: scalar) - * @param nztrue (dimension: scalar) - * @param nmaxevent (dimension: scalar) - * @param ts (dimension: nt) + * @param nytrue Number of observables + * @param nztrue Number of event outputs + * @param nmaxevent Maximal number of events to track + * @param ts Timepoints (dimension: nt) */ ExpData(int nytrue, int nztrue, int nmaxevent, std::vector ts); @@ -54,11 +54,11 @@ class ExpData : public SimulationParameters { * @brief constructor that initializes timepoints and fixed parameters from * vectors * - * @param nytrue (dimension: scalar) - * @param nztrue (dimension: scalar) - * @param nmaxevent (dimension: scalar) - * @param ts (dimension: nt) - * @param fixedParameters (dimension: nk) + * @param nytrue Number of observables + * @param nztrue Number of event outputs + * @param nmaxevent Maximal number of events to track + * @param ts Timepoints (dimension: nt) + * @param fixedParameters Model constants (dimension: nk) */ ExpData(int nytrue, int nztrue, int nmaxevent, std::vector ts, std::vector fixedParameters); @@ -66,14 +66,17 @@ class ExpData : public SimulationParameters { /** * @brief constructor that initializes timepoints and data from vectors * - * @param nytrue (dimension: scalar) - * @param nztrue (dimension: scalar) - * @param nmaxevent (dimension: scalar) - * @param ts (dimension: nt) - * @param observedData (dimension: nt x nytrue, row-major) - * @param observedDataStdDev (dimension: nt x nytrue, row-major) - * @param observedEvents (dimension: nmaxevent x nztrue, row-major) - * @param observedEventsStdDev (dimension: nmaxevent x nztrue, row-major) + * @param nytrue Number of observables + * @param nztrue Number of event outputs + * @param nmaxevent Maximal number of events to track + * @param ts Timepoints (dimension: nt) + * @param observedData observed data (dimension: nt x nytrue, row-major) + * @param observedDataStdDev standard deviation of observed data + * (dimension: nt x nytrue, row-major) + * @param observedEvents observed events + * (dimension: nmaxevents x nztrue, row-major) + * @param observedEventsStdDev standard deviation of observed events/roots + * (dimension: nmaxevents x nztrue, row-major) */ ExpData(int nytrue, int nztrue, int nmaxevent, std::vector ts, std::vector const &observedData, @@ -142,7 +145,7 @@ class ExpData : public SimulationParameters { int nt() const; /** - * @brief set function that copies data from input to ExpData::ts + * @brief Set function that copies data from input to ExpData::ts * * @param ts timepoints */ @@ -373,11 +376,11 @@ class ExpData : public SimulationParameters { /** * @brief get function that returns a pointer to standard deviation of - * observed event data at ieth occurrence + * observed event data at ie-th occurrence * * @param ie event occurrence * - * @return pointer to standard deviation of observed event data at ieth + * @return pointer to standard deviation of observed event data at ie-th * occurrence */ const realtype *getObservedEventsStdDevPtr(int ie) const; @@ -429,6 +432,7 @@ class ExpData : public SimulationParameters { /** @brief observed data (dimension: nt x nytrue, row-major) */ std::vector observed_data_; + /** * @brief standard deviation of observed data (dimension: nt x nytrue, * row-major) @@ -439,6 +443,7 @@ class ExpData : public SimulationParameters { * @brief observed events (dimension: nmaxevents x nztrue, row-major) */ std::vector observed_events_; + /** * @brief standard deviation of observed events/roots * (dimension: nmaxevents x nztrue, row-major) diff --git a/deps/AMICI/include/amici/exception.h b/deps/AMICI/include/amici/exception.h index 5b9b2c226..6556e5fcd 100644 --- a/deps/AMICI/include/amici/exception.h +++ b/deps/AMICI/include/amici/exception.h @@ -130,12 +130,8 @@ class IntegrationFailureB : public AmiException { * and an error will be thrown */ class SetupFailure : public AmiException { -public: - /** - * @brief Constructor, simply calls AmiException constructor - * @param msg - */ - explicit SetupFailure(const char *msg) : AmiException(msg) {} + public: + using AmiException::AmiException; }; diff --git a/deps/AMICI/include/amici/misc.h b/deps/AMICI/include/amici/misc.h index dd59b03fc..ee069b522 100644 --- a/deps/AMICI/include/amici/misc.h +++ b/deps/AMICI/include/amici/misc.h @@ -44,8 +44,8 @@ gsl::span slice(std::vector &data, int index, unsigned size) { */ template -const gsl::span slice(const std::vector &data, - int index, unsigned size) { +gsl::span slice(const std::vector &data, + int index, unsigned size) { if ((index + 1) * size > data.size()) throw std::out_of_range("requested slice is out of data range"); if (size > 0) diff --git a/deps/AMICI/include/amici/model.h b/deps/AMICI/include/amici/model.h index 4d998e3c2..1e4780844 100644 --- a/deps/AMICI/include/amici/model.h +++ b/deps/AMICI/include/amici/model.h @@ -642,6 +642,45 @@ class Model : public AbstractModel, public ModelDimensions { throw AmiException("Mismatch in conservation law sensitivity size"); state_ = state; }; + + /** + * @brief Sets the estimated lower boundary for sigma_y. When :meth:`setAddSigmaResiduals` is + * activated, this lower boundary must ensure that log(sigma) + min_sigma > 0. + * @param min_sigma lower boundary + */ + void setMinimumSigmaResiduals(double min_sigma) { + min_sigma_ = min_sigma; + } + + /** + * @brief Gets the specified estimated lower boundary for sigma_y. + * @return lower boundary + */ + realtype getMinimumSigmaResiduals() const { + return min_sigma_; + } + + /** + * @brief Specifies whether residuals should be added to account for parameter dependent sigma. + * + * If set to true, additional residuals of the form \f$ \sqrt{\log(\sigma) + C} \f$ will be added. + * This enables least-squares optimization for variables with Gaussian noise assumption and parameter + * dependent standard deviation sigma. The constant \f$ C \f$ can be set via + * :meth:`setMinimumSigmaResiduals`. + * + * @param sigma_res if true, additional residuals are added + */ + void setAddSigmaResiduals(bool sigma_res) { + sigma_res_ = sigma_res; + } + + /** + * @brief Checks whether residuals should be added to account for parameter dependent sigma. + * @return sigma_res + */ + bool getAddSigmaResiduals() const { + return sigma_res_; + } /** * @brief Get the list of parameters for which sensitivities are computed. @@ -767,7 +806,7 @@ class Model : public AbstractModel, public ModelDimensions { /** * @brief Get sensitivity of time-resolved observables. * - * Total derivative \f$sy = dydx * sx + dydp\f$ + * Total derivative \f$ sy = dydx * sx + dydp\f$ * (only for forward sensitivities). * @param sy buffer (shape `ny` x `nplist`, row-major) * @param t Timpoint @@ -801,7 +840,7 @@ class Model : public AbstractModel, public ModelDimensions { const int it, const ExpData *edata); /** - * @brief Add time-resolved measurement negative log-likelihood \f$Jy\f$. + * @brief Add time-resolved measurement negative log-likelihood \f$ Jy \f$. * @param Jy Buffer (shape 1) * @param it Timepoint index * @param x State variables @@ -812,7 +851,7 @@ class Model : public AbstractModel, public ModelDimensions { /** * @brief Add sensitivity of time-resolved measurement negative log-likelihood - * \f$Jy\f$. + * \f$ Jy \f$. * * @param sllh First-order buffer (shape `nplist`) * @param s2llh Second-order buffer (shape `nJ - 1` x `nplist`, row-major) @@ -829,7 +868,7 @@ class Model : public AbstractModel, public ModelDimensions { /** * @brief Add sensitivity of time-resolved measurement negative - * log-likelihood \f$Jy\f$. + * log-likelihood \f$ Jy \f$. * * Partial derivative (to be used with adjoint sensitivities). * @@ -847,7 +886,7 @@ class Model : public AbstractModel, public ModelDimensions { const ExpData &edata); /** - * @brief Get state sensitivity of the negative loglikelihood \f$Jy\f$, + * @brief Get state sensitivity of the negative loglikelihood \f$ Jy \f$, * partial derivative (to be used with adjoint sensitivities). * * @param dJydx Output buffer (shape `nJ` x `nx_solver`, row-major) @@ -978,7 +1017,7 @@ class Model : public AbstractModel, public ModelDimensions { /** * @brief Add sensitivity of time-resolved measurement negative - * log-likelihood \f$Jy\f$. + * log-likelihood \f$ Jy \f$. * * Total derivative (to be used with forward sensitivities). * @@ -1001,7 +1040,7 @@ class Model : public AbstractModel, public ModelDimensions { /** * @brief Add sensitivity of time-resolved measurement negative - * log-likelihood \f$Jy\f$. + * log-likelihood \f$ Jy \f$. * * Partial derivative (to be used with adjoint sensitivities). * @@ -1022,7 +1061,7 @@ class Model : public AbstractModel, public ModelDimensions { const ExpData &edata); /** - * @brief State sensitivity of the negative loglikelihood \f$Jz\f$. + * @brief State sensitivity of the negative loglikelihood \f$ Jz \f$. * * Partial derivative (to be used with adjoint sensitivities). * @@ -1305,7 +1344,7 @@ class Model : public AbstractModel, public ModelDimensions { void fy(realtype t, const AmiVector &x); /** - * @brief Compute partial derivative of observables \f$y\f$ w.r.t. model + * @brief Compute partial derivative of observables \f$ y \f$ w.r.t. model * parameters `p`. * @param t Current timepoint * @param x Current state @@ -1313,7 +1352,7 @@ class Model : public AbstractModel, public ModelDimensions { void fdydp(realtype t, const AmiVector &x); /** - * @brief Compute partial derivative of observables \f$y\f$ w.r.t. state + * @brief Compute partial derivative of observables \f$ y \f$ w.r.t. state * variables `x`. * @param t Current timepoint * @param x Current state @@ -1336,7 +1375,7 @@ class Model : public AbstractModel, public ModelDimensions { void fdsigmaydp(int it, const ExpData *edata); /** - * @brief Compute negative log-likelihood of measurements \f$y\f$. + * @brief Compute negative log-likelihood of measurements \f$ y \f$. * * @param Jy Variable to which llh will be added * @param it Timepoint index @@ -1347,7 +1386,7 @@ class Model : public AbstractModel, public ModelDimensions { /** * @brief Compute partial derivative of time-resolved measurement negative - * log-likelihood \f$Jy\f$. + * log-likelihood \f$ Jy \f$. * @param it timepoint index * @param x state variables * @param edata Pointer to experimental data @@ -1365,7 +1404,7 @@ class Model : public AbstractModel, public ModelDimensions { /** * @brief Compute sensitivity of time-resolved measurement negative - * log-likelihood \f$Jy\f$ w.r.t. parameters for the given timepoint. + * log-likelihood \f$ Jy \f$ w.r.t. parameters for the given timepoint. * @param it timepoint index * @param x state variables * @param edata pointer to experimental data instance @@ -1374,7 +1413,7 @@ class Model : public AbstractModel, public ModelDimensions { /** * @brief Sensitivity of time-resolved measurement negative log-likelihood - * \f$Jy\f$ w.r.t. state variables. + * \f$ Jy \f$ w.r.t. state variables. * @param it Timepoint index * @param x State variables * @param edata Pointer to experimental data instance @@ -1428,7 +1467,7 @@ class Model : public AbstractModel, public ModelDimensions { void fdrzdp(int ie, realtype t, const AmiVector &x); /** - * @brief Compute sensitivity of event-resolved measurements \f$rz\f$ w.r.t. + * @brief Compute sensitivity of event-resolved measurements \f$ rz \f$ w.r.t. * model states `x`. * @param ie Event index * @param t Current timepoint @@ -1469,7 +1508,7 @@ class Model : public AbstractModel, public ModelDimensions { /** * @brief Compute partial derivative of event measurement negative - * log-likelihood \f$Jz\f$. + * log-likelihood \f$ Jz \f$. * @param ie Event index * @param nroots Event index * @param t Current timepoint @@ -1481,7 +1520,7 @@ class Model : public AbstractModel, public ModelDimensions { /** * @brief Compute sensitivity of event measurement negative log-likelihood - * \f$Jz\f$ w.r.t. standard deviation sigmaz. + * \f$ Jz \f$ w.r.t. standard deviation sigmaz. * @param ie Event index * @param nroots Event index * @param t Current timepoint @@ -1704,6 +1743,12 @@ class Model : public AbstractModel, public ModelDimensions { * checked for finiteness */ bool always_check_finite_ {false}; + + /** indicates whether sigma residuals are to be added for every datapoint */ + bool sigma_res_ {false}; + + /** offset to ensure positivity of sigma residuals, only has an effect when `sigma_res_` is `true` */ + realtype min_sigma_ {50.0}; private: /** Sparse dwdp implicit temporary storage (shape `ndwdp`) */ diff --git a/deps/AMICI/include/amici/newton_solver.h b/deps/AMICI/include/amici/newton_solver.h index 73a924a97..01c033aeb 100644 --- a/deps/AMICI/include/amici/newton_solver.h +++ b/deps/AMICI/include/amici/newton_solver.h @@ -154,6 +154,8 @@ class NewtonSolverDense : public NewtonSolver { NewtonSolverDense(const NewtonSolverDense&) = delete; + NewtonSolverDense& operator=(const NewtonSolverDense& other) = delete; + ~NewtonSolverDense() override; /** @@ -212,6 +214,8 @@ class NewtonSolverSparse : public NewtonSolver { NewtonSolverSparse(const NewtonSolverSparse&) = delete; + NewtonSolverSparse& operator=(const NewtonSolverSparse& other) = delete; + ~NewtonSolverSparse() override; /** diff --git a/deps/AMICI/include/amici/rdata.h b/deps/AMICI/include/amici/rdata.h index 819fc1716..ec8fe146b 100644 --- a/deps/AMICI/include/amici/rdata.h +++ b/deps/AMICI/include/amici/rdata.h @@ -29,18 +29,17 @@ namespace amici { /** * @brief Stores all data to be returned by amici::runAmiciSimulation. * - * NOTE: multidimensional arrays are stored in row-major order - * (FORTRAN-style) + * NOTE: multi-dimensional arrays are stored in row-major order (C-style) */ class ReturnData: public ModelDimensions { public: /** - * @brief default constructor + * @brief Default constructor */ ReturnData() = default; /** - * @brief ReturnData + * @brief Constructor * @param ts see amici::SimulationParameters::ts * @param model_dimensions Model dimensions * @param nplist see amici::ModelDimensions::nplist @@ -52,8 +51,10 @@ class ReturnData: public ModelDimensions { * @param sensi see amici::Solver::sensi * @param sensi_meth see amici::Solver::sensi_meth * @param rdrm see amici::Solver::rdata_reporting - * @param quadratic_llh whether model defines a quadratic nllh and computing res, sres and - * FIM makes sense + * @param quadratic_llh whether model defines a quadratic nllh and + * computing res, sres and FIM makes sense + * @param sigma_res indicates whether additional residuals are to be added for each sigma + * @param sigma_offset offset to ensure real-valuedness of sigma residuals */ ReturnData(std::vector ts, ModelDimensions const& model_dimensions, @@ -61,7 +62,8 @@ class ReturnData: public ModelDimensions { int newton_maxsteps, std::vector pscale, SecondOrderMode o2mode, SensitivityOrder sensi, SensitivityMethod sensi_meth, - RDataReporting rdrm, bool quadratic_llh); + RDataReporting rdrm, bool quadratic_llh, bool sigma_res, + realtype sigma_offset); /** * @brief constructor that uses information from model and solver to @@ -76,10 +78,10 @@ class ReturnData: public ModelDimensions { /** * @brief constructor that uses information from model and solver to * appropriately initialize fields - * @param preeq simulated preequilibration problem, pass nullptr to ignore - * @param fwd simulated forward problem, pass nullptr to ignore - * @param bwd simulated backward problem, pass nullptr to ignore - * @param posteq simulated postequilibration problem, pass nullptr to ignore + * @param preeq simulated preequilibration problem, pass `nullptr` to ignore + * @param fwd simulated forward problem, pass `nullptr` to ignore + * @param bwd simulated backward problem, pass `nullptr` to ignore + * @param posteq simulated postequilibration problem, pass `nullptr` to ignore * @param model matching model instance * @param solver matching solver instance * @param edata matching experimental data @@ -137,7 +139,7 @@ class ReturnData: public ModelDimensions { std::vector srz; /** - * second order parameter derivative of event trigger output (shape + * second-order parameter derivative of event trigger output (shape * `nmaxevent` x `nztrue` x `nplist` x `nplist`, row-major) */ std::vector s2rz; @@ -305,28 +307,30 @@ class ReturnData: public ModelDimensions { std::vector sx0; /** - * preequilibration sensitivities found by Newton solver (shape `nplist` x `nx`, row-major) + * preequilibration sensitivities found by Newton solver + * (shape `nplist` x `nx`, row-major) */ std::vector sx_ss; - /** loglikelihood value */ + /** log-likelihood value */ realtype llh = 0.0; - /** chi2 value */ + /** \f$\chi^2\f$ value */ realtype chi2 = 0.0; - /** parameter derivative of loglikelihood (shape `nplist`) */ + /** parameter derivative of log-likelihood (shape `nplist`) */ std::vector sllh; /** - * second order parameter derivative of loglikelihood (shape `nJ-1` x `nplist`, row-major) + * second-order parameter derivative of log-likelihood + * (shape `nJ-1` x `nplist`, row-major) */ std::vector s2llh; /** status code */ int status = 0; - /** number of states (alias nx_rdata, kept for backward compatibility) */ + /** number of states (alias `nx_rdata`, kept for backward compatibility) */ int nx{0}; /** @@ -347,10 +351,10 @@ class ReturnData: public ModelDimensions { /** maximal number of newton iterations for steady state calculation */ int newton_maxsteps{0}; - /** scaling of parameterization (lin,log,log10) */ + /** scaling of parameterization */ std::vector pscale; - /** flag indicating whether second order sensitivities were requested */ + /** flag indicating whether second-order sensitivities were requested */ SecondOrderMode o2mode{SecondOrderMode::none}; /** sensitivity order */ @@ -371,9 +375,15 @@ class ReturnData: public ModelDimensions { template friend void boost::serialization::serialize(Archive &ar, ReturnData &r, unsigned int version); + + /** boolean indicating whether residuals for standard deviations have been added */ + bool sigma_res; protected: - + + /** offset for sigma_residuals */ + realtype sigma_offset; + /** timepoint for model evaluation*/ realtype t_; @@ -425,16 +435,16 @@ class ReturnData: public ModelDimensions { void initializeObjectiveFunction(bool enable_chi2); /** - * @brief extracts data from a preequilibration steadystateproblem - * @param preeq Steadystateproblem for preequilibration + * @brief extracts data from a preequilibration SteadystateProblem + * @param preeq SteadystateProblem for preequilibration * @param model Model instance to compute return values */ void processPreEquilibration(SteadystateProblem const &preeq, Model &model); /** - * @brief extracts data from a preequilibration steadystateproblem - * @param posteq Steadystateproblem for postequilibration + * @brief extracts data from a preequilibration SteadystateProblem + * @param posteq SteadystateProblem for postequilibration * @param model Model instance to compute return values * @param edata ExpData instance containing observable data */ @@ -457,7 +467,7 @@ class ReturnData: public ModelDimensions { * @brief extracts results from backward problem * @param fwd forward problem * @param bwd backward problem - * @param preeq Steadystateproblem for preequilibration + * @param preeq SteadystateProblem for preequilibration * @param model model that was used for forward/backward simulation */ void processBackwardProblem(ForwardProblem const &fwd, @@ -516,8 +526,9 @@ class ReturnData: public ModelDimensions { /** * @brief Chi-squared function * @param it time index + * @param edata ExpData instance containing observable data */ - void fchi2(int it); + void fchi2(int it, const ExpData &edata); /** * @brief Residual sensitivity function @@ -572,8 +583,8 @@ class ReturnData: public ModelDimensions { } /** - * @brief Extracts output information for data-points, expects that x_solver and sx_solver were - * were set appropriately + * @brief Extracts output information for data-points, expects that + * x_solver_ and sx_solver_ were set appropriately * @param it timepoint index * @param model model that was used in forward solve * @param edata ExpData instance carrying experimental data @@ -581,8 +592,8 @@ class ReturnData: public ModelDimensions { void getDataOutput(int it, Model &model, ExpData const *edata); /** - * @brief Extracts data information for forward sensitivity analysis, expects that x_solver and - * sx_solver were were set appropriately + * @brief Extracts data information for forward sensitivity analysis, + * expects that x_solver_ and sx_solver_ were set appropriately * @param it index of current timepoint * @param model model that was used in forward solve * @param edata ExpData instance carrying experimental data @@ -590,10 +601,11 @@ class ReturnData: public ModelDimensions { void getDataSensisFSA(int it, Model &model, ExpData const *edata); /** - * @brief Extracts output information for events, expects that x_solver and sx_solver were - * were set appropriately + * @brief Extracts output information for events, expects that x_solver_ + * and sx_solver_ were set appropriately * @param t event timepoint - * @param rootidx information about which roots fired (1 indicating fired, 0/-1 for not) + * @param rootidx information about which roots fired + * (1 indicating fired, 0/-1 for not) * @param model model that was used in forward solve * @param edata ExpData instance carrying experimental data */ @@ -601,8 +613,8 @@ class ReturnData: public ModelDimensions { Model &model, ExpData const *edata); /** - * @brief Extracts event information for forward sensitivity analysis, expects that x_solver and - * sx_solver were set appropriately + * @brief Extracts event information for forward sensitivity analysis, + * expects that x_solver_ and sx_solver_ were set appropriately * @param ie index of event type * @param t event timepoint * @param model model that was used in forward solve @@ -615,11 +627,13 @@ class ReturnData: public ModelDimensions { * @brief Updates contribution to likelihood from quadratures (xQB), * if preequilibration was run in adjoint mode * @param model model that was used for forward/backward simulation - * @param preeq Steadystateproblem for preequilibration + * @param preeq SteadystateProblem for preequilibration + * @param llhS0 contribution to likelihood for initial state sensitivities + * of preequilibration * @param xQB vector with quadratures from adjoint computation */ void handleSx0Backward(const Model &model, SteadystateProblem const &preeq, - AmiVector &xQB) const; + std::vector &llhS0, AmiVector &xQB) const; /** * @brief Updates contribution to likelihood for initial state sensitivities diff --git a/deps/AMICI/include/amici/returndata_matlab.h b/deps/AMICI/include/amici/returndata_matlab.h index c4944622f..ae9b05885 100644 --- a/deps/AMICI/include/amici/returndata_matlab.h +++ b/deps/AMICI/include/amici/returndata_matlab.h @@ -53,7 +53,7 @@ void writeMatlabField0(mxArray *matlabStruct, const char *fieldName, */ template void writeMatlabField1(mxArray *matlabStruct, const char *fieldName, - std::vector const &fieldData, const int dim0); + gsl::span const &fieldData, const int dim0); /** * @brief initialize matrix, attach to the field and write data diff --git a/deps/AMICI/include/amici/serialization.h b/deps/AMICI/include/amici/serialization.h index f816d5663..ebb2ec87d 100644 --- a/deps/AMICI/include/amici/serialization.h +++ b/deps/AMICI/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_; } @@ -290,18 +292,22 @@ char *serializeToChar(T const& data, int *size) { template T deserializeFromChar(const char *buffer, int size) { + namespace ba = ::boost::archive; + namespace bio = ::boost::iostreams; + + bio::basic_array_source device(buffer, size); + bio::stream> s(device); + + T data; + try { - ::boost::iostreams::basic_array_source device(buffer, size); - ::boost::iostreams::stream<::boost::iostreams::basic_array_source> s( - device); - ::boost::archive::binary_iarchive iar(s); - T data; + // archive must be destroyed BEFORE returning + ba::binary_iarchive iar(s); iar >> data; - - return data; - } catch(::boost::archive::archive_exception const& e) { + } catch(ba::archive_exception const& e) { throw AmiException("Deserialization from char failed: %s", e.what()); } + return data; } /** @@ -314,21 +320,22 @@ T deserializeFromChar(const char *buffer, int size) { template std::string serializeToString(T const& data) { - try { - std::string serialized; - ::boost::iostreams::back_insert_device inserter(serialized); - ::boost::iostreams::stream< - ::boost::iostreams::back_insert_device> - s(inserter); - ::boost::archive::binary_oarchive oar(s); + namespace ba = ::boost::archive; + namespace bio = ::boost::iostreams; - oar << data; - s.flush(); + std::string serialized; + bio::back_insert_device inserter(serialized); + bio::stream> os(inserter); - return serialized; - } catch(::boost::archive::archive_exception const& e) { + try { + // archive must be destroyed BEFORE returning + ba::binary_oarchive oar(os); + oar << data; + } catch(ba::archive_exception const& e) { throw AmiException("Serialization to string failed: %s", e.what()); } + + return serialized; } /** @@ -341,22 +348,23 @@ std::string serializeToString(T const& data) { template std::vector serializeToStdVec(T const& data) { - try{ - std::string serialized; - ::boost::iostreams::back_insert_device inserter(serialized); - ::boost::iostreams::stream<::boost::iostreams::back_insert_device> - s(inserter); - ::boost::archive::binary_oarchive oar(s); + namespace ba = ::boost::archive; + namespace bio = ::boost::iostreams; - oar << data; - s.flush(); + std::vector buffer; + bio::stream< + bio::back_insert_device< + std::vector>> os(buffer); - std::vector buf(serialized.begin(), serialized.end()); - - return buf; - } catch(::boost::archive::archive_exception const& e) { - throw AmiException("Serialization to StdVec failed: %s", e.what()); + try{ + // archive must be destroyed BEFORE returning + ba::binary_oarchive oar(os); + oar << data; + } catch(ba::archive_exception const& e) { + throw AmiException("Serialization to std::vector failed: %s", e.what()); } + + return buffer; } /** @@ -369,20 +377,23 @@ std::vector serializeToStdVec(T const& data) { template T deserializeFromString(std::string const& serialized) { - try{ - ::boost::iostreams::basic_array_source device(serialized.data(), - serialized.size()); - ::boost::iostreams::stream<::boost::iostreams::basic_array_source> s( - device); - ::boost::archive::binary_iarchive iar(s); - T deserialized; + namespace ba = ::boost::archive; + namespace bio = ::boost::iostreams; - iar >> deserialized; + bio::basic_array_source device(serialized.data(), serialized.size()); + bio::stream> os(device); + T deserialized; - return deserialized; - } catch(::boost::archive::archive_exception const& e) { - throw AmiException("Deserialization from StdVec failed: %s", e.what()); + try{ + // archive must be destroyed BEFORE returning + ba::binary_iarchive iar(os); + iar >> deserialized; + } catch(ba::archive_exception const& e) { + throw AmiException("Deserialization from std::string failed: %s", + e.what()); } + + return deserialized; } diff --git a/deps/AMICI/include/amici/steadystateproblem.h b/deps/AMICI/include/amici/steadystateproblem.h index 3629a4702..bd7efe47c 100644 --- a/deps/AMICI/include/amici/steadystateproblem.h +++ b/deps/AMICI/include/amici/steadystateproblem.h @@ -248,7 +248,6 @@ class SteadystateProblem { return x_; }; - /** * @brief Returns state sensitivity at steadystate * @return sx @@ -321,6 +320,12 @@ class SteadystateProblem { */ void getAdjointUpdates(Model &model, const ExpData &edata); + /** + * @brief Return the adjoint state + * @return xB adjoint state + */ + AmiVector const& getAdjointState() const { return xB_; } + /** * @brief Accessor for xQB * @return xQB @@ -372,7 +377,7 @@ class SteadystateProblem { AmiVector xQ_; /** quadrature state vector */ AmiVector xQB_; - /** quadrature state vector */ + /** time-derivative of quadrature state vector */ AmiVector xQBdot_; /** maximum number of steps for Newton solver for allocating numlinsteps */ diff --git a/deps/AMICI/include/amici/vector.h b/deps/AMICI/include/amici/vector.h index 25462354b..c50499f10 100644 --- a/deps/AMICI/include/amici/vector.h +++ b/deps/AMICI/include/amici/vector.h @@ -14,7 +14,7 @@ namespace amici { /** Since const N_Vector is not what we want */ using const_N_Vector = - std::add_const::type>::type *; + std::add_const_t> *; inline const realtype* N_VGetArrayPointerConst(const_N_Vector x) { return N_VGetArrayPointer(const_cast(x)); diff --git a/deps/AMICI/matlab/@amimodel/amimodel.m b/deps/AMICI/matlab/@amimodel/amimodel.m index 1b77aac6b..cef415bdf 100644 --- a/deps/AMICI/matlab/@amimodel/amimodel.m +++ b/deps/AMICI/matlab/@amimodel/amimodel.m @@ -241,6 +241,8 @@ function updateWrapPath(this,wrap_path) generateC(this) + generateRebuildM(this) + compileC(this) generateM(this,amimodelo2) diff --git a/deps/AMICI/matlab/@amimodel/generateC.m b/deps/AMICI/matlab/@amimodel/generateC.m index 6b5e8264f..d2d0435a3 100644 --- a/deps/AMICI/matlab/@amimodel/generateC.m +++ b/deps/AMICI/matlab/@amimodel/generateC.m @@ -191,12 +191,12 @@ function generateC(this) initstr = num2str(transpose(this.z2event), '%d, '); fprintf(fid,[' std::vector{' initstr(1:end-1) '})\n']); fprintf(fid,[' {};\n\n']); -fprintf(fid,[' virtual amici::Model* clone() const override { return new Model_' this.modelname '(*this); };\n\n']); -fprintf(fid,[' const std::string getAmiciCommit() const override { return "' getCommitHash(fileparts(fileparts(mfilename('fullpath')))) '"; };\n\n']); +fprintf(fid,[' amici::Model* clone() const override { return new Model_' this.modelname '(*this); };\n\n']); +fprintf(fid,[' std::string getAmiciCommit() const override { return "' getCommitHash(fileparts(fileparts(mfilename('fullpath')))) '"; };\n\n']); for ifun = this.funs cppFunctionName = strrep(ifun{1}, 'sigma_', 'sigma'); - fprintf(fid,[' virtual void f' cppFunctionName this.fun.(ifun{1}).argstr ' override {\n']); + fprintf(fid,[' void f' cppFunctionName this.fun.(ifun{1}).argstr ' override {\n']); if(checkIfFunctionBodyIsNonEmpty(this,ifun{1})) fprintf(fid,[' ' cppFunctionName '_' this.modelname '' removeTypes(this.fun.(ifun{1}).argstr) ';\n']); end diff --git a/deps/AMICI/matlab/@amimodel/generateRebuildM.m b/deps/AMICI/matlab/@amimodel/generateRebuildM.m new file mode 100644 index 000000000..56b213af7 --- /dev/null +++ b/deps/AMICI/matlab/@amimodel/generateRebuildM.m @@ -0,0 +1,26 @@ +function generateRebuildM(this) +% generateRebuildM generates a Matlab script for recompilation of this +% model +% +% Return values: +% void + + +filename = fullfile(this.wrap_path,'models',this.modelname,['rebuild_',this.modelname,'.m']); +% would require struct to string conversion, skipping for now +amimodelo2 = '[]'; + +fid = fopen(filename, 'w'); + +fprintf(fid, ['function ' ['rebuild_', this.modelname] '()\n']); +fprintf(fid, ['modelName = ''' this.modelname ''';\n']); +fprintf(fid, 'amimodel.compileAndLinkModel(modelName, '''', [], [], [], []);\n'); +fprintf(fid, ['amimodel.generateMatlabWrapper(' num2str(this.nx) ', ' num2str(this.ny) ... + ', ' num2str(this.np) ', ' num2str(this.nk) ', ' num2str(this.nz) ', ' num2str(this.o2flag) ', ' ... + amimodelo2 ', [''simulate_'' modelName ''.m''], ''' ... + this.modelname ''', ''' this.param ''', ' num2str(this.forward) ', ' num2str(this.adjoint) ');\n']); +fprintf(fid, 'end\n'); + +fclose(fid); +end + diff --git a/deps/AMICI/matlab/amiwrap.m b/deps/AMICI/matlab/amiwrap.m index 842b3a3a5..838d95c10 100644 --- a/deps/AMICI/matlab/amiwrap.m +++ b/deps/AMICI/matlab/amiwrap.m @@ -169,8 +169,10 @@ function amiwrap( varargin ) % generate the matlab wrapper disp('Generating M code ...') if(o2flag) + model.generateRebuildM() model.generateM(modelo2); else + model.generateRebuildM() model.generateM([]); end diff --git a/deps/AMICI/matlab/tests/testModels.m b/deps/AMICI/matlab/tests/testModels.m index a0e3516a9..baf1c57bd 100644 --- a/deps/AMICI/matlab/tests/testModels.m +++ b/deps/AMICI/matlab/tests/testModels.m @@ -4,24 +4,33 @@ function testModels() % disable specific warnings for these tests, some tests are supposed % to produce warnings warningreset = warning; - warning('off','AMICI:mex:simulation') - warning('off','AMICI:mex:CVODES:CVode:TOO_MUCH_WORK') + warning('off','AMICI:simulation') + warning('off','AMICI:CVODES:CVode:TOO_MUCH_WORK') + % second-order currently not supported via rebuild_*.m (GitHub Actions) + % only via wrapTestModels ignoredTests = {'/model_jakstat_adjoint/sensiadjointemptysensind', ... - '/model_jakstat_adjoint/sensiforwardemptysensind'}; + '/model_jakstat_adjoint/sensiforwardemptysensind', ... + '/model_jakstat_adjoint/sensi2adjoint', ... + '/model_jakstat_adjoint/sensi2forward', ... + '/model_jakstat_adjoint/sensi2forwardlogparam', ... + '/model_neuron/sensi2forward'}; + model_dir = [fileparts(mfilename('fullpath')) '/../../models/']; cd(fileparts(mfilename('fullpath'))) addpath(genpath('../../tests/cpputest')); addpath(genpath('../examples')); % wrapTestModels() - cd(fileparts(mfilename('fullpath'))) + cd(fileparts(mfilename('fullpath'))) hdf5file = fullfile(fileparts(mfilename('fullpath')), ... '../../tests/cpputest', 'expectedResults.h5'); - + info = h5info(hdf5file); for imodel = 1:length(info.Groups) - if(~isempty(regexp(info.Groups(imodel).Name(2:end),'^model_neuron'))) + modelname = info.Groups(imodel).Name(2:end); + + if(~isempty(regexp(modelname,'^model_neuron'))) model_atol = 1e-9; model_rtol = 1e-4; else @@ -29,13 +38,25 @@ function testModels() model_rtol = 1e-5; end for itest = 1:length(info.Groups(imodel).Groups) - if(ismember(info.Groups(imodel).Groups(itest).Name, ignoredTests)) + testname = info.Groups(imodel).Groups(itest).Name; + if(ismember(testname, ignoredTests)) continue end + + display(testname); [results,options,data,t,theta,kappa] = readDataFromHDF5(info.Groups(imodel).Groups(itest),hdf5file); - sol = getResults(info.Groups(imodel).Name(2:end),options,data,t,theta,kappa); + + % rebuild model + old_path = addpath([model_dir modelname]); + old_pwd = cd([model_dir modelname]); + rebuild = str2func(['rebuild_' modelname]); + rebuild(); + cd(old_pwd); + + sol = getResults(modelname,options,data,t,theta,kappa); compareResults(sol,results); + path(old_path); end end diff --git a/deps/AMICI/models/model_calvetti/model_calvetti.h b/deps/AMICI/models/model_calvetti/model_calvetti.h index 97ba91b8f..0a326de31 100644 --- a/deps/AMICI/models/model_calvetti/model_calvetti.h +++ b/deps/AMICI/models/model_calvetti/model_calvetti.h @@ -1,6 +1,6 @@ #ifndef _amici_model_calvetti_h #define _amici_model_calvetti_h -/* Generated by amiwrap (R2017b) 0a85246ec55554a1db269634c806f27f071f487f */ +/* Generated by amiwrap (R2017b) 2bd39716102b9842354964196889d40d2eb2731c */ #include #include #include "amici/defines.h" @@ -65,138 +65,138 @@ class Model_model_calvetti : public amici::Model_DAE { std::vector{}) {}; - virtual amici::Model* clone() const override { return new Model_model_calvetti(*this); }; + amici::Model* clone() const override { return new Model_model_calvetti(*this); }; - const std::string getAmiciCommit() const override { return "0a85246ec55554a1db269634c806f27f071f487f"; }; + std::string getAmiciCommit() const override { return "2bd39716102b9842354964196889d40d2eb2731c"; }; - virtual void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { + void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_calvetti(JSparse, t, x, p, k, h, cj, dx, w, dwdx); } - virtual void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { Jy_model_calvetti(nllh, iy, p, k, y, sigmay, my); } - virtual void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fM(realtype *M, const realtype t, const realtype *x, const realtype *p, const realtype *k) override { + void fM(realtype *M, const realtype t, const realtype *x, const realtype *p, const realtype *k) override { M_model_calvetti(M, t, x, p, k); } - virtual void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydsigma_model_calvetti(dJydsigma, iy, p, k, y, sigmay, my); } - virtual void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydy_model_calvetti(dJydy, iy, p, k, y, sigmay, my); } - virtual void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { } - virtual void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { + void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { } - virtual void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { + void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { } - virtual void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { + void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { dwdx_model_calvetti(dwdx, t, x, p, k, h, w, tcl); } - virtual void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *dx, const realtype *w, const realtype *dwdp) override { + void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *dx, const realtype *w, const realtype *dwdp) override { } - virtual void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { } - virtual void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { dydx_model_calvetti(dydx, t, x, p, k, h, w, dwdx); } - virtual void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx) override { root_model_calvetti(root, t, x, p, k, h, dx); } - virtual void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { sigmay_model_calvetti(sigmay, t, p, k); } - virtual void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { + void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { } - virtual void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { } - virtual void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { + void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { } - virtual void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { w_model_calvetti(w, t, x, p, k, h, tcl); } - virtual void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { + void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { x0_model_calvetti(x0, t, p, k); } - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx, const realtype *w) override { + void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx, const realtype *w) override { xdot_model_calvetti(xdot, t, x, p, k, h, dx, w); } - virtual void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { y_model_calvetti(y, t, x, p, k, h, w); } - virtual void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } }; diff --git a/deps/AMICI/models/model_calvetti/rebuild_model_calvetti.m b/deps/AMICI/models/model_calvetti/rebuild_model_calvetti.m new file mode 100644 index 000000000..ef44a7afc --- /dev/null +++ b/deps/AMICI/models/model_calvetti/rebuild_model_calvetti.m @@ -0,0 +1,5 @@ +function rebuild_model_calvetti() +modelName = 'model_calvetti'; +amimodel.compileAndLinkModel(modelName, '', [], [], [], []); +amimodel.generateMatlabWrapper(6, 6, 0, 6, 0, 0, [], ['simulate_' modelName '.m'], 'model_calvetti', 'lin', 1, 1); +end diff --git a/deps/AMICI/models/model_dirac/model_dirac.h b/deps/AMICI/models/model_dirac/model_dirac.h index 5a22ab5d5..2eb5cdb4b 100644 --- a/deps/AMICI/models/model_dirac/model_dirac.h +++ b/deps/AMICI/models/model_dirac/model_dirac.h @@ -1,6 +1,6 @@ #ifndef _amici_model_dirac_h #define _amici_model_dirac_h -/* Generated by amiwrap (R2017b) 0a85246ec55554a1db269634c806f27f071f487f */ +/* Generated by amiwrap (R2017b) 2bd39716102b9842354964196889d40d2eb2731c */ #include #include #include "amici/defines.h" @@ -65,135 +65,135 @@ class Model_model_dirac : public amici::Model_ODE { std::vector{}) {}; - virtual amici::Model* clone() const override { return new Model_model_dirac(*this); }; + amici::Model* clone() const override { return new Model_model_dirac(*this); }; - const std::string getAmiciCommit() const override { return "0a85246ec55554a1db269634c806f27f071f487f"; }; + std::string getAmiciCommit() const override { return "2bd39716102b9842354964196889d40d2eb2731c"; }; - virtual void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_dirac(JSparse, t, x, p, k, h, w, dwdx); } - virtual void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { Jy_model_dirac(nllh, iy, p, k, y, sigmay, my); } - virtual void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydsigma_model_dirac(dJydsigma, iy, p, k, y, sigmay, my); } - virtual void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydy_model_dirac(dJydy, iy, p, k, y, sigmay, my); } - virtual void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { deltasx_model_dirac(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); } - virtual void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { + void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { deltax_model_dirac(deltax, t, x, p, k, h, ie, xdot, xdot_old); } - virtual void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { + void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { } - virtual void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { + void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { } - virtual void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dxdotdp_model_dirac(dxdotdp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { } - virtual void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { dydx_model_dirac(dydx, t, x, p, k, h, w, dwdx); } - virtual void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { root_model_dirac(root, t, x, p, k, h); } - virtual void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { sigmay_model_dirac(sigmay, t, p, k); } - virtual void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { + void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { } - virtual void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { stau_model_dirac(stau, t, x, p, k, h, sx, ip, ie); } - virtual void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { + void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { } - virtual void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { } - virtual void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { + void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { } - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { xdot_model_dirac(xdot, t, x, p, k, h, w); } - virtual void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { y_model_dirac(y, t, x, p, k, h, w); } - virtual void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } }; diff --git a/deps/AMICI/models/model_dirac/rebuild_model_dirac.m b/deps/AMICI/models/model_dirac/rebuild_model_dirac.m new file mode 100644 index 000000000..66aa6f62d --- /dev/null +++ b/deps/AMICI/models/model_dirac/rebuild_model_dirac.m @@ -0,0 +1,5 @@ +function rebuild_model_dirac() +modelName = 'model_dirac'; +amimodel.compileAndLinkModel(modelName, '', [], [], [], []); +amimodel.generateMatlabWrapper(2, 1, 4, 0, 0, 0, [], ['simulate_' modelName '.m'], 'model_dirac', 'log10', 1, 1); +end diff --git a/deps/AMICI/models/model_events/model_events.h b/deps/AMICI/models/model_events/model_events.h index 77c803e25..2cf13ace8 100644 --- a/deps/AMICI/models/model_events/model_events.h +++ b/deps/AMICI/models/model_events/model_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_events_h #define _amici_model_events_h -/* Generated by amiwrap (R2017b) 0a85246ec55554a1db269634c806f27f071f487f */ +/* Generated by amiwrap (R2017b) 2bd39716102b9842354964196889d40d2eb2731c */ #include #include #include "amici/defines.h" @@ -79,148 +79,148 @@ class Model_model_events : public amici::Model_ODE { std::vector{1, 2}) {}; - virtual amici::Model* clone() const override { return new Model_model_events(*this); }; + amici::Model* clone() const override { return new Model_model_events(*this); }; - const std::string getAmiciCommit() const override { return "0a85246ec55554a1db269634c806f27f071f487f"; }; + std::string getAmiciCommit() const override { return "2bd39716102b9842354964196889d40d2eb2731c"; }; - virtual void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_events(JSparse, t, x, p, k, h, w, dwdx); } - virtual void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { Jrz_model_events(nllh, iz, p, k, rz, sigmaz); } - virtual void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { Jy_model_events(nllh, iy, p, k, y, sigmay, my); } - virtual void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { Jz_model_events(nllh, iz, p, k, z, sigmaz, mz); } - virtual void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { dJrzdsigma_model_events(dJrzdsigma, iz, p, k, rz, sigmaz); } - virtual void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { dJrzdz_model_events(dJrzdz, iz, p, k, rz, sigmaz); } - virtual void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydsigma_model_events(dJydsigma, iy, p, k, y, sigmay, my); } - virtual void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydy_model_events(dJydy, iy, p, k, y, sigmay, my); } - virtual void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { dJzdsigma_model_events(dJzdsigma, iz, p, k, z, sigmaz, mz); } - virtual void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { dJzdz_model_events(dJzdz, iz, p, k, z, sigmaz, mz); } - virtual void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { deltasx_model_events(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); } - virtual void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { + void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { } - virtual void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { drzdx_model_events(drzdx, ie, t, x, p, k, h); } - virtual void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { + void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { } - virtual void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { + void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { } - virtual void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dxdotdp_model_events(dxdotdp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dydp_model_events(dydp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { dydx_model_events(dydx, t, x, p, k, h, w, dwdx); } - virtual void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { dzdx_model_events(dzdx, ie, t, x, p, k, h); } - virtual void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { root_model_events(root, t, x, p, k, h); } - virtual void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { rz_model_events(rz, ie, t, x, p, k, h); } - virtual void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { sigmay_model_events(sigmay, t, p, k); } - virtual void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { + void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { sigmaz_model_events(sigmaz, t, p, k); } - virtual void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { srz_model_events(srz, ie, t, x, p, k, h, sx, ip); } - virtual void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { stau_model_events(stau, t, x, p, k, h, sx, ip, ie); } - virtual void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { + void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { } - virtual void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { sz_model_events(sz, ie, t, x, p, k, h, sx, ip); } - virtual void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { } - virtual void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { + void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { x0_model_events(x0, t, p, k); } - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { xdot_model_events(xdot, t, x, p, k, h, w); } - virtual void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { y_model_events(y, t, x, p, k, h, w); } - virtual void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { z_model_events(z, ie, t, x, p, k, h); } diff --git a/deps/AMICI/models/model_events/rebuild_model_events.m b/deps/AMICI/models/model_events/rebuild_model_events.m new file mode 100644 index 000000000..bbb591694 --- /dev/null +++ b/deps/AMICI/models/model_events/rebuild_model_events.m @@ -0,0 +1,5 @@ +function rebuild_model_events() +modelName = 'model_events'; +amimodel.compileAndLinkModel(modelName, '', [], [], [], []); +amimodel.generateMatlabWrapper(3, 1, 4, 4, 2, 0, [], ['simulate_' modelName '.m'], 'model_events', 'log10', 1, 1); +end diff --git a/deps/AMICI/models/model_jakstat_adjoint/model_jakstat_adjoint.h b/deps/AMICI/models/model_jakstat_adjoint/model_jakstat_adjoint.h index b4b1d35c8..ce4eb29b7 100644 --- a/deps/AMICI/models/model_jakstat_adjoint/model_jakstat_adjoint.h +++ b/deps/AMICI/models/model_jakstat_adjoint/model_jakstat_adjoint.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_h #define _amici_model_jakstat_adjoint_h -/* Generated by amiwrap (R2017b) 0a85246ec55554a1db269634c806f27f071f487f */ +/* Generated by amiwrap (R2017b) 2bd39716102b9842354964196889d40d2eb2731c */ #include #include #include "amici/defines.h" @@ -68,138 +68,138 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { std::vector{}) {}; - virtual amici::Model* clone() const override { return new Model_model_jakstat_adjoint(*this); }; + amici::Model* clone() const override { return new Model_model_jakstat_adjoint(*this); }; - const std::string getAmiciCommit() const override { return "0a85246ec55554a1db269634c806f27f071f487f"; }; + std::string getAmiciCommit() const override { return "2bd39716102b9842354964196889d40d2eb2731c"; }; - virtual void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint(JSparse, t, x, p, k, h, w, dwdx); } - virtual void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { Jy_model_jakstat_adjoint(nllh, iy, p, k, y, sigmay, my); } - virtual void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydsigma_model_jakstat_adjoint(dJydsigma, iy, p, k, y, sigmay, my); } - virtual void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydy_model_jakstat_adjoint(dJydy, iy, p, k, y, sigmay, my); } - virtual void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { } - virtual void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { + void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { } - virtual void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { dsigmaydp_model_jakstat_adjoint(dsigmaydp, t, p, k, ip); } - virtual void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { + void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { dwdp_model_jakstat_adjoint(dwdp, t, x, p, k, h, w, tcl, stcl); } - virtual void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { + void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { dwdx_model_jakstat_adjoint(dwdx, t, x, p, k, h, w, tcl); } - virtual void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dxdotdp_model_jakstat_adjoint(dxdotdp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dydp_model_jakstat_adjoint(dydp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { dydx_model_jakstat_adjoint(dydx, t, x, p, k, h, w, dwdx); } - virtual void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { sigmay_model_jakstat_adjoint(sigmay, t, p, k); } - virtual void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { + void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { } - virtual void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { } - virtual void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { + void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { sx0_model_jakstat_adjoint(sx0, t, x0, p, k, ip); } - virtual void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { w_model_jakstat_adjoint(w, t, x, p, k, h, tcl); } - virtual void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { + void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { x0_model_jakstat_adjoint(x0, t, p, k); } - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { xdot_model_jakstat_adjoint(xdot, t, x, p, k, h, w); } - virtual void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { y_model_jakstat_adjoint(y, t, x, p, k, h, w); } - virtual void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } }; diff --git a/deps/AMICI/models/model_jakstat_adjoint/rebuild_model_jakstat_adjoint.m b/deps/AMICI/models/model_jakstat_adjoint/rebuild_model_jakstat_adjoint.m new file mode 100644 index 000000000..443952d4c --- /dev/null +++ b/deps/AMICI/models/model_jakstat_adjoint/rebuild_model_jakstat_adjoint.m @@ -0,0 +1,5 @@ +function rebuild_model_jakstat_adjoint() +modelName = 'model_jakstat_adjoint'; +amimodel.compileAndLinkModel(modelName, '', [], [], [], []); +amimodel.generateMatlabWrapper(9, 3, 17, 2, 0, 0, [], ['simulate_' modelName '.m'], 'model_jakstat_adjoint', 'log10', 1, 1); +end diff --git a/deps/AMICI/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h b/deps/AMICI/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h index f726def6e..273de3a97 100644 --- a/deps/AMICI/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h +++ b/deps/AMICI/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_o2_h #define _amici_model_jakstat_adjoint_o2_h -/* Generated by amiwrap (R2017b) 0a85246ec55554a1db269634c806f27f071f487f */ +/* Generated by amiwrap (R2017b) 2bd39716102b9842354964196889d40d2eb2731c */ #include #include #include "amici/defines.h" @@ -68,138 +68,138 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { std::vector{}) {}; - virtual amici::Model* clone() const override { return new Model_model_jakstat_adjoint_o2(*this); }; + amici::Model* clone() const override { return new Model_model_jakstat_adjoint_o2(*this); }; - const std::string getAmiciCommit() const override { return "0a85246ec55554a1db269634c806f27f071f487f"; }; + std::string getAmiciCommit() const override { return "2bd39716102b9842354964196889d40d2eb2731c"; }; - virtual void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint_o2(JSparse, t, x, p, k, h, w, dwdx); } - virtual void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { Jy_model_jakstat_adjoint_o2(nllh, iy, p, k, y, sigmay, my); } - virtual void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydsigma_model_jakstat_adjoint_o2(dJydsigma, iy, p, k, y, sigmay, my); } - virtual void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydy_model_jakstat_adjoint_o2(dJydy, iy, p, k, y, sigmay, my); } - virtual void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { } - virtual void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { + void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { } - virtual void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { dsigmaydp_model_jakstat_adjoint_o2(dsigmaydp, t, p, k, ip); } - virtual void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { + void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { dwdp_model_jakstat_adjoint_o2(dwdp, t, x, p, k, h, w, tcl, stcl); } - virtual void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { + void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { dwdx_model_jakstat_adjoint_o2(dwdx, t, x, p, k, h, w, tcl); } - virtual void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dxdotdp_model_jakstat_adjoint_o2(dxdotdp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dydp_model_jakstat_adjoint_o2(dydp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { dydx_model_jakstat_adjoint_o2(dydx, t, x, p, k, h, w, dwdx); } - virtual void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { sigmay_model_jakstat_adjoint_o2(sigmay, t, p, k); } - virtual void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { + void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { } - virtual void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { } - virtual void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { + void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { sx0_model_jakstat_adjoint_o2(sx0, t, x0, p, k, ip); } - virtual void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { w_model_jakstat_adjoint_o2(w, t, x, p, k, h, tcl); } - virtual void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { + void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { x0_model_jakstat_adjoint_o2(x0, t, p, k); } - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { xdot_model_jakstat_adjoint_o2(xdot, t, x, p, k, h, w); } - virtual void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { y_model_jakstat_adjoint_o2(y, t, x, p, k, h, w); } - virtual void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } }; diff --git a/deps/AMICI/models/model_nested_events/model_nested_events.h b/deps/AMICI/models/model_nested_events/model_nested_events.h index 0f5d29450..ceab6cb1a 100644 --- a/deps/AMICI/models/model_nested_events/model_nested_events.h +++ b/deps/AMICI/models/model_nested_events/model_nested_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_nested_events_h #define _amici_model_nested_events_h -/* Generated by amiwrap (R2017b) 0a85246ec55554a1db269634c806f27f071f487f */ +/* Generated by amiwrap (R2017b) 2bd39716102b9842354964196889d40d2eb2731c */ #include #include #include "amici/defines.h" @@ -68,138 +68,138 @@ class Model_model_nested_events : public amici::Model_ODE { std::vector{}) {}; - virtual amici::Model* clone() const override { return new Model_model_nested_events(*this); }; + amici::Model* clone() const override { return new Model_model_nested_events(*this); }; - const std::string getAmiciCommit() const override { return "0a85246ec55554a1db269634c806f27f071f487f"; }; + std::string getAmiciCommit() const override { return "2bd39716102b9842354964196889d40d2eb2731c"; }; - virtual void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_nested_events(JSparse, t, x, p, k, h, w, dwdx); } - virtual void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { Jy_model_nested_events(nllh, iy, p, k, y, sigmay, my); } - virtual void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydsigma_model_nested_events(dJydsigma, iy, p, k, y, sigmay, my); } - virtual void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydy_model_nested_events(dJydy, iy, p, k, y, sigmay, my); } - virtual void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { deltaqB_model_nested_events(deltaqB, t, x, p, k, h, ip, ie, xdot, xdot_old, xB); } - virtual void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { deltasx_model_nested_events(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); } - virtual void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { + void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { deltax_model_nested_events(deltax, t, x, p, k, h, ie, xdot, xdot_old); } - virtual void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { + void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { } - virtual void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { + void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { } - virtual void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dxdotdp_model_nested_events(dxdotdp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { } - virtual void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { dydx_model_nested_events(dydx, t, x, p, k, h, w, dwdx); } - virtual void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { root_model_nested_events(root, t, x, p, k, h); } - virtual void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { sigmay_model_nested_events(sigmay, t, p, k); } - virtual void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { + void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { } - virtual void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { stau_model_nested_events(stau, t, x, p, k, h, sx, ip, ie); } - virtual void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { + void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { sx0_model_nested_events(sx0, t, x0, p, k, ip); } - virtual void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { } - virtual void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { + void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { x0_model_nested_events(x0, t, p, k); } - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { xdot_model_nested_events(xdot, t, x, p, k, h, w); } - virtual void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { y_model_nested_events(y, t, x, p, k, h, w); } - virtual void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } }; diff --git a/deps/AMICI/models/model_nested_events/rebuild_model_nested_events.m b/deps/AMICI/models/model_nested_events/rebuild_model_nested_events.m new file mode 100644 index 000000000..38f3e1b9c --- /dev/null +++ b/deps/AMICI/models/model_nested_events/rebuild_model_nested_events.m @@ -0,0 +1,5 @@ +function rebuild_model_nested_events() +modelName = 'model_nested_events'; +amimodel.compileAndLinkModel(modelName, '', [], [], [], []); +amimodel.generateMatlabWrapper(1, 1, 5, 0, 0, 0, [], ['simulate_' modelName '.m'], 'model_nested_events', 'log10', 1, 1); +end diff --git a/deps/AMICI/models/model_neuron/model_neuron.h b/deps/AMICI/models/model_neuron/model_neuron.h index df2611a59..3aaeb06a4 100644 --- a/deps/AMICI/models/model_neuron/model_neuron.h +++ b/deps/AMICI/models/model_neuron/model_neuron.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_h #define _amici_model_neuron_h -/* Generated by amiwrap (R2017b) 0a85246ec55554a1db269634c806f27f071f487f */ +/* Generated by amiwrap (R2017b) 2bd39716102b9842354964196889d40d2eb2731c */ #include #include #include "amici/defines.h" @@ -82,151 +82,151 @@ class Model_model_neuron : public amici::Model_ODE { std::vector{1}) {}; - virtual amici::Model* clone() const override { return new Model_model_neuron(*this); }; + amici::Model* clone() const override { return new Model_model_neuron(*this); }; - const std::string getAmiciCommit() const override { return "0a85246ec55554a1db269634c806f27f071f487f"; }; + std::string getAmiciCommit() const override { return "2bd39716102b9842354964196889d40d2eb2731c"; }; - virtual void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron(JSparse, t, x, p, k, h, w, dwdx); } - virtual void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { Jrz_model_neuron(nllh, iz, p, k, rz, sigmaz); } - virtual void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { Jy_model_neuron(nllh, iy, p, k, y, sigmay, my); } - virtual void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { Jz_model_neuron(nllh, iz, p, k, z, sigmaz, mz); } - virtual void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { dJrzdsigma_model_neuron(dJrzdsigma, iz, p, k, rz, sigmaz); } - virtual void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { dJrzdz_model_neuron(dJrzdz, iz, p, k, rz, sigmaz); } - virtual void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydsigma_model_neuron(dJydsigma, iy, p, k, y, sigmay, my); } - virtual void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydy_model_neuron(dJydy, iy, p, k, y, sigmay, my); } - virtual void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { dJzdsigma_model_neuron(dJzdsigma, iz, p, k, z, sigmaz, mz); } - virtual void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { dJzdz_model_neuron(dJzdz, iz, p, k, z, sigmaz, mz); } - virtual void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { deltaqB_model_neuron(deltaqB, t, x, p, k, h, ip, ie, xdot, xdot_old, xB); } - virtual void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { deltasx_model_neuron(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); } - virtual void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { + void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { deltax_model_neuron(deltax, t, x, p, k, h, ie, xdot, xdot_old); } - virtual void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { deltaxB_model_neuron(deltaxB, t, x, p, k, h, ie, xdot, xdot_old, xB); } - virtual void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { drzdx_model_neuron(drzdx, ie, t, x, p, k, h); } - virtual void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { + void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { } - virtual void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { + void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { } - virtual void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dxdotdp_model_neuron(dxdotdp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { } - virtual void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { dydx_model_neuron(dydx, t, x, p, k, h, w, dwdx); } - virtual void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { dzdx_model_neuron(dzdx, ie, t, x, p, k, h); } - virtual void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { root_model_neuron(root, t, x, p, k, h); } - virtual void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { rz_model_neuron(rz, ie, t, x, p, k, h); } - virtual void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { sigmay_model_neuron(sigmay, t, p, k); } - virtual void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { + void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { sigmaz_model_neuron(sigmaz, t, p, k); } - virtual void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { srz_model_neuron(srz, ie, t, x, p, k, h, sx, ip); } - virtual void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { stau_model_neuron(stau, t, x, p, k, h, sx, ip, ie); } - virtual void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { + void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { sx0_model_neuron(sx0, t, x0, p, k, ip); } - virtual void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { sz_model_neuron(sz, ie, t, x, p, k, h, sx, ip); } - virtual void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { } - virtual void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { + void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { x0_model_neuron(x0, t, p, k); } - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { xdot_model_neuron(xdot, t, x, p, k, h, w); } - virtual void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { y_model_neuron(y, t, x, p, k, h, w); } - virtual void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { z_model_neuron(z, ie, t, x, p, k, h); } diff --git a/deps/AMICI/models/model_neuron/rebuild_model_neuron.m b/deps/AMICI/models/model_neuron/rebuild_model_neuron.m new file mode 100644 index 000000000..0c368819d --- /dev/null +++ b/deps/AMICI/models/model_neuron/rebuild_model_neuron.m @@ -0,0 +1,5 @@ +function rebuild_model_neuron() +modelName = 'model_neuron'; +amimodel.compileAndLinkModel(modelName, '', [], [], [], []); +amimodel.generateMatlabWrapper(2, 1, 4, 2, 1, 0, [], ['simulate_' modelName '.m'], 'model_neuron', 'log10', 1, 1); +end diff --git a/deps/AMICI/models/model_neuron_o2/model_neuron_o2.h b/deps/AMICI/models/model_neuron_o2/model_neuron_o2.h index 8ec152b98..79904d771 100644 --- a/deps/AMICI/models/model_neuron_o2/model_neuron_o2.h +++ b/deps/AMICI/models/model_neuron_o2/model_neuron_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_o2_h #define _amici_model_neuron_o2_h -/* Generated by amiwrap (R2017b) 0a85246ec55554a1db269634c806f27f071f487f */ +/* Generated by amiwrap (R2017b) 2bd39716102b9842354964196889d40d2eb2731c */ #include #include #include "amici/defines.h" @@ -84,153 +84,153 @@ class Model_model_neuron_o2 : public amici::Model_ODE { std::vector{1, 1, 1, 1, 1}) {}; - virtual amici::Model* clone() const override { return new Model_model_neuron_o2(*this); }; + amici::Model* clone() const override { return new Model_model_neuron_o2(*this); }; - const std::string getAmiciCommit() const override { return "0a85246ec55554a1db269634c806f27f071f487f"; }; + std::string getAmiciCommit() const override { return "2bd39716102b9842354964196889d40d2eb2731c"; }; - virtual void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron_o2(JSparse, t, x, p, k, h, w, dwdx); } - virtual void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { Jrz_model_neuron_o2(nllh, iz, p, k, rz, sigmaz); } - virtual void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { Jy_model_neuron_o2(nllh, iy, p, k, y, sigmay, my); } - virtual void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { Jz_model_neuron_o2(nllh, iz, p, k, z, sigmaz, mz); } - virtual void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { dJrzdsigma_model_neuron_o2(dJrzdsigma, iz, p, k, rz, sigmaz); } - virtual void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { dJrzdz_model_neuron_o2(dJrzdz, iz, p, k, rz, sigmaz); } - virtual void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydsigma_model_neuron_o2(dJydsigma, iy, p, k, y, sigmay, my); } - virtual void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydy_model_neuron_o2(dJydy, iy, p, k, y, sigmay, my); } - virtual void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { dJzdsigma_model_neuron_o2(dJzdsigma, iz, p, k, z, sigmaz, mz); } - virtual void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { dJzdz_model_neuron_o2(dJzdz, iz, p, k, z, sigmaz, mz); } - virtual void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { deltaqB_model_neuron_o2(deltaqB, t, x, p, k, h, ip, ie, xdot, xdot_old, xB); } - virtual void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { deltasx_model_neuron_o2(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); } - virtual void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { + void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { deltax_model_neuron_o2(deltax, t, x, p, k, h, ie, xdot, xdot_old); } - virtual void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { deltaxB_model_neuron_o2(deltaxB, t, x, p, k, h, ie, xdot, xdot_old, xB); } - virtual void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { drzdx_model_neuron_o2(drzdx, ie, t, x, p, k, h); } - virtual void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { + void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { } - virtual void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { + void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { dwdx_model_neuron_o2(dwdx, t, x, p, k, h, w, tcl); } - virtual void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dxdotdp_model_neuron_o2(dxdotdp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { } - virtual void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { dydx_model_neuron_o2(dydx, t, x, p, k, h, w, dwdx); } - virtual void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { dzdx_model_neuron_o2(dzdx, ie, t, x, p, k, h); } - virtual void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { root_model_neuron_o2(root, t, x, p, k, h); } - virtual void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { rz_model_neuron_o2(rz, ie, t, x, p, k, h); } - virtual void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { sigmay_model_neuron_o2(sigmay, t, p, k); } - virtual void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { + void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { sigmaz_model_neuron_o2(sigmaz, t, p, k); } - virtual void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { srz_model_neuron_o2(srz, ie, t, x, p, k, h, sx, ip); } - virtual void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { stau_model_neuron_o2(stau, t, x, p, k, h, sx, ip, ie); } - virtual void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { + void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { sx0_model_neuron_o2(sx0, t, x0, p, k, ip); } - virtual void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { sz_model_neuron_o2(sz, ie, t, x, p, k, h, sx, ip); } - virtual void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { w_model_neuron_o2(w, t, x, p, k, h, tcl); } - virtual void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { + void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { x0_model_neuron_o2(x0, t, p, k); } - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { xdot_model_neuron_o2(xdot, t, x, p, k, h, w); } - virtual void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { y_model_neuron_o2(y, t, x, p, k, h, w); } - virtual void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { z_model_neuron_o2(z, ie, t, x, p, k, h); } diff --git a/deps/AMICI/models/model_robertson/model_robertson.h b/deps/AMICI/models/model_robertson/model_robertson.h index bedd9e642..9e3c40f29 100644 --- a/deps/AMICI/models/model_robertson/model_robertson.h +++ b/deps/AMICI/models/model_robertson/model_robertson.h @@ -1,6 +1,6 @@ #ifndef _amici_model_robertson_h #define _amici_model_robertson_h -/* Generated by amiwrap (R2017b) 0a85246ec55554a1db269634c806f27f071f487f */ +/* Generated by amiwrap (R2017b) 2bd39716102b9842354964196889d40d2eb2731c */ #include #include #include "amici/defines.h" @@ -66,139 +66,139 @@ class Model_model_robertson : public amici::Model_DAE { std::vector{}) {}; - virtual amici::Model* clone() const override { return new Model_model_robertson(*this); }; + amici::Model* clone() const override { return new Model_model_robertson(*this); }; - const std::string getAmiciCommit() const override { return "0a85246ec55554a1db269634c806f27f071f487f"; }; + std::string getAmiciCommit() const override { return "2bd39716102b9842354964196889d40d2eb2731c"; }; - virtual void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { + void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_robertson(JSparse, t, x, p, k, h, cj, dx, w, dwdx); } - virtual void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { Jy_model_robertson(nllh, iy, p, k, y, sigmay, my); } - virtual void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fM(realtype *M, const realtype t, const realtype *x, const realtype *p, const realtype *k) override { + void fM(realtype *M, const realtype t, const realtype *x, const realtype *p, const realtype *k) override { M_model_robertson(M, t, x, p, k); } - virtual void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydsigma_model_robertson(dJydsigma, iy, p, k, y, sigmay, my); } - virtual void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydy_model_robertson(dJydy, iy, p, k, y, sigmay, my); } - virtual void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { } - virtual void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { + void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { } - virtual void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { + void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { dwdp_model_robertson(dwdp, t, x, p, k, h, w, tcl, stcl); } - virtual void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { + void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { dwdx_model_robertson(dwdx, t, x, p, k, h, w, tcl); } - virtual void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *dx, const realtype *w, const realtype *dwdp) override { + void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *dx, const realtype *w, const realtype *dwdp) override { dxdotdp_model_robertson(dxdotdp, t, x, p, k, h, ip, dx, w, dwdp); } - virtual void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { } - virtual void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { dydx_model_robertson(dydx, t, x, p, k, h, w, dwdx); } - virtual void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx) override { } - virtual void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { sigmay_model_robertson(sigmay, t, p, k); } - virtual void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { + void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { } - virtual void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { } - virtual void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { + void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { } - virtual void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { w_model_robertson(w, t, x, p, k, h, tcl); } - virtual void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { + void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { x0_model_robertson(x0, t, p, k); } - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx, const realtype *w) override { + void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx, const realtype *w) override { xdot_model_robertson(xdot, t, x, p, k, h, dx, w); } - virtual void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { y_model_robertson(y, t, x, p, k, h, w); } - virtual void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } }; diff --git a/deps/AMICI/models/model_robertson/rebuild_model_robertson.m b/deps/AMICI/models/model_robertson/rebuild_model_robertson.m new file mode 100644 index 000000000..3fcf9fe46 --- /dev/null +++ b/deps/AMICI/models/model_robertson/rebuild_model_robertson.m @@ -0,0 +1,5 @@ +function rebuild_model_robertson() +modelName = 'model_robertson'; +amimodel.compileAndLinkModel(modelName, '', [], [], [], []); +amimodel.generateMatlabWrapper(3, 3, 3, 1, 0, 0, [], ['simulate_' modelName '.m'], 'model_robertson', 'log10', 1, 1); +end diff --git a/deps/AMICI/models/model_steadystate/model_steadystate.h b/deps/AMICI/models/model_steadystate/model_steadystate.h index 2637d681b..c009c86ca 100644 --- a/deps/AMICI/models/model_steadystate/model_steadystate.h +++ b/deps/AMICI/models/model_steadystate/model_steadystate.h @@ -1,6 +1,6 @@ #ifndef _amici_model_steadystate_h #define _amici_model_steadystate_h -/* Generated by amiwrap (R2017b) 0a85246ec55554a1db269634c806f27f071f487f */ +/* Generated by amiwrap (R2017b) 2bd39716102b9842354964196889d40d2eb2731c */ #include #include #include "amici/defines.h" @@ -65,135 +65,135 @@ class Model_model_steadystate : public amici::Model_ODE { std::vector{}) {}; - virtual amici::Model* clone() const override { return new Model_model_steadystate(*this); }; + amici::Model* clone() const override { return new Model_model_steadystate(*this); }; - const std::string getAmiciCommit() const override { return "0a85246ec55554a1db269634c806f27f071f487f"; }; + std::string getAmiciCommit() const override { return "2bd39716102b9842354964196889d40d2eb2731c"; }; - virtual void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_steadystate(JSparse, t, x, p, k, h, w, dwdx); } - virtual void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fJrz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fJy(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { Jy_model_steadystate(nllh, iy, p, k, y, sigmay, my); } - virtual void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fJz(double *nllh, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdsigma(double *dJrzdsigma, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { + void fdJrzdz(double *dJrzdz, const int iz, const realtype *p, const realtype *k, const double *rz, const double *sigmaz) override { } - virtual void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydsigma(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydsigma_model_steadystate(dJydsigma, iy, p, k, y, sigmay, my); } - virtual void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { + void fdJydy(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my) override { dJydy_model_steadystate(dJydy, iy, p, k, y, sigmay, my); } - virtual void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdsigma(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { + void fdJzdz(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz) override { } - virtual void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { } - virtual void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { + void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { } - virtual void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { + void fdeltaxB(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - virtual void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdrzdp(double *drzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { } - virtual void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { + void fdwdp(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl) override { dwdp_model_steadystate(dwdp, t, x, p, k, h, w, tcl, stcl); } - virtual void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { + void fdwdx(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl) override { dwdx_model_steadystate(dwdx, t, x, p, k, h, w, tcl); } - virtual void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdxdotdp(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { dxdotdp_model_steadystate(dxdotdp, t, x, p, k, h, ip, w, dwdp); } - virtual void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { + void fdydp(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp) override { } - virtual void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { + void fdydx(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { dydx_model_steadystate(dydx, t, x, p, k, h, w, dwdx); } - virtual void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { + void fdzdp(double *dzdp, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip) override { } - virtual void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - virtual void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { sigmay_model_steadystate(sigmay, t, p, k); } - virtual void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { + void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { } - virtual void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { } - virtual void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { + void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { } - virtual void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { + void fsz(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - virtual void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + void fw(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { w_model_steadystate(w, t, x, p, k, h, tcl); } - virtual void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { + void fx0(realtype *x0, const realtype t, const realtype *p, const realtype *k) override { x0_model_steadystate(x0, t, p, k); } - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fxdot(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { xdot_model_steadystate(xdot, t, x, p, k, h, w); } - virtual void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { + void fy(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w) override { y_model_steadystate(y, t, x, p, k, h, w); } - virtual void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void fz(double *z, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } }; diff --git a/deps/AMICI/models/model_steadystate/rebuild_model_steadystate.m b/deps/AMICI/models/model_steadystate/rebuild_model_steadystate.m new file mode 100644 index 000000000..f7a6f63e5 --- /dev/null +++ b/deps/AMICI/models/model_steadystate/rebuild_model_steadystate.m @@ -0,0 +1,5 @@ +function rebuild_model_steadystate() +modelName = 'model_steadystate'; +amimodel.compileAndLinkModel(modelName, '', [], [], [], []); +amimodel.generateMatlabWrapper(3, 3, 5, 4, 0, 0, [], ['simulate_' modelName '.m'], 'model_steadystate', 'log10', 1, 1); +end diff --git a/deps/AMICI/python/amici/__main__.py b/deps/AMICI/python/amici/__main__.py new file mode 100644 index 000000000..dac523027 --- /dev/null +++ b/deps/AMICI/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/deps/AMICI/python/amici/gradient_check.py b/deps/AMICI/python/amici/gradient_check.py index badf98afe..6055e2bdd 100644 --- a/deps/AMICI/python/amici/gradient_check.py +++ b/deps/AMICI/python/amici/gradient_check.py @@ -67,6 +67,8 @@ def check_finite_difference(x0: Sequence[float], og_sensitivity_order = solver.getSensitivityOrder() og_parameters = model.getParameters() og_plist = model.getParameterList() + if edata: + og_eplist = edata.plist # sensitivity p = copy.deepcopy(x0) @@ -74,6 +76,8 @@ def check_finite_difference(x0: Sequence[float], model.setParameters(p) model.setParameterList(plist) + if edata: + edata.plist = plist # simulation with gradient if int(og_sensitivity_order) < int(SensitivityOrder.first): @@ -122,6 +126,8 @@ def check_finite_difference(x0: Sequence[float], solver.setSensitivityOrder(og_sensitivity_order) model.setParameters(og_parameters) model.setParameterList(og_plist) + if edata: + edata.plist = og_eplist def check_derivatives(model: Model, @@ -190,18 +196,18 @@ def check_derivatives(model: Model, if 'ssigmay' in rdata.keys() \ and rdata['ssigmay'] is not None \ - and rdata['ssigmay'].any(): + and rdata['ssigmay'].any() and not model.getAddSigmaResiduals(): leastsquares_applicable = False if check_least_squares and leastsquares_applicable: fields += ['res', 'y'] check_results(rdata, 'FIM', - np.dot(rdata['sres'].transpose(), rdata['sres']), + np.dot(rdata['sres'].T, rdata['sres']), assert_fun, 1e-8, 1e-4) check_results(rdata, 'sllh', - -np.dot(rdata['res'].transpose(), rdata['sres']), + -np.dot(rdata['res'].T, rdata['sres']), assert_fun, 1e-8, 1e-4) for ip, pval in enumerate(p): diff --git a/deps/AMICI/python/amici/numpy.py b/deps/AMICI/python/amici/numpy.py index adace3b18..5d8fd51d0 100644 --- a/deps/AMICI/python/amici/numpy.py +++ b/deps/AMICI/python/amici/numpy.py @@ -195,8 +195,10 @@ def __init__(self, rdata: Union[ReturnDataPtr, ReturnData]): 'sllh': [rdata.nplist], 's2llh': [rdata.np, rdata.nplist], - 'res': [rdata.nt * rdata.nytrue], - 'sres': [rdata.nt * rdata.nytrue, rdata.nplist], + 'res': [rdata.nt * rdata.nytrue * + (2 if rdata.sigma_res else 1)], + 'sres': [rdata.nt * rdata.nytrue * + (2 if rdata.sigma_res else 1), rdata.nplist], 'FIM': [rdata.nplist, rdata.nplist], # diagnosis diff --git a/deps/AMICI/python/amici/ode_export.py b/deps/AMICI/python/amici/ode_export.py index b6391f880..b5ec800af 100644 --- a/deps/AMICI/python/amici/ode_export.py +++ b/deps/AMICI/python/amici/ode_export.py @@ -45,7 +45,7 @@ ) from .logging import get_logger, log_execution_time, set_log_level from .constants import SymbolId -from .import_utils import smart_subs_dict +from .import_utils import smart_subs_dict, toposort_symbols # Template for model simulation main.cpp file CXX_MAIN_TEMPLATE_FILE = os.path.join(amiciSrcPath, 'main.template.cpp') @@ -78,9 +78,9 @@ 'const realtype *k, const realtype *y, const realtype *sigmay, ' 'const realtype *my)', }, - 'dJydsigmay': { + 'dJydsigma': { 'signature': - '(realtype *dJydsigmay, const int iy, const realtype *p, ' + '(realtype *dJydsigma, const int iy, const realtype *p, ' 'const realtype *k, const realtype *y, const realtype *sigmay, ' 'const realtype *my)', }, @@ -189,12 +189,31 @@ 'const realtype *p, const realtype *k, const realtype *h, ' 'const realtype *sx, const int ip, const int ie)' }, + 'deltax': { + 'signature': + '(double *deltax, const realtype t, const realtype *x, ' + 'const realtype *p, const realtype *k, const realtype *h, ' + 'const int ie, const realtype *xdot, const realtype *xdot_old)' + }, + 'ddeltaxdx': { + 'signature': '()', + 'flags': ['dont_generate_body'] + }, + 'ddeltaxdt': { + 'signature': '()', + 'flags': ['dont_generate_body'] + }, + 'ddeltaxdp': { + 'signature': '()', + 'flags': ['dont_generate_body'] + }, 'deltasx': { 'signature': '(realtype *deltasx, const realtype t, const realtype *x, ' 'const realtype *p, const realtype *k, const realtype *h, ' - 'const realtype *w, const int ip, const int ie, const realtype *xdot, ' - 'const realtype *xdot_old, const realtype *sx, const realtype *stau)' + 'const realtype *w, const int ip, const int ie, ' + 'const realtype *xdot, const realtype *xdot_old, ' + 'const realtype *sx, const realtype *stau)' }, 'w': { 'signature': @@ -270,12 +289,23 @@ sensi_functions = [ function for function in functions if 'const int ip' in functions[function]['signature'] - and function != 'sxdot' +] +# list of sensitivity functions +sparse_sensi_functions = [ + function for function in functions + if 'const int ip' not in functions[function]['signature'] + and function.endswith('dp') or function.endswith('dp_explicit') ] # list of event functions event_functions = [ function for function in functions - if 'const int ie' in functions[function]['signature'] + if 'const int ie' in functions[function]['signature'] and + 'const int ip' not in functions[function]['signature'] +] +event_sensi_functions = [ + function for function in functions + if 'const int ie' in functions[function]['signature'] and + 'const int ip' in functions[function]['signature'] ] # list of multiobs functions multiobs_functions = [ @@ -353,6 +383,7 @@ def __init__(self, if not isinstance(name, str): raise TypeError(f'name must be str, was {type(name)}') + self._name: str = name self._value: sp.Expr = cast_to_sym(value, 'value') @@ -687,6 +718,7 @@ def __init__(self, """ super(LogLikelihood, self).__init__(identifier, name, value) + class Event(ModelQuantity): """ An Event defines either a SBML event or a root of the argument of a @@ -727,6 +759,13 @@ def __init__(self, self._state_update = state_update self._observable = event_observable + def __eq__(self, other): + """ + Check equality of events at the level of trigger/root functions, as we + need to collect unique root functions for roots.cpp + """ + return self.get_val() == other.get_val() + # defines the type of some attributes in ODEModel symbol_to_type = { @@ -1021,14 +1060,14 @@ def import_from_sbml_importer(self, dxdotdw_updates = [] - def transform_dxdt_to_concentration(specie_id, dxdt): + def transform_dxdt_to_concentration(species_id, dxdt): """ Produces the appropriate expression for the first derivative of a species with respect to time, for species that reside in compartments with a constant volume, or a volume that is defined by an assignment or rate rule. - :param specie_id: + :param species_id: The identifier of the species (generated in "sbml_import.py"). :param dxdt: @@ -1045,13 +1084,13 @@ def transform_dxdt_to_concentration(specie_id, dxdt): # species in (i) compartments with a rate rule, (ii) compartments # with an assignment rule, and (iii) compartments with a constant # volume, respectively. - specie = si.symbols[SymbolId.SPECIES][specie_id] + species = si.symbols[SymbolId.SPECIES][species_id] - comp = specie['compartment'] - x_index = specie['index'] + comp = species['compartment'] + x_index = species['index'] if comp in si.symbols[SymbolId.SPECIES]: dv_dt = si.symbols[SymbolId.SPECIES][comp]['dt'] - xdot = (dxdt - dv_dt * specie_id) / comp + xdot = (dxdt - dv_dt * species_id) / comp dxdotdw_updates.extend( (x_index, w_index, xdot.diff(r_flux)) for w_index, r_flux in enumerate(fluxes) @@ -1072,8 +1111,8 @@ def transform_dxdt_to_concentration(specie_id, dxdt): for var in comp_rate_vars: dv_dt += \ v.diff(var) * si.symbols[SymbolId.SPECIES][var]['dt'] - dv_dx = v.diff(specie_id) - xdot = (dxdt - dv_dt * specie_id) / (dv_dx * specie_id + v) + dv_dx = v.diff(species_id) + xdot = (dxdt - dv_dt * species_id) / (dv_dx * species_id + v) dxdotdw_updates.extend( (x_index, w_index, xdot.diff(r_flux)) for w_index, r_flux in enumerate(fluxes) @@ -1097,19 +1136,19 @@ def transform_dxdt_to_concentration(specie_id, dxdt): # create dynamics without respecting conservation laws first dxdt = smart_multiply(si.stoichiometric_matrix, MutableDenseMatrix(fluxes)) - for ix, ((specie_id, specie), formula) in enumerate(zip( + for ix, ((species_id, species), formula) in enumerate(zip( symbols[SymbolId.SPECIES].items(), dxdt )): - assert ix == specie['index'] # check that no reordering occurred + assert ix == species['index'] # check that no reordering occurred # rate rules and amount species don't need to be updated - if 'dt' in specie: + if 'dt' in species: continue - if specie['amount']: - specie['dt'] = formula + if species['amount']: + species['dt'] = formula else: - specie['dt'] = transform_dxdt_to_concentration(specie_id, - formula) + species['dt'] = transform_dxdt_to_concentration(species_id, + formula) # create all basic components of the ODE model and add them. for symbol_name in symbols: @@ -1120,6 +1159,8 @@ def transform_dxdt_to_concentration(specie_id, dxdt): args += ['dt', 'init'] else: args += ['value'] + if symbol_name == SymbolId.EVENT: + args += ['state_update', 'event_observable'] protos = [ { @@ -1174,16 +1215,6 @@ def transform_dxdt_to_concentration(specie_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' - for index, event in enumerate(self._events): - self._events[index] = Event( - identifier=event.get_id(), - name=event.get_name(), - value=event.get_val().subs(zip(self._syms['w'], self.eq('w'))), - 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() @@ -1377,7 +1408,7 @@ def sym(self, else: return self._syms[name] - def sparsesym(self, name: str) -> List[str]: + def sparsesym(self, name: str, force_generate: bool = True) -> List[str]: """ Returns (and constructs if necessary) the sparsified identifiers for a sparsified symbolic variable. @@ -1385,15 +1416,18 @@ def sparsesym(self, name: str) -> List[str]: :param name: name of the symbolic variable + :param force_generate: + whether the symbols should be generated if not available + :return: linearized Matrix containing the symbolic identifiers """ if name not in sparse_functions: raise ValueError(f'{name} is not marked as sparse') - if name not in self._sparsesyms: + if name not in self._sparsesyms and force_generate: self._generate_sparse_symbol(name) - return self._sparsesyms[name] + return self._sparsesyms.get(name, []) def eq(self, name: str) -> sp.Matrix: """ @@ -1578,7 +1612,6 @@ def _generate_symbol(self, name: str, *, from_sbml: bool = False) -> None: length = self.eq(name).shape[0] else: length = len(self.eq(name)) - self._syms[name] = sp.Matrix([ sp.Symbol(f'{name}{i}', real=True) for i in range(length) ]) @@ -1587,8 +1620,10 @@ def generate_basic_variables(self, *, from_sbml: bool = False) -> None: """ Generates the symbolic identifiers for all variables in ODEModel.variable_prototype - """ + :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() @@ -1606,17 +1641,25 @@ 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 = [] + roots = copy.deepcopy(self._events) for state in self._states: - state.set_dt(_process_heavisides(state.get_dt(), roots)) + state.set_dt(self._process_heavisides(state.get_dt(), roots)) for expr in self._expressions: - expr.set_val(_process_heavisides(expr.get_val(), roots)) + 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 + if root in self._events: + continue + # add roots of heaviside functions self.add_component(root) def get_appearance_counts(self, idxs: List[int]) -> List[int]: @@ -1710,7 +1753,10 @@ def _compute_equation(self, name: str) -> None: name of the symbolic variable """ - match_deriv = re.match(r'd([\w_]+)d([a-z_]+)', name) + # replacement ensures that we don't have to adapt name in abstract + # model and keep backwards compatibility with matlab + match_deriv = re.match(r'd([\w_]+)d([a-z_]+)', + name.replace('dJydsigma', 'dJydsigmay')) time_symbol = sp.Matrix([symbol_with_assumptions('t')]) if name in self._equation_prototype: @@ -1794,7 +1840,8 @@ def _compute_equation(self, name: str) -> None: elif name == 'dtcldx': # this is always zero - self._eqs[name] = sp.zeros(self.num_cons_law(), self.num_states_solver()) + self._eqs[name] = \ + sp.zeros(self.num_cons_law(), self.num_states_solver()) elif name == 'dtcldp': # force symbols @@ -1815,31 +1862,86 @@ def _compute_equation(self, name: str) -> None: # backsubstitution of optimized right hand side terms into RHS # calling subs() is costly. Due to looping over events though, the # following lines are only evaluated if a model has events - tmp_xdot = self._eqs['xdot'].subs(zip(self._syms['w'], - self._eqs['w'])) - self._eqs[name] = smart_multiply(self.eq('drootdx'), tmp_xdot) + \ - self.eq('drootdt') + w_sorted = \ + toposort_symbols(dict(zip(self._syms['w'], self._eqs['w']))) + tmp_xdot = smart_subs_dict(self._eqs['xdot'], w_sorted) + self._eqs[name] = ( + smart_multiply(self.eq('drootdx'), tmp_xdot) + + self.eq('drootdt') + ) - elif name == 'stau': + elif name == 'deltax': + # fill boluses for Heaviside functions, as empty state updates + # would cause problems when writing the function file later + event_eqs = [] + for event in self._events: + if event._state_update is None: + event_eqs.append(sp.zeros(self.num_states_solver(), 1)) + else: + event_eqs.append(event._state_update) + + self._eqs[name] = event_eqs + + elif name == 'ddeltaxdx': self._eqs[name] = [ - -self.eq('sroot')[ie, :] / self.eq('drootdt_total')[ie] + smart_jacobian(self.eq('deltax')[ie], self.sym('x')) for ie in range(self.num_events()) ] - elif name == 'deltasx': + elif name == 'ddeltaxdt': self._eqs[name] = [ - smart_multiply((self.eq('xdot_old') - self.eq('xdot')), - self.eq('stau')[ie]) + smart_jacobian(self.eq('deltax')[ie], time_symbol) for ie in range(self.num_events()) ] + elif name == 'ddeltaxdp': + self._eqs[name] = [ + smart_jacobian(self.eq('deltax')[ie], self.sym('p')) + for ie in range(self.num_events()) + ] + + elif name == 'stau': + self._eqs[name] = [ + -self.eq('sroot')[ie, :] / self.eq('drootdt_total')[ie] + for ie in range(self.num_events()) + ] + + elif name == 'deltasx': + event_eqs = [] + for ie, event in enumerate(self._events): + if event._state_update is not None: + # ====== chain rule for the state variables =============== + # get xdot with expressions back-substituted + tmp_eq = smart_multiply( + (self.sym('xdot_old') - self.sym('xdot')), + self.eq('stau')[ie]) + # construct an enhanced state sensitivity, which accounts + # for the time point sensitivity as well + tmp_dxdp = self.sym('sx') * sp.ones(1, self.num_par()) + tmp_dxdp += smart_multiply(self.sym('xdot'), + self.eq('stau')[ie]) + tmp_eq += smart_multiply(self.eq('ddeltaxdx')[ie], + tmp_dxdp) + # ====== chain rule for the time point ==================== + tmp_eq += smart_multiply(self.eq('ddeltaxdt')[ie], + self.eq('stau')[ie]) + # ====== partial derivative for the parameters ============ + tmp_eq += self.eq('ddeltaxdp')[ie] + else: + tmp_eq = smart_multiply( + (self.eq('xdot_old') - self.eq('xdot')), + self.eq('stau')[ie]) + + event_eqs.append(tmp_eq) + + self._eqs[name] = event_eqs + elif name == 'xdot_old': # force symbols self._eqs[name] = self.sym(name) - elif match_deriv: - self._derivative(match_deriv.group(1), match_deriv.group(2)) + self._derivative(match_deriv.group(1), match_deriv.group(2), name) else: raise ValueError(f'Unknown equation {name}') @@ -1861,7 +1963,8 @@ def _compute_equation(self, name: str) -> None: self._eqs[name] = [dec(sub_eq.applyfunc)(self._simplify) for sub_eq in self._eqs[name]] else: - self._eqs[name] = dec(self._eqs[name].applyfunc)(self._simplify) + self._eqs[name] = \ + dec(self._eqs[name].applyfunc)(self._simplify) def sym_names(self) -> List[str]: """ @@ -2230,6 +2333,150 @@ def conservation_law_has_multispecies(self, n_species = len(state_set.intersection(tcl.get_val().free_symbols)) return n_species > 1 + def _expr_is_time_dependent(self, expr: sp.Expr) -> bool: + """Determine whether an expression is time-dependent. + + :param expr: + The expression. + + :returns: + Whether the expression is time-dependent. + """ + # `expr.free_symbols` will be different to `self._states.keys()`, so + # it's easier to compare as `str`. + expr_syms = {str(sym) for sym in expr.free_symbols} + + # Check if the time variable is in the expression. + if 't' in expr_syms: + return True + + # Check if any time-dependent states are in the expression. + state_syms = [str(sym) for sym in self._states] + for state in expr_syms.intersection(state_syms): + if not self.state_is_constant(state_syms.index(state)): + return True + + return False + + def _get_unique_root( + self, + root_found: sp.Expr, + roots: List[Event], + ) -> sp.Symbol: + """ + Collects roots of Heaviside functions and events and stores them in + the roots list. It checks for redundancy to not store symbolically + equivalent root functions more than once. + + :param root_found: + equation of the root function + :param roots: + list of already known root functions with identifier + + :returns: + unique identifier for root, or `None` if the root is not + time-dependent + """ + + if not self._expr_is_time_dependent(root_found): + return None + + for root in roots: + if sp.simplify(root_found - root.get_val()) == 0: + return root.get_id() + + # create an event for a new root function + root_symstr = f'Heaviside_{len(roots)}' + roots.append(Event( + identifier=sp.Symbol(root_symstr), + name=root_symstr, + value=root_found, + state_update=None, + event_observable=None + )) + return roots[-1].get_id() + + def _collect_heaviside_roots( + self, + args: Sequence[sp.Expr], + ) -> List[sp.Expr]: + """ + Recursively checks an expression for the occurrence of Heaviside + functions and return all roots found + + :param args: + args attribute of the expanded expression + + :returns: + root functions that were extracted from Heaviside function + arguments + """ + root_funs = [] + for arg in args: + if arg.func == sp.Heaviside: + root_funs.append(arg.args[0]) + elif arg.has(sp.Heaviside): + root_funs.extend(self._collect_heaviside_roots(arg.args)) + + # substitute 'w' expressions into root expressions now, to avoid + # 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 + ] + + return root_funs + + def _process_heavisides( + self, + dxdt: sp.Expr, + roots: List[Event], + ) -> sp.Expr: + """ + Parses the RHS of a state variable, checks for Heaviside functions, + collects unique roots functions that can be tracked by SUNDIALS and + replaces Heaviside Functions by amici helper variables that will be + updated based on SUNDIALS root tracking. + + :param dxdt: + right hand side of state variable + :param roots: + list of known root functions with identifier + + :returns: + dxdt with Heaviside functions replaced by amici helper variables + """ + + # expanding the rhs will in general help to collect the same + # heaviside function + dt_expanded = dxdt.expand() + # track all the old Heaviside expressions in tmp_roots_old + # replace them later by the new expressions + heavisides = [] + # run through the expression tree and get the roots + tmp_roots_old = self._collect_heaviside_roots(dt_expanded.args) + for tmp_old in tmp_roots_old: + # we want unique identifiers for the roots + tmp_new = self._get_unique_root(tmp_old, roots) + # `tmp_new` is None if the root is not time-dependent. + if tmp_new is None: + continue + # For Heavisides, we need to add the negative function as well + self._get_unique_root(sp.sympify(- tmp_old), roots) + heavisides.append((sp.Heaviside(tmp_old), tmp_new)) + + if heavisides: + # only apply subs if necessary + for heaviside_sympy, heaviside_amici in heavisides: + dxdt = dxdt.subs(heaviside_sympy, heaviside_amici) + + return dxdt + def _print_with_exception(math: sp.Expr) -> str: """ @@ -2361,6 +2608,9 @@ class ODEExporter: :ivar _build_hints: If the given model uses special functions, this set contains hints for model building. + + :ivar generate_sensitivity_code: + Specifies whether code for sensitivity computation is to be generated """ def __init__( @@ -2370,7 +2620,8 @@ def __init__( verbose: Optional[Union[bool, int]] = False, assume_pow_positivity: Optional[bool] = False, compiler: Optional[str] = None, - allow_reinit_fixpar_initcond: Optional[bool] = True + allow_reinit_fixpar_initcond: Optional[bool] = True, + generate_sensitivity_code: Optional[bool] = True ): """ Generate AMICI C++ files for the ODE provided to the constructor. @@ -2395,6 +2646,9 @@ def __init__( :param allow_reinit_fixpar_initcond: see :class:`amici.ode_export.ODEExporter` + + :param generate_sensitivity_code specifies whether code required for + sensitivity computation will be generated """ set_log_level(logger, verbose) @@ -2419,6 +2673,7 @@ def __init__( self.allow_reinit_fixpar_initcond: bool = allow_reinit_fixpar_initcond self._build_hints = set() + self.generate_sensitivity_code: bool = generate_sensitivity_code @log_execution_time('generating cpp code', logger) def generate_model_code(self) -> None: @@ -2459,15 +2714,29 @@ def _generate_c_code(self) -> None: Create C++ code files for the model based on ODEExporter.model """ for function in self.functions.keys(): + if function in sensi_functions + sparse_sensi_functions and \ + not self.generate_sensitivity_code: + continue + if 'dont_generate_body' not in \ self.functions[function].get('flags', []): dec = log_execution_time(f'writing {function}.cpp', logger) dec(self._write_function_file)(function) - if function in sparse_functions: + if function in sparse_functions \ + and 'body' in self.functions[function]: self._write_function_index(function, 'colptrs') self._write_function_index(function, 'rowvals') for name in self.model.sym_names(): + # only generate for those that have nontrivial implementation, + # check for both basic variables (not in functions) and function + # computed values + if (name in self.functions and + 'body' not in self.functions[name] and + name not in nobody_functions) or \ + (name not in self.functions and + len(self.model.sym(name)) == 0): + continue self._write_index_files(name) self._write_wrapfunctions_cpp() @@ -2560,8 +2829,8 @@ def _generate_m_code(self) -> None: lines.append("amimodel.compileAndLinkModel" "(modelName, '', [], [], [], []);") lines.append(f"amimodel.generateMatlabWrapper({nxtrue_rdata}, " - f"{nytrue}, {self.model.num_par()}, {self.model.num_const()}, " - f"{nz}, {o2flag}, ...\n [], " + f"{nytrue}, {self.model.num_par()}, " + f"{self.model.num_const()}, {nz}, {o2flag}, ...\n [], " "['simulate_' modelName '.m'], modelName, ...\n" " 'lin', 1, 1);") @@ -2595,11 +2864,14 @@ def _write_index_files(self, name: str) -> None: symbol_name = strip_pysb(symbol) if str(symbol) == '0': continue + if str(symbol_name) == '': + raise ValueError(f'{name} contains a symbol called ""') lines.append( f'#define {symbol_name} {name}[{index}]' ) - with open(os.path.join(self.model_path, f'{name}.h'), 'w') as fileout: + filename = os.path.join(self.model_path, f'{self.model_name}_{name}.h') + with open(filename, 'w') as fileout: fileout.write('\n'.join(lines)) def _write_function_file(self, function: str) -> None: @@ -2637,13 +2909,33 @@ def _write_function_file(self, function: str) -> None: lines.append('') - for sym in self.model.sym_names(): - # added |double for data - # added '[0]*' for initial conditions - if re.search( - fr'const (realtype|double) \*{sym}[0]*[,)]+', signature - ) or (function == sym and function not in non_unique_id_symbols): - lines.append(f'#include "{sym}.h"') + # extract symbols that need definitions from signature + # don't add includes for files that won't be generated. + # Unfortunately we cannot check for `self.functions[sym]['body']` + # here since it may not have been generated yet. + for match in re.findall( + fr'const (realtype|double) \*([\w]+)[0]*[,\)]+', signature + ): + sym = match[1] + if sym not in self.model.sym_names(): + continue + + if sym in sparse_functions: + iszero = smart_is_zero_matrix(self.model.sparseeq(sym)) + elif sym in self.functions: + iszero = smart_is_zero_matrix(self.model.eq(sym)) + else: + iszero = len(self.model.sym(sym)) == 0 + + if iszero: + continue + + lines.append(f'#include "{self.model_name}_{sym}.h"') + + # include return symbols + if function in self.model.sym_names() and \ + function not in non_unique_id_symbols: + lines.append(f'#include "{self.model_name}_{function}.h"') lines.extend([ '', @@ -2664,7 +2956,11 @@ def _write_function_file(self, function: str) -> None: # starting (^|\W) for the following match body = [re.sub(r'(^|\W)std::pow\(', r'\1amici::pos_pow(', line) for line in body] - self.functions[function]['body'] = body + + if body: + self.functions[function]['body'] = body + else: + return lines += body lines.extend([ '}', @@ -2732,9 +3028,11 @@ def _write_function_index(self, function: str, indextype: str) -> None: static_array_name = f"{function}_{indextype}_{self.model_name}_" if function in multiobs_functions: # list of index vectors - lines.append("static constexpr std::array, {len(values)}> " - f"{static_array_name} = {{{{") + lines.append( + "static constexpr std::array, {len(values)}> " + f"{static_array_name} = {{{{" + ) lines.extend([' {' + ', '.join(map(str, index_vector)) + '}, ' for index_vector in values]) @@ -2753,9 +3051,15 @@ def _write_function_index(self, function: str, indextype: str) -> None: if len(values): if function in multiobs_functions: - lines.append(f" {function}.set_{setter}(gsl::make_span({static_array_name}[index]));") + lines.append( + f" {function}.set_{setter}" + f"(gsl::make_span({static_array_name}[index]));" + ) else: - lines.append(f" {function}.set_{setter}(gsl::make_span({static_array_name}));") + lines.append( + f" {function}.set_{setter}" + f"(gsl::make_span({static_array_name}));" + ) lines.extend([ '}' @@ -2789,9 +3093,13 @@ def _get_function_body(self, lines = [] - if len(equations) == 0 or (isinstance(equations, (sp.Matrix, - sp.ImmutableDenseMatrix)) - and min(equations.shape) == 0): + if ( + len(equations) == 0 + or ( + isinstance(equations, (sp.Matrix, sp.ImmutableDenseMatrix)) + and min(equations.shape) == 0 + ) + ): # dJydy is a list return lines @@ -2856,6 +3164,12 @@ def _get_function_body(self, f'{_print_with_exception(formula)};') elif function in event_functions: + cases = {ie: _get_sym_lines_array(equations[ie], function, 0) + for ie in range(self.model.num_events()) + if not smart_is_zero_matrix(equations[ie])} + lines.extend(get_switch_statement('ie', cases, 1)) + + elif function in event_sensi_functions: outer_cases = {} for ie, inner_equations in enumerate(equations): inner_lines = [] @@ -2883,10 +3197,11 @@ def _get_function_body(self, for iobs in range(self.model.num_obs()) if not smart_is_zero_matrix(equations[iobs])} else: - cases = {iobs: _get_sym_lines_array(equations[:, iobs], function, - 0) - for iobs in range(self.model.num_obs()) - if not smart_is_zero_matrix(equations[:, iobs])} + cases = { + iobs: _get_sym_lines_array(equations[:, iobs], function, 0) + for iobs in range(self.model.num_obs()) + if not smart_is_zero_matrix(equations[:, iobs]) + } lines.extend(get_switch_statement('iy', cases, 1)) elif function in self.model.sym_names() \ @@ -2943,12 +3258,16 @@ def _write_model_header_cpp(self) -> None: 'NEVENT': str(self.model.num_events()), 'NOBJECTIVE': '1', 'NW': str(len(self.model.sym('w'))), - 'NDWDP': str(len(self.model.sparsesym('dwdp'))), + 'NDWDP': str(len(self.model.sparsesym( + 'dwdp', force_generate=self.generate_sensitivity_code + ))), 'NDWDX': str(len(self.model.sparsesym('dwdx'))), 'NDWDW': str(len(self.model.sparsesym('dwdw'))), 'NDXDOTDW': str(len(self.model.sparsesym('dxdotdw'))), 'NDXDOTDP_EXPLICIT': str(len(self.model.sparsesym( - 'dxdotdp_explicit'))), + 'dxdotdp_explicit', + force_generate=self.generate_sensitivity_code + ))), 'NDXDOTDX_EXPLICIT': str(len(self.model.sparsesym( 'dxdotdx_explicit'))), 'NDJYDY': 'std::vector{%s}' @@ -2993,11 +3312,39 @@ def _write_model_header_cpp(self) -> None: if self.model._has_quadratic_nllh else 'false', } - for fun in [ - 'w', 'dwdp', 'dwdx', 'dwdw', 'x_rdata', 'x_solver', 'total_cl', - 'dxdotdw', 'dxdotdp_explicit', 'dxdotdx_explicit', - 'dJydy' - ]: + for fun, fundef in self.functions.items(): + if fun in nobody_functions: + continue + + if 'body' not in fundef: + tpl_data[f'{fun.upper()}_DEF'] = '' + + if fun in sensi_functions + sparse_sensi_functions and \ + not self.generate_sensitivity_code: + impl = '' + else: + impl = get_model_override_implementation( + fun, self.model_name, nobody=True + ) + + tpl_data[f'{fun.upper()}_IMPL'] = impl + + if fun in sparse_functions: + for indexfield in ['colptrs', 'rowvals']: + if fun in sparse_sensi_functions and \ + not self.generate_sensitivity_code: + impl = '' + else: + impl = get_sunindex_override_implementation( + fun, self.model_name, indexfield, nobody=True + ) + tpl_data[f'{fun.upper()}_{indexfield.upper()}_DEF'] \ + = '' + tpl_data[f'{fun.upper()}_{indexfield.upper()}_IMPL'] \ + = impl + + continue + tpl_data[f'{fun.upper()}_DEF'] = \ get_function_extern_declaration(fun, self.model_name) tpl_data[f'{fun.upper()}_IMPL'] = \ @@ -3045,8 +3392,8 @@ def _get_symbol_name_initializer_list(self, name: str) -> str: """ return '\n'.join( [ - f'"{symbol}",' - for symbol in self.model.name(name) + f'"{symbol}", // {name}[{idx}]' + for idx, symbol in enumerate(self.model.name(name)) ] ) @@ -3063,8 +3410,8 @@ def _get_symbol_id_initializer_list(self, name: str) -> str: """ return '\n'.join( [ - f'"{strip_pysb(symbol)}",' - for symbol in self.model.sym(name) + f'"{strip_pysb(symbol)}", // {name}[{idx}]' + for idx, symbol in enumerate(self.model.sym(name)) ] ) @@ -3073,18 +3420,10 @@ def _write_c_make_file(self): Write CMake CMakeLists.txt file for this model. """ - sources = [self.model_name + '_' + function + '.cpp ' - for function in self.functions.keys() - if self.functions[function].get('body', None) is not None] - - # add extra source files for sparse matrices - for function in sparse_functions: - sources.append(self.model_name + '_' + function - + '_colptrs.cpp') - sources.append(self.model_name + '_' + function - + '_rowvals.cpp ') - - sources.append(f'{self.model_name}.cpp') + sources = [ + f + ' ' for f in os.listdir(self.model_path) + if f.endswith('.cpp') and f != 'main.cpp' + ] template_data = {'MODELNAME': self.model_name, 'SOURCES': '\n'.join(sources), @@ -3266,7 +3605,8 @@ def get_sunindex_extern_declaration(fun: str, name: str, f'(SUNMatrixWrapper &{indextype}{index_arg});' -def get_model_override_implementation(fun: str, name: str) -> str: +def get_model_override_implementation(fun: str, name: str, + nobody: bool = False) -> str: """ Constructs amici::Model::* override implementation for a given function @@ -3276,14 +3616,21 @@ def get_model_override_implementation(fun: str, name: str) -> str: :param name: model name + :param nobody: + whether the function has a nontrivial implementation + :return: c++ function implementation string """ - return \ - 'virtual void f{fun}{signature} override {{\n' \ - '{ind8}{fun}_{name}{eval_signature};\n' \ - '{ind4}}}\n'.format( + impl = 'virtual void f{fun}{signature} override {{' + + if nobody: + impl += '}}\n' + else: + impl += '\n{ind8}{fun}_{name}{eval_signature};\n{ind4}}}\n' + + return impl.format( ind4=' '*4, ind8=' '*8, fun=fun, @@ -3294,7 +3641,8 @@ def get_model_override_implementation(fun: str, name: str) -> str: def get_sunindex_override_implementation(fun: str, name: str, - indextype: str) -> str: + indextype: str, + nobody: bool = False) -> str: """ Constructs the amici::Model:: function implementation for an index function of a given function @@ -3308,6 +3656,9 @@ def get_sunindex_override_implementation(fun: str, name: str, :param indextype: index function {'colptrs', 'rowvals'} + :param nobody: + whether the corresponding function has a nontrivial implementation + :return: c++ function implementation string @@ -3315,10 +3666,14 @@ def get_sunindex_override_implementation(fun: str, name: str, index_arg = ', int index' if fun in multiobs_functions else '' index_arg_eval = ', index' if fun in multiobs_functions else '' - return \ - 'virtual void f{fun}_{indextype}{signature} override {{\n' \ - '{ind8}{fun}_{indextype}_{name}{eval_signature};\n' \ - '{ind4}}}\n'.format( + impl = 'virtual void f{fun}_{indextype}{signature} override {{' + + if nobody: + impl += '}}\n' + else: + impl += '{ind8}{fun}_{indextype}_{name}{eval_signature};\n{ind4}}}\n' + + return impl.format( ind4=' '*4, ind8=' '*8, fun=fun, @@ -3354,10 +3709,11 @@ def remove_typedefs(signature: str) -> str: 'const int ', 'int ', 'SUNMatrixContent_Sparse ', + 'gsl::span' ] for typedef in typedefs: - signature = signature.replace(typedef, ' ') + signature = signature.replace(typedef, '') return signature @@ -3641,93 +3997,3 @@ def _custom_print_min(self, expr): return self._print(expr.args[0]) return "%smin(%s, %s)" % (self._ns, self._print(expr.args[0]), self._print(Min(*expr.args[1:]))) - - -def _collect_heaviside_roots(args: Sequence[sp.Expr]) -> List[sp.Expr]: - """ - Recursively checks an expression for the occurrence of Heaviside - functions and return all roots found - - :param args: - args attribute of the expanded expression - - :returns: - root functions that were extracted from Heaviside function arguments - """ - root_funs = [] - for arg in args: - if arg.func == sp.Heaviside: - root_funs.append(arg.args[0]) - elif arg.has(sp.Heaviside): - root_funs.extend(_collect_heaviside_roots(arg.args)) - - return root_funs - - -def _get_unique_root(root_found: sp.Expr, roots: List[Event]) -> sp.Symbol: - """ - Collects roots of Heaviside functions and events and stores them in - the roots list. It checks for redundancy to not store symbolically - equivalent root functions more than once. - - :param root_found: - equation of the root function - :param roots: - list of already known root functions with identifier - - :returns: - unique identifier for root - """ - for root in roots: - if sp.simplify(root_found - root.get_val()) == 0: - return root.get_id() - - # create an event for a new root function - root_symstr = f'Heaviside_{len(roots)}' - roots.append(Event( - identifier=sp.Symbol(root_symstr), - name=root_symstr, - value=root_found, - state_update=None, - event_observable=None - )) - return roots[-1].get_id() - - -def _process_heavisides(dxdt: sp.Expr, roots: List[Event]) -> sp.Expr: - """ - Parses the RHS of a state variable, checks for Heaviside functions, - collects unique roots functions that can be tracked by SUNDIALS and - replaces Heaviside Functions by amici helper variables that will be - updated based on SUNDIALS root tracking. - - :param dxdt: - right hand side of state variable - :param roots: - list of known root functions with identifier - - :returns: - dxdt with Heaviside functions replaced by amici helper variables - """ - - # expanding the rhs will in general help to collect the same - # heaviside function - dt_expanded = dxdt.expand() - # track all the old Heaviside expressions in tmp_roots_old - # replace them later by the new expressions - heavisides = [] - # run through the expression tree and get the roots - tmp_roots_old = _collect_heaviside_roots(dt_expanded.args) - for tmp_old in tmp_roots_old: - # we want unique identifiers for the roots - tmp_new = _get_unique_root(tmp_old, roots) - # For Heavisides, we need to add the negative function as well - _get_unique_root(sp.sympify(- tmp_old), roots) - heavisides.append((sp.Heaviside(tmp_old), tmp_new)) - - if heavisides: - # only apply subs if necessary - for heaviside_sympy, heaviside_amici in heavisides: - dxdt = dxdt.subs(heaviside_sympy, heaviside_amici) - - return dxdt diff --git a/deps/AMICI/python/amici/parameter_mapping.py b/deps/AMICI/python/amici/parameter_mapping.py index 9f91c6b1a..e7dcc0d2e 100644 --- a/deps/AMICI/python/amici/parameter_mapping.py +++ b/deps/AMICI/python/amici/parameter_mapping.py @@ -236,12 +236,21 @@ def _get_par(model_par, value): scales = [petab_to_amici_scale(scale_map_sim_var[par_id]) for par_id in amici_model.getParameterIds()] + # plist + plist = [ + ip for ip, par_id in enumerate(amici_model.getParameterIds()) + if isinstance(parameter_mapping.map_sim_var[par_id], str) + ] + if parameters: edata.parameters = parameters if scales: edata.pscale = amici.parameterScalingFromIntVector(scales) + if plist: + edata.plist = plist + ########################################################################## # fixed parameters preequilibration if map_preeq_fix: diff --git a/deps/AMICI/python/amici/petab_import.py b/deps/AMICI/python/amici/petab_import.py index 68fb53e3d..bfbbf744a 100644 --- a/deps/AMICI/python/amici/petab_import.py +++ b/deps/AMICI/python/amici/petab_import.py @@ -459,6 +459,21 @@ def import_model_sbml( sbml_importer = amici.SbmlImporter(sbml_model) sbml_model = sbml_importer.sbml + allow_n_noise_pars = \ + not petab.lint.observable_table_has_nontrivial_noise_formula( + observable_df + ) + if measurement_table is not None and \ + petab.lint.measurement_table_has_timepoint_specific_mappings( + measurement_table, + allow_scalar_numeric_noise_parameters=allow_n_noise_pars + ): + raise ValueError( + 'AMICI does not support importing models with timepoint specific ' + 'mappings for noise or observable parameters. Please flatten ' + 'the problem and try again.' + ) + if observable_df is not None: observables, noise_distrs, sigmas = \ get_observation_model(observable_df) @@ -574,10 +589,10 @@ def import_model_sbml( import_model = import_model_sbml -def get_observation_model(observable_df: pd.DataFrame - ) -> Tuple[Dict[str, Dict[str, str]], - Dict[str, str], - Dict[str, Union[str, float]]]: +def get_observation_model( + observable_df: pd.DataFrame, +) -> Tuple[Dict[str, Dict[str, str]], Dict[str, str], + Dict[str, Union[str, float]]]: """ Get observables, sigmas, and noise distributions from PEtab observation table in a format suitable for @@ -596,13 +611,13 @@ def get_observation_model(observable_df: pd.DataFrame observables = {} sigmas = {} + nan_pat = r'^[nN]a[nN]$' for _, observable in observable_df.iterrows(): - oid = observable.name + oid = str(observable.name) # need to sanitize due to https://github.com/PEtab-dev/PEtab/issues/447 - pat = r'^[nN]a[nN]$' - name = re.sub(pat, '', str(observable.get(OBSERVABLE_NAME, ''))) - formula_obs = re.sub(pat, '', str(observable[OBSERVABLE_FORMULA])) - formula_noise = re.sub(pat, '', str(observable[NOISE_FORMULA])) + name = re.sub(nan_pat, '', str(observable.get(OBSERVABLE_NAME, ''))) + formula_obs = re.sub(nan_pat, '', str(observable[OBSERVABLE_FORMULA])) + formula_noise = re.sub(nan_pat, '', str(observable[NOISE_FORMULA])) observables[oid] = {'name': name, 'formula': formula_obs} sigmas[oid] = formula_noise @@ -617,7 +632,8 @@ def get_observation_model(observable_df: pd.DataFrame return observables, noise_distrs, sigmas -def petab_noise_distributions_to_amici(observable_df: pd.DataFrame) -> Dict: +def petab_noise_distributions_to_amici(observable_df: pd.DataFrame + ) -> Dict[str, str]: """ Map from the petab to the amici format of noise distribution identifiers. @@ -689,6 +705,10 @@ def parse_cli_args(): parser.add_argument('--no-compile', action='store_false', dest='compile', help='Only generate model code, do not compile') + parser.add_argument('--flatten', dest='flatten', default=False, + action='store_true', + help='Flatten measurement specific overrides of ' + 'observable and noise parameters') # Call with set of files parser.add_argument('-s', '--sbml', dest='sbml_file_name', @@ -740,6 +760,9 @@ def main(): # First check for valid PEtab petab.lint_problem(pp) + if args.flatten: + petab.flatten_timepoint_specific_output_overrides(pp) + import_model(model_name=args.model_name, sbml_model=pp.sbml_model, condition_table=pp.condition_df, diff --git a/deps/AMICI/python/amici/petab_import_pysb.py b/deps/AMICI/python/amici/petab_import_pysb.py index 4f0abd212..3d33906e5 100644 --- a/deps/AMICI/python/amici/petab_import_pysb.py +++ b/deps/AMICI/python/amici/petab_import_pysb.py @@ -47,8 +47,10 @@ def __init__(self, pysb_model: 'pysb.Model' = None, *args, **kwargs): :param args: See :meth:`petab.Problem.__init__` :param kwargs: See :meth:`petab.Problem.__init__` """ - + flatten = kwargs.pop('flatten', False) super().__init__(*args, **kwargs) + if flatten: + petab.flatten_timepoint_specific_output_overrides(self) self.pysb_model: 'pysb.Model' = pysb_model self._add_observation_model() @@ -108,17 +110,33 @@ def from_files(condition_file: str = None, visualization_files: Union[str, Iterable[str]] = None, observable_files: Union[str, Iterable[str]] = None, pysb_model_file: str = None, - ) -> 'PysbPetabProblem': + flatten: bool = False) -> 'PysbPetabProblem': """ Factory method to load model and tables from files. - Arguments: - condition_file: PEtab condition table - measurement_file: PEtab measurement table - parameter_file: PEtab parameter table - visualization_files: PEtab visualization tables - observable_files: PEtab observables tables - pysb_model_file: PySB model file + :param condition_file: + PEtab condition table + + :param measurement_file: + PEtab measurement table + + :param parameter_file: + PEtab parameter table + + :param visualization_files: + PEtab visualization tables + + :param observable_files: + PEtab observables tables + + :param pysb_model_file: + PySB model file + + :param flatten: + Flatten the petab problem + + :return: + Petab Problem """ condition_df = measurement_df = parameter_df = visualization_df = None @@ -152,18 +170,27 @@ def from_files(condition_file: str = None, measurement_df=measurement_df, parameter_df=parameter_df, observable_df=observable_df, - visualization_df=visualization_df) + visualization_df=visualization_df, + flatten=flatten + ) @staticmethod - def from_yaml(yaml_config: Union[Dict, str]) -> 'PysbPetabProblem': + def from_yaml(yaml_config: Union[Dict, str], + flatten: bool = False) -> 'PysbPetabProblem': """ Factory method to load model and tables as specified by YAML file. NOTE: The PySB model is currently expected in the YAML file under ``sbml_files``. - Arguments: - yaml_config: PEtab configuration as dictionary or YAML file name + :param yaml_config: + PEtab configuration as dictionary or YAML file name + + :param flatten: + Flatten the petab problem + + :return: + Petab Problem """ from petab.yaml import (load_yaml, is_composite_problem, assert_single_condition_and_sbml_file) @@ -210,7 +237,8 @@ def from_yaml(yaml_config: Union[Dict, str]) -> 'PysbPetabProblem': for f in problem0.get(VISUALIZATION_FILES, [])], observable_files=[ os.path.join(path_prefix, f) - for f in problem0.get(OBSERVABLE_FILES, [])] + for f in problem0.get(OBSERVABLE_FILES, [])], + flatten=flatten ) @@ -236,6 +264,11 @@ def create_dummy_sbml( dummy_sbml_model.setExtentUnits("mole") dummy_sbml_model.setSubstanceUnits('mole') + # mandatory if there are species + c = dummy_sbml_model.createCompartment() + c.setId('dummy_compartment') + c.setConstant(False) + # parameters are required for parameter mapping for parameter in pysb_model.parameters: p = dummy_sbml_model.createParameter() @@ -261,6 +294,9 @@ def create_dummy_sbml( s.setId(component.name) s.setInitialAmount(0.0) s.setHasOnlySubstanceUnits(False) + s.setBoundaryCondition(False) + s.setCompartment('dummy_compartment') + s.setConstant(False) return document, dummy_sbml_model diff --git a/deps/AMICI/python/amici/petab_objective.py b/deps/AMICI/python/amici/petab_objective.py index 7b4d4fcf6..6ae8ab0ca 100644 --- a/deps/AMICI/python/amici/petab_objective.py +++ b/deps/AMICI/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 } @@ -262,7 +258,12 @@ def create_parameter_mapping( prelim_parameter_mapping = \ petab_problem.get_optimization_to_simulation_parameter_mapping( - warn_unmapped=False, scaled_parameters=scaled_parameters) + warn_unmapped=False, scaled_parameters=scaled_parameters, + allow_timepoint_specific_numeric_noise_parameters= + not petab.lint.observable_table_has_nontrivial_noise_formula( + petab_problem.observable_df + ) + ) parameter_mapping = ParameterMapping() for (_, condition), prelim_mapping_for_condition in \ @@ -727,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/deps/AMICI/python/amici/pysb_import.py b/deps/AMICI/python/amici/pysb_import.py index 878222fcf..ce1e1ef0b 100644 --- a/deps/AMICI/python/amici/pysb_import.py +++ b/deps/AMICI/python/amici/pysb_import.py @@ -49,6 +49,7 @@ def pysb2amici( compute_conservation_laws: bool = True, compile: bool = True, simplify: Callable = lambda x: sp.powsimp(x, deep=True), + generate_sensitivity_code: bool = True, ): """ Generate AMICI C++ files for the provided model. @@ -93,7 +94,7 @@ def pysb2amici( :attr:`logging.DEBUG`/:attr:`logging.ERROR` :param assume_pow_positivity: - if set to ``true``, a special pow function is used to avoid problems + if set to ``True``, a special pow function is used to avoid problems with state variables that may become negative due to numerical errors @@ -102,17 +103,21 @@ def pysb2amici( extension :param compute_conservation_laws: - if set to ``true``, conservation laws are automatically computed and + if set to ``True``, conservation laws are automatically computed and applied such that the state-jacobian of the ODE right-hand-side has - full rank. This option should be set to ``true`` when using the Newton + full rank. This option should be set to ``True`` when using the Newton algorithm to compute steadystates :param compile: - If ``true``, build the python module for the generated model. If false, + If ``True``, build the python module for the generated model. If false, just generate the source code. :param simplify: see :attr:`amici.ODEModel._simplify` + + :param generate_sensitivity_code: + if set to ``False``, code for sensitivity computation will not be + generated """ if observables is None: observables = [] diff --git a/deps/AMICI/python/amici/sbml_import.py b/deps/AMICI/python/amici/sbml_import.py index 73ae6aa2f..ab9cfd9ba 100644 --- a/deps/AMICI/python/amici/sbml_import.py +++ b/deps/AMICI/python/amici/sbml_import.py @@ -217,6 +217,7 @@ def sbml2amici(self, compute_conservation_laws: bool = True, simplify: Callable = lambda x: sp.powsimp(x, deep=True), log_as_log10: bool = True, + generate_sensitivity_code: bool = True, **kwargs) -> None: """ Generate and compile AMICI C++ files for the model provided to the @@ -256,11 +257,11 @@ def sbml2amici(self, callable generating a custom noise string. :param verbose: - verbosity level for logging, True/False default to - logging.Error/logging.DEBUG + verbosity level for logging, ``True``/``False`` default to + ``logging.Error``/``logging.DEBUG`` :param assume_pow_positivity: - if set to True, a special pow function is + if set to ``True``, a special pow function is used to avoid problems with state variables that may become negative due to numerical errors @@ -272,21 +273,28 @@ def sbml2amici(self, see :class:`amici.ode_export.ODEExporter` :param compile: - If True, compile the generated Python package, - if False, just generate code. + If ``True``, compile the generated Python package, + if ``False``, just generate code. :param compute_conservation_laws: - if set to true, conservation laws are automatically computed and - applied such that the state-jacobian of the ODE right-hand-side has - full rank. This option should be set to True when using the newton - algorithm to compute steadystate sensitivities. + if set to ``True``, conservation laws are automatically computed + and applied such that the state-jacobian of the ODE + right-hand-side has full rank. This option should be set to + ``True`` when using the newton algorithm to compute steadystate + sensitivities. :param simplify: see :attr:`ODEModel._simplify` :param log_as_log10: - If True, log in the SBML model will be parsed as `log10` (default), - if False, log will be parsed as natural logarithm `ln` + If ``True``, log in the SBML model will be parsed as ``log10`` + (default), if ``False``, log will be parsed as natural logarithm + ``ln`` + + :param generate_sensitivity_code: + If ``False``, the code required for sensitivity computation will + not be generated + """ set_log_level(logger, verbose) @@ -337,6 +345,14 @@ def sbml2amici(self, sbml.L3P_PARSE_LOG_AS_LN ) self._process_sbml(constant_parameters) + if self.symbols.get(SymbolId.EVENT, False): + if compute_conservation_laws: + logger.warning( + 'Conservation laws are currently not supported for models ' + 'with events, and will be turned off.' + ) + compute_conservation_laws = False + self._process_observables(observables, sigmas, noise_distributions) self._replace_compartments_with_volumes() @@ -352,7 +368,8 @@ def sbml2amici(self, verbose=verbose, assume_pow_positivity=assume_pow_positivity, compiler=compiler, - allow_reinit_fixpar_initcond=allow_reinit_fixpar_initcond + allow_reinit_fixpar_initcond=allow_reinit_fixpar_initcond, + generate_sensitivity_code=generate_sensitivity_code ) exporter.set_name(model_name) exporter.set_paths(output_dir) @@ -372,10 +389,6 @@ def _process_sbml(self, constant_parameters: List[str] = None) -> None: :param constant_parameters: SBML Ids identifying constant parameters """ - - if constant_parameters is None: - constant_parameters = [] - self.check_support() self._gather_locals() self._process_parameters(constant_parameters) @@ -385,6 +398,7 @@ def _process_sbml(self, constant_parameters: List[str] = None) -> None: self._process_rules() self._process_initial_assignments() self._process_species_references() + self._process_events() def check_support(self) -> None: """ @@ -396,9 +410,6 @@ def check_support(self) -> None: and self.sbml.all_elements_from_plugins.getSize(): raise SBMLException('SBML extensions are currently not supported!') - if self.sbml.getNumEvents(): - raise SBMLException('Events are currently not supported!') - if any([not rule.isAssignment() and not isinstance( self.sbml.getElementBySId(rule.getVariable()), (sbml.Compartment, sbml.Species, sbml.Parameter) @@ -414,12 +425,69 @@ def check_support(self) -> None: ) for rule in self.sbml.getListOfRules()]): raise SBMLException('Only assignment and rate rules are ' 'currently supported for compartments, ' - 'species, and parameters! Error ' - f'occurred with rule: {rule.getVariable()}') + 'species, and parameters!') if any([r.getFast() for r in self.sbml.getListOfReactions()]): raise SBMLException('Fast reactions are currently not supported!') + # Check events for unsupported functionality + self.check_event_support() + + def check_event_support(self) -> None: + """ + Check possible events in the model, as AMICI does currently not support + + * delays in events + * priorities of events + * events fired at initial time + + Furthermore, event triggers are optional (e.g., if an event is fired at + initial time, no trigger function is necessary). + In this case, warn that this event will have no effect. + """ + for event in self.sbml.getListOfEvents(): + event_id = event.getId() + # Check for delays in events + delay = event.getDelay() + if delay is not None: + try: + delay_time = float(self._sympy_from_sbml_math(delay)) + if delay_time != 0: + raise ValueError + # `TypeError` would be raised in the above `float(...)` + # if the delay is not a fixed time + except (TypeError, ValueError): + raise SBMLException('Events with execution delays are ' + 'currently not supported in AMICI.') + # Check for priorities + if event.getPriority() is not None: + raise SBMLException(f'Event {event_id} has a priority ' + 'specified. This is currently not ' + 'supported in AMICI.') + + # check trigger + trigger_sbml = event.getTrigger() + if trigger_sbml is None: + logger.warning(f'Event {event_id} trigger has no trigger, ' + 'so will be skipped.') + continue + if trigger_sbml.getMath() is None: + logger.warning(f'Event {event_id} trigger has no trigger ' + 'expression, so a dummy trigger will be set.') + if not trigger_sbml.getInitialValue(): + # True: event not executed if triggered at time == 0 + # (corresponding to AMICI default). Raise if set to False. + raise SBMLException( + f'Event {event_id} has a trigger that has an initial ' + 'value of False. This is currently not supported in AMICI.' + ) + + if not trigger_sbml.getPersistent(): + raise SBMLException( + f'Event {event_id} has a non-persistent trigger.' + 'This is currently not supported in AMICI.' + ) + @log_execution_time('gathering local SBML symbols', logger) def _gather_locals(self) -> None: """ @@ -573,6 +641,7 @@ def _process_species(self) -> None: 'index': len(self.symbols[SymbolId.SPECIES]), } + self._convert_event_assignment_parameter_targets_to_species() self._process_species_initial() self._process_rate_rules() @@ -615,11 +684,10 @@ def _process_species_initial(self): @log_execution_time('processing SBML rate rules', logger) def _process_rate_rules(self): """ - Process assignment and rate rules for species, compartments and - parameters. Compartments and parameters with rate rules are - implemented as species. Note that, in the case of species, - rate rules may describe the change in amount, not concentration, - of a species. + Process rate rules for species, compartments and parameters. + Compartments and parameters with rate rules are implemented as species. + Note that, in the case of species, rate rules may describe the change + in amount, not concentration, of a species. """ rules = self.sbml.getListOfRules() # compartments with rules are replaced with constants in the relevant @@ -735,6 +803,16 @@ def _process_parameters(self, for parameter in self.sbml.getListOfParameters() if parameter.getId() in constant_parameters ] + for parameter in fixed_parameters: + if self._get_element_initial_assignment(parameter.getId()) is not \ + None or self.is_assignment_rule_target(parameter) or \ + self.is_rate_rule_target(parameter): + raise SBMLException( + f'Cannot turn parameter {parameter.getId()} into a ' + 'constant/fixed parameter since it either has an ' + 'initial assignment or is the target of an assignment or ' + 'rate rule.' + ) parameters = [ parameter for parameter @@ -869,6 +947,179 @@ def _process_time(self) -> None: self._replace_in_all_expressions(sbml_time_symbol, amici_time_symbol) + def _convert_event_assignment_parameter_targets_to_species(self): + """ + Convert parameters that are targets of event assignments to species. + + This is for the convenience of only implementing event assignments for + "species". + """ + parameter_targets = \ + _collect_event_assignment_parameter_targets(self.sbml) + for parameter_target in parameter_targets: + # Parameter rate rules already exist as species. + if parameter_target in self.symbols[SymbolId.SPECIES]: + continue + if parameter_target in self.parameter_assignment_rules: + raise SBMLException( + 'AMICI does not currently support models with SBML events ' + 'that affect parameters that are also the target of ' + 'assignment rules.' + ) + parameter_def = None + for symbol_id in {SymbolId.PARAMETER, SymbolId.FIXED_PARAMETER}: + if parameter_target in self.symbols[symbol_id]: + # `parameter_target` should only exist in one of the + # `symbol_id` dictionaries. + if parameter_def is not None: + raise AssertionError( + 'Unexpected error. The parameter target of an ' + 'event assignment was processed twice.' + ) + parameter_def = \ + self.symbols[symbol_id].pop(parameter_target) + if parameter_def is None: + raise AssertionError( + 'Unexpected error. The parameter target of an event ' + 'assignment could not be found.' + ) + # Fixed parameters are added as species such that they can be + # targets of events. + self.symbols[SymbolId.SPECIES][parameter_target] = { + 'name': parameter_def['name'], + 'init': sp.Float(parameter_def['value']), + # 'compartment': None, # can ignore for amounts + 'constant': False, + 'amount': True, + # 'conversion_factor': 1.0, # can be ignored + 'index': len(self.symbols[SymbolId.SPECIES]), + 'dt': sp.Float(0), + } + + @log_execution_time('processing SBML events', logger) + def _process_events(self) -> None: + """Process SBML events.""" + events = self.sbml.getListOfEvents() + + def get_empty_bolus_value() -> sp.Float: + """ + Used in the event update vector for species that are not affected + by the event. + """ + return sp.Symbol('AMICI_EMTPY_BOLUS') + + # Used to update species concentrations when an event affects a + # compartment. + concentration_species_by_compartment = { + symbol_with_assumptions(c.getId()): [] + for c in self.sbml.getListOfCompartments() + } + for species, species_def in self.symbols[SymbolId.SPECIES].items(): + if ( + # Species is a concentration + not species_def.get('amount', True) and + # Species has a compartment + 'compartment' in species_def + ): + concentration_species_by_compartment[ + species_def['compartment'] + ].append(species) + + for ievent, event in enumerate(events): + # get the event id (which is optional unfortunately) + event_id = event.getId() + if event_id is None or event_id == '': + event_id = f'event_{ievent}' + event_sym = sp.Symbol(event_id) + + # get and parse the trigger function + trigger_sbml = event.getTrigger() + trigger_sym = self._sympy_from_sbml_math(trigger_sbml) + trigger = _parse_event_trigger(trigger_sym) + + # Currently, all event assignment targets must exist in + # self.symbols[SymbolId.SPECIES] + state_vector = list(self.symbols[SymbolId.SPECIES].keys()) + + # parse the boluses / event assignments + bolus = [get_empty_bolus_value() for _ in state_vector] + event_assignments = event.getListOfEventAssignments() + compartment_event_assignments = set() + for event_assignment in event_assignments: + variable_sym = \ + symbol_with_assumptions(event_assignment.getVariable()) + if event_assignment.getMath() is None: + # Ignore event assignments with no change in value. + continue + formula = self._sympy_from_sbml_math(event_assignment) + try: + # Try to find the species in the state vector. + index = state_vector.index(variable_sym) + bolus[index] = formula + except ValueError: + raise SBMLException( + 'Could not process event assignment for ' + f'{str(variable_sym)}. AMICI currently only allows ' + 'event assignments to species; parameters; or, ' + 'compartments with rate rules, at the moment.' + ) + try: + # Try working with the formula now to detect errors + # here instead of at multiple points downstream. + _ = formula - variable_sym + except TypeError: + raise SBMLException( + 'Could not process event assignment for ' + f'{str(variable_sym)}. AMICI only allows symbolic ' + 'expressions as event assignments.' + ) + if variable_sym in concentration_species_by_compartment: + compartment_event_assignments.add(variable_sym) + + for comp, assignment in \ + self.compartment_assignment_rules.items(): + if variable_sym not in assignment.free_symbols: + continue + compartment_event_assignments.add(comp) + + # Update the concentration of species with concentration units + # in compartments that were affected by the event assignments. + for compartment_sym in compartment_event_assignments: + for species_sym in concentration_species_by_compartment[ + compartment_sym + ]: + # If the species was not affected by an event assignment + # then the old value should be updated. + if ( + bolus[state_vector.index(species_sym)] + == get_empty_bolus_value() + ): + species_value = species_sym + # else the species was affected by an event assignment, + # hence the updated value should be updated further. + else: + species_value = bolus[state_vector.index(species_sym)] + # New species value is old amount / new volume. + bolus[state_vector.index(species_sym)] = ( + species_value * compartment_sym / formula + ) + + # Subtract the current species value from each species with an + # update, as the bolus will be added on to the current species + # value during simulation. + for index in range(len(bolus)): + if bolus[index] != get_empty_bolus_value(): + bolus[index] -= state_vector[index] + bolus[index] = bolus[index].subs(get_empty_bolus_value(), + sp.Float(0.0)) + + self.symbols[SymbolId.EVENT][event_sym] = { + 'name': event_id, + 'value': trigger, + 'state_update': sp.MutableDenseMatrix(bolus), + 'event_observable': None, + } + @log_execution_time('processing SBML observables', logger) def _process_observables( self, @@ -1229,7 +1480,8 @@ def _replace_in_all_expressions(self, for k, v in self.symbols[symbol].items() } - for symbol in [SymbolId.OBSERVABLE, SymbolId.LLHY, SymbolId.SIGMAY]: + for symbol in [SymbolId.OBSERVABLE, SymbolId.LLHY, + SymbolId.SIGMAY]: if old not in self.symbols[symbol]: continue self.symbols[symbol][new] = self.symbols[symbol][old] @@ -1237,12 +1489,19 @@ def _replace_in_all_expressions(self, # replace in values for symbol in [SymbolId.OBSERVABLE, SymbolId.LLHY, SymbolId.SIGMAY, - SymbolId.EXPRESSION]: + SymbolId.EXPRESSION, SymbolId.EVENT]: if not self.symbols.get(symbol, None): continue for element in self.symbols[symbol].values(): element['value'] = smart_subs(element['value'], old, new) + # replace in event state updates (boluses) + if self.symbols.get(SymbolId.EVENT, False): + for event in self.symbols[SymbolId.EVENT].values(): + for index in range(len(event['state_update'])): + event['state_update'][index] = \ + smart_subs(event['state_update'][index], old, new) + if SymbolId.SPECIES in self.symbols: for species in self.symbols[SymbolId.SPECIES].values(): species['init'] = smart_subs(species['init'], @@ -1268,7 +1527,8 @@ def _clean_reserved_symbols(self) -> None: """ Remove all reserved symbols from self.symbols """ - reserved_symbols = ['x', 'k', 'p', 'y', 'w', 'h', 't'] + reserved_symbols = ['x', 'k', 'p', 'y', 'w', 'h', 't', + 'AMICI_EMPTY_BOLUS'] for sym in reserved_symbols: old_symbol = symbol_with_assumptions(sym) new_symbol = symbol_with_assumptions(f'amici_{sym}') @@ -1372,8 +1632,7 @@ def _get_element_stoichiometry(self, return sp.Float(1.0) - def is_assignment_rule_target(self, - element: sbml.SBase) -> bool: + def is_assignment_rule_target(self, element: sbml.SBase) -> bool: """ Checks if an element has a valid assignment rule in the specified model. @@ -1390,6 +1649,23 @@ def is_assignment_rule_target(self, return True + def is_rate_rule_target(self, element: sbml.SBase) -> bool: + """ + Checks if an element has a valid assignment rule in the specified + model. + + :param element: + SBML variable + + :return: + boolean indicating truth of function name + """ + a = self.sbml.getRateRuleByVariable(element.getId()) + if a is None or self._sympy_from_sbml_math(a) is None: + return False + + return True + def _check_lib_sbml_errors(sbml_doc: sbml.SBMLDocument, show_warnings: bool = False) -> None: @@ -1525,7 +1801,7 @@ def _parse_special_functions(sym: sp.Expr, toplevel: bool = True) -> sp.Expr: if isinstance(sym, (sp.Function, sp.Mul, sp.Add)): sym._args = args - + elif toplevel and isinstance(sym, BooleanAtom): # Replace boolean constants by numbers so they can be differentiated # must not replace in Piecewise function. Therefore, we only replace @@ -1537,7 +1813,7 @@ def _parse_special_functions(sym: sp.Expr, toplevel: bool = True) -> sp.Expr: def _denest_piecewise( args: Sequence[Union[sp.Expr, sp.logic.boolalg.Boolean, bool]] - ) -> Tuple[Union[sp.Expr, sp.logic.boolalg.Boolean, bool]]: +) -> Tuple[Union[sp.Expr, sp.logic.boolalg.Boolean, bool]]: """ Denest piecewise functions that contain piecewise as condition @@ -1582,8 +1858,8 @@ def _denest_piecewise( def _parse_piecewise_to_heaviside(args: Iterable[sp.Expr]) -> sp.Expr: """ - Piecewise functions cannot be transformed into C++ right away, but AMICI has - a special interface for Heaviside function, so we transform them + Piecewise functions cannot be transformed into C++ right away, but AMICI + has a special interface for Heaviside functions, so we transform them. :param args: symbolic expressions for arguments of the piecewise function @@ -1602,14 +1878,14 @@ def _parse_piecewise_to_heaviside(args: Iterable[sp.Expr]) -> sp.Expr: if trigger == sp.false: continue - tmp = _parse_trigger(trigger) + tmp = _parse_heaviside_trigger(trigger) formula += coeff * sp.simplify(not_condition * tmp) not_condition *= (1-tmp) return formula -def _parse_trigger(trigger: sp.Expr) -> sp.Expr: +def _parse_heaviside_trigger(trigger: sp.Expr) -> sp.Expr: """ Recursively translates a boolean trigger function into a real valued root function @@ -1619,6 +1895,7 @@ def _parse_trigger(trigger: sp.Expr) -> sp.Expr: """ if trigger.is_Relational: root = trigger.args[0] - trigger.args[1] + _check_unsupported_functions(root, 'sympy.Expression') # normalize such that we always implement <, # this ensures that we can correctly evaluate the condition if @@ -1640,15 +1917,56 @@ def _parse_trigger(trigger: sp.Expr) -> sp.Expr: # or(x,y) = not(and(not(x),not(y)) if isinstance(trigger, sp.Or): - return 1-sp.Mul(*[1-_parse_trigger(arg) + return 1-sp.Mul(*[1-_parse_heaviside_trigger(arg) for arg in trigger.args]) if isinstance(trigger, sp.And): - return sp.Mul(*[_parse_trigger(arg) + return sp.Mul(*[_parse_heaviside_trigger(arg) for arg in trigger.args]) - raise SBMLException('AMICI can not parse piecewise functions ' - f'with argument {trigger}.') + raise SBMLException( + 'AMICI can not parse piecewise/event trigger functions with argument ' + f'{trigger}.' + ) + + +def _parse_event_trigger(trigger: sp.Expr) -> sp.Expr: + """ + Recursively translates a boolean trigger function into a real valued + root function + + :param trigger: + :return: real valued root function expression + """ + # Events can be defined without trigger, i.e., the event will never fire. + # In this case, set a dummy trigger: + if trigger is None: + return sp.Float(1.0) + if trigger.is_Relational: + root = trigger.args[0] - trigger.args[1] + _check_unsupported_functions(root, 'sympy.Expression') + + # convert relational expressions into trigger functions + if isinstance(trigger, sp.core.relational.LessThan) or \ + isinstance(trigger, sp.core.relational.StrictLessThan): + # y < x or y <= x + return -root + if isinstance(trigger, sp.core.relational.GreaterThan) or \ + isinstance(trigger, sp.core.relational.StrictGreaterThan): + # y >= x or y > x + return root + + # or(x,y): any of {x,y} is > 0: sp.Max(x, y) + if isinstance(trigger, sp.Or): + return sp.Max(*[_parse_event_trigger(arg) for arg in trigger.args]) + # and(x,y): all out of {x,y} are > 0: sp.Min(x, y) + if isinstance(trigger, sp.And): + return sp.Min(*[_parse_event_trigger(arg) for arg in trigger.args]) + + raise SBMLException( + 'AMICI can not parse piecewise/event trigger functions with argument ' + f'{trigger}.' + ) def _parse_logical_operators(math_str: Union[str, float, None] @@ -1864,3 +2182,17 @@ def replace_logx(math_str: Union[str, float, None]) -> Union[str, float, None]: return re.sub( r'(^|\W)log(\d+)\(', r'\g<1>1/ln(\2)*ln(', math_str ) + + +def _collect_event_assignment_parameter_targets(sbml_model: sbml.Model): + targets = set() + sbml_parameters = sbml_model.getListOfParameters() + sbml_parameter_ids = [p.getId() for p in sbml_parameters] + for event in sbml_model.getListOfEvents(): + for event_assignment in event.getListOfEventAssignments(): + target_id = event_assignment.getVariable() + if target_id in sbml_parameter_ids: + targets.add(_get_identifier_symbol( + sbml_parameters[sbml_parameter_ids.index(target_id)] + )) + return targets diff --git a/deps/AMICI/python/examples/example_presimulation/ExampleExperimentalConditions.ipynb b/deps/AMICI/python/examples/example_presimulation/ExampleExperimentalConditions.ipynb new file mode 100644 index 000000000..07da70c02 --- /dev/null +++ b/deps/AMICI/python/examples/example_presimulation/ExampleExperimentalConditions.ipynb @@ -0,0 +1,462 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# AMICI Python example \"Experimental Conditions\"\n", + "In this example we will explore some more options for the initialization of experimental conditions, including how to reset initial conditions based on changing values for `fixedParameters` as well as an additional presimulation phase on top of preequilibration. This notebook is expected to run from the `python/example_presimulation` directory." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# SBML model we want to import\n", + "sbml_file = 'model_presimulation.xml'\n", + "# Name of the model that will also be the name of the python module\n", + "model_name = 'model_presimulation'\n", + "# Directory to which the generated model code is written\n", + "model_output_dir = model_name\n", + "\n", + "import libsbml\n", + "import amici\n", + "import amici.plotting\n", + "import os\n", + "import sys\n", + "import importlib\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from pprint import pprint" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model Loading\n", + "Here we load a simple model of protein phosphorylation that can be inhibited by a drug. This model was created using PySB (see `createModel.py`)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Species:\n", + "[('__s0', \"PROT(kin=None, drug=None, phospho='u')\"),\n", + " ('__s1', 'DRUG(bound=None)'),\n", + " ('__s2', 'KIN(bound=None)'),\n", + " ('__s3', \"DRUG(bound=1) ._br_PROT(kin=None, drug=1, phospho='u')\"),\n", + " ('__s4', \"KIN(bound=1) ._br_PROT(kin=1, drug=None, phospho='u')\"),\n", + " ('__s5', \"PROT(kin=None, drug=None, phospho='p')\")]\n", + "\n", + "Reactions:\n", + "PROT_DRUG_bind: __s0 + __s1 <-> __s3\t\t[-(koff_prot_drug * __s3) + kon_prot_drug * __s0 * __s1]\n", + "PROT_KIN_bind: __s0 + __s2 -> __s4\t\t[kon_prot_kin * __s0 * __s2]\n", + "PROT_KIN_phospho: __s4 -> __s2 + __s5\t\t[kphospho_prot_kin * __s4]\n", + "PROT_dephospho: __s5 -> __s0\t\t[kdephospho_prot * __s5]\n", + "Parameters:\n", + "[('initProt', 'initProt'),\n", + " ('initDrug', 'initDrug'),\n", + " ('initKin', 'initKin'),\n", + " ('pPROT_obs', 'pPROT_obs'),\n", + " ('PROT_0', 'PROT_0'),\n", + " ('DRUG_0', 'DRUG_0'),\n", + " ('KIN_0', 'KIN_0'),\n", + " ('kon_prot_drug', 'kon_prot_drug'),\n", + " ('koff_prot_drug', 'koff_prot_drug'),\n", + " ('kon_prot_kin', 'kon_prot_kin'),\n", + " ('kphospho_prot_kin', 'kphospho_prot_kin'),\n", + " ('kdephospho_prot', 'kdephospho_prot'),\n", + " ('__obs0', 'pPROT'),\n", + " ('__obs1', 'tPROT')]\n" + ] + } + ], + "source": [ + "sbml_reader = libsbml.SBMLReader()\n", + "sbml_doc = sbml_reader.readSBML(sbml_file)\n", + "sbml_model = sbml_doc.getModel()\n", + "\n", + "print('Species:')\n", + "pprint([(s.getId(),s.getName()) for s in sbml_model.getListOfSpecies()])\n", + "\n", + "print('\\nReactions:')\n", + "for reaction in sbml_model.getListOfReactions():\n", + " reactants = ' + '.join(['%s %s'%(int(r.getStoichiometry()) if r.getStoichiometry() > 1 else '', r.getSpecies()) for r in reaction.getListOfReactants()])\n", + " products = ' + '.join(['%s %s'%(int(r.getStoichiometry()) if r.getStoichiometry() > 1 else '', r.getSpecies()) for r in reaction.getListOfProducts()])\n", + " reversible = '<' if reaction.getReversible() else ''\n", + " print('%3s: %10s %1s->%10s\\t\\t[%s]' % (reaction.getName(), \n", + " reactants,\n", + " reversible,\n", + " products,\n", + " libsbml.formulaToL3String(reaction.getKineticLaw().getMath())))\n", + " \n", + "print('Parameters:')\n", + "pprint([(p.getId(),p.getName()) for p in sbml_model.getListOfParameters()])" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "# Create an SbmlImporter instance for our SBML model\n", + "sbml_importer = amici.SbmlImporter(sbml_file)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For this example we want specify the initial drug and kinase concentrations as experimental conditions. Accordingly we specify them as `fixedParameters`. The meaning of `fixedParameters` is defined in the [Glossary](https://amici.readthedocs.io/en/latest/glossary.html#term-fixed-parameters), which we display here for convenience." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import IFrame\n", + "IFrame('https://amici.readthedocs.io/en/latest/glossary.html#term-fixed-parameters', width=600, height=175)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "fixedParameters = ['DRUG_0','KIN_0']" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The SBML model specifies a single observable named `pPROT` which describes the fraction of phosphorylated Protein. We load this observable using [amici.assignmentRules2observables](https://amici.readthedocs.io/en/latest/generated/amici.sbml_import.html#amici.sbml_import.assignmentRules2observables)." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Observables:\n", + "{'__obs0': {'formula': '__s5', 'name': 'pPROT'}}\n" + ] + } + ], + "source": [ + "# Retrieve model output names and formulae from AssignmentRules and remove the respective rules\n", + "observables = amici.assignmentRules2observables(\n", + " sbml_importer.sbml, # the libsbml model object\n", + " filter_function=lambda variable: variable.getName() == 'pPROT' \n", + " )\n", + "print('Observables:')\n", + "pprint(observables)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now the model is ready for compilation using [sbml2amici](https://amici.readthedocs.io/en/latest/generated/amici.sbml_import.SbmlImporter.html#amici.sbml_import.SbmlImporter.sbml2amici). Note that we here pass `fixedParameters` as arguments to `constant_parameters`, which ensures that amici is aware that we want to have them as `fixedParameters`:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "sbml_importer.sbml2amici(model_name, \n", + " model_output_dir, \n", + " verbose=False,\n", + " observables=observables,\n", + " constant_parameters=fixedParameters)\n", + "# load the generated module\n", + "model_module = amici.import_model_module(model_name, model_output_dir)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To simulate the model we need to create an instance via the `getModel()` method in the generated model module." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Create Model instance\n", + "model = model_module.getModel()\n", + "\n", + "# Create solver instance\n", + "solver = model.getSolver()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The only thing we need to simulate the model is a timepoint vector, which can be specified using the [setTimepoints](https://amici.readthedocs.io/en/latest/generated/amici.amici.Model.html#amici.amici.Model.setTimepoints) method. If we do not specify any additional options, the default values for `fixedParameters` and `parameters` that were specified in the SBML file will be used." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Run simulation using default model parameters and solver options\n", + "model.setTimepoints(np.linspace(0, 60, 60)) \n", + "rdata = amici.runAmiciSimulation(model, solver)\n", + "amici.plotting.plotObservableTrajectories(rdata)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Simulation options can be specified either in the [Model](https://amici.readthedocs.io/en/latest/generated/amici.amici.Model.html) or in an [ExpData](https://amici.readthedocs.io/en/latest/generated/amici.amici.ExpData.html) instance. The `ExpData` instance can also carry experimental data. To initialize an `ExpData` instance from simulation results, amici offers some [convenient constructors](https://amici.readthedocs.io/en/latest/generated/amici.amici.ExpData.html#amici.amici.ExpData). In the following we will initialize an `ExpData` object from simulation results, but add noise with standard deviation `0.1` and specify the standard deviation accordingly. Moreover, we will specify custom values for `DRUG_0=0` and `KIN_0=2`. If `fixedParameter` is specified in an `ExpData` instance, [runAmiciSimulation](https://amici.readthedocs.io/en/latest/generated/amici.html#amici.runAmiciSimulation) will use those parameters instead of the ones specified in the `Model` instance." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "edata = amici.ExpData(rdata, 0.1, 0.0)\n", + "edata.fixedParameters = [0,2]\n", + "rdata = amici.runAmiciSimulation(model, solver, edata)\n", + "amici.plotting.plotObservableTrajectories(rdata)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For many biological systems, it is reasonable to assume that they start in a\n", + " steady state. In this example we want to specify an experiment where a pretreatment with a drug is performed _before_ the kinase is added. We assume that the pretreatment is sufficiently long such that the system reaches steadystate before the kinase is added. To implement this in amici, we can specify `fixedParametersPreequilibration` in the `ExpData` object. This automatically adds a preequilibration phase where the model is run to steadystate, before regular simulation starts. Here we set `DRUG_0=3` and `KIN_0=0` for the preequilibration. This means that there is no kinase available in the preequilibration phase. " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "edata.fixedParametersPreequilibration = [3,0]\n", + "rdata = amici.runAmiciSimulation(model, solver, edata)\n", + "amici.plotting.plotObservableTrajectories(rdata)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The resulting trajectory is definitely not what one may expect. The problem is that the `DRUG_0` and `KIN_0` set initial conditions for species in the model. By default these initial conditions are only applied at the very beginning of the simulation, i.e., before the preequilibration. Accordingly, the `fixedParameters` that we specified do not have any effect. To fix this, we need to set the `reinitializeFixedParameterInitialStates` attribue to `True`, to spefify that AMICI reinitializes all states that have `fixedParameter`-dependent initial states." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "edata.reinitializeFixedParameterInitialStates = True" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this option activated, the kinase concentration will be reinitialized after the preequilibration and we will see the expected change in fractional phosphorylation:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "rdata = amici.runAmiciSimulation(model, solver, edata)\n", + "amici.plotting.plotObservableTrajectories(rdata)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On top of preequilibration, we can also specify presimulation. This option can be used to specify pretreatments where the system is not assumed to reach steadystate. Presimulation can be activated by specifying `t_presim` and `edata.fixedParametersPresimulation`. If both `fixedParametersPresimulation` and `fixedParametersPreequilibration` are specified, preequilibration will be performed first, followed by presimulation, followed by regular simulation. For this example we specify `DRUG_0=10` and `KIN_0=0` for the presimulation and `DRUG_0=10` and `KIN_0=2` for the regular simulation. We do not overwrite the `DRUG_0=3` and `KIN_0=0` that was previously specified for preequilibration." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3.0, 0.0)\n", + "(10.0, 0.0)\n", + "(10.0, 2.0)\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYYAAAEZCAYAAACTsIJzAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAApiUlEQVR4nO3deXyU5bn/8c+VnUAgJOwEDMiiqLghuFYRqVi36ukiWo8VLd3U2mMXlxaXY3+ttkdrq+2p3fRYrStVqlRUxFqtCyAiO4RFSNhCgLBlmSTX7495aJOYQBIy88wk3/frNa+ZZ5mZ6wnDfOd+lvs2d0dERGS/lLALEBGRxKJgEBGRBhQMIiLSgIJBREQaUDCIiEgDCgYREWlAwSCdipndYWZ/CruOAzlYjWa2zszOiWdN0rkoGKTDMbMvm9kiM9tnZpvN7Ndmlht2XSLJQsEgHYqZ3QTcA3wX6AGcDBwGvGpmGXGqIS0e7yMSKwoG6TDMrDtwJ3C9u7/s7hF3Xwd8ASgEvhSsmmVmT5nZbjP7wMyOrfca3zezkmDZCjObEMxPMbObzWy1mZWZ2dNmlhcsKzQzN7NrzGw98LqZ/c3MrmtU30IzuzR4/ICZbTCzXWY238zOaLQ5zdbY6DUPVFeWmf0pmL/TzOaaWd9D+ytLZ6BgkI7kVCALmF5/prvvAWYCE4NZFwPPAHnAE8DzZpZuZiOB64CT3D0HOBdYFzzneuCzwJnAAGAH8FCj9z8TODJ43p+ByfsXmNkooi2Xl4JZc4Hj6tXwjJll1XutJmtsYpsPVNdVRFtNg4B84GtARROvIdKAgkE6kl7ANnevaWLZpmA5wHx3f9bdI8B9RMPkZKAWyARGmVm6u69z99XBc74G3Obuxe5eBdwBfK7RbqM73H2vu1cAfwGOM7PDgmVXANOD5+Luf3L3Mnevcff/Cd53ZL3Xaq7Gxg5UV4RoIAxz91p3n+/uuw7+Z5TOTsEgHck2oFcz+/j7B8sBNuyf6e51QDEwwN2LgBuJfrluNbMnzWxAsOphwF+CXTI7gWVEg6T+rpn6r7ubaOvgsmDWZODx/cvN7DtmtszMyoPX68G/g6vZGpvYrgPV9RgwC3jSzDaa2b3NtDpEGlAwSEfyDlAFXFp/ppl1A84DZgezBtVblgIUABsB3P0Jdz+d6BeuEz2QDdEv6vPcPbfeLcvdS+q9VeOuiv8MTDazU4j+4p8TvOcZwPeIHvvo6e65QDlg9Z7bbI2NNFtXcIzlTncfRXQ32wXAfzb5lxOpR8EgHYa7lxM9+PxLM5sUHDcoBJ4m+ov7sWDVE83s0qBlcSPRMHnXzEaa2dlmlglUEt0fXxc853+BH+3fNWRmvc3s4oOUNJNowNwFPBX88gfIAWqAUiDNzKYB3Rs9t8kam3iPZusys/FmdoyZpQK7iO5aqmviNUQaUDBIh+Lu9wK3Aj8j+mX4HtFf1RP2798HXgC+SPRA7ZXApcG+/EzgJ0R3OW0G+gC3BM95AJgBvGJmu4l+SY87SC1VRA+En0P0APJ+s4CXgZXAx0RDaEOjpzdXY2MHqqsf8Gzwd1gG/J1/h6NIs0wD9YiISH1qMYiISAMKBhERaUDBICIiDSgYRESkgaTv7KtXr15eWFgYdhkiIkll/vz529y9d1PLkj4YCgsLmTdvXthliIgkFTP7uLll2pUkIiINKBhERKQBBYOIiDSQ9McYmhKJRCguLqaysjLsUtpFVlYWBQUFpKerY0wRib0OGQzFxcXk5ORQWFiImR38CQnM3SkrK6O4uJghQ4aEXY6IdAIdcldSZWUl+fn5SR8KAGZGfn5+h2n9iEji65DBAHSIUNivI22LiCS+DrkrSUQkDO5ObZ0TqXWqa+uI7L/V/Hu6ptaJ1EXva2rriNRF72vqPDovWFZb59TUObV1dURqnTrfPx1dr9adCUf04dhBue2+HQoGEemQ3J3KSB37qmvYV13LvupaKiK1VFTXUhn59+N9kVqqItF5lZG66H1NLVWROqpqotNVNXVU1UTvq/ffauuoikS/7PdPV9fWEc+RDPrkZCoYOqJHH32Uu+++G4Af/OAHXHXVVSFXJBIud2dvdS3lFRF2BbfdlTXsqow+3lNVw+6qGvZU1rCn3v3e6hr2VtWyt6qGvVU17IvUtvpLOjXFyEpLITM99V/3mfvvU1PolplGRnYKmekpZKSmkJEW3FJTSU8zMlJTSA/mp6emkJFqpAfz0lKjy9OCx+kpwX2qkRY8TktJITUlmJeaQlqKkZpipJr9a3lKCtF7i91uZgVDiLZv386dd97JvHnzMDNOPPFELrroInr27Bl2aSLtwt3ZVVHDtr1VbN9bTdmeKrbvjbBjXzU79lazPbjfWRGhfF+E8ororabuwN/oGWkp5GSm0S0rja4Z0fs+OVlk56fSLTON7Iw0umamkp2RRnZGKl0yUskObl3S0+iSkUqX9Oh0ZnoKWenR6fTUDnvYtVU6fDDc+dclLN24q11fc9SA7tx+4VHNLp82bRp5eXnceOONANx222306dOHb33rWw3WmzVrFhMnTiQvLw+AiRMn8vLLLzN58uR2rVekvdXU1lG6p4otu6rYXF7Jll2VlO6uYuvu6H3pnipKd1dRtqe62S/57IxUemZn0LNrOj2zMxiY24UeXdLJzU6nR5forXtWOt2D+5ystOCWTkaavsBjqcMHQximTJnCpZdeyo033khdXR1PPvkk77///ifWKykpYdCgQf+aLigooKSkJJ6lijRpV2WEDdv3sWF7BRt3VrCpvIKNOysp2Rmd3ranisbf96kpRq9uGfTOyaR3t0xG9e9OfrdM8rtm0KtbJvndMsjvmkle12gYZKalhrNxclBxDQYzm0R08PJU4Hfu/pNGywcDjwK5wTo3u/vMQ3nPA/2yj5XCwkLy8/NZsGABW7Zs4fjjjyc/Pz/udYg0x90p3V3FurJ9rNu2l7Vle/m4bC8btlewfvs+yisiDdbPTEthYG4XBuR24cwRvenfI4u+PbLom5NFvx5Z9O2eRX7XDFJSdGp1RxC3YDCzVOAhYCJQDMw1sxnuvrTeaj8Annb3X5vZKGAmUBivGtvTtddeyyOPPMLmzZuZMmVKk+sMHDiQN95441/TxcXFnHXWWfEpUDqFSG0dH5fto2jrHlaX7qFoa/S2pnQPe6tr/7VeeqoxqGc2BXnZjC7oweC8bAblZVPQswsDc7uQ1zVD19N0IvFsMYwFitx9DYCZPQlcDNQPBge6B497ABvjWF+7uuSSS5g2bRqRSIQnnniiyXXOPfdcbr31Vnbs2AHAK6+8wo9//ON4likdyNZdlSzdtIsVm3ezPLit3rqH6tq6f60zoEcWh/fpxufHDGJIr64U9urKkPyuDMjNIk0HXiUQz2AYCGyoN10MjGu0zh3AK2Z2PdAVOKepFzKzqcBUgMGDB7d7oe0hIyOD8ePHk5ubS2pq0/tS8/Ly+OEPf8hJJ50E/PugtcjBbCqvYFFxOYtLylm8cReLSsop3V31r+X9e2Qxsl8OnxrRi5F9cxjWpxuH9+5G10wdVpSDS7RPyWTgEXf/HzM7BXjMzI5297r6K7n7w8DDAGPGjInj5SQtV1dXx7vvvsszzzxzwPWmTJnS7K4mEYDKSC2LSspZsH4HC9bvZMH6nWzeFe07K8VgeJ8czhjei6MH9OCoAd0Z2S+H3OyMkKuWZBbPYCgBBtWbLgjm1XcNMAnA3d8xsyygF7A1LhW2k6VLl3LBBRdwySWXMHz48LDLkSSzqzLC/I938N6a7by/toxFJeVEaqO/fwbnZTNuaB7HDcpldEEuo/p3p0uGzu6R9hXPYJgLDDezIUQD4TLg8kbrrAcmAI+Y2ZFAFlAaxxrbxahRo1izZs2/phctWsSVV17ZYJ3MzEzee++9eJcmCagyUsv7a7fzVtE2/rl6G0s37qLOoweERxfkcs3pQznxsJ4cPziXXt0ywy5XOoG4BYO715jZdcAsoqei/sHdl5jZXcA8d58B3AT81sy+TfRA9Jfd29bziLsnzFkUxxxzDB9++GGbn9/GP4EkKHdn+ebdvLGilLeKSpm7bgfVNXWkpxonDO7J9WcPZ9yQPI4f3FOtAQlFXI8xBNckzGw0b1q9x0uB0w71fbKysigrK+sQYzLsH6gnKysr7FLkEFRGanlnTRmvL9vK68u3UrKzAoAj+uXwnycfxmnDezFuSB7ZGYl22E86ow75KSwoKKC4uJjS0qTbC9Wk/UN7SnLZU1XD7GVb+Nuizfx9ZSkVkVq6pKdyxvBe3DBhGONH9qFPdwW+JJ4OGQzp6ekaBlNCsbsywuxlW5m5aBNvrCyluqaOPjmZ/MeJAznnyL6cPDSfrHTtHpLE1iGDQSSeamrr+MeqbUxfUMIrSzZTVVNH3+6ZXD52MOeP7s+Jg3uqqwhJKgoGkTZasrGc6R+U8MKHG9m2p4rc7HS+MGYQFx83gBMUBpLEFAwirbCvuoYXF27i8fc+ZmFxOempxtlH9OHSEwoYP7KPuoOWDkHBINICK7fs5vF3P2b6ghJ2V9YwrE83br9wFJ89biA9u+oqY+lYFAwizairc/6+qpTf/2MtbxVtIyM1hc8c04/Lxx3GSYU9k/5UaJHmKBhEGqmM1PL8ghJ+99ZairbuoW/3TL43aSSXnTSYPLUOpBNQMIgEdldG+L93PuYPb62lbG81o/p35/4vHsv5xwzQsQPpVBQM0umVV0R49J/r+P1baymviHDmiN589cyhnDI0+a+cF2kLBYN0WuUVEf7w1lr+8PZadlfWcM6RfblhwjBGF+SGXZpIqBQM0ulURmp57J2PeXBOEeUVESYd1Y/rzh7G0QN7hF2aSEJQMEinUVfnvLCwhJ/NWknJzgo+NaI33580kqMGKBBE6lMwSKfwz6Jt3P3SMpZu2sXRA7tz7+dGc9qwXmGXJZKQFAzSoW3cWcGPXlrGS4s2UdCzCw9cdhwXjh6g7ipEDkDBIB1SdU0dv3trDb+cXUSdO98+ZwRfPXOoejYVaQEFg3Q4b63axrQXFrNm214mjurLtAtGMSgvO+yyRJKGgkE6jPKKCD96aSlPzyvmsPxs/vjlkxh/RJ+wyxJJOgoG6RBmL9vCrX9ZROnuKr525uHceM5w7TYSaSMFgyS1HXuruevFpfxlQQkj++bw8JVjOHZQbthliSQ1BYMkrTdXlnLTMwvZsbeaGyYM57rxw9SnkUg7UDBI0qmuqeNnr6zg4TfXMKJvNx65+iRdpCbSjhQMklTWlO7hhicXsLhkF186eTA/OH+UjiWItDMFgyQFd+fZ+cXcPmMJGWkp/ObKEzn3qH5hlyXSISkYJOFVRmq5/YUlPDVvAycPzeP+Lx5H/x5dwi5LpMNSMEhC27izgq//aT4Li8u5bvwwvj1xBKnqzkIkphQMkrDeWV3GdU98QFVNnXYdicSRgkESjrvz+7fW8uO/LacwP5vfXDmGYX26hV2WSKehYJCEEqmt47a/LOLpecWce1Rffvb5Y8nJSg+7LJFORcEgCWNXZYRvPv4B/1i1jevPHsa3zxmh7rFFQqBgkISwcWcFUx6ZS9HWPdz7udF8YcygsEsS6bQUDBK6xSXlTHlkLhXVtTxy9VhOH66R1UTCpGCQUL25spSv/Wk+PbMzeOzr4xjZLyfskkQ6PQWDhOblxZu4/s8LGN4nh0euPok+3bPCLklEUDBISJ6bX8x3n13IcYNy+ePVY+nRRWceiSQKBYPE3WPvrOOHLyzhtGH5PHzlGLpm6mMokkj0P1Li6tdvrOael5dzzpF9efDy49UzqkgCUjBI3Nz/6koemL2Ki44dwP984VjSUzWojkgiUjBIXDw0p4gHZq/i8ycW8JP/GK2O8EQSWFx/spnZJDNbYWZFZnZzM+t8wcyWmtkSM3sinvVJbPzuH2v46awVXHL8QIWCSBKIW4vBzFKBh4CJQDEw18xmuPvSeusMB24BTnP3HWbWJ171SWz83zvruPulZZx/TH9++jmFgkgyiGeLYSxQ5O5r3L0aeBK4uNE6XwEecvcdAO6+NY71STt7au56pr2whImj+vLzy44jTccURJJCPP+nDgQ21JsuDubVNwIYYWZvm9m7ZjapqRcys6lmNs/M5pWWlsaoXDkUzy8o4ebpizhzRG8evPx4HWgWSSKJ9r81DRgOnAVMBn5rZrmNV3L3h919jLuP6d27d3wrlIN6Y8VWbnpmIScPyec3V55IZppOSRVJJvEMhhKgfpeZBcG8+oqBGe4ecfe1wEqiQSFJYlFxOd94/ANG9M3h4f88UdcpiCSheAbDXGC4mQ0xswzgMmBGo3WeJ9pawMx6Ed21tCaONcohWF+2j6sfeZ+e2Rk8cvVJGmBHJEnFLRjcvQa4DpgFLAOedvclZnaXmV0UrDYLKDOzpcAc4LvuXhavGqXtyvZUcdUf36emznl0ylj6qkM8kaRl7h52DYdkzJgxPm/evLDL6NQqqmuZ/Nt3WbZpF49fO44xhXlhlyQiB2Fm8919TFPLEu3gsySZ2jrn+j8v4KPinfxi8vEKBZEOQMEgh+Sns1bw2rIt3H7hUZx7VL+wyxGRdqBgkDZ7fkEJ//v31VwxbjBXnVoYdjki0k4UDNImCzfs5HvPfcS4IXncfuFRYZcjIu1IwSCttmVXJVMfm0efnEx+/aUTyUjTx0ikI1G329IqlZFapj42n92VNUz/xqnkdc0IuyQRaWcKBmkxd+fW6YtYuGEnv7nyRI7o1z3skkQkBrQPQFrsT+9+zPQFJfzXxBE6A0mkA1MwSIt8VLyT/35xGWcf0Yfrxg8LuxwRiSEFgxxU+b4I33j8A3rnZPI/nz+WFA22I9Kh6RiDHJC7c9MzC9myq5Knv3oKPXWwWaTDU4tBDui3/1jDa8u2cOtnjuT4wT3DLkdE4kDBIM2au24797y8gvOO7seXdWWzSKehYJAmle2p4ronPmBQzy7c87nRmOm4gkhnoWCQT3B3bp6+iB17Izx0xQl014A7Ip2KgkE+4cm5G3h16Ra+N2kkRw3oEXY5IhJnrQ4GM+tqZhrIt4Nau20vd/11KacNy2fKaUPCLkdEQnDQYDCzFDO73MxeMrOtwHJgk5ktNbOfmpmuduogIrV13PjkAjLSUviZrlcQ6bRa0mKYAxwO3AL0c/dB7t4HOB14F7jHzL4UwxolTn45exULi8v5f5ccQ/8eXcIuR0RC0pIL3M5x90jjme6+HXgOeM7MdHQyyc1bt50H5xTxHycUcP7o/mGXIyIhakkwXN/oVEUHtgFvuftagKaCQ5LH7soI3376Qwb27MIdF40KuxwRCVlLdiXlNLp1B8YAfzOzy2JYm8TJ/5u5nJIdFdz/hePI0ampIp3eQVsM7n5nU/PNLA94DXiyvYuS+Hm7aBt/fn89Uz81lDGFeWGXIyIJoM3XMQTHGHTaShLbW1XDzdM/YkivrvzXxBFhlyMiCaLNvaua2XhgRzvWInH201krKN5RwdNfPYWsdF2aIiJRBw0GM1tE9IBzfXnARuCqWBQlsTd33XYefWcdV51SyEnahSQi9bSkxXBBo2kHytx9bwzqkTiojNTy/Wc/YmBuF7577siwyxGRBNOSg88fNzXfzE4HJrv7N9u9Komp+19byZpte3n82nF0zdRYTSLSUKu+FczseOBy4PPAWmB6LIqS2Fm4YSe/fXMNk8cO4rRhvcIuR0QSUEuOMYwAJge3bcBTgLn7+BjXJu2spraOm6cvondOJrd85siwyxGRBNWSFsNy4B/ABe5eBGBm345pVRITj77zMcs27eLXGmNBRA6gJdcxXApsAuaY2W/NbAK6fiHpbCqv4L5XVjB+ZG8mHd0v7HJEJIEdNBjc/Xl3vww4gmhPqzcCfczs12b26RjXJ+3krr8upabOufOiozVMp4gcUIuvfHb3ve7+hLtfCBQAC4Dvx6wyaTdzlm/lb4s3c8OE4QzOzw67HBFJcC0ZqOcTPy/dfYe7P+zuE5pbRxJDRXUt02Ys5vDeXfnKGUPDLkdEkkCLBuoxs+vNbHD9mWaWYWZnm9mj6ArohPXQnCI2bK/g7s8eQ0aahvgWkYNryVlJk4ApwJ/NbAiwE8gCUoFXgJ+7+4KYVShtVrR1N795czWXHj+QUw7PD7scEUkSLbnyuRL4FfCrYKS2XkCFu++McW1yCNydaS8soUt6Kreer2sWRKTlWrVvwd0j7r6praFgZpPMbIWZFZnZzQdY7z/MzM1sTFveR2DWks38c3UZN316JL26ZYZdjogkkbjtdDazVOAh4DxgFDDZzD4xjqSZ5QDfAt6LV20dTWWklrtfWsbIvjlcMW7wwZ8gIlJPPI9GjgWK3H2Nu1cTHfnt4ibW+2/gHqAyjrV1KL9/ay3FOyqYduEo0lJ1wFlEWqfV3xpm1jX49d9aA4EN9aaLg3n1X/sEYJC7v3SQGqaa2Twzm1daWtqGUjquzeWVPDSniHOP6qtO8kSkTVpyHUOKmV1uZi+Z2VaifSdtMrOlZvZTMxvWHoWYWQpwH3DTwdYNrqEY4+5jevfu3R5v32Hc8/Jyamqd2z7zib10IiIt0qLrGIDDgVuAfu4+yN37AKcD7wL3mNmXWvA6JcCgetMFwbz9coCjgTfMbB1wMjBDB6Bbbv7HO/jLghKuPWOIrnAWkTZryXUM57h7xMwK3b1u/0x33w48BzwXnMZ6MHOB4cG1ECXAZUTHdtj/euVET4UFwMzeAL7j7vNatCWdXF2dc9dfl9AnJ5Nvjm+XRpyIdFIt6UQvEjz8xKA8ZnZyo3UO9Do1wHXALGAZ8LS7LzGzu8zsolZVLZ/w3AfFLCwu5+bzjtCobCJySFoyUM8XgBOAHDM7ElhRr+XwMDC6pW/m7jOBmY3mTWtm3bNa+rqd3d6qGu6dtYLjBuXy2eMGHvwJIiIH0JKflm8T7QLjWqIHh0ea2U5gI1ARu9KkpX73j7WU7q7if790Aikp6s9QRA5NS7rEKAH+z8xWu/vbAGaWDxQSPUNJQrR1dyW/eXM15x3djxMPywu7HBHpAFqyK8k86u3989y9DChrvE6MapQDeOC1VVTX1PG9SUeEXYqIdBDqdjuJFW3dw5NzN3DFuMEM6dU17HJEpINoa7fbXYiGirrdDtE9Ly+nS3oqN0wYHnYpItKBqNvtJPX+2u28unQL3z13JPnqPVVE2lGrTngPLnT7OpBmZh8CH7r7yphUJs1yd340cxn9umcx5bQhYZcjIh1MqzvRC647eAAoBy4xs9+2e1VyQC8t2sTCDTu56dMj6JLRlv4MRUSa1+IWg5m9SrSLioXuvoXoFcyzYlaZNKm6po57X17BEf1yuPSEgrDLEZEOqDUthu8DPzezP5pZ/1gVJAf21Nz1rN++j++fdwSpuphNRGKgxcHg7h+4+3jgReBlM7vdzLrErjRprKK6ll+8XsTYwjzOGqHuxkUkNlp1jMHMDFgB/Bq4HlhlZlfGojD5pEf+uY7S3VV8d9JIov8UIiLtr8XBYGZvE+0u+36iI699GTgLGGtmD8eiOPm38ooI//v31Ywf2ZuTCtX1hYjETmtOV50KLG2i64vrzWxZO9YkTfjtm2sor4jwnXNHhl2KiHRwLQ4Gd19ygMXnt0Mt0ozS3VX84e21XDC6P0cN6BF2OSLSwbX6OoamuPua9ngdadpDc4qoqqnjvyaOCLsUEekE2iUYJHaKd+zjiffW8/kTCxjau1vY5YhIJ6BgSHAPvLYKQB3liUjcKBgS2OrSPTz3QTFfOvkwBuTqkhERiQ8FQwL7xexVZKal8o3xh4ddioh0IgqGBLVqy25mLNzIVacW0kvdaotIHCkYEtTPZ68iOz2VqZ8aGnYpItLJKBgS0PLNu3jpo01cfdoQ8rpmhF2OiHQyCoYE9PNXV5GTmca1Z2gQHhGJPwVDglmysZyXl2zm6tOHkJut1oKIxJ+CIcH8/LVV5GSlcc3pai2ISDgUDAlkUXE5ry7dwlfOGEqPLulhlyMinZSCIYHc/9pKenRJ5+rTCsMuRUQ6MQVDgvhww05eX76VqZ8aSk6WWgsiEh4FQ4J44LWV9MxO56pTC8MuRUQ6OQVDAli4YSdzVpRy7RlD6ZbZmrGTRETan4IhAfxi9ipy1VoQkQShYAjZouJyZi/fyrWnD1FrQUQSgoIhZA/MXkWPLmotiEjiUDCEaHFJOa8t28I1pw/RmUgikjAUDCH6xezoVc5qLYhIIlEwhGTpxl28snQLU04boqucRSShKBhC8ovZ0R5Up5ymPpFEJLHENRjMbJKZrTCzIjO7uYnl/2VmS83sIzObbWaHxbO+eFm2aVe0B9XTCumRrdaCiCSWuAWDmaUCDwHnAaOAyWY2qtFqC4Ax7j4aeBa4N171xdODrxfRLTONKepBVUQSUDxbDGOBIndf4+7VwJPAxfVXcPc57r4vmHwXKIhjfXGxcstuZi7exJdPLdR4CyKSkOIZDAOBDfWmi4N5zbkG+FtMKwrBL18vIjs9VeMtiEjCSshLbc3sS8AY4Mxmlk8FpgIMHjw4jpUdmqKte3jxo4187czD6amxnEUkQcWzxVACDKo3XRDMa8DMzgFuAy5y96qmXsjdH3b3Me4+pnfv3jEpNhYemlNEVloq16q1ICIJLJ7BMBcYbmZDzCwDuAyYUX8FMzse+A3RUNgax9pibu22vbzwYQlXnnIY+d0ywy5HRKRZcQsGd68BrgNmAcuAp919iZndZWYXBav9FOgGPGNmH5rZjGZeLuk8+HoRGWkpfOWMoWGXIiJyQHE9xuDuM4GZjeZNq/f4nHjWEy8fl+3l+Q9L+PKphfTOUWtBRBKbrnyOg1/NWU1qivHVT6m1ICKJT8EQYxu27+O5D4q5fOxg+nTPCrscEZGDUjDE2K/eWE2KGV89U60FEUkOCoYY2rB9H8/M28AXTxpE/x5dwi5HRKRFFAwx9Ks3ikgx4xvjDw+7FBGRFlMwxEi0tVDMZWPVWhCR5KJgiJGH5gSthbOGhV2KiEirKBhiYMP2fTw7v5jJYwfRr4fORBKR5KJgiIEHXy8iJcX4uloLIpKEFAztbH3Zv69bUGtBRJKRgqGdPTRnf2tBZyKJSHJSMLSj9WX7eDZoLfTVVc4ikqQUDO3owTmrSFNrQUSSnIKhnawu3cOz84u5fJxaCyKS3BQM7eS+V1aSlZ7KN8frTCQRSW4KhnawuKSclxZt4trTh9BLo7OJSJJTMLSDe2etIDc7nWs13oKIdAAKhkP07poy3lxZyjfOOpzuWelhlyMicsgUDIfA3bn35eX0657Ff55SGHY5IiLtQsFwCGYv28oH63dyw4ThZKWnhl2OiEi7UDC0UV2d87NXVlCYn83nxxSEXY6ISLtRMLTRjIUbWb55N9+eOIL0VP0ZRaTj0DdaG1TV1HLfqys5sn93Lhw9IOxyRETalYKhDf7w1jrWb9/HzecdQUqKhV2OiEi7UjC00pZdlfzy9VVMHNWXM0f0DrscEZF2p2BopZ/8bTk1dc4Pzx8VdikiIjGhYGiFeeu285cFJUw9YyiD87PDLkdEJCYUDC1UW+fc8dcl9OuexTfGq1ttEem4FAwt9NTcDSwu2cWt5x9JdkZa2OWIiMSMgqEFyvdF+Oms5YwtzOPC0f3DLkdEJKYUDC1w/2srKa+IcMdFR2Gm01NFpGNTMBzEgvU7eOzdj7li3GGMGtA97HJERGJOwXAA5RURrv/zAvp1z+I7nx4ZdjkiInGho6jNcHdumf4Rm8srefprp9AjW2MtiEjnoBZDMx5/bz0zF23mO+eO5ITBPcMuR0QkbhQMTVi2aRd3vbiUT43ozdQzNFyniHQuCoZG9lXXcN0TH5DbJZ37vnCsOskTkU5HxxgamfbCEtZs28vj14yjV7fMsMsREYk7BUNgx95qfjRzGc/OL+aGs4dx6rBeYZckIhKKuO5KMrNJZrbCzIrM7OYmlmea2VPB8vfMrDDWNbk70z8oZsJ9f+f5BSV8c/zh3DBheKzfVkQkYcWtxWBmqcBDwESgGJhrZjPcfWm91a4Bdrj7MDO7DLgH+GKsalq3bS+3Pb+It4vKOGFwLj++dDQj++XE6u1ERJJCPHcljQWK3H0NgJk9CVwM1A+Gi4E7gsfPAg+ambm7t3cxT8/dwA9fWExGagr//dmjuWLsYB1oFhEhvsEwENhQb7oYGNfcOu5eY2blQD6wrf5KZjYVmAowePDgNhUzpHdXJhzZh9svPIq+3bPa9BoiIh1RUh58dveHgYcBxowZ06bWxEmFeZxUmNeudYmIdATxPPhcAgyqN10QzGtyHTNLA3oAZXGpTkREgPgGw1xguJkNMbMM4DJgRqN1ZgBXBY8/B7wei+MLIiLSvLjtSgqOGVwHzAJSgT+4+xIzuwuY5+4zgN8Dj5lZEbCdaHiIiEgcxfUYg7vPBGY2mjet3uNK4PPxrElERBpSX0kiItKAgkFERBpQMIiISAMKBhERacCS/WxQMysFPm7j03vR6KrqJKZtSTwdZTtA25KoDmVbDnP33k0tSPpgOBRmNs/dx4RdR3vQtiSejrIdoG1JVLHaFu1KEhGRBhQMIiLSQGcPhofDLqAdaVsST0fZDtC2JKqYbEunPsYgIiKf1NlbDCIi0oiCQUREGui0wWBmk8xshZkVmdnNYdfTGmb2BzPbamaL683LM7NXzWxVcN8zzBpbwswGmdkcM1tqZkvM7FvB/GTcliwze9/MFgbbcmcwf4iZvRd8zp4KupxPeGaWamYLzOzFYDpZt2OdmS0ysw/NbF4wL+k+XwBmlmtmz5rZcjNbZmanxGpbOmUwmFkq8BBwHjAKmGxmo8KtqlUeASY1mnczMNvdhwOzg+lEVwPc5O6jgJOBbwb/Dsm4LVXA2e5+LHAcMMnMTgbuAe5392HADuCa8EpslW8By+pNJ+t2AIx39+Pqne+fjJ8vgAeAl939COBYov8+sdkWd+90N+AUYFa96VuAW8Kuq5XbUAgsrje9AugfPO4PrAi7xjZs0wvAxGTfFiAb+IDomObbgLRgfoPPXaLeiI6uOBs4G3gRsGTcjqDWdUCvRvOS7vNFdDTLtQQnDMV6WzpliwEYCGyoN10czEtmfd19U/B4M9A3zGJay8wKgeOB90jSbQl2v3wIbAVeBVYDO929JlglWT5nPwe+B9QF0/kk53YAOPCKmc03s6nBvGT8fA0BSoE/Brv4fmdmXYnRtnTWYOjQPPrzIWnOQzazbsBzwI3uvqv+smTaFnevdffjiP7iHgscEW5FrWdmFwBb3X1+2LW0k9Pd/QSiu42/aWafqr8wiT5facAJwK/d/XhgL412G7XntnTWYCgBBtWbLgjmJbMtZtYfILjfGnI9LWJm6URD4XF3nx7MTspt2c/ddwJziO5yyTWz/SMlJsPn7DTgIjNbBzxJdHfSAyTfdgDg7iXB/VbgL0QDOxk/X8VAsbu/F0w/SzQoYrItnTUY5gLDgzMtMoiOLT0j5JoO1QzgquDxVUT31yc0MzOi43wvc/f76i1Kxm3pbWa5weMuRI+VLCMaEJ8LVkv4bXH3W9y9wN0Lif6/eN3dryDJtgPAzLqaWc7+x8CngcUk4efL3TcDG8xsZDBrArCUWG1L2AdVQjyY8xlgJdH9wLeFXU8ra/8zsAmIEP0lcQ3R/cCzgVXAa0Be2HW2YDtOJ9r0/Qj4MLh9Jkm3ZTSwINiWxcC0YP5Q4H2gCHgGyAy71lZs01nAi8m6HUHNC4Pbkv3/z5Px8xXUfRwwL/iMPQ/0jNW2qEsMERFpoLPuShIRkWYoGEREpAEFg4iINKBgEBGRBhQMIiLSgIJBREQaUDCIiEgDCgaRNjKzAjP7YjPLupjZ34Mu3ptanmFmb9brZkIkYSgYRNpuAtH+apoyBZju7rVNLXT3aqJXrDYZLCJhUjCItIGZnQ7cB3wuGB1saKNVriDotybos+elYHS3xfVaGc8H64kkFDVjRdrA3d8ys7nAd9x9cf1lQceMQ919XTBrErDR3c8PlvcI5i8GTopTySItphaDSNuNBJY3Mb8XsLPe9CJgopndY2ZnuHs5RMdvAKr39wAqkigUDCJtYGa9gHL/96hm9VUAWfsn3H0l0WMRi4C7zWxavXUzgcpY1irSWtqVJNI2hcDGpha4+45gmM8sd680swHAdnf/k5ntBK4FMLN8YJu7R+JVtEhLqMUg0jbLgV7BweRTm1j+CtHxJgCOAd4PxoO+Hbg7mD8eeCnWhYq0lsZjEIkBMzsB+La7X3mAdaYDNwe7mkQShloMIjHg7h8Acw50gRvwvEJBEpFaDCIi0oBaDCIi0oCCQUREGlAwiIhIAwoGERFpQMEgIiINKBhERKSB/w9sALbuh+nNvgAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "edata.t_presim = 10\n", + "edata.fixedParametersPresimulation = [10.0, 0.0]\n", + "edata.fixedParameters = [10.0, 2.0]\n", + "print(edata.fixedParametersPreequilibration)\n", + "print(edata.fixedParametersPresimulation)\n", + "print(edata.fixedParameters)\n", + "rdata = amici.runAmiciSimulation(model, solver, edata)\n", + "amici.plotting.plotObservableTrajectories(rdata)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python3", + "language": "python", + "name": "python" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + }, + "pycharm": { + "stem_cell": { + "cell_type": "raw", + "metadata": { + "collapsed": false + }, + "source": [] + } + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/deps/AMICI/python/examples/example_presimulation/model_presimulation.ipynb b/deps/AMICI/python/examples/example_presimulation/model_presimulation.ipynb deleted file mode 100644 index 882bbaaec..000000000 --- a/deps/AMICI/python/examples/example_presimulation/model_presimulation.ipynb +++ /dev/null @@ -1,416 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# AMICI Python example \"presimulation\"\n", - "In this example we will explore some more options for the initialization of experimental conditions, including how to reset initial conditions based on changing values for fixedParameters as well as an additional presimulation phase on top of preequilibration" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "# SBML model we want to import\n", - "sbml_file = 'model_presimulation.xml'\n", - "# Name of the model that will also be the name of the python module\n", - "model_name = 'model_presimulation'\n", - "# Directory to which the generated model code is written\n", - "model_output_dir = model_name\n", - "\n", - "import libsbml\n", - "import amici\n", - "import amici.plotting\n", - "import os\n", - "import sys\n", - "import importlib\n", - "import numpy as np\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Model Loading\n", - "Here we load a simple model of protein phosphorylation that can be inhibited by a drug. This model was created using PySB (see `createModel.py`)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Species: [('__s0', \"PROT(kin=None, drug=None, phospho='u')\"), ('__s1', 'DRUG(bound=None)'), ('__s2', 'KIN(bound=None)'), ('__s3', \"DRUG(bound=1) ._br_PROT(kin=None, drug=1, phospho='u')\"), ('__s4', \"KIN(bound=1) ._br_PROT(kin=1, drug=None, phospho='u')\"), ('__s5', \"PROT(kin=None, drug=None, phospho='p')\")]\n", - "\n", - "Reactions:\n", - "PROT_DRUG_bind: __s0 + __s1 <-> __s3\t\t[__s0 * __s1 * kon_prot_drug - __s3 * koff_prot_drug]\n", - "PROT_KIN_bind: __s0 + __s2 -> __s4\t\t[__s0 * __s2 * kon_prot_kin]\n", - "PROT_KIN_phospho: __s4 -> __s2 + __s5\t\t[__s4 * kphospho_prot_kin]\n", - "PROT_dephospho: __s5 -> __s0\t\t[__s5 * kdephospho_prot]\n", - "Parameters: [('initProt', 'initProt'), ('initDrug', 'initDrug'), ('initKin', 'initKin'), ('pPROT_obs', 'pPROT_obs'), ('PROT_0', 'PROT_0'), ('DRUG_0', 'DRUG_0'), ('KIN_0', 'KIN_0'), ('kon_prot_drug', 'kon_prot_drug'), ('koff_prot_drug', 'koff_prot_drug'), ('kon_prot_kin', 'kon_prot_kin'), ('kphospho_prot_kin', 'kphospho_prot_kin'), ('kdephospho_prot', 'kdephospho_prot'), ('__obs0', 'pPROT'), ('__obs1', 'tPROT')]\n" - ] - } - ], - "source": [ - "sbml_reader = libsbml.SBMLReader()\n", - "sbml_doc = sbml_reader.readSBML(sbml_file)\n", - "sbml_model = sbml_doc.getModel()\n", - "dir(sbml_doc)\n", - "\n", - "print('Species: ', [(s.getId(),s.getName()) for s in sbml_model.getListOfSpecies()])\n", - "\n", - "print('\\nReactions:')\n", - "for reaction in sbml_model.getListOfReactions():\n", - " reactants = ' + '.join(['%s %s'%(int(r.getStoichiometry()) if r.getStoichiometry() > 1 else '', r.getSpecies()) for r in reaction.getListOfReactants()])\n", - " products = ' + '.join(['%s %s'%(int(r.getStoichiometry()) if r.getStoichiometry() > 1 else '', r.getSpecies()) for r in reaction.getListOfProducts()])\n", - " reversible = '<' if reaction.getReversible() else ''\n", - " print('%3s: %10s %1s->%10s\\t\\t[%s]' % (reaction.getName(), \n", - " reactants,\n", - " reversible,\n", - " products,\n", - " libsbml.formulaToL3String(reaction.getKineticLaw().getMath())))\n", - " \n", - "print('Parameters: ', [(p.getId(),p.getName()) for p in sbml_model.getListOfParameters()])" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "# Create an SbmlImporter instance for our SBML model\n", - "sbml_importer = amici.SbmlImporter(sbml_file)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For this example we want specify the initial drug and kinase concentrations as experimental conditions. Accordingly we specify them as fixedParameters." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "fixedParameters = ['DRUG_0','KIN_0']" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The SBML model specifies a single observable named `pPROT` which describes the fraction of phosphorylated Protein. We load this observable using `amici.assignmentRules2observables`." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Observables: {'__obs0': {'name': 'pPROT', 'formula': '__s5'}}\n" - ] - } - ], - "source": [ - "# Retrieve model output names and formulae from AssignmentRules and remove the respective rules\n", - "observables = amici.assignmentRules2observables(\n", - " sbml_importer.sbml, # the libsbml model object\n", - " filter_function=lambda variable: variable.getName() == 'pPROT' \n", - " )\n", - "print('Observables:', observables)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now the model is ready for compilation:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "sbml_importer.sbml2amici(model_name, \n", - " model_output_dir, \n", - " verbose=False,\n", - " observables=observables,\n", - " constant_parameters=fixedParameters)\n", - "sys.path.insert(0, os.path.abspath(model_output_dir))\n", - "# load the compiled module\n", - "model_module = importlib.import_module(model_name)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To simulate the model we need to create an instance via the `getModel()` method in the generated model module." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "# Create Model instance\n", - "model = model_module.getModel()\n", - "# set timepoints for which we want to simulate the model\n", - "\n", - "\n", - "# Create solver instance\n", - "solver = model.getSolver()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The only thing we need to simulate the model is a timepoint vector, which can be specified using the `setTimepoints()` method. If we do not specify any additional options, the default values for fixedParameters and Parameters that were specified in the SBML file will be used." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "# Run simulation using default model parameters and solver options\n", - "model.setTimepoints(np.linspace(0, 60, 60)) \n", - "rdata = amici.runAmiciSimulation(model, solver)\n", - "amici.plotting.plotObservableTrajectories(rdata)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Simulation options can be specified either in the Model or in an ExpData object. The ExpData object can also carry experimental data. To initialize an ExpData object from simulation routines, amici offers some convenient constructors. In the following we will initialize an ExpData object from simulation results, but add noise with standard deviation `0.1` and specify the standard deviation accordingly. Moreover, we will specify custom values for `DRUG_0=0` and `KIN_0=2`. If fixedParameter is specfied in an ExpData object, runAmiciSimulation will use those parameters instead of the ones specified in the Model object." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "edata = amici.ExpData(rdata, 0.1, 0.0)\n", - "edata.fixedParameters = [0,2]\n", - "rdata = amici.runAmiciSimulation(model, solver, edata)\n", - "amici.plotting.plotObservableTrajectories(rdata)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For many biological systems, it is reasonable to assume that they start in a\n", - " steady state. In this example we want to specify an experiment where a pretreatment with a drug is performed _before_ the kinase is added. We assume that the pretreatment is sufficiently long such that the system reaches steadystate before the kinase is added. To implement this in amici, we can specify `fixedParametersPreequilibration` in the ExpData object. Here we set `DRUG_0=3` and `KIN_0=0` for the preequilibration." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZQAAAEZCAYAAACw69OmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAZfUlEQVR4nO3dfbRddX3n8fdHAsQqAgkPAglelAw2LkbQC2iLU5DnqYoyjCUKTQcZVmcJS2ydCmXJU3Utsa3oTK0zjFqjVgERNZVKQIRO6xLMDeDiWSLicMNzEsCnIMh3/jg7cLieJPcm+957TvJ+rXXWPfu3f+ec7y8c7ufu3++cvVNVSJK0qV403QVIkjYPBookqRUGiiSpFQaKJKkVBookqRUGiiSpFQaKNA5JzkvypemuY302VGOS+5IcPpU1actioEiNJH+S5NYkv0zyUJJPJ9lhuuuSBoWBIgFJ/hy4EPjvwPbAG4BXANck2WaKapgxFa8jTRYDRVu8JC8DzgdOr6qrqurpqroPeCcwBJzYdJ2Z5NIkP0tyU5LXdj3HB5OsaPbdneSwpv1FSc5M8uMkK5NclmRWs28oSSV5T5L/B3w3ybeTnDamvh8mOa65/8kk9yd5MsmyJG8aM5x11jjmOddX18wkX2raH0+yNMmum/avrC2BgSLB7wEzgSu6G6vq58A/A0c0TccCXwVmAV8GvpFk6yT7AKcBB1TVdsBRwH3NY04H3g78AbA7sBr41JjX/wPgd5vHfQVYsHZHkvl0jpSubJqWAvt11fDVJDO7nqtnjT3GvL66FtI5SpsLzAb+FPhVj+eQXsBAkWAn4LGqeqbHvgeb/QDLquryqnoa+DidEHoD8BtgW2B+kq2r6r6q+nHzmD8Fzq6q0ap6CjgPOH7M9NZ5VfWLqvoV8HVgvySvaPa9G7iieSxV9aWqWllVz1TV3zavu0/Xc62rxrHWV9fTdIJk76r6TVUtq6onN/zPqC2dgSLBY8BO61jD2K3ZD3D/2saqehYYBXavquXAGXR+KT+S5JIkuzddXwF8vZk6ehy4k04AdU8hdT/vz+gcjZzQNC0A/nHt/iQfSHJnkiea59ue5wNvnTX2GNf66voisAS4JMkDST62jqMc6QUMFAm+DzwFHNfdmOSlwDHAtU3T3K59LwLmAA8AVNWXq+pgOr+oi84CP3R+wR9TVTt03WZW1Yqulxp7yu+vAAuSvJHOEcZ1zWu+CfgLOms7O1bVDsATQLoeu84ax1hnXc0a0vlVNZ/OdOBbgD/u/U8nPc9A0Ravqp6gsyj/P5Mc3ayLDAGX0fkL/4tN19cnOa45kjmDTgjdkGSfJG9Osi2whs56w7PNY/4X8JG1U1hJdk5y7AZK+mc6wXQBcGlzpAGwHfAM8CgwI8k5wMvGPLZnjT1eY511JTk0yb5JtgKepDMF9myP55BewECRgKr6GPCXwN/Q+SV6I52/4g9bu34BfBP4IzoL2CcBxzVrFdsCH6UzNfYQsAtwVvOYTwKLgauT/IzOL/eDNlDLU3Q+IHA4nYX1tZYAVwE/An5KJ7zuH/PwddU41vrqejlwefPvcCfwLzwfqtI6xQtsSZLa4BGKJKkVBookqRUGiiSpFQaKJKkVW/TJ6HbaaacaGhqa7jIkaaAsW7bssaraeWz7Fh0oQ0NDjIyMTHcZkjRQkvy0V7tTXpKkVhgokqRWGCiSpFZs0WsoktSWp59+mtHRUdasWTPdpbRm5syZzJkzh623Ht/Jpg0USWrB6Ogo2223HUNDQyTZ8AP6XFWxcuVKRkdH2Wuvvcb1GKe8JKkFa9asYfbs2ZtFmAAkYfbs2RM64jJQJKklm0uYrDXR8RgokqRWGCiSpFYYKJK0BVq0aBHz5s1j3rx5LFq0qJXn9FNekrSFWbVqFeeffz4jIyMk4fWvfz1ve9vb2HHHHTfpeQ0USWrZ+f90O3c88GSrzzl/95dx7ltfs94+55xzDrNmzeKMM84A4Oyzz2aXXXbhfe973wv6LVmyhCOOOIJZs2YBcMQRR3DVVVexYMGCTarRKS9J2kycfPLJfOELXwDg2Wef5ZJLLuHEE0/8rX4rVqxg7ty5z23PmTOHFStWbPLre4QiSS3b0JHEZBkaGmL27NncfPPNPPzww+y///7Mnj17yl7fQJGkzcgpp5zC5z//eR566CFOPvnknn322GMPrr/++ue2R0dHOeSQQzb5tZ3ykqTNyDve8Q6uuuoqli5dylFHHdWzz1FHHcXVV1/N6tWrWb16NVdfffU6+06ERyiStBnZZpttOPTQQ9lhhx3YaqutevaZNWsWH/rQhzjggAOA5xfzN5WBIkmbkWeffZYbbriBr371q+vtd/LJJ69zSmxjOeUlSZuJO+64g7333pvDDjuMefPmTfnre4QiSZuJ+fPnc++99z63feutt3LSSSe9oM+2227LjTfeOCmvb6BIUkuqqq/OOLzvvvtyyy23bPTjq2pC/Z3ykqQWzJw5k5UrV074l3C/WnuBrZkzZ477MR6hSFIL5syZw+joKI8++uh0l9KatZcAHi8DRZJasPXWW4/7UrmbK6e8JEmt6KtASXJ0kruTLE9yZo/92ya5tNl/Y5KhMfv3TPLzJB+YqpolSR19EyhJtgI+BRwDzAcWJJk/ptt7gNVVtTdwEXDhmP0fB7492bVKkn5b3wQKcCCwvKrurapfA5cAx47pcyyw9tJilwOHpfmMXpK3Az8Bbp+ieiVJXfopUPYA7u/aHm3aevapqmeAJ4DZSV4KfBA4f0MvkuTUJCNJRjanT2NI0nTrp0DZFOcBF1XVzzfUsaourqrhqhreeeedJ78ySdpC9NPHhlcAc7u25zRtvfqMJpkBbA+sBA4Cjk/yMWAH4Nkka6rq7ya/bEkS9FegLAXmJdmLTnCcALxrTJ/FwELg+8DxwHer87XUN63tkOQ84OeGiSRNrb4JlKp6JslpwBJgK+BzVXV7kguAkapaDHwW+GKS5cAqOqEjSeoD2VzOO7MxhoeHa2RkZLrLkKSBkmRZVQ2Pbd9cFuUlSdPMQJEktcJAkSS1wkCRJLXCQJEktcJAkSS1wkCRJLXCQJEktcJAkSS1wkCRJLXCQJEktcJAkSS1wkCRJLXCQJEktcJAkSS1wkCRJLXCQJEktcJAkSS1wkCRJLXCQJEktcJAkSS1wkCRJLXCQJEktcJAkSS1wkCRJLXCQJEktcJAkSS1wkCRJLXCQJEktcJAkSS1oq8CJcnRSe5OsjzJmT32b5vk0mb/jUmGmvYjkixLcmvz881TXbskben6JlCSbAV8CjgGmA8sSDJ/TLf3AKuram/gIuDCpv0x4K1VtS+wEPji1FQtSVqrbwIFOBBYXlX3VtWvgUuAY8f0ORZY1Ny/HDgsSarq5qp6oGm/HXhxkm2npGpJEtBfgbIHcH/X9mjT1rNPVT0DPAHMHtPnPwE3VdVTk1SnJKmHGdNdQJuSvIbONNiR6+lzKnAqwJ577jlFlUnS5q+fjlBWAHO7tuc0bT37JJkBbA+sbLbnAF8H/riqfryuF6mqi6tquKqGd9555xbLl6QtWz8FylJgXpK9kmwDnAAsHtNnMZ1Fd4Djge9WVSXZAbgSOLOqvjdlFUuSntM3gdKsiZwGLAHuBC6rqtuTXJDkbU23zwKzkywH/gxY+9Hi04C9gXOS3NLcdpniIUjSFi1VNd01TJvh4eEaGRmZ7jIkaaAkWVZVw2Pb++YIRZI02AwUSVIrDBRJUisMFElSKwwUSVIrDBRJUisMFElSKwwUSVIrDBRJUisMFElSKwwUSVIrDBRJUisMFElSKyYcKElekmSryShGkjS4NhgoSV6U5F1JrkzyCHAX8GCSO5L8dZK9J79MSVK/G88RynXAq4CzgJdX1dyq2gU4GLgBuDDJiZNYoyRpAMwYR5/Dq+rpsY1VtQr4GvC1JFu3XpkkaaCMJ1BOT9K9XcBjwL9V1U8AegWOJGnLMp4pr+3G3F4GDAPfTnLCJNYmSRogGzxCqarze7UnmQV8B7ik7aIkSYNno7+H0qyhZIMdJUlbhI0OlCSHAqtbrEWSNMA2OOWV5FY6C/HdZgEPAAsnoyhJ0uAZz6e83jJmu4CVVfWLSahHkjSgxrMo/9Ne7UkOBhZU1Xtbr0qSNHDGc4TynCT7A+8C/jPwE+CKyShKkjR4xrOG8u+ABc3tMeBSIFV16CTXJkkaIOM5QrkL+FfgLVW1HCDJ+ye1KknSwBnPx4aPAx4Erkvyf5Icht8/kSSNscFAqapvVNUJwKvpnHn4DGCXJJ9OcuRkFyhJGgzj/mJjVf2iqr5cVW8F5gA3Ax+ctMokSQNlPBfY+q3prapaXVUXV9Vh6+qzMZIcneTuJMuTnNlj/7ZJLm3235hkqGvfWU373UmOaqMeSdL4jesCW0lOT7Jnd2OSbZK8OckiWvjGfHNZ4U8BxwDzgQVJ5o/p9h5gdVXtDVwEXNg8dj5wAvAa4Gjg771MsSRNrfF8yuto4GTgK0n2Ah4HZgJbAVcDn6iqm1uo5UBgeVXdC5DkEuBY4I6uPscC5zX3Lwf+rjk6Oha4pKqeAn6SZHnzfN9voa7fcv4/3c4dDzw5GU8tSZNu/u4v49y3vqb15x3PN+XXAH9P56/+rYGdgF9V1eMt17IHcH/X9ihw0Lr6VNUzSZ4AZjftN4x57B69XiTJqcCpAHvuuWevLpKkjTChb8o3V2Z8cJJqmRJVdTFwMcDw8PDYk16Oy2QkuyQNuo0+ff0kWAHM7dqe07T17JNkBrA9sHKcj5UkTaJ+CpSlwLwkeyXZhs4i++IxfRbz/AcAjge+W1XVtJ/QfApsL2Ae8IMpqluSxASnvACSvARYU1W/abOQZk3kNGAJnQX/z1XV7UkuAEaqajHwWeCLzaL7KjqhQ9PvMjoL+M8A7227PknS+qXzB/56OiQvovOL+93AAcBTwLZ0ThR5JfC/157ja9AMDw/XyMjIdJchSQMlybKqGh7bPq7voQCvAs4CXl5Vc6tqF+BgOp+sujDJia1WK0kaOOOZ8jq8qp5OMlRVz65trKpVwNeArzUfJ5YkbcHGc3LIp5u7v3UxrSRvGNNHkrSFGs+5vN6Z5KPAdkl+t1lTWeviyStNkjRIxjPl9T06p1o5Bfg4sE+Sx4EHgF9NYm2SpAEynlOvrAC+kOTHVfU9gCSzgSE6V3OUJGlc15RPdXxvbVtVraTzDfUX9JmkGiVJA6BvTl8vSRpsG3v6+hfTCaM2T18vSRpg/XT6eknSAJvw6euT/DdgRpJbgFuq6keTU5okaZBM+OSQVXVOkl2B/YB3JNm7qv5r+6VJkgbJuAMlyTXAB6rqh1X1MJ2zAi+ZtMokSQNlItdD+SDwiST/kGS3ySpIkjSYxh0oVXVTVR0KfAu4Ksm5SV48eaVJkgbJhK7YmCTA3cCngdOBe5KcNBmFSZIGy7gDJcn36Fyn/SJgD+BPgEOAA5N4kkhJ2sJN5FNepwJ39DjFyulJ7myxJknSABp3oFTV7evZ/Yct1CJJGmATWkNZl6q6t43nkSQNrlYCRZIkA0WS1AoDRZLUCgNFktQKA0WS1AoDRZLUCgNFktQKA0WS1AoDRZLUCgNFktSKvgiUJLOSXJPknubnjuvot7Dpc0+ShU3b7yS5MsldSW5P8tGprV6SBH0SKMCZwLVVNQ+4ttl+gSSzgHOBg4ADgXO7gudvqurVwP7A7yc5ZmrKliSt1S+BciywqLm/CHh7jz5HAddU1aqqWg1cAxxdVb+squsAqurXwE3AnCmoWZLUpV8CZdeqerC5/xCwa48+ewD3d22PNm3PSbID8FY6RzmSpCk0kQtsbZIk3wFe3mPX2d0bVVVJxl7EazzPPwP4CvA/1nc6/SSn0rlYGHvuuedEX0aStA5TFihVdfi69iV5OMluVfVgkt2AR3p0W0HnksNrzQGu79q+GLinqj6xgToubvoyPDw84eCSJPXWL1Nei4GFzf2FwDd79FkCHJlkx2Yx/simjSQfBrYHzpiCWiVJPfRLoHwUOCLJPcDhzTZJhpN8BqCqVgF/BSxtbhdU1aokc+hMm80HbkpyS5JTpmMQkrQlS9WWO+szPDxcIyMj012GJA2UJMuqanhse78coUiSBpyBIklqhYEiSWqFgSJJaoWBIklqhYEiSWqFgSJJaoWBIklqhYEiSWqFgSJJaoWBIklqhYEiSWqFgSJJaoWBIklqhYEiSWqFgSJJaoWBIklqhYEiSWqFgSJJaoWBIklqhYEiSWqFgSJJaoWBIklqhYEiSWqFgSJJaoWBIklqhYEiSWqFgSJJaoWBIklqhYEiSWqFgSJJakVfBEqSWUmuSXJP83PHdfRb2PS5J8nCHvsXJ7lt8iuWJI3VF4ECnAlcW1XzgGub7RdIMgs4FzgIOBA4tzt4khwH/HxqypUkjdUvgXIssKi5vwh4e48+RwHXVNWqqloNXAMcDZDkpcCfAR+eglolST30S6DsWlUPNvcfAnbt0WcP4P6u7dGmDeCvgL8FfrmhF0pyapKRJCOPPvroJpQsSeo2Y6peKMl3gJf32HV290ZVVZKawPPuB7yqqt6fZGhD/avqYuBigOHh4XG/jiRp/aYsUKrq8HXtS/Jwkt2q6sEkuwGP9Oi2Ajika3sOcD3wRmA4yX10xrNLkuur6hAkSVOmX6a8FgNrP7W1EPhmjz5LgCOT7Ngsxh8JLKmqT1fV7lU1BBwM/MgwkaSp1y+B8lHgiCT3AIc32yQZTvIZgKpaRWetZGlzu6BpkyT1gVRtucsIw8PDNTIyMt1lSNJASbKsqobHtvfLEYokacAZKJKkVhgokqRWGCiSpFYYKJKkVhgokqRWGCiSpFYYKJKkVhgokqRWGCiSpFYYKJKkVhgokqRWGCiSpFYYKJKkVhgokqRWGCiSpFYYKJKkVhgokqRWGCiSpFYYKJKkVhgokqRWGCiSpFYYKJKkVhgokqRWpKqmu4Zpk+RR4Kcb+fCdgMdaLGc6bS5j2VzGAY6lX20uY9nUcbyiqnYe27hFB8qmSDJSVcPTXUcbNpexbC7jAMfSrzaXsUzWOJzykiS1wkCRJLXCQNl4F093AS3aXMayuYwDHEu/2lzGMinjcA1FktQKj1AkSa0wUCRJrTBQJijJ0UnuTrI8yZnTXc9EJPlckkeS3NbVNivJNUnuaX7uOJ01jleSuUmuS3JHktuTvK9pH7jxJJmZ5AdJftiM5fymfa8kNzbvtUuTbDPdtY5Hkq2S3JzkW832oI7jviS3JrklyUjTNnDvL4AkOyS5PMldSe5M8sbJGIuBMgFJtgI+BRwDzAcWJJk/vVVNyOeBo8e0nQlcW1XzgGub7UHwDPDnVTUfeAPw3ua/xSCO5yngzVX1WmA/4OgkbwAuBC6qqr2B1cB7prHGiXgfcGfX9qCOA+DQqtqv6zsbg/j+AvgkcFVVvRp4LZ3/Pu2Ppaq8jfMGvBFY0rV9FnDWdNc1wTEMAbd1bd8N7Nbc3w24e7pr3MhxfRM4YtDHA/wOcBNwEJ1vMs9o2l/w3uvXGzCn+eX0ZuBbQAZxHE2t9wE7jWkbuPcXsD3wE5oPYU3mWDxCmZg9gPu7tkebtkG2a1U92Nx/CNh1OovZGEmGgP2BGxnQ8TTTRLcAjwDXAD8GHq+qZ5oug/Je+wTwF8CzzfZsBnMcAAVcnWRZklObtkF8f+0FPAr8QzMV+ZkkL2ESxmKg6DnV+VNloD5HnuSlwNeAM6rqye59gzSeqvpNVe1H5y/8A4FXT3NJE5bkLcAjVbVsumtpycFV9To6U9zvTfIfuncO0PtrBvA64NNVtT/wC8ZMb7U1FgNlYlYAc7u25zRtg+zhJLsBND8fmeZ6xi3J1nTC5B+r6oqmeWDHA1BVjwPX0Zka2iHJjGbXILzXfh94W5L7gEvoTHt9ksEbBwBVtaL5+QjwdTpBP4jvr1FgtKpubLYvpxMwrY/FQJmYpcC85lMr2wAnAIunuaZNtRhY2NxfSGctou8lCfBZ4M6q+njXroEbT5Kdk+zQ3H8xnbWgO+kEy/FNt74fS1WdVVVzqmqIzv8b362qdzNg4wBI8pIk2629DxwJ3MYAvr+q6iHg/iT7NE2HAXcwCWPxm/ITlOQ/0pkn3gr4XFV9ZJpLGrckXwEOoXPq6oeBc4FvAJcBe9I5lf87q2rVdNU4XkkOBv4VuJXn5+v/ks46ykCNJ8m/BxbReU+9CLisqi5I8ko6f+nPAm4GTqyqp6av0vFLcgjwgap6yyCOo6n5683mDODLVfWRJLMZsPcXQJL9gM8A2wD3Av+F5r1Gi2MxUCRJrXDKS5LUCgNFktQKA0WS1AoDRZLUCgNFktQKA0WS1AoDRZLUCgNFmmJJ5iT5o3Xse3GSf2kuldBr/zZJ/m/XqUykvmGgSFPvMDrnUurlZOCKqvpNr51V9Ws6p4fvGUjSdDJQpCnUnDLm48DxzZUAXzmmy7tpzqnUnE/qyuZKjrd1HdV8o+kn9RUPm6UpVFX/lmQpnfNc3da9rznh6Cur6r6m6Wjggar6w2b/9k37bcABU1SyNG4eoUhTbx/grh7tOwGPd23fChyR5MIkb6qqJ6Bz7RTg12vPhiv1CwNFmkJJdgKe6LqCYbdfATPXblTVj+istdwKfDjJOV19twXWTGat0kQ55SVNrSHggV47qmp1cyngmVW1JsnuwKqq+lKSx4FTAJpTqD9WVU9PWdXSOHiEIk2tu4CdmkX23+ux/2rg4Ob+vsAPmmvNnwt8uGk/FLhy0iuVJsjroUh9JMnrgPdX1Unr6XMFcGYzJSb1DY9QpD5SVTcB163vi43ANwwT9SOPUCRJrfAIRZLUCgNFktQKA0WS1AoDRZLUCgNFktQKA0WS1Ir/Dzyf2G9rrD3hAAAAAElFTkSuQmCC\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "edata.fixedParametersPreequilibration = [3,0]\n", - "rdata = amici.runAmiciSimulation(model, solver, edata)\n", - "amici.plotting.plotObservableTrajectories(rdata)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The resulting trajectory is definitely not what one may expect. The problem is that the `DRUG_0` and `KIN_0` set initial condtions for species in the model. By default these initial conditions are only applied at the very beginning of the simulation, i.e., before the preequilibration. Accordingly, the fixedParameters that we specified do not have any effect. To fix this, we need to activate reinitialization of states that depend on fixedParameters via `ExpData.reinitializeFixedParameterInitialStates`" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "edata.reinitializeFixedParameterInitialStates = True" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With this option activated, the kinase concentration will be reinitialized after the preequilibration and we will see the expected change in fractional phosphorylation:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "rdata = amici.runAmiciSimulation(model, solver, edata)\n", - "amici.plotting.plotObservableTrajectories(rdata)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "On top of preequilibration, we can also specify presimulation. This option can be used to specify pretreatments where the system is not assumed to reach steadystate. Presimulation can be activated by specifying `t_presim` and `edata.fixedParametersPresimulation`. If both `fixedParametersPresimulation` and `fixedParametersPreequilibration` are specified, preequilibration will be performed first, followed by presimulation, followed by regular simulation. For this example we specify `DRUG_0=10` and `KIN_0=0` for the presimulation and `DRUG_0=10` and `KIN_0=2` for the regular simulation. We do not overwrite the `DRUG_0=3` and `KIN_0=0` that was previously specified for preequilibration." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(3.0, 0.0)\n", - "(10.0, 0.0)\n", - "(10.0, 2.0)\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "edata.t_presim = 10\n", - "edata.fixedParametersPresimulation = [10.0,0.0]\n", - "edata.fixedParameters = [10.0,2.0]\n", - "print(edata.fixedParametersPreequilibration)\n", - "print(edata.fixedParametersPresimulation)\n", - "print(edata.fixedParameters)\n", - "rdata = amici.runAmiciSimulation(model, solver, edata)\n", - "amici.plotting.plotObservableTrajectories(rdata)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.7" - }, - "pycharm": { - "stem_cell": { - "cell_type": "raw", - "source": [], - "metadata": { - "collapsed": false - } - } - } - }, - "nbformat": 4, - "nbformat_minor": 1 -} \ No newline at end of file diff --git a/deps/AMICI/python/sdist/amici/__main__.py b/deps/AMICI/python/sdist/amici/__main__.py new file mode 120000 index 000000000..cfa13d34d --- /dev/null +++ b/deps/AMICI/python/sdist/amici/__main__.py @@ -0,0 +1 @@ +../../amici/__main__.py \ No newline at end of file diff --git a/deps/AMICI/python/sdist/setup.cfg b/deps/AMICI/python/sdist/setup.cfg index 735b68e74..8e8fdbaea 100644 --- a/deps/AMICI/python/sdist/setup.cfg +++ b/deps/AMICI/python/sdist/setup.cfg @@ -41,7 +41,7 @@ include_package_data = True zip_safe = False [options.extras_require] -petab = petab>=0.1.11 +petab = petab>=0.1.17 pysb = pysb>=1.11.0 [options.package_data] diff --git a/deps/AMICI/python/tests/test_events.py b/deps/AMICI/python/tests/test_events.py new file mode 100644 index 000000000..8bb34ecf8 --- /dev/null +++ b/deps/AMICI/python/tests/test_events.py @@ -0,0 +1,351 @@ +"""Tests for SBML events, including piecewise expressions.""" +import numpy as np +import pytest +import os +from scipy.linalg import expm +from copy import deepcopy + +from util import ( + create_sbml_model, + create_amici_model, + check_trajectories_without_sensitivities, + check_trajectories_with_forward_sensitivities, +) + +@pytest.fixture(params=[ + 'events_plus_heavisides', + 'nested_events', +]) +def model(request): + """Returns the requested AMICI model and analytical expressions.""" + ( + initial_assignments, + parameters, + rate_rules, + species, + events, + timepoints, + x_pected, + sx_pected + ) = get_model_definition(request.param) + + # SBML model + sbml_document, sbml_model = create_sbml_model( + initial_assignments=initial_assignments, + parameters=parameters, + rate_rules=rate_rules, + species=species, + events=events, + # uncomment `to_file` to save SBML model to file for inspection + # to_file=sbml_test_models / (model_name + '.sbml'), + ) + + # AMICI model + amici_model = create_amici_model( + sbml_model=sbml_model, + model_name=request.param, + ) + amici_model.setTimepoints(timepoints) + + return amici_model, parameters, timepoints, x_pected, sx_pected + + +def get_model_definition(model_name): + if model_name == 'events_plus_heavisides': + return model_definition_events_plus_heavisides() + if model_name == 'nested_events': + return model_definition_nested_events() + else: + raise NotImplementedError( + f'Model with name {model_name} is not implemented.' + ) + + +def model_definition_events_plus_heavisides(): + """Test model for state- and parameter-dependent heavisides. + + ODEs + ---- + d/dt x_1: + - { 0, t < delta + - { -alpha * x_1, t >= delta + d/dt x_2: + - beta * x_1 - gamma * x_2 + d/dt x_3: + - { -eta * x_3, t < zeta + - { -eta * x_3 + 1, t >= zeta + + Events: + ------- + event_1: + trigger: k1 - x_3 + bolus: [[ -x_3 / 2], + [ 0], + [ 0]] + event_2: + trigger: t - zeta + bolus: [[ 0], + [ 0], + [ zeta / 3]] + """ + # Model components + species = ['x_1', 'x_2', 'x_3'] + initial_assignments = { + 'x_1': 'k1', + 'x_2': 'k2', + 'x_3': 'k3', + } + rate_rules = { + 'x_1': 'piecewise( -alpha * x_1, time >= delta, 0)', + 'x_2': 'beta * x_1 - gamma * x_2', + 'x_3': '-eta * x_3 + piecewise( 1, time >= zeta, 0)', + } + parameters = { + 'k1': 2, + 'k2': 0.01, + 'k3': 5, + 'alpha': 2, + 'beta': 3, + 'gamma': 2, + 'delta': 3, + 'eta': 1, + 'zeta': 5, + } + events = { + 'event_1': { + 'trigger': 'x_3 < k1', + 'target': 'x_1', + 'assignment': 'x_1 - x_3 / 2' + }, + 'event_2': { + 'trigger': 'time >= zeta', + 'target': 'x_3', + 'assignment': 'x_3 + zeta / 3' + } + } + timepoints = np.linspace(0, 8, 400) + + # Analytical solution + def x_pected(t, k1, k2, k3, alpha, beta, gamma, delta, eta, zeta): + # The system reads dx/dt = Ax + b + # x0 = (k1, k2, k3) + x0 = np.array([[k1], [k2], [k3]]) + + # gather event time points + event_1_time = (np.log(k3) - np.log(k1)) / eta # k1 > x3 + event_2_time = delta + event_3_time = zeta + + def get_early_x(t): + # compute dynamics + if t < event_1_time: + # Define A + A = np.array([[0, 0, 0], + [beta, -gamma, 0], + [0, 0, -eta]]) + tmp_x = expm(t * A) + return np.matmul(tmp_x, x0) + + elif t <= event_2_time: + # "simulate" until first event + A = np.array([[0, 0, 0], + [beta, -gamma, 0], + [0, 0, -eta]]) + tmp_x = expm(event_1_time * A) + x1 = np.matmul(tmp_x, x0) + # apply bolus + delta_x = np.array([[float(-x1[2, :] / 2)], [0], [0]]) + x1 += delta_x + # "simulate" on + tmp_x = expm((t - event_1_time) * A) + return np.matmul(tmp_x, x1) + + if t < event_2_time: + x = get_early_x(t).flatten() + elif t < event_3_time: + x2 = get_early_x(event_2_time) + + A = np.array([[-alpha, 0, 0], + [beta, -gamma, 0], + [0, 0, -eta]]) + tmp_x = expm((t - event_2_time) * A) + x = np.matmul(tmp_x, x2).flatten() + else: + x2 = get_early_x(event_2_time) + + A = np.array([[-alpha, 0, 0], + [beta, -gamma, 0], + [0, 0, -eta]]) + tmp_x = expm((event_3_time - event_2_time) * A) + x3 = np.matmul(tmp_x, x2) + # apply bolus + x3 += np.array([[0], [0], [zeta / 3]]) + + hom_x = np.matmul(expm((t - event_3_time) * A), x3) + inhom_x = [[0], [0], + [-np.exp(-eta * (t - event_3_time)) / (eta) + + 1 / (eta)]] + + x = (hom_x + inhom_x).flatten() + + return np.array(x) + + def sx_pected(t, parameters): + # get sx, w.r.t. parameters, via finite differences + sx = [] + + for ip in parameters: + eps = 1e-6 + perturbed_params = deepcopy(parameters) + perturbed_params[ip] += eps + sx_p = x_pected(t, **perturbed_params) + perturbed_params[ip] -= 2*eps + sx_m = x_pected(t, **perturbed_params) + sx.append((sx_p - sx_m) / (2 * eps)) + + return np.array(sx) + + return ( + initial_assignments, + parameters, + rate_rules, + species, + events, + timepoints, + x_pected, + sx_pected + ) + + + +def model_definition_nested_events(): + """Test model for state- and parameter-dependent heavisides. + + ODEs + ---- + d/dt x_1: + inflow_1 - decay_1 * x1 + d/dt x_2: + - decay_2 * x_2 + + Events: + ------- + event_1: + trigger: x_1 > inflow_1 / decay_2 + bolus: [[ 0], + [ -1 / time]] + event_2: + trigger: x_2 > 0.5 + bolus: [[ bolus], + [ bolus]] + """ + # Model components + species = ['x_1', 'x_2'] + initial_assignments = { + 'x_1': 'k1', + 'x_2': 'k2', + } + rate_rules = { + 'x_1': 'inflow_1 - decay_1 * x_1', + 'x_2': '- decay_2 * x_2', + } + parameters = { + 'k1': 0, + 'k2': 0, + 'inflow_1': 4, + 'decay_1': 2, + 'decay_2': 5, + 'bolus': 0, # for bolus != 0, nested event sensitivities are off! + } + events = { + 'event_1': { + 'trigger': 'x_1 > inflow_1 / decay_2', + 'target': 'x_2', + 'assignment': 'x_2 - 1 / time' + }, + 'event_2': { + 'trigger': 'x_2 < - 0.5', + 'target': ['x_1', 'x_2'], + 'assignment': ['x_1 + bolus', 'x_2 + bolus'], + } + } + timepoints = np.linspace(0, 1, 101) + + # Analytical solution + def x_pected(t, k1, k2, inflow_1, decay_1, decay_2, bolus): + # gather temporary variables + # event_time = x_1 > inflow_1 / decay_2 + equil = inflow_1 / decay_1 + tmp1 = inflow_1 / decay_2 - inflow_1 / decay_1 + tmp2 = k1 - inflow_1 / decay_1 + event_time = (- 1 / decay_1) * np.log( tmp1 / tmp2) + + def get_early_x(t): + # compute dynamics before event + x_1 = equil * (1 - np.exp(-decay_1 * t)) + k1*np.exp(-decay_1 * t) + x_2 = k2 * np.exp(-decay_2 * t) + return np.array([[x_1], [x_2]]) + + if t < event_time: + x = get_early_x(t).flatten() + else: + # compute state after event + x_tau = get_early_x(event_time) + tau_x1 = x_tau[0] + bolus + tau_x2 = x_tau[1] - 1 / event_time + bolus + + # compute dynamics after event + inhom = np.exp(decay_1 * event_time) * tau_x1 + x_1 = equil * (1 - np.exp(decay_1 * (event_time - t))) + \ + inhom * np.exp(- decay_1 * t) + x_2 = tau_x2 * np.exp(decay_2 * event_time) * np.exp(-decay_2 * t) + + x = np.array([[x_1], [x_2]]) + + return x.flatten() + + def sx_pected(t, parameters): + # get sx, w.r.t. parameters, via finite differences + sx = [] + + for ip in parameters: + eps = 1e-6 + perturbed_params = deepcopy(parameters) + perturbed_params[ip] += eps + sx_p = x_pected(t, **perturbed_params) + perturbed_params[ip] -= 2*eps + sx_m = x_pected(t, **perturbed_params) + sx.append((sx_p - sx_m) / (2 * eps)) + + return np.array(sx) + + return ( + initial_assignments, + parameters, + rate_rules, + species, + events, + timepoints, + x_pected, + sx_pected + ) + + +def test_models(model): + amici_model, parameters, timepoints, x_pected, sx_pected = model + + result_expected_x = np.array([ + x_pected(t, **parameters) + for t in timepoints + ]) + result_expected_sx = np.array([ + sx_pected(t, parameters) + for t in timepoints + ]) + + # assert correctness of trajectories + check_trajectories_without_sensitivities(amici_model, + result_expected_x) + check_trajectories_with_forward_sensitivities(amici_model, + result_expected_x, + result_expected_sx) diff --git a/deps/AMICI/python/tests/test_heavisides.py b/deps/AMICI/python/tests/test_heavisides.py index 557b539d7..1c84ae0ac 100644 --- a/deps/AMICI/python/tests/test_heavisides.py +++ b/deps/AMICI/python/tests/test_heavisides.py @@ -1,23 +1,14 @@ """Tests for SBML events, including piecewise expressions.""" -import importlib -import libsbml import numpy as np -from pathlib import Path import pytest -import sys - -from amici import ( - AmiciModel, - runAmiciSimulation, - SbmlImporter, - SensitivityMethod, - SensitivityOrder -) -sbml_test_models = Path('sbml_test_models') -sbml_test_models_output_dir = sbml_test_models / 'amici_models' -sbml_test_models_output_dir.mkdir(parents=True, exist_ok=True) +from util import ( + create_sbml_model, + create_amici_model, + check_trajectories_without_sensitivities, + check_trajectories_with_forward_sensitivities, +) @pytest.fixture(params=[ 'state_and_parameter_dependent_heavisides', @@ -31,6 +22,7 @@ def model(request): parameters, rate_rules, species, + events, timepoints, x_pected, sx_pected @@ -42,6 +34,7 @@ def model(request): parameters=parameters, rate_rules=rate_rules, species=species, + events=events, # uncomment `to_file` to save SBML model to file for inspection # to_file=sbml_test_models / (model_name + '.sbml'), ) @@ -68,120 +61,12 @@ def test_models(model): for t in timepoints ]) - # --- Test the state trajectories without sensitivities ------------------- - # Does the AMICI simulation match the analytical solution? - solver = amici_model.getSolver() - rdata = runAmiciSimulation(amici_model, solver=solver) - solver.setAbsoluteTolerance(1e-15) - np.testing.assert_almost_equal(rdata['x'], result_expected_x, decimal=5) - - # Show that we can do arbitrary precision here (test 8 digits) - solver = amici_model.getSolver() - solver.setAbsoluteTolerance(1e-15) - solver.setRelativeTolerance(1e-12) - rdata = runAmiciSimulation(amici_model, solver=solver) - np.testing.assert_almost_equal(rdata['x'], result_expected_x, decimal=8) - - # --- Test the state trajectories with sensitivities ---------------------- - # Does the AMICI simulation match the analytical solution? - solver = amici_model.getSolver() - solver.setSensitivityOrder(SensitivityOrder.first) - solver.setSensitivityMethod(SensitivityMethod.forward) - solver.setAbsoluteTolerance(1e-15) - rdata = runAmiciSimulation(amici_model, solver=solver) - - np.testing.assert_almost_equal(rdata['x'], result_expected_x, decimal=5) - np.testing.assert_almost_equal(rdata['sx'], result_expected_sx, decimal=5) - - # Show that we can do arbitrary precision here (test 8 digits) - solver = amici_model.getSolver() - solver.setSensitivityOrder(SensitivityOrder.first) - solver.setSensitivityMethod(SensitivityMethod.forward) - solver.setAbsoluteTolerance(1e-15) - solver.setRelativeTolerance(1e-13) - solver.setAbsoluteToleranceFSA(1e-15) - solver.setRelativeToleranceFSA(1e-13) - rdata = runAmiciSimulation(amici_model, solver=solver) - np.testing.assert_almost_equal(rdata['x'], result_expected_x, decimal=8) - np.testing.assert_almost_equal(rdata['sx'], result_expected_sx, decimal=8) - - -def create_amici_model(sbml_model, model_name) -> AmiciModel: - sbml_importer = SbmlImporter(sbml_model) - output_dir = sbml_test_models_output_dir / model_name - sbml_importer.sbml2amici( - model_name=model_name, - output_dir=str(output_dir) - ) - - sys.path.insert(0, str(output_dir.resolve())) - model_module = importlib.import_module(model_name) - - model = model_module.getModel() - return model - - -def create_sbml_model( - initial_assignments, - parameters, - rate_rules, - species, - to_file: str = None, -): - """Create an SBML model from simple definitions. - - See the model definitions and usage in :py:func:`model` for example input. - - The default initial concentration of species is `1.0`. This can currently - be changed by specifying an initial assignment. - """ - document = libsbml.SBMLDocument(3, 1) - model = document.createModel() - - compartment = model.createCompartment() - compartment.setId('compartment') - compartment.setConstant(True) - compartment.setSize(1) - compartment.setSpatialDimensions(3) - compartment.setUnits('dimensionless') - - for species_id in species: - species = model.createSpecies() - species.setId(species_id) - species.setCompartment('compartment') - species.setConstant(False) - species.setSubstanceUnits('dimensionless') - species.setBoundaryCondition(False) - species.setHasOnlySubstanceUnits(False) - species.setInitialConcentration(1.0) - - for target, formula in initial_assignments.items(): - initial_assignment = model.createInitialAssignment() - initial_assignment.setSymbol(target) - initial_assignment.setMath(libsbml.parseL3Formula(formula)) - - for target, formula in rate_rules.items(): - rate_rule = model.createRateRule() - rate_rule.setVariable(target) - rate_rule.setMath(libsbml.parseL3Formula(formula)) - - for parameter_id, parameter_value in parameters.items(): - parameter = model.createParameter() - parameter.setId(parameter_id) - parameter.setConstant(True) - parameter.setValue(parameter_value) - parameter.setUnits('dimensionless') - - if to_file: - libsbml.writeSBMLToFile( - document, - str(to_file), - ) - - # Need to return document, else AMICI throws an error. - # (possibly due to garbage collection?) - return document, model + check_trajectories_without_sensitivities(amici_model, + result_expected_x) + check_trajectories_with_forward_sensitivities(amici_model, + result_expected_x, + result_expected_sx) def get_model_definition(model_name): @@ -227,6 +112,7 @@ def model_definition_state_and_parameter_dependent_heavisides(): 'zeta': 0.25, } timepoints = np.linspace(0, 10, 100) + events = {} # Analytical solution def x_pected(t, alpha, beta, gamma, delta, eta, zeta): @@ -313,6 +199,7 @@ def sx_pected(t, alpha, beta, gamma, delta, eta, zeta): parameters, rate_rules, species, + events, timepoints, x_pected, sx_pected @@ -349,6 +236,7 @@ def model_definition_piecewise_with_boolean_operations(): 'x_1_0': 1, } timepoints = np.linspace(0, 5, 100) + events = {} # Analytical solution def x_pected(t, x_1_0, alpha, beta, gamma, delta): @@ -389,6 +277,7 @@ def sx_pected(t, x_1_0, alpha, beta, gamma, delta): parameters, rate_rules, species, + events, timepoints, x_pected, sx_pected @@ -424,6 +313,7 @@ def model_definition_piecewise_many_conditions(): 'x_1_0': 1, } timepoints = np.linspace(0, t_final, 100) + events = {} # Analytical solution def x_pected(t, x_1_0): @@ -440,6 +330,7 @@ def sx_pected(t, x_1_0): parameters, rate_rules, species, + events, timepoints, x_pected, sx_pected diff --git a/deps/AMICI/python/tests/test_pregenerated_models.py b/deps/AMICI/python/tests/test_pregenerated_models.py index e339e03a5..6bd63768b 100755 --- a/deps/AMICI/python/tests/test_pregenerated_models.py +++ b/deps/AMICI/python/tests/test_pregenerated_models.py @@ -3,19 +3,17 @@ """Run simulations with Matlab-AMICI pre-generated models and verify using saved expectations.""" -import sys import h5py import amici -import unittest -import importlib import os -import copy from amici.gradient_check import check_derivatives, check_results import pytest +import numpy as np + options_file = os.path.join(os.path.dirname(__file__), '..', '..', - 'tests', 'cpputest', 'testOptions.h5') + 'tests', 'cpputest', 'testOptions.h5') expected_results_file = os.path.join(os.path.dirname(__file__), '..', '..', 'tests', 'cpputest', 'expectedResults.h5') expected_results = h5py.File(expected_results_file, 'r') @@ -147,6 +145,8 @@ def test_pregenerated_model(sub_test, case): with pytest.raises(RuntimeError): solver.setSensitivityMethod(amici.SensitivityMethod.adjoint) + chi2_ref = rdata.chi2 + # test likelihood mode solver.setReturnDataReportingMode(amici.RDataReporting.likelihood) rdata = amici.runAmiciSimulation(model, solver, edata) @@ -155,6 +155,35 @@ def test_pregenerated_model(sub_test, case): fields=['t', 'llh', 'sllh', 's2llh', 'FIM'], **verify_simulation_opts ) + # test sigma residuals + + if model_name == 'model_jakstat_adjoint' and \ + solver.getSensitivityMethod() != amici.SensitivityMethod.adjoint: + model.setAddSigmaResiduals(True) + solver.setReturnDataReportingMode(amici.RDataReporting.full) + rdata = amici.runAmiciSimulation(model, solver, edata) + # check whether activation changes chi2 + assert chi2_ref != rdata.chi2 + + if edata and solver.getSensitivityMethod() and \ + solver.getSensitivityOrder() and len(model.getParameterList()): + check_derivatives(model, solver, edata, assert_fun, + **check_derivative_opts) + + chi2_ref = rdata.chi2 + res_ref = rdata.res + + model.setMinimumSigmaResiduals(100) + rdata = amici.runAmiciSimulation(model, solver, edata) + # check whether changing the minimum changes res but not chi2 + assert np.isclose(chi2_ref, rdata.chi2) + assert not np.allclose(res_ref, rdata.res) + + model.setMinimumSigmaResiduals(-10) + rdata = amici.runAmiciSimulation(model, solver, edata) + # check whether having a bad minimum results in nan chi2 + assert np.isnan(rdata.chi2) + with pytest.raises(RuntimeError): model.getParameterByName('thisParameterDoesNotExist') diff --git a/deps/AMICI/python/tests/test_sbml_import.py b/deps/AMICI/python/tests/test_sbml_import.py index 5540b5c92..a9b84c267 100644 --- a/deps/AMICI/python/tests/test_sbml_import.py +++ b/deps/AMICI/python/tests/test_sbml_import.py @@ -1,6 +1,7 @@ """Tests related to amici.sbml_import""" import os +import sys import re from urllib.request import urlopen import shutil @@ -29,6 +30,10 @@ def simple_sbml_model(): s1.setId('S1') s1.setCompartment('C1') model.addSpecies(s1) + p1 = model.createParameter() + p1.setId('p1') + p1.setValue(0.0) + model.addParameter(p1) return document, model @@ -46,6 +51,32 @@ def test_sbml2amici_no_observables(simple_sbml_model): compute_conservation_laws=False) +@pytest.mark.skipif(sys.platform in ['win32', 'cygwin'], + reason="windows stinks") +def test_nosensi(simple_sbml_model): + sbml_doc, sbml_model = simple_sbml_model + sbml_importer = SbmlImporter(sbml_source=sbml_model, + from_file=False) + + with TemporaryDirectory() as tmpdir: + sbml_importer.sbml2amici(model_name="test", + output_dir=tmpdir, + observables=None, + compute_conservation_laws=False, + generate_sensitivity_code=False) + + model_module = amici.import_model_module(module_name='test', + module_path=tmpdir) + + model = model_module.getModel() + model.setTimepoints(np.linspace(0, 60, 61)) + solver = model.getSolver() + solver.setSensitivityOrder(amici.SensitivityOrder.first) + solver.setSensitivityMethod(amici.SensitivityMethod.forward) + rdata = amici.runAmiciSimulation(model, solver) + assert rdata.status == amici.AMICI_ERROR + + def assert_fun(x): assert x diff --git a/deps/AMICI/python/tests/util.py b/deps/AMICI/python/tests/util.py new file mode 100644 index 000000000..cac811b11 --- /dev/null +++ b/deps/AMICI/python/tests/util.py @@ -0,0 +1,173 @@ +"""Tests for SBML events, including piecewise expressions.""" +import libsbml +import numpy as np +from pathlib import Path + +from amici import ( + AmiciModel, + import_model_module, + runAmiciSimulation, + SbmlImporter, + SensitivityMethod, + SensitivityOrder +) + + +def create_amici_model(sbml_model, model_name) -> AmiciModel: + """ + Import an sbml file and create an AMICI model from it + """ + sbml_test_models = Path('sbml_test_models') + sbml_test_models_output_dir = sbml_test_models / 'amici_models' + sbml_test_models_output_dir.mkdir(parents=True, exist_ok=True) + + sbml_importer = SbmlImporter(sbml_model) + output_dir = sbml_test_models_output_dir / model_name + sbml_importer.sbml2amici( + model_name=model_name, + output_dir=str(output_dir) + ) + + model_module = import_model_module(model_name, str(output_dir.resolve())) + model = model_module.getModel() + return model + + +def create_sbml_model( + initial_assignments, + parameters, + rate_rules, + species, + events, + to_file: str = None, +): + """Create an SBML model from simple definitions. + + See the model definitions and usage in :py:func:`model` for example input. + + The default initial concentration of species is `1.0`. This can currently + be changed by specifying an initial assignment. + """ + document = libsbml.SBMLDocument(3, 1) + model = document.createModel() + + compartment = model.createCompartment() + compartment.setId('compartment') + compartment.setConstant(True) + compartment.setSize(1) + compartment.setSpatialDimensions(3) + compartment.setUnits('dimensionless') + + for species_id in species: + species = model.createSpecies() + species.setId(species_id) + species.setCompartment('compartment') + species.setConstant(False) + species.setSubstanceUnits('dimensionless') + species.setBoundaryCondition(False) + species.setHasOnlySubstanceUnits(False) + species.setInitialConcentration(1.0) + + for target, formula in initial_assignments.items(): + initial_assignment = model.createInitialAssignment() + initial_assignment.setSymbol(target) + initial_assignment.setMath(libsbml.parseL3Formula(formula)) + + for target, formula in rate_rules.items(): + rate_rule = model.createRateRule() + rate_rule.setVariable(target) + rate_rule.setMath(libsbml.parseL3Formula(formula)) + + for parameter_id, parameter_value in parameters.items(): + parameter = model.createParameter() + parameter.setId(parameter_id) + parameter.setConstant(True) + parameter.setValue(parameter_value) + parameter.setUnits('dimensionless') + + for event_id, event_def in events.items(): + event = model.createEvent() + event.setId(event_id) + event.setName(event_id) + event.setUseValuesFromTriggerTime(True) + trigger = event.createTrigger() + trigger.setMath(libsbml.parseL3Formula(event_def['trigger'])) + trigger.setPersistent(True) + trigger.setInitialValue(True) + if isinstance(event_def['target'], list): + assignments = [] + for ia, event_target in enumerate(event_def['target']): + event_assignment = event_def['assignment'][ia] + assignments.append(event.createEventAssignment()) + assignments[ia].setVariable(event_target) + assignments[ia].setMath( + libsbml.parseL3Formula(event_assignment)) + else: + assignment = event.createEventAssignment() + assignment.setVariable(event_def['target']) + assignment.setMath(libsbml.parseL3Formula(event_def['assignment'])) + + if to_file: + libsbml.writeSBMLToFile( + document, + str(to_file), + ) + + # Need to return document, else AMICI throws an error. + # (possibly due to garbage collection?) + return document, model + + +def check_trajectories_without_sensitivities( + amici_model: AmiciModel, + result_expected_x: np.ndarray, +): + """ + Check whether the AMICI simulation matches a known solution + (ideally an analytically calculated one). + """ + + # Does the AMICI simulation match the analytical solution? + solver = amici_model.getSolver() + solver.setAbsoluteTolerance(1e-15) + rdata = runAmiciSimulation(amici_model, solver=solver) + np.testing.assert_almost_equal(rdata['x'], result_expected_x, decimal=5) + + # Show that we can do arbitrary precision here (test 8 digits) + solver = amici_model.getSolver() + solver.setAbsoluteTolerance(1e-15) + solver.setRelativeTolerance(1e-12) + rdata = runAmiciSimulation(amici_model, solver=solver) + np.testing.assert_almost_equal(rdata['x'], result_expected_x, decimal=8) + + +def check_trajectories_with_forward_sensitivities( + amici_model: AmiciModel, + result_expected_x: np.ndarray, + result_expected_sx: np.ndarray, +): + """ + Check whether the forward sensitivities of the AMICI simulation match + a known solution (ideally an analytically calculated one). + """ + + # Show that we can do arbitrary precision here (test 8 digits) + solver = amici_model.getSolver() + solver.setAbsoluteTolerance(1e-15) + solver.setSensitivityOrder(SensitivityOrder.first) + solver.setSensitivityMethod(SensitivityMethod.forward) + rdata = runAmiciSimulation(amici_model, solver=solver) + np.testing.assert_almost_equal(rdata['x'], result_expected_x, decimal=5) + np.testing.assert_almost_equal(rdata['sx'], result_expected_sx, decimal=5) + + # Show that we can do arbitrary precision here (test 8 digits) + solver = amici_model.getSolver() + solver.setSensitivityOrder(SensitivityOrder.first) + solver.setSensitivityMethod(SensitivityMethod.forward) + solver.setAbsoluteTolerance(1e-15) + solver.setRelativeTolerance(1e-13) + solver.setAbsoluteToleranceFSA(1e-15) + solver.setRelativeToleranceFSA(1e-13) + rdata = runAmiciSimulation(amici_model, solver=solver) + np.testing.assert_almost_equal(rdata['x'], result_expected_x, decimal=8) + np.testing.assert_almost_equal(rdata['sx'], result_expected_sx, decimal=8) diff --git a/deps/AMICI/scripts/downloadAndBuildDoxygen.sh b/deps/AMICI/scripts/downloadAndBuildDoxygen.sh index 9e6bab2ca..8cae173e6 100755 --- a/deps/AMICI/scripts/downloadAndBuildDoxygen.sh +++ b/deps/AMICI/scripts/downloadAndBuildDoxygen.sh @@ -9,7 +9,7 @@ DOXYGEN_DIR="${AMICI_PATH}"/ThirdParty/doxygen cd "${AMICI_PATH}"/ThirdParty if [[ ! -d ${DOXYGEN_DIR} ]]; then # git clone --depth 1 https://github.com/doxygen/doxygen.git "${DOXYGEN_DIR}" - git clone --single-branch --branch master --depth 1 https://github.com/doxygen/doxygen.git "${DOXYGEN_DIR}" + git clone --single-branch --branch Release_1_9_1 --depth 1 https://github.com/doxygen/doxygen.git "${DOXYGEN_DIR}" fi cd "${DOXYGEN_DIR}" diff --git a/deps/AMICI/scripts/installAmiciArchive.sh b/deps/AMICI/scripts/installAmiciArchive.sh index 20f4251ee..25de4f9f9 100755 --- a/deps/AMICI/scripts/installAmiciArchive.sh +++ b/deps/AMICI/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/deps/AMICI/scripts/run-SBMLTestsuite.sh b/deps/AMICI/scripts/run-SBMLTestsuite.sh index 9906442b5..1767a16df 100755 --- a/deps/AMICI/scripts/run-SBMLTestsuite.sh +++ b/deps/AMICI/scripts/run-SBMLTestsuite.sh @@ -26,5 +26,5 @@ if [[ -d "${RESULT_DIR}" ]]; then fi mkdir "${RESULT_DIR}" -pytest ./tests/testSBMLSuite.py --cases="${args}" -rfsE -s -n auto \ +pytest ./tests/testSBMLSuite.py --cases="${args}" -rfsE -n auto \ --cov=amici --cov-report=xml:"coverage_SBMLSuite.xml" --cov-append diff --git a/deps/AMICI/sonar-project.properties b/deps/AMICI/sonar-project.properties index 3dda19a12..f376ff3bd 100644 --- a/deps/AMICI/sonar-project.properties +++ b/deps/AMICI/sonar-project.properties @@ -9,7 +9,19 @@ sonar.organization=icb-dcm sonar.projectKey=ICB-DCM_AMICI sonar.sources=. -sonar.exclusions=build/**,ThirdParty/**,doc/**,models/**,python/sdist/amici/**,**/*.html,**/*.m,model_*/**,**/sbml_test_models/** +sonar.exclusions=\ + build/**,\ + ThirdParty/**,\ + doc/**,\ + models/**,\ + model_*/**,\ + **/amici_models/**,\ + python/sdist/amici/**,\ + **/*.html,\ + **/*.m,\ + **/sbml_test_models/**,\ + documentation/model_dir/**,\ + matlab/mtoc/** sonar.sourceEncoding=UTF-8 diff --git a/deps/AMICI/src/abstract_model.cpp b/deps/AMICI/src/abstract_model.cpp index e9469125c..f866eb7db 100644 --- a/deps/AMICI/src/abstract_model.cpp +++ b/deps/AMICI/src/abstract_model.cpp @@ -2,13 +2,13 @@ namespace amici { -const std::string +std::string AbstractModel::getAmiciVersion() const { throw AmiException("Version not set during code generation"); } -const std::string +std::string AbstractModel::getAmiciCommit() const { throw AmiException("Commit not set during code generation"); diff --git a/deps/AMICI/src/amici.cpp b/deps/AMICI/src/amici.cpp index 72da4c2a4..841fdb98a 100644 --- a/deps/AMICI/src/amici.cpp +++ b/deps/AMICI/src/amici.cpp @@ -193,6 +193,13 @@ AmiciApplication::runAmiciSimulation(Solver& solver, "AMICI simulation failed:\n%s\nError occurred in:\n%s", ex.what(), ex.getBacktrace()); + } catch (std::exception const& ex) { + rdata->status = AMICI_ERROR; + if (rethrow) + throw; + warningF("AMICI:simulation", + "AMICI simulation failed:\n%s\n", + ex.what()); } rdata->processSimulationObjects( diff --git a/deps/AMICI/src/forwardproblem.cpp b/deps/AMICI/src/forwardproblem.cpp index a0f4de08c..8147edce0 100644 --- a/deps/AMICI/src/forwardproblem.cpp +++ b/deps/AMICI/src/forwardproblem.cpp @@ -157,9 +157,10 @@ void ForwardProblem::handleEvent(realtype *tlastroot, const bool seflag) { /* only check this in the first event fired, otherwise this will always * be true */ if (t_ == *tlastroot) { - throw AmiException("AMICI is stuck in an event, as the initial" - "step-size after the event is too small. To fix " - "this, increase absolute and relative tolerances!"); + throw AmiException("AMICI is stuck in an event, as the initial " + "step-size after the event is too small. " + "To fix this, increase absolute and relative " + "tolerances!"); } *tlastroot = t_; } @@ -231,6 +232,13 @@ void ForwardProblem::handleEvent(realtype *tlastroot, const bool seflag) { } /* fire the secondary event */ if (secondevent > 0) { + /* Secondary events may result in wrong forward sensitivities, + * if the secondary event has a bolus... */ + if (solver->computingFSA()) + solver->app->warning("AMICI:simulation", + "Secondary event was triggered. Depending on " + "the bolus of the secondary event, forward " + "sensitivities can be incorrect."); handleEvent(tlastroot, true); } diff --git a/deps/AMICI/src/hdf5.cpp b/deps/AMICI/src/hdf5.cpp index 12ef25cf7..b548e4d54 100644 --- a/deps/AMICI/src/hdf5.cpp +++ b/deps/AMICI/src/hdf5.cpp @@ -1,3 +1,12 @@ +/** + * Functions for HDF5 I/O + * + * NOTE: Use only `const char*` versions of any HDF5 functions, not the + * `std::string` version. On many systems, HDF5 libraries are still not compiled + * with C++11 support, but use the old C++03 ABI, which will lead to linking + * issues. + */ + #include "amici/hdf5.h" #include "amici/amici.h" @@ -97,7 +106,7 @@ void createGroup(H5::H5File const& file, std::unique_ptr readSimulationExpData(std::string const& hdf5Filename, std::string const& hdf5Root, Model const& model) { - H5::H5File file(hdf5Filename, H5F_ACC_RDONLY); + H5::H5File file(hdf5Filename.c_str(), H5F_ACC_RDONLY); hsize_t m, n; @@ -495,7 +504,7 @@ void createAndWriteInt1DDataset(H5::H5File const& file, gsl::span buffer) { hsize_t size = buffer.size(); H5::DataSpace dataspace(1, &size); - auto dataset = file.createDataSet(datasetName, H5::PredType::NATIVE_INT, + auto dataset = file.createDataSet(datasetName.c_str(), H5::PredType::NATIVE_INT, dataspace); dataset.write(buffer.data(), H5::PredType::NATIVE_INT); } @@ -505,7 +514,7 @@ void createAndWriteDouble1DDataset(const H5::H5File &file, gsl::span buffer) { hsize_t size = buffer.size(); H5::DataSpace dataspace(1, &size); - auto dataset = file.createDataSet(datasetName, H5::PredType::NATIVE_DOUBLE, + auto dataset = file.createDataSet(datasetName.c_str(), H5::PredType::NATIVE_DOUBLE, dataspace); dataset.write(buffer.data(), H5::PredType::NATIVE_DOUBLE); } @@ -516,7 +525,7 @@ void createAndWriteDouble2DDataset(const H5::H5File &file, hsize_t n) { const hsize_t adims[] {m, n}; H5::DataSpace dataspace(2, adims); - auto dataset = file.createDataSet(datasetName, H5::PredType::NATIVE_DOUBLE, + auto dataset = file.createDataSet(datasetName.c_str(), H5::PredType::NATIVE_DOUBLE, dataspace); dataset.write(buffer.data(), H5::PredType::NATIVE_DOUBLE); } @@ -527,7 +536,7 @@ void createAndWriteInt2DDataset(H5::H5File const& file, hsize_t n) { const hsize_t adims[] {m, n}; H5::DataSpace dataspace(2, adims); - auto dataset = file.createDataSet(datasetName, H5::PredType::NATIVE_INT, + auto dataset = file.createDataSet(datasetName.c_str(), H5::PredType::NATIVE_INT, dataspace); dataset.write(buffer.data(), H5::PredType::NATIVE_INT); } @@ -538,7 +547,7 @@ void createAndWriteDouble3DDataset(H5::H5File const& file, hsize_t n, hsize_t o) { const hsize_t adims[] {m, n, o}; H5::DataSpace dataspace(3, adims); - auto dataset = file.createDataSet(datasetName, H5::PredType::NATIVE_DOUBLE, + auto dataset = file.createDataSet(datasetName.c_str(), H5::PredType::NATIVE_DOUBLE, dataspace); dataset.write(buffer.data(), H5::PredType::NATIVE_DOUBLE); } @@ -871,14 +880,14 @@ void readSolverSettingsFromHDF5(H5::H5File const& file, Solver &solver, void readSolverSettingsFromHDF5(const std::string &hdffile, Solver &solver, const std::string &datasetPath) { - H5::H5File file(hdffile, H5F_ACC_RDONLY, H5P_DEFAULT); + H5::H5File file(hdffile.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); readSolverSettingsFromHDF5(file, solver, datasetPath); } void readModelDataFromHDF5(const std::string &hdffile, Model &model, const std::string &datasetPath) { - H5::H5File file(hdffile, H5F_ACC_RDONLY, H5P_DEFAULT); + H5::H5File file(hdffile.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); readModelDataFromHDF5(file, model, datasetPath); } @@ -951,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(sigma_res)); + } + + if(attributeExists(file, datasetPath, "min_sigma")) { + auto min_sigma = getDoubleScalarAttribute(file, datasetPath, + "min_sigma"); + model.setMinimumSigmaResiduals(min_sigma); + } } @@ -958,12 +978,12 @@ H5::H5File createOrOpenForWriting(const std::string &hdf5filename) { AMICI_H5_SAVE_ERROR_HANDLER; try { - H5::H5File file(hdf5filename, H5F_ACC_RDWR); + H5::H5File file(hdf5filename.c_str(), H5F_ACC_RDWR); AMICI_H5_RESTORE_ERROR_HANDLER; return file; } catch(...) { AMICI_H5_RESTORE_ERROR_HANDLER; - return H5::H5File(hdf5filename, H5F_ACC_EXCL); + return H5::H5File(hdf5filename.c_str(), H5F_ACC_EXCL); } } @@ -977,13 +997,13 @@ bool locationExists(const H5::H5File &file, const std::string &location) bool locationExists(const std::string &filename, const std::string &location) { - H5::H5File file(filename, H5F_ACC_RDONLY); + H5::H5File file(filename.c_str(), H5F_ACC_RDONLY); return locationExists(file, location); } std::vector getIntDataset1D(const H5::H5File &file, std::string const& name) { - auto dataset = file.openDataSet(name); + auto dataset = file.openDataSet(name.c_str()); auto dataspace = dataset.getSpace(); int rank = dataspace.getSimpleExtentNdims(); @@ -1002,7 +1022,7 @@ std::vector getIntDataset1D(const H5::H5File &file, std::vector getDoubleDataset1D(const H5::H5File &file, const std::string &name) { - auto dataset = file.openDataSet(name); + auto dataset = file.openDataSet(name.c_str()); auto dataspace = dataset.getSpace(); int rank = dataspace.getSimpleExtentNdims(); @@ -1025,7 +1045,7 @@ std::vector getDoubleDataset2D(const H5::H5File &file, { m = n = 0; - auto dataset = file.openDataSet(name); + auto dataset = file.openDataSet(name.c_str()); auto dataspace = dataset.getSpace(); int rank = dataspace.getSimpleExtentNdims(); @@ -1050,7 +1070,7 @@ std::vector getDoubleDataset3D(const H5::H5File &file, { m = n = o = 0; - auto dataset = file.openDataSet(name); + auto dataset = file.openDataSet(name.c_str()); auto dataspace = dataset.getSpace(); int rank = dataspace.getSimpleExtentNdims(); diff --git a/deps/AMICI/src/model.cpp b/deps/AMICI/src/model.cpp index 1058655bf..2123be742 100644 --- a/deps/AMICI/src/model.cpp +++ b/deps/AMICI/src/model.cpp @@ -185,7 +185,9 @@ bool operator==(const Model &a, const Model &b) { (a.state_.plist == b.state_.plist) && (a.x0data_ == b.x0data_) && (a.sx0data_ == b.sx0data_) && (a.nmaxevent_ == b.nmaxevent_) && - (a.state_is_non_negative_ == b.state_is_non_negative_); + (a.state_is_non_negative_ == b.state_is_non_negative_) && + (a.sigma_res_ == b.sigma_res_) && + (a.min_sigma_ == b.min_sigma_); } bool operator==(const ModelDimensions &a, const ModelDimensions &b) { diff --git a/deps/AMICI/src/model_header.ODE_template.h b/deps/AMICI/src/model_header.ODE_template.h index 99e5257a7..79eec1d51 100644 --- a/deps/AMICI/src/model_header.ODE_template.h +++ b/deps/AMICI/src/model_header.ODE_template.h @@ -26,21 +26,12 @@ extern std::array stateIds; extern std::array observableIds; extern std::array expressionIds; -extern void Jy_TPL_MODELNAME(realtype *nllh, const int iy, const realtype *p, - const realtype *k, const realtype *y, - const realtype *sigmay, const realtype *my); -extern void dJydsigmay_TPL_MODELNAME(realtype *dJydsigmay, const int iy, - const realtype *p, const realtype *k, - const realtype *y, const realtype *sigmay, - const realtype *my); +TPL_JY_DEF +TPL_DJYDSIGMA_DEF TPL_DJYDY_DEF TPL_DJYDY_COLPTRS_DEF TPL_DJYDY_ROWVALS_DEF - -extern void root_TPL_MODELNAME(realtype *root, const realtype t, - const realtype *x, const realtype *p, - const realtype *k, const realtype *h); - +TPL_ROOT_DEF TPL_DWDP_DEF TPL_DWDP_COLPTRS_DEF TPL_DWDP_ROWVALS_DEF @@ -59,54 +50,20 @@ TPL_DXDOTDP_EXPLICIT_ROWVALS_DEF TPL_DXDOTDX_EXPLICIT_DEF TPL_DXDOTDX_EXPLICIT_COLPTRS_DEF TPL_DXDOTDX_EXPLICIT_ROWVALS_DEF - -extern void dydx_TPL_MODELNAME(realtype *dydx, const realtype t, - const realtype *x, const realtype *p, - const realtype *k, const realtype *h, - const realtype *w, const realtype *dwdx); -extern void dydp_TPL_MODELNAME(realtype *dydp, const realtype t, - const realtype *x, const realtype *p, - const realtype *k, const realtype *h, - const int ip, const realtype *w, - const realtype *dwp); -extern void dsigmaydp_TPL_MODELNAME(realtype *dsigmaydp, const realtype t, - const realtype *p, const realtype *k, - const int ip); -extern void sigmay_TPL_MODELNAME(realtype *sigmay, const realtype t, - const realtype *p, const realtype *k); +TPL_DYDX_DEF +TPL_DYDP_DEF +TPL_SIGMAY_DEF +TPL_DSIGMAYDP_DEF TPL_W_DEF -extern void x0_TPL_MODELNAME(realtype *x0, const realtype t, const realtype *p, - const realtype *k); -extern void x0_fixedParameters_TPL_MODELNAME(realtype *x0, const realtype t, - const realtype *p, - const realtype *k, - gsl::span reinitialization_state_idxs); -extern void sx0_TPL_MODELNAME(realtype *sx0, const realtype t, - const realtype *x0, const realtype *p, - const realtype *k, const int ip); -extern void sx0_fixedParameters_TPL_MODELNAME(realtype *sx0, const realtype t, - const realtype *x0, - const realtype *p, - const realtype *k, const int ip, - gsl::span reinitialization_state_idxs); -extern void xdot_TPL_MODELNAME(realtype *xdot, const realtype t, - const realtype *x, const realtype *p, - const realtype *k, const realtype *h, - const realtype *w); -extern void y_TPL_MODELNAME(realtype *y, const realtype t, const realtype *x, - const realtype *p, const realtype *k, - const realtype *h, const realtype *w); -extern void stau_TPL_MODELNAME(realtype *stau, const realtype t, - const realtype *x, const realtype *p, - const realtype *k, const realtype *h, - const realtype *sx, const int ip, const int ie); -extern void deltasx_TPL_MODELNAME(realtype *deltasx, const realtype t, - const realtype *x, const realtype *p, - const realtype *k, const realtype *h, - const realtype *w, const int ip, - const int ie, const realtype *xdot, - const realtype *xdot_old, const realtype *sx, - const realtype *stau); +TPL_X0_DEF +TPL_X0_FIXEDPARAMETERS_DEF +TPL_SX0_DEF +TPL_SX0_FIXEDPARAMETERS_DEF +TPL_XDOT_DEF +TPL_Y_DEF +TPL_STAU_DEF +TPL_DELTAX_DEF +TPL_DELTASX_DEF TPL_X_RDATA_DEF TPL_X_SOLVER_DEF TPL_TOTAL_CL_DEF @@ -178,20 +135,7 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { const realtype *k, const realtype *rz, const realtype *sigmaz) override {} - /** model specific implementation of fJy - * @param nllh negative log-likelihood for measurements y - * @param iy output index - * @param p parameter vector - * @param k constant vector - * @param y model output at timepoint - * @param sigmay measurement standard deviation at timepoint - * @param my measurements at timepoint - **/ - virtual void fJy(realtype *nllh, const int iy, const realtype *p, - const realtype *k, const realtype *y, - const realtype *sigmay, const realtype *my) override { - Jy_TPL_MODELNAME(nllh, iy, p, k, y, sigmay, my); - } + TPL_JY_IMPL /** model specific implementation of fJz * @param nllh negative log-likelihood for event measurements z @@ -232,23 +176,7 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { const realtype *k, const realtype *rz, const realtype *sigmaz) override {} - /** model specific implementation of fdJydsigma - * @param dJydsigma Sensitivity of time-resolved measurement - * negative log-likelihood Jy w.r.t. standard deviation sigmay - * @param iy output index - * @param p parameter vector - * @param k constant vector - * @param y model output at timepoint - * @param sigmay measurement standard deviation at timepoint - * @param my measurement at timepoint - **/ - virtual void fdJydsigma(realtype *dJydsigma, const int iy, - const realtype *p, const realtype *k, - const realtype *y, const realtype *sigmay, - const realtype *my) override { - dJydsigmay_TPL_MODELNAME(dJydsigma, iy, p, k, y, sigmay, my); - } - + TPL_DJYDSIGMA_IMPL /** model specific implementation of fdJzdsigma * @param dJzdsigma Sensitivity of event measurement @@ -299,46 +227,9 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { const realtype *xdot_old, const realtype *xB) override {} - /** model specific implementation of fdeltasx - * @param deltasx sensitivity update - * @param t current time - * @param x current state - * @param p parameter vector - * @param k constant vector - * @param h heaviside vector - * @param w repeating elements vector - * @param ip sensitivity index - * @param ie event index - * @param xdot new model right hand side - * @param xdot_old previous model right hand side - * @param sx state sensitivity - * @param stau event-time sensitivity - **/ - virtual void fdeltasx(realtype *deltasx, const realtype t, - const realtype *x, const realtype *p, - const realtype *k, const realtype *h, - const realtype *w, const int ip, const int ie, - const realtype *xdot, const realtype *xdot_old, - const realtype *sx, const realtype *stau) override { - deltasx_TPL_MODELNAME(deltasx, t, x, p, k, h, w, ip, ie, xdot, - xdot_old, sx, stau); - } + TPL_DELTASX_IMPL - /** model specific implementation of fdeltax - * @param deltax state update - * @param t current time - * @param x current state - * @param p parameter vector - * @param k constant vector - * @param h heaviside vector - * @param ie event index - * @param xdot new model right hand side - * @param xdot_old previous model right hand side - **/ - virtual void fdeltax(realtype *deltax, const realtype t, const realtype *x, - const realtype *p, const realtype *k, - const realtype *h, const int ie, const realtype *xdot, - const realtype *xdot_old) override {} + TPL_DELTAX_IMPL /** model specific implementation of fdeltaxB * @param deltaxB adjoint state update @@ -386,18 +277,7 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { const realtype *x, const realtype *p, const realtype *k, const realtype *h) override {} - /** model specific implementation of fsigmay - * @param dsigmaydp partial derivative of standard deviation of measurements - * @param t current time - * @param p parameter vector - * @param k constant vector - * @param ip sensitivity index - **/ - virtual void fdsigmaydp(realtype *dsigmaydp, const realtype t, - const realtype *p, const realtype *k, - const int ip) override { - dsigmaydp_TPL_MODELNAME(dsigmaydp, t, p, k, ip); - } + TPL_DSIGMAYDP_IMPL /** model specific implementation of fsigmaz * @param dsigmazdp partial derivative of standard deviation of event @@ -439,35 +319,9 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_DXDOTDX_EXPLICIT_COLPTRS_IMPL TPL_DXDOTDX_EXPLICIT_ROWVALS_IMPL - /** model specific implementation of fdydx - * @param dydx partial derivative of observables y w.r.t. model states x - * @param t current time - * @param x current state - * @param p parameter vector - * @param k constant vector - * @param h heaviside vector - **/ - virtual void fdydx(realtype *dydx, const realtype t, const realtype *x, - const realtype *p, const realtype *k, const realtype *h, - const realtype *w, const realtype *dwdx) override { - dydx_TPL_MODELNAME(dydx, t, x, p, k, h, w, dwdx); - } + TPL_DYDX_IMPL - /** model specific implementation of fdydp - * @param dydp partial derivative of observables y w.r.t. model parameters p - * @param t current time - * @param x current state - * @param p parameter vector - * @param k constant vector - * @param h heaviside vector - * @param ip parameter index w.r.t. which the derivative is requested - **/ - virtual void fdydp(realtype *dydp, const realtype t, const realtype *x, - const realtype *p, const realtype *k, const realtype *h, - const int ip, const realtype *w, - const realtype *dwdp) override { - dydp_TPL_MODELNAME(dydp, t, x, p, k, h, ip, w, dwdp); - } + TPL_DYDP_IMPL /** model specific implementation of fdzdp * @param dzdp partial derivative of event-resolved output z w.r.t. model @@ -498,19 +352,7 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { const realtype *x, const realtype *p, const realtype *k, const realtype *h) override {} - /** model specific implementation for froot - * @param root values of the trigger function - * @param t timepoint - * @param x Vector with the states - * @param p parameter vector - * @param k constants vector - * @param h heaviside vector - **/ - virtual void froot(realtype *root, const realtype t, const realtype *x, - const realtype *p, const realtype *k, - const realtype *h) override { - root_TPL_MODELNAME(root, t, x, p, k, h); - } + TPL_ROOT_IMPL /** model specific implementation of frz * @param rz value of root function at current timepoint (non-output events @@ -526,16 +368,7 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { const realtype *x, const realtype *p, const realtype *k, const realtype *h) override {} - /** model specific implementation of fsigmay - * @param sigmay standard deviation of measurements - * @param t current time - * @param p parameter vector - * @param k constant vector - **/ - virtual void fsigmay(realtype *sigmay, const realtype t, const realtype *p, - const realtype *k) override { - sigmay_TPL_MODELNAME(sigmay, t, p, k); - } + TPL_SIGMAY_IMPL /** model specific implementation of fsigmaz * @param sigmaz standard deviation of event measurements @@ -562,54 +395,9 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { const realtype *h, const realtype *sx, const int ip) override {} - /** model specific implementation of fstau - * @param stau total derivative of event timepoint - * @param t current time - * @param x current state - * @param p parameter vector - * @param k constant vector - * @param h heaviside vector - * @param sx current state sensitivity - * @param ip sensitivity index - * @param ie event index - **/ - virtual void fstau(realtype *stau, const realtype t, const realtype *x, - const realtype *p, const realtype *k, const realtype *h, - const realtype *sx, const int ip, - const int ie) override { - stau_TPL_MODELNAME(stau, t, x, p, k, h, sx, ip, ie); - } - - /** model specific implementation of fsx0 - * @param sx0 initial state sensitivities - * @param t initial time - * @param x0 initial state - * @param p parameter vector - * @param k constant vector - * @param ip sensitivity index - **/ - virtual void fsx0(realtype *sx0, const realtype t, const realtype *x0, - const realtype *p, const realtype *k, - const int ip) override { - sx0_TPL_MODELNAME(sx0, t, x0, p, k, ip); - } - - /** model specific implementation of fsx0_fixedParameters - * @param sx0 initial state sensitivities - * @param t initial time - * @param x0 initial state - * @param p parameter vector - * @param k constant vector - * @param ip sensitivity index - **/ - virtual void fsx0_fixedParameters(realtype *sx0, const realtype t, - const realtype *x0, const realtype *p, - const realtype *k, - const int ip, - gsl::span reinitialization_state_idxs - ) override { - sx0_fixedParameters_TPL_MODELNAME(sx0, t, x0, p, k, ip, reinitialization_state_idxs); - } + TPL_STAU_IMPL + TPL_SX0_IMPL + TPL_SX0_FIXEDPARAMETERS_IMPL /** model specific implementation of fsz * @param sz Sensitivity of rz, total derivative @@ -629,59 +417,13 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_W_IMPL - /** model specific implementation of fx0 - * @param x0 initial state - * @param t initial time - * @param p parameter vector - * @param k constant vector - **/ - virtual void fx0(realtype *x0, const realtype t, const realtype *p, - const realtype *k) override { - x0_TPL_MODELNAME(x0, t, p, k); - } + TPL_X0_IMPL - /** model specific implementation of fx0_fixedParameters - * @param x0 initial state - * @param t initial time - * @param p parameter vector - * @param k constant vector - **/ - virtual void fx0_fixedParameters(realtype *x0, const realtype t, - const realtype *p, - const realtype *k, - gsl::span reinitialization_state_idxs - ) override { - x0_fixedParameters_TPL_MODELNAME(x0, t, p, k, reinitialization_state_idxs); - } + TPL_X0_FIXEDPARAMETERS_IMPL - /** model specific implementation for fxdot - * @param xdot residual function - * @param t timepoint - * @param x Vector with the states - * @param p parameter vector - * @param k constants vector - * @param h heaviside vector - * @param w vector with helper variables - **/ - virtual void fxdot(realtype *xdot, const realtype t, const realtype *x, - const realtype *p, const realtype *k, const realtype *h, - const realtype *w) override { - xdot_TPL_MODELNAME(xdot, t, x, p, k, h, w); - } + TPL_XDOT_IMPL - /** model specific implementation of fy - * @param y model output at current timepoint - * @param t current time - * @param x current state - * @param p parameter vector - * @param k constant vector - * @param h heaviside vector - **/ - virtual void fy(realtype *y, const realtype t, const realtype *x, - const realtype *p, const realtype *k, const realtype *h, - const realtype *w) override { - y_TPL_MODELNAME(y, t, x, p, k, h, w); - } + TPL_Y_IMPL /** model specific implementation of fz * @param z value of event output @@ -805,18 +547,18 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { } /** - * @brief returns the amici version that was used to generate the model - * @return ver amici version string + * @brief returns the AMICI version that was used to generate the model + * @return AMICI version string */ - virtual const std::string getAmiciVersion() const override { + virtual std::string getAmiciVersion() const override { return "TPL_AMICI_VERSION_STRING"; } /** - & @brief returns the amici version that was used to generate the model - * @return commit amici git commit hash + * @brief returns the amici version that was used to generate the model + * @return AMICI git commit hash */ - virtual const std::string getAmiciCommit() const override { + virtual std::string getAmiciCommit() const override { return "TPL_AMICI_COMMIT_STRING"; } diff --git a/deps/AMICI/src/rdata.cpp b/deps/AMICI/src/rdata.cpp index d369ec7db..df64d76eb 100644 --- a/deps/AMICI/src/rdata.cpp +++ b/deps/AMICI/src/rdata.cpp @@ -11,6 +11,7 @@ #include "amici/symbolic_functions.h" #include +#include namespace amici { @@ -21,8 +22,9 @@ ReturnData::ReturnData(Solver const &solver, const Model &model) solver.getNewtonMaxSteps(), model.getParameterScale(), model.o2mode, solver.getSensitivityOrder(), solver.getSensitivityMethod(), - solver.getReturnDataReportingMode(), model.hasQuadraticLLH()) { -} + solver.getReturnDataReportingMode(), model.hasQuadraticLLH(), + model.getAddSigmaResiduals(), + model.getMinimumSigmaResiduals()) {} ReturnData::ReturnData(std::vector ts, ModelDimensions const& model_dimensions, @@ -31,12 +33,14 @@ ReturnData::ReturnData(std::vector ts, std::vector pscale, SecondOrderMode o2mode, SensitivityOrder sensi, SensitivityMethod sensi_meth, RDataReporting rdrm, - bool quadratic_llh) + bool quadratic_llh, bool sigma_res, + realtype sigma_offset) : ModelDimensions(model_dimensions), ts(std::move(ts)), nx(nx_rdata), nxtrue(nxtrue_rdata), nplist(nplist), nmaxevent(nmaxevent), nt(nt), newton_maxsteps(newton_maxsteps), pscale(std::move(pscale)), o2mode(o2mode), sensi(sensi), - sensi_meth(sensi_meth), rdata_reporting(rdrm), x_solver_(nx_solver), + sensi_meth(sensi_meth), rdata_reporting(rdrm), sigma_res(sigma_res), + sigma_offset(sigma_offset), x_solver_(nx_solver), sx_solver_(nx_solver, nplist), x_rdata_(nx), sx_rdata_(nx, nplist), nroots_(ne) { switch (rdata_reporting) { @@ -72,7 +76,8 @@ void ReturnData::initializeResidualReporting(bool enable_res) { y.resize(nt * ny, 0.0); sigmay.resize(nt * ny, 0.0); if (enable_res) - res.resize(nt * nytrue, 0.0); + res.resize((sigma_res ? 2 : 1) * nt * nytrue, 0.0); + if ((sensi_meth == SensitivityMethod::forward && sensi >= SensitivityOrder::first) || sensi >= SensitivityOrder::second) { @@ -80,7 +85,7 @@ void ReturnData::initializeResidualReporting(bool enable_res) { sy.resize(nt * ny * nplist, 0.0); ssigmay.resize(nt * ny * nplist, 0.0); if (enable_res) - sres.resize(nt * nytrue * nplist, 0.0); + sres.resize((sigma_res ? 2 : 1) * nt * nytrue * nplist, 0.0); } } @@ -293,7 +298,7 @@ void ReturnData::getDataOutput(int it, Model &model, ExpData const *edata) { if (!isNaN(llh)) model.addObservableObjective(llh, it, x_solver_, *edata); fres(it, model, *edata); - fchi2(it); + fchi2(it, *edata); } if (sensi >= SensitivityOrder::first && nplist > 0) { @@ -414,7 +419,7 @@ void ReturnData::processBackwardProblem(ForwardProblem const &fwd, auto xQB = bwd.getAdjointQuadrature(); if (preeq && preeq->hasQuadrature()) { - handleSx0Backward(model, *preeq, xQB); + handleSx0Backward(model, *preeq, llhS0, xQB); } else { handleSx0Forward(model, llhS0, xB); } @@ -433,6 +438,7 @@ void ReturnData::processBackwardProblem(ForwardProblem const &fwd, void ReturnData::handleSx0Backward(const Model &model, SteadystateProblem const &preeq, + std::vector &llhS0, AmiVector &xQB) const { /* If preequilibration is run in adjoint mode, the scalar product of sx0 with its adjoint counterpart (see handleSx0Forward()) is not necessary: @@ -441,9 +447,23 @@ void ReturnData::handleSx0Backward(const Model &model, and so is the scalar product. Instead of the scalar product, the quadratures xQB from preequilibration contribute to the gradient (see example notebook on equilibration for further documentation). */ - auto xQBpreeq = preeq.getAdjointQuadrature(); + const auto &xQBpreeq = preeq.getAdjointQuadrature(); for (int ip = 0; ip < model.nplist(); ++ip) - xQB[ip] += xQBpreeq[ip]; + xQB[ip] += xQBpreeq.at(ip); + + /* We really need references here, as sx0 can be large... */ + const auto& sx0preeq = preeq.getStateSensitivity(); + const auto& xBpreeq = preeq.getAdjointState(); + + /* Add the contribution for sx0 from preequilibration. If backward + * preequilibration was done by simulation due to a singular Jacobian, + * xB is not necessarily 0 and we may get a non-zero contribution here. */ + for (int ip = 0; ip < model.nplist(); ++ip) { + llhS0[ip] = 0.0; + for (int ix = 0; ix < model.nxtrue_solver; ++ix) { + llhS0[ip] += xBpreeq.at(ix) * sx0preeq.at(ix, ip); + } + } } void ReturnData::handleSx0Forward(const Model &model, @@ -477,26 +497,58 @@ void ReturnData::handleSx0Forward(const Model &model, void ReturnData::processSolver(Solver const &solver) { cpu_time = solver.getCpuTime(); - if (!numsteps.empty()) - numsteps = solver.getNumSteps(); - if (!numrhsevals.empty()) - numrhsevals = solver.getNumRhsEvals(); - if (!numerrtestfails.empty()) - numerrtestfails = solver.getNumErrTestFails(); - if (!numnonlinsolvconvfails.empty()) - numnonlinsolvconvfails = solver.getNumNonlinSolvConvFails(); - if (!order.empty()) - order = solver.getLastOrder(); + + const std::vector *tmp; + + if (!numsteps.empty()) { + tmp = &solver.getNumSteps(); + // copy_n instead of assignment to ensure length `nt` + // (vector from solver may be shorter in case of integration errors) + std::copy_n(tmp->cbegin(), tmp->size(), numsteps.begin()); + } + + if (!numsteps.empty()) { + tmp = &solver.getNumRhsEvals(); + std::copy_n(tmp->cbegin(), tmp->size(), numrhsevals.begin()); + } + + if (!numerrtestfails.empty()) { + tmp = &solver.getNumErrTestFails(); + std::copy_n(tmp->cbegin(), tmp->size(), numerrtestfails.begin()); + } + + if (!numnonlinsolvconvfails.empty()) { + tmp = &solver.getNumNonlinSolvConvFails(); + std::copy_n(tmp->cbegin(), tmp->size(), numnonlinsolvconvfails.begin()); + } + + if (!order.empty()) { + tmp = &solver.getLastOrder(); + std::copy_n(tmp->cbegin(), tmp->size(), order.begin()); + } cpu_timeB = solver.getCpuTimeB(); - if (!numstepsB.empty()) - numstepsB = solver.getNumStepsB(); - if (!numrhsevalsB.empty()) - numrhsevalsB = solver.getNumRhsEvalsB(); - if (!numerrtestfailsB.empty()) - numerrtestfailsB = solver.getNumErrTestFailsB(); - if (!numnonlinsolvconvfailsB.empty()) - numnonlinsolvconvfailsB = solver.getNumNonlinSolvConvFailsB(); + + if (!numstepsB.empty()) { + tmp = &solver.getNumStepsB(); + std::copy_n(tmp->cbegin(), tmp->size(), numstepsB.begin()); + } + + if (!numrhsevalsB.empty()) { + tmp = &solver.getNumRhsEvalsB(); + std::copy_n(tmp->cbegin(), tmp->size(), numrhsevalsB.begin()); + } + + if (!numerrtestfailsB.empty()) { + tmp = &solver.getNumErrTestFailsB(); + std::copy_n(tmp->cbegin(), tmp->size(), numerrtestfailsB.begin()); + } + + if (!numnonlinsolvconvfailsB.empty()) { + tmp = &solver.getNumNonlinSolvConvFailsB(); + std::copy_n(tmp->cbegin(), tmp->size(), + numnonlinsolvconvfailsB.begin()); + } } void ReturnData::readSimulationState(SimulationState const &state, @@ -617,9 +669,10 @@ void ReturnData::applyChainRuleFactorToSimulationResults(const Model &model) { if (!sres.empty()) - for (int iyt = 0; iyt < nytrue * nt; ++iyt) + for (int ires = 0; ires < static_cast(res.size()); ++ires) for (int ip = 0; ip < nplist; ++ip) - sres.at((iyt * nplist + ip)) *= pcoefficient.at(ip); + sres.at((ires * nplist + ip)) *= pcoefficient.at(ip); + if(!FIM.empty()) for (int ip = 0; ip < nplist; ++ip) @@ -728,9 +781,8 @@ static realtype fres(realtype y, realtype my, realtype sigma_y) { return (y - my) / sigma_y; } -static realtype fsres(realtype y, realtype sy, realtype my, - realtype sigma_y, realtype ssigma_y) { - return (sy - ssigma_y * fres(y, my, sigma_y)) / sigma_y; +static realtype fres_error(realtype sigma_y, realtype sigma_offset) { + return sqrt(2*log(sigma_y) + sigma_offset); } void ReturnData::fres(const int it, Model &model, const ExpData &edata) { @@ -750,19 +802,35 @@ void ReturnData::fres(const int it, Model &model, const ExpData &edata) { continue; res.at(iyt) = amici::fres(y_it.at(iy), observedData[iy], sigmay_it.at(iy)); + if (sigma_res) + res.at(iyt + nt * nytrue) = fres_error(sigmay_it.at(iy), + sigma_offset); } } -void ReturnData::fchi2(const int it) { +void ReturnData::fchi2(const int it, const ExpData &edata) { if (res.empty() || isNaN(chi2)) return; for (int iy = 0; iy < nytrue; ++iy) { int iyt_true = iy + it * nytrue; chi2 += pow(res.at(iyt_true), 2); + if (sigma_res && edata.isSetObservedData(it, iy)) + chi2 += pow(res.at(iyt_true + nt * nytrue), 2) - sigma_offset; } } +static realtype fsres(realtype y, realtype sy, realtype my, + realtype sigma_y, realtype ssigma_y) { + return (sy - ssigma_y * fres(y, my, sigma_y)) / sigma_y; +} + +static realtype fsres_error(realtype sigma_y, realtype ssigma_y, + realtype sigma_offset) { + return ssigma_y / ( fres_error(sigma_y, sigma_offset) * sigma_y); +} + + void ReturnData::fsres(const int it, Model &model, const ExpData &edata) { if (sres.empty()) return; @@ -786,6 +854,14 @@ void ReturnData::fsres(const int it, Model &model, const ExpData &edata) { sres.at(idx) = amici::fsres(y_it.at(iy), sy_it.at(iy + ny * ip), observedData[iy], sigmay_it.at(iy), ssigmay_it.at(iy + ny * ip)); + if (sigma_res) { + int idx_res = + (iy + it * edata.nytrue() + edata.nytrue() * edata.nt()) * + nplist + ip; + sres.at(idx_res) = amici::fsres_error(sigmay_it.at(iy), + ssigmay_it.at(iy + ny * ip), + sigma_offset); + } } } } @@ -805,17 +881,19 @@ void ReturnData::fFIM(int it, Model &model, const ExpData &edata) { model.getObservableSigmaSensitivity(ssigmay_it, it, &edata); /* - * https://www.wolframalpha.com/input/?i=d%2Fdu+d%2Fdv+0.5*log%282+*+pi+*+s%28u%2Cv%29%5E2%29+%2B+0.5+*+%28%28y%28u%2Cv%29+-+m%29%2Fs%28u%2Cv%29%29%5E2 - * r = (m - y) - * d/du(d/(dv)(0.5 log(2 π s^2) + 0.5 ((y - m)/s)^2)) = - * (-s_du*y_dv*r + 2*s_dv*y_du*r - s_du_dv*r^2 - - * 222222222222 2222222222222 *********** + * https://www.wolframalpha.com/input/?i=d%2Fdu+d%2Fdv+log%28s%28u%2Cv%29%29+%2B+0.5+*+%28r%28u%2Cv%29%2Fs%28u%2Cv%29%29%5E2 + * r = (y - m) + * r_du = y_du + * d/du(d/(dv)(log(s) + 0.5 (r/s)^2)) = + * -(2*y_du*s_dv)*r/s^3 - (2*y_dv*s_du)*r/s^3 + y_du_dv*r/s^2 + * 22222222222222222222 2222222222222222222 ############# + * + * + (y_dv*y_du)/s^2 + (3*s_dv*s_du)*r^2/s^4 - s_du_dv*r^2/s^3 + * 111111111111111 333333333333333333333 *************** * - * s*y_du_dv*r + s_du_dv*s^2 + 2*s_dv*s_du*s + s*y_dv*y_du)/s^3 - - * ########### +++++++++++ ------------- 11111111111 + * - (s_dv*s_du)/s^2 + (s_du_dv)/s + * +++++++++++ * - * (3*s_du*(-s_dv*r^2 - s*y_dv*r + s_dv*s^2))/s^4 - * 333333333 22222222 -------- * * we compute this using fsres: * sres_u * sres_v = (y_du*s - s_du * r) * (y_dv*s - s_dv * r) / s^4 @@ -824,15 +902,35 @@ void ReturnData::fFIM(int it, Model &model, const ExpData &edata) { * * r should be on the same order as s. We keep 1/s^2 and drop 1/s terms. * drop: - * ********: r^2/s^3 term - * ########: r/s^2 term + * ********: r^2/s^3 term, typically zero anyways + * ########: r/s^2 term, requires second order sensitivities * ++++++++: 1/s term, typically zero anyways * * keep: - * ---------: accounts for .5(2*pi*sigma^2) - * 123123123: accounted for by sres*sres, but - * -3*(s_dv*y_du + s_du*y_dv)*r/s^3 is missing from 2222 and - * -2*s_du*s_dv*r^2/s^4 is missing from 3333 + * 123123123: accounted for by sres*sres, + * but + * - (s_dv*s_du)/s^2 is unaccounted for and + * - (s_dv*y_du + s_du*y_dv)*r/s^3 is missing from 2222 and + * + 2*(s_du*s_dv)*r^2/s^4 is missing from 3333 + * + * s_dv*y_du and s_du*y_dv are usually zero since we do not have parameters + * that affect both observables and sigmas. Accordingly, it is hard to know + * emprically whether these terms are important or not. + * + * This leaves us with + * + (s_du*s_dv)(2*r^2-s^2)/s^4 + * which may be problematic, since this expression does not factorise and + * may thus introduce directions of negative curvature. + * + * For the least squares trick, where error residuals + * er = sqrt(log(s) + c), with sensitivity er_du = s_du/(2*s*er). This + * would yield terms (s_du*s_dv)*(s^2/(4*er^2))/s^4. + * These terms are guaranteed to yield positive curvature, but go to zero + * in the limit c -> Infty. + * + * Empirically, simply taking this limit and dropping all missing terms, + * works substantially better. This was evaluated using the fides optimizer + * on the Boehm2014 Benchmark example. */ auto observedData = edata.getObservedDataPtr(it); @@ -843,16 +941,24 @@ void ReturnData::fFIM(int it, Model &model, const ExpData &edata) { auto y = y_it.at(iy); auto m = observedData[iy]; auto s = sigmay_it.at(iy); + // auto r = amici::fres(y, m, s); for (int ip = 0; ip < nplist; ++ip) { auto dy_i = sy_it.at(iy + ny * ip); auto ds_i = ssigmay_it.at(iy + ny * ip); + auto sr_i = amici::fsres(y, dy_i, m, s, ds_i); + realtype sre_i = 0.0; + if (sigma_res) + sre_i = amici::fsres_error(s, ds_i, sigma_offset); for (int jp = 0; jp < nplist; ++jp) { auto dy_j = sy_it.at(iy + ny * jp); auto ds_j = ssigmay_it.at(iy + ny * jp); - FIM.at(ip + nplist * jp) += - amici::fsres(y, dy_i, m, s, ds_i) * - amici::fsres(y, dy_j, m, s, ds_j) - - ds_i * ds_j / pow(s, 2.0); + auto sr_j = amici::fsres(y, dy_j, m, s, ds_j); + FIM.at(ip + nplist * jp) += sr_i*sr_j; + if (sigma_res) { + auto sre_j = amici::fsres_error(s, ds_j, sigma_offset); + FIM.at(ip + nplist * jp) += sre_i * sre_j; + } + /*+ ds_i*ds_j*(2*pow(r/pow(s,2.0), 2.0) - 1/pow(s,2.0));*/ } } } diff --git a/deps/AMICI/src/returndata_matlab.cpp b/deps/AMICI/src/returndata_matlab.cpp index 58fe9cf68..0a1d79961 100644 --- a/deps/AMICI/src/returndata_matlab.cpp +++ b/deps/AMICI/src/returndata_matlab.cpp @@ -46,7 +46,7 @@ mxArray *initMatlabReturnFields(ReturnData const *rdata) { writeMatlabField0(matlabSolutionStruct, "status", rdata->status); - writeMatlabField1(matlabSolutionStruct, "t", rdata->ts, rdata->nt); + writeMatlabField1(matlabSolutionStruct, "t", gsl::make_span(rdata->ts), rdata->nt); writeMatlabField0(matlabSolutionStruct, "llh", rdata->llh); writeMatlabField0(matlabSolutionStruct, "chi2", rdata->chi2); @@ -64,7 +64,7 @@ mxArray *initMatlabReturnFields(ReturnData const *rdata) { writeMatlabField2(matlabSolutionStruct, "sigmay", rdata->sigmay, rdata->nt, rdata->ny, perm1); } if (rdata->sensi >= SensitivityOrder::first) { - writeMatlabField1(matlabSolutionStruct, "sllh", rdata->sllh, rdata->nplist); + writeMatlabField1(matlabSolutionStruct, "sllh", gsl::make_span(rdata->sllh), rdata->nplist); writeMatlabField2(matlabSolutionStruct, "sx0", rdata->sx0, rdata->nplist, rdata->nx, perm0); if (rdata->sensi_meth == SensitivityMethod::forward) { @@ -141,18 +141,33 @@ mxArray *initMatlabDiagnosisFields(ReturnData const *rdata) { if (!std::isinf(rdata->ts[it])) finite_nt++; - writeMatlabField1(matlabDiagnosisStruct, "numsteps", rdata->numsteps, finite_nt); - writeMatlabField1(matlabDiagnosisStruct, "numrhsevals", rdata->numrhsevals, finite_nt); - writeMatlabField1(matlabDiagnosisStruct, "numerrtestfails", rdata->numerrtestfails, finite_nt); - writeMatlabField1(matlabDiagnosisStruct, "numnonlinsolvconvfails", rdata->numnonlinsolvconvfails, finite_nt); - writeMatlabField1(matlabDiagnosisStruct, "order", rdata->order, finite_nt); + writeMatlabField1( + matlabDiagnosisStruct, "numsteps", + gsl::make_span(rdata->numsteps).subspan(0, finite_nt), + finite_nt); + writeMatlabField1( + matlabDiagnosisStruct, "numrhsevals", + gsl::make_span(rdata->numrhsevals).subspan(0, finite_nt), + finite_nt); + writeMatlabField1( + matlabDiagnosisStruct, "numerrtestfails", + gsl::make_span(rdata->numerrtestfails).subspan(0, finite_nt), + finite_nt); + writeMatlabField1( + matlabDiagnosisStruct, "numnonlinsolvconvfails", + gsl::make_span(rdata->numnonlinsolvconvfails).subspan(0, finite_nt), + finite_nt); + writeMatlabField1( + matlabDiagnosisStruct, "order", + gsl::make_span(rdata->order).subspan(0, finite_nt), + finite_nt); if (rdata->nx > 0) { - writeMatlabField1(matlabDiagnosisStruct, "xdot", rdata->xdot, rdata->nx_solver); + writeMatlabField1(matlabDiagnosisStruct, "xdot", gsl::make_span(rdata->xdot), rdata->nx_solver); writeMatlabField2(matlabDiagnosisStruct, "J", rdata->J, rdata->nx_solver, rdata->nx_solver, perm1); - writeMatlabField1(matlabDiagnosisStruct, "preeq_status", rdata->preeq_status, 3); - writeMatlabField1(matlabDiagnosisStruct, "preeq_numsteps", rdata->preeq_numsteps, 3); + writeMatlabField1(matlabDiagnosisStruct, "preeq_status", gsl::make_span(rdata->preeq_status), 3); + writeMatlabField1(matlabDiagnosisStruct, "preeq_numsteps", gsl::make_span(rdata->preeq_numsteps), 3); writeMatlabField2(matlabDiagnosisStruct, "preeq_numlinsteps", rdata->preeq_numlinsteps, rdata->preeq_numlinsteps.size() > 0 @@ -163,8 +178,8 @@ mxArray *initMatlabDiagnosisFields(ReturnData const *rdata) { writeMatlabField0(matlabDiagnosisStruct, "preeq_t", rdata->preeq_t); writeMatlabField0(matlabDiagnosisStruct, "preeq_wrms", rdata->preeq_wrms); - writeMatlabField1(matlabDiagnosisStruct, "posteq_status", rdata->posteq_status, 3); - writeMatlabField1(matlabDiagnosisStruct, "posteq_numsteps", rdata->posteq_numsteps, 3); + writeMatlabField1(matlabDiagnosisStruct, "posteq_status", gsl::make_span(rdata->posteq_status), 3); + writeMatlabField1(matlabDiagnosisStruct, "posteq_numsteps", gsl::make_span(rdata->posteq_numsteps), 3); writeMatlabField2(matlabDiagnosisStruct, "posteq_numlinsteps", rdata->posteq_numlinsteps, rdata->posteq_numlinsteps.size() > 0 @@ -177,10 +192,23 @@ mxArray *initMatlabDiagnosisFields(ReturnData const *rdata) { } if (rdata->sensi >= SensitivityOrder::first) { if (rdata->sensi_meth == SensitivityMethod::adjoint) { - writeMatlabField1(matlabDiagnosisStruct, "numstepsB", rdata->numstepsB, finite_nt); - writeMatlabField1(matlabDiagnosisStruct, "numrhsevalsB", rdata->numrhsevalsB, finite_nt); - writeMatlabField1(matlabDiagnosisStruct, "numerrtestfailsB", rdata->numerrtestfailsB, finite_nt); - writeMatlabField1(matlabDiagnosisStruct, "numnonlinsolvconvfailsB", rdata->numnonlinsolvconvfailsB, finite_nt); + writeMatlabField1( + matlabDiagnosisStruct, "numstepsB", + gsl::make_span(rdata->numstepsB).subspan(0, finite_nt), + finite_nt); + writeMatlabField1( + matlabDiagnosisStruct, "numrhsevalsB", + gsl::make_span(rdata->numrhsevalsB).subspan(0, finite_nt), + finite_nt); + writeMatlabField1( + matlabDiagnosisStruct, "numerrtestfailsB", + gsl::make_span(rdata->numerrtestfailsB).subspan(0, finite_nt), + finite_nt); + writeMatlabField1( + matlabDiagnosisStruct, "numnonlinsolvconvfailsB", + gsl::make_span(rdata->numnonlinsolvconvfailsB + ).subspan(0, finite_nt), + finite_nt); } } @@ -201,16 +229,19 @@ void writeMatlabField0(mxArray *matlabStruct, const char *fieldName, template void writeMatlabField1(mxArray *matlabStruct, const char *fieldName, - std::vector const& fieldData, int dim0) { + gsl::span const& fieldData, int dim0) { if(fieldData.size() != dim0) - throw AmiException("Dimension mismatch when writing rdata->%s to matlab results",fieldName); + throw AmiException("Dimension mismatch when writing rdata->%s to " + "matlab results (expected %d, got %d)", + fieldName, dim0, static_cast(fieldData.size())); std::vector dim = {(mwSize)(dim0), (mwSize)(1)}; double *array = initAndAttachArray(matlabStruct, fieldName, dim); + auto data_ptr = fieldData.data(); for(int i = 0; i < dim0; i++) - array[i] = static_cast(fieldData[i]); + array[i] = static_cast(data_ptr[i]); } template diff --git a/deps/AMICI/src/steadystateproblem.cpp b/deps/AMICI/src/steadystateproblem.cpp index f2f4c91a9..969c5723f 100644 --- a/deps/AMICI/src/steadystateproblem.cpp +++ b/deps/AMICI/src/steadystateproblem.cpp @@ -101,9 +101,6 @@ void SteadystateProblem::workSteadyStateBackwardProblem(Solver *solver, clock_t starttime = clock(); computeSteadyStateQuadrature(newtonSolver.get(), solver, model); cpu_timeB_ = (double)((clock() - starttime) * 1000) / CLOCKS_PER_SEC; - - /* Finalize by setting adjoint state to zero (its steady state) */ - xB_.zero(); } void SteadystateProblem::findSteadyState(Solver *solver, @@ -285,6 +282,9 @@ void SteadystateProblem::getQuadratureByLinSolve(NewtonSolver *newtonSolver, computeQBfromQ(model, xQ_, xQB_); /* set flag that quadratures is available (for processing in rdata) */ hasQuadrature_ = true; + + /* Finalize by setting adjoint state to zero (its steady state) */ + xB_.zero(); } catch (NewtonFailure const &) { hasQuadrature_ = false; } @@ -374,6 +374,10 @@ bool SteadystateProblem::getSensitivityFlag(const Model *model, steady_state_status_[1] == SteadyStateStatus::success && model->getSteadyStateSensitivityMode() == SteadyStateSensitivityMode::simulationFSA; + bool simulationStartedInSteadystate = + steady_state_status_[0] == SteadyStateStatus::success && + numsteps_[0] == 0; + /* Do we need forward sensis for postequilibration? */ bool needForwardSensisPosteq = !preequilibration && !forwardSensisAlreadyComputed && @@ -388,7 +392,8 @@ bool SteadystateProblem::getSensitivityFlag(const Model *model, /* Do we need to do the linear system solve to get forward sensitivities? */ bool needForwardSensisNewton = - needForwardSensisPreeq || needForwardSensisPosteq; + (needForwardSensisPreeq || needForwardSensisPosteq) && + !simulationStartedInSteadystate; /* When we're creating a new solver object */ bool needForwardSensiAtCreation = needForwardSensisPreeq && @@ -400,7 +405,9 @@ bool SteadystateProblem::getSensitivityFlag(const Model *model, return needForwardSensisNewton; case SteadyStateContext::sensiStorage: - return needForwardSensisNewton || forwardSensisAlreadyComputed; + return needForwardSensisNewton || + forwardSensisAlreadyComputed || + simulationStartedInSteadystate; case SteadyStateContext::solverCreation: return needForwardSensiAtCreation; diff --git a/deps/AMICI/src/sundials_matrix_wrapper.cpp b/deps/AMICI/src/sundials_matrix_wrapper.cpp index 21d690e73..4e080958c 100644 --- a/deps/AMICI/src/sundials_matrix_wrapper.cpp +++ b/deps/AMICI/src/sundials_matrix_wrapper.cpp @@ -629,14 +629,15 @@ void SUNMatrixWrapper::transpose(SUNMatrixWrapper &C, const realtype alpha, if (!matrix_ || !C.matrix_) return; - if (!((C.matrix_id() == SUNMATRIX_SPARSE && C.sparsetype() == CSC_MAT) - || C.matrix_id() == SUNMATRIX_DENSE)) + auto C_matrix_id = C.matrix_id(); + if (!((C_matrix_id == SUNMATRIX_SPARSE && C.sparsetype() == CSC_MAT) + || C_matrix_id == SUNMATRIX_DENSE)) throw std::domain_error("Not Implemented."); check_csc(this); assert(rows() == C.rows()); assert(columns() == C.columns()); - if (C.matrix_id() == SUNMATRIX_SPARSE) { + if (C_matrix_id == SUNMATRIX_SPARSE) { if (!C.capacity() && num_nonzeros()) C.reallocate(num_nonzeros()); assert(C.capacity() >= num_nonzeros()); @@ -651,40 +652,38 @@ void SUNMatrixWrapper::transpose(SUNMatrixWrapper &C, const realtype alpha, // see https://github.com/DrTimothyAldenDavis/SuiteSparse/blob/master/CSparse/Source/cs_transpose.c - sunindextype aidx; - sunindextype cidx; - sunindextype acol; - std::vector w; - - sunindextype ccol; - sunindextype crow; - sunindextype widx; - - if (C.matrix_id()== SUNMATRIX_SPARSE) { + auto nrows = rows(); + if (C_matrix_id == SUNMATRIX_SPARSE) { w = std::vector(columns()); - for (acol = 0; acol < rows(); acol++) /* row counts */ - for (aidx = get_indexptr(acol); - aidx < get_indexptr(acol+1); aidx++) { - widx = (acol/blocksize)*blocksize + get_indexval(aidx) % blocksize; - w.at(widx)++; - assert(w[widx] <= rows()); + for (sunindextype acol = 0; acol < nrows; acol++) { /* row counts */ + auto next_indexptr = get_indexptr(acol+1); + for (sunindextype aidx = get_indexptr(acol); + aidx < next_indexptr; aidx++) { + sunindextype widx = (acol/blocksize)*blocksize + get_indexval(aidx) % blocksize; + assert(widx >= 0 && widx < (sunindextype)w.size()); + w[widx]++; + assert(w[widx] <= nrows); } + } /* row pointers */ cumsum(gsl::make_span(C.indexptrs_, C.columns()+1), w); } - for (acol = 0; acol < rows(); acol++) + for (sunindextype acol = 0; acol < nrows; acol++) { - for (aidx = get_indexptr(acol); aidx < get_indexptr(acol+1); aidx++) + auto next_indexptr = get_indexptr(acol+1); + + for (sunindextype aidx = get_indexptr(acol); aidx < next_indexptr; aidx++) { - ccol = (acol/blocksize)*blocksize + get_indexval(aidx) % blocksize; - crow = (get_indexval(aidx)/blocksize)*blocksize + acol % blocksize; - assert(crow < rows()); + sunindextype ccol = (acol/blocksize)*blocksize + get_indexval(aidx) % blocksize; + sunindextype crow = (get_indexval(aidx)/blocksize)*blocksize + acol % blocksize; + assert(crow < nrows); assert(ccol < columns()); - if (C.matrix_id() == SUNMATRIX_SPARSE) { + if (C_matrix_id == SUNMATRIX_SPARSE) { assert(aidx < capacity()); - cidx = w.at(ccol)++; + assert(ccol >= 0 && ccol < (sunindextype)w.size()); + sunindextype cidx = w[ccol]++; C.set_indexval(cidx, crow); /* place A(i,j) as entry C(j,i) */ C.set_data(cidx, alpha * get_data(aidx)); } else { diff --git a/deps/AMICI/tests/benchmark-models/benchmark_models.yaml b/deps/AMICI/tests/benchmark-models/benchmark_models.yaml index ed89cb252..d290171e8 100644 --- a/deps/AMICI/tests/benchmark-models/benchmark_models.yaml +++ b/deps/AMICI/tests/benchmark-models/benchmark_models.yaml @@ -5,7 +5,9 @@ Bachmann_MSB2011: Becker_Science2010: llh: -364.118614198023 -#Beer_MolBioSystems2014 None +Beer_MolBioSystems2014: + llh: 58622.9145631413 + note: benchmark collection reference parameters do not match petab, but reference llh has been confirmed for parameters reported there up to sign Boehm_JProteomeRes2014: llh: -138.22199693517703 @@ -16,8 +18,7 @@ Borghans_BiophysChem1997: note: benchmark collection reference value matches up to sign when applying log10-correction +sum(log(meas*log(10)) / 2 Brannmark_JBC2010: - llh: 283.778227541074 - note: unchecked + llh: -141.889113770537 #Bruno_JExpBio2016: None @@ -26,7 +27,7 @@ Chen_MSB2009: note: benchmark collection reference ignores factor 1/2 Crauste_CellSystems2017: - llh: 190.96398465243203 + llh: -190.96521897435176 note: benchmark collection only reports chi2 value, but llh value can be derived Elowitz_Nature2000: @@ -34,8 +35,7 @@ Elowitz_Nature2000: note: benchmark collection reference value matches up to sign when applying log10-correction +sum(log(meas*log(10))) / 2 Fiedler_BMC2016: - llh: -117.16780323362 - note: unchecked + llh: 58.58390161681 Fujita_SciSignal2010: llh: 53.08749124997969 diff --git a/deps/AMICI/tests/benchmark-models/test_benchmark_collection.sh b/deps/AMICI/tests/benchmark-models/test_benchmark_collection.sh index 6f14a8dd6..0422dd3e2 100755 --- a/deps/AMICI/tests/benchmark-models/test_benchmark_collection.sh +++ b/deps/AMICI/tests/benchmark-models/test_benchmark_collection.sh @@ -7,14 +7,18 @@ # Confirmed to be working models=" +Beer_MolBioSystems2014 Boehm_JProteomeRes2014 Borghans_BiophysChem1997 +Brannmark_JBC2010 +Crauste_CellSystems2017 Elowitz_Nature2000 -Schwen_PONE2014 +Fiedler_BMC2016 Fujita_SciSignal2010 +Schwen_PONE2014 Sneyd_PNAS2002 -Zheng_PNAS2012 -Weber_BMC2015" +Weber_BMC2015 +Zheng_PNAS2012" # # Not matching reference for unclear reasons @@ -28,20 +32,12 @@ Weber_BMC2015" # # no reference value: # Alkan_SciSignal2018 -# Beer_MolBioSystems2014 # Blasi_CellSystems2016 -# Crauste_CellSystems2017 # Hass_PONE2017 # Korkut_eLIFE2015 # Perelson_Science1996 # Bruno_JExpBio2016 # -# Timepoint-specific parameter overrides -# Fiedler_BMC2016 -# Brannmark_JBC2010 -# Isensee_JCB2018 -# Sobotta_Frontiers2017 -# # yaml missing: # Casaletto_PNAS2019 # @@ -59,6 +55,9 @@ Weber_BMC2015" # # Evaluation is known to be inconsistent: # Chen_MSB2009 +# +# Integration Failure: +# Isensee_JCB2018 set -e @@ -91,7 +90,7 @@ for model in $models; do yaml="${model_dir}"/"${model}"/"${model}".yaml amici_model_dir=test_bmc/"${model}" mkdir -p "$amici_model_dir" - cmd_import="amici_import_petab --verbose -y ${yaml} -o ${amici_model_dir} -n ${model}" + cmd_import="amici_import_petab --verbose -y ${yaml} -o ${amici_model_dir} -n ${model} --flatten" cmd_run="$script_path/test_petab_model.py --verbose -y ${yaml} -d ${amici_model_dir} -m ${model} -c" printf '=%.0s' {1..40} diff --git a/deps/AMICI/tests/benchmark-models/test_petab_model.py b/deps/AMICI/tests/benchmark-models/test_petab_model.py index 370b38df6..692a7aadd 100755 --- a/deps/AMICI/tests/benchmark-models/test_petab_model.py +++ b/deps/AMICI/tests/benchmark-models/test_petab_model.py @@ -75,6 +75,7 @@ def main(): # load PEtab files problem = petab.Problem.from_yaml(args.yaml_file_name) + petab.flatten_timepoint_specific_output_overrides(problem) # load model if args.model_directory: diff --git a/deps/AMICI/tests/conftest.py b/deps/AMICI/tests/conftest.py index e6e186535..89eb1342d 100644 --- a/deps/AMICI/tests/conftest.py +++ b/deps/AMICI/tests/conftest.py @@ -75,13 +75,21 @@ def pytest_sessionfinish(session, exitstatus): def write_passed_tags(passed_ids, out=sys.stdout): """Write tags of passed SBML semantic test cases""" - passed_tags = set() + passed_component_tags = set() + passed_test_tags = set() + from testSBMLSuite import get_tags_for_test for test_id in passed_ids: - passed_tags |= get_tags_for_test(test_id) - - out.write("At least one test with the following tags has passed:\n") - out.write(' ' + '\n '.join(passed_tags)) + cur_component_tags, cur_test_tags = get_tags_for_test(test_id) + passed_component_tags |= cur_component_tags + passed_test_tags |= cur_test_tags + + out.write("\nAt least one test with the following component tags has " + "passed:\n") + out.write(' ' + '\n '.join(sorted(passed_component_tags))) + out.write("\n\nAt least one test with the following test tags has " + "passed:\n") + out.write(' ' + '\n '.join(sorted(passed_test_tags))) def pytest_runtest_logreport(report: "TestReport") -> None: diff --git a/deps/AMICI/tests/cpputest/expectedResults.h5 b/deps/AMICI/tests/cpputest/expectedResults.h5 index 8d993ab2c..3525c1b4b 100644 Binary files a/deps/AMICI/tests/cpputest/expectedResults.h5 and b/deps/AMICI/tests/cpputest/expectedResults.h5 differ diff --git a/deps/AMICI/tests/cpputest/testOptions.h5 b/deps/AMICI/tests/cpputest/testOptions.h5 index 8a4df7a3e..e2bf3f658 100644 Binary files a/deps/AMICI/tests/cpputest/testOptions.h5 and b/deps/AMICI/tests/cpputest/testOptions.h5 differ diff --git a/deps/AMICI/tests/cpputest/testfunctions.cpp b/deps/AMICI/tests/cpputest/testfunctions.cpp index 3a997392e..382e7fa43 100644 --- a/deps/AMICI/tests/cpputest/testfunctions.cpp +++ b/deps/AMICI/tests/cpputest/testfunctions.cpp @@ -38,7 +38,7 @@ void simulateVerifyWrite(const std::string& path) void simulateVerifyWrite(const std::string &path, double atol, double rtol) { - simulateVerifyWrite(NEW_OPTION_FILE, HDFFILE, HDFFILEWRITE, std::move(path), atol, rtol); + simulateVerifyWrite(NEW_OPTION_FILE, HDFFILE, HDFFILEWRITE, path, atol, rtol); } void simulateWithDefaultOptions() { @@ -73,7 +73,7 @@ void simulateVerifyWrite(const std::string& hdffileOptions, const std::string& h // write // delete destination group - H5::H5File in(hdffileOptions, H5F_ACC_RDONLY); + H5::H5File in(hdffileOptions.c_str(), H5F_ACC_RDONLY); auto out = amici::hdf5::createOrOpenForWriting(hdffilewrite); if(hdf5::locationExists(out, path)) H5Ldelete(out.getId(), path.c_str(), H5P_DEFAULT); @@ -169,7 +169,7 @@ void verifyReturnData(std::string const& hdffile, std::string const& resultPath, } // compare to saved data in hdf file - H5::H5File file(hdffile, H5F_ACC_RDONLY); + H5::H5File file(hdffile.c_str(), H5F_ACC_RDONLY); hsize_t m, n; diff --git a/deps/AMICI/tests/cpputest/unittests/tests1.cpp b/deps/AMICI/tests/cpputest/unittests/tests1.cpp index a0b487c17..869c6dc9f 100644 --- a/deps/AMICI/tests/cpputest/unittests/tests1.cpp +++ b/deps/AMICI/tests/cpputest/unittests/tests1.cpp @@ -20,7 +20,7 @@ namespace generic_model { std::unique_ptr getModel() { - return std::unique_ptr(new amici::Model_Test()); + return std::make_unique(); } } // namespace generic_model @@ -82,10 +82,6 @@ TEST_GROUP(model) z2event); std::vector unscaled{ NAN }; - - void setup() {} - - void teardown() {} }; TEST(model, testScalingLin) @@ -178,13 +174,7 @@ TEST(model, reinitializeFixedParameterInitialStates) AmiVectorArray sx(model.np(), nx); } -TEST_GROUP(symbolicFunctions){ void setup(){ - -} - - void teardown(){ - - } }; +TEST_GROUP(symbolicFunctions){}; TEST(symbolicFunctions, testSign) { @@ -240,13 +230,7 @@ TEST(symbolicFunctions, testpos_pow) CHECK_EQUAL(pow(0.1, 3), amici::pos_pow(0.1, 3)); } -TEST_GROUP(amiciSolver){ void setup(){ - -} - - void teardown(){ - - } }; +TEST_GROUP(amiciSolver){ }; TEST(amiciSolver, testEquality) { @@ -270,13 +254,7 @@ TEST(amiciSolver, testClone) CHECK_FALSE(*i2 == *c2); } -TEST_GROUP(amiciSolverIdas){ void setup(){ - -} - - void teardown(){ - - } }; +TEST_GROUP(amiciSolverIdas){}; TEST(amiciSolverIdas, testConstructionDestruction) { @@ -323,7 +301,7 @@ TEST_GROUP(edata) SecondOrderMode::none, std::vector(), std::vector()); - void setup() + void setup() override { model->setTimepoints(timepoints); model->setNMaxEvent(nmaxevent); @@ -331,7 +309,7 @@ TEST_GROUP(edata) testModel.setNMaxEvent(nmaxevent); } - void teardown() {} + void teardown() override {} }; TEST(edata, testConstructors1) @@ -792,10 +770,6 @@ TEST_GROUP(amivector) std::vector vec1{ 1, 2, 4, 3 }; std::vector vec2{ 4, 1, 2, 3 }; std::vector vec3{ 4, 4, 2, 1 }; - - void setup() {} - - void teardown() {} }; TEST(amivector, vector) @@ -836,7 +810,7 @@ TEST_GROUP(sunmatrixwrapper) // result std::vector d{1.3753, 1.5084, 1.1655}; - void setup() { + void setup() override { A.set_data(0, 0, 0.69); A.set_data(1, 0, 0.32); A.set_data(2, 0, 0.95); @@ -865,8 +839,6 @@ TEST_GROUP(sunmatrixwrapper) B.set_indexval(6, 3); } - - void teardown() {} }; TEST(sunmatrixwrapper, sparse_multiply) diff --git a/deps/AMICI/tests/cpputest/unittests/testsSerialization.cpp b/deps/AMICI/tests/cpputest/unittests/testsSerialization.cpp index 2c7623880..520f3b34e 100644 --- a/deps/AMICI/tests/cpputest/unittests/testsSerialization.cpp +++ b/deps/AMICI/tests/cpputest/unittests/testsSerialization.cpp @@ -96,7 +96,7 @@ checkReturnDataEqual(amici::ReturnData const& r, amici::ReturnData const& s) // clang-format off TEST_GROUP(dataSerialization){ amici::CVodeSolver solver; - void setup() { + void setup() override { // set non-default values for all members solver.setAbsoluteTolerance(1e-4); solver.setRelativeTolerance(1e-5); @@ -113,16 +113,13 @@ TEST_GROUP(dataSerialization){ solver.setPreequilibration(true); solver.setStateOrdering(static_cast(amici::SUNLinSolKLU::StateOrdering::COLAMD)); solver.setInterpolationType(amici::InterpolationType::polynomial); - solver.setStabilityLimitFlag(0); + solver.setStabilityLimitFlag(false); solver.setLinearSolver(amici::LinearSolver::dense); solver.setLinearMultistepMethod(amici::LinearMultistepMethod::adams); solver.setNonlinearSolverIteration(amici::NonlinearSolverIteration::newton); solver.setInternalSensitivityMethod(amici::InternalSensitivityMethod::staggered); solver.setReturnDataReportingMode(amici::RDataReporting::likelihood); } - - void teardown() { - } }; // clang-format on diff --git a/deps/AMICI/tests/generateTestConfig/example_neuron.py b/deps/AMICI/tests/generateTestConfig/example_neuron.py index 8c730ff56..97cc6c698 100755 --- a/deps/AMICI/tests/generateTestConfig/example_neuron.py +++ b/deps/AMICI/tests/generateTestConfig/example_neuron.py @@ -21,7 +21,7 @@ def __init__(self): self.modelOptions['pscale'] = 2 self.solverOptions['atol'] = 1e-16 - self.solverOptions['maxsteps'] = 1e45 + self.solverOptions['maxsteps'] = 1e5 self.solverOptions['nmaxevent'] = 22 self.solverOptions['rtol'] = 1e-12 self.solverOptions['sens_ind'] = [] diff --git a/deps/AMICI/tests/performance/reference.yml b/deps/AMICI/tests/performance/reference.yml index b641ac92a..085363b6a 100644 --- a/deps/AMICI/tests/performance/reference.yml +++ b/deps/AMICI/tests/performance/reference.yml @@ -2,7 +2,10 @@ create_sdist: 5 install_sdist: 150 petab_import: 2100 -install_model: 350 +install_model: 120 +install_model_O0: 40 +install_model_O1: 90 +install_model_O2: 120 forward_simulation: 2 forward_sensitivities: 2 adjoint_sensitivities: 2 diff --git a/deps/AMICI/tests/performance/test.py b/deps/AMICI/tests/performance/test.py index 0f853c4a6..cf58c116b 100755 --- a/deps/AMICI/tests/performance/test.py +++ b/deps/AMICI/tests/performance/test.py @@ -5,47 +5,73 @@ import petab import subprocess import os +import re +import shutil from amici.petab_import import import_model -def main(): +def parse_args(): arg = sys.argv[1] + if '_' in arg and re.match(r'O[0-2]', arg.split("_")[-1]): + optim = arg.split("_")[-1] + os.environ['AMICI_CXXFLAGS'] = f'-{optim}' + suffix = f'_{optim}' + arg = '_'.join(arg.split("_")[:-1]) + else: + suffix = '' - if arg == 'compilation': - git_dir = os.path.join(os.curdir, 'CS_Signalling_ERBB_RAS_AKT') - if not os.path.exists(git_dir): - subprocess.run([ - 'git', 'clone', '--depth', '1', - 'https://github.com/ICB-DCM/CS_Signalling_ERBB_RAS_AKT'] - ) - os.chdir(os.path.join(os.curdir, 'CS_Signalling_ERBB_RAS_AKT')) - - pp = petab.Problem.from_yaml('FroehlichKes2018/PEtab/FroehlichKes2018.yaml') - petab.lint_problem(pp) - os.chdir(os.path.dirname(os.path.abspath(os.curdir))) - import_model(model_name='CS_Signalling_ERBB_RAS_AKT_petab', - sbml_model=pp.sbml_model, - condition_table=pp.condition_df, - observable_table=pp.observable_df, - measurement_table=pp.measurement_df, - compile=False, - verbose=True) - os.chdir(os.path.join(os.curdir, 'CS_Signalling_ERBB_RAS_AKT_petab')) - - subprocess.run(['python', 'setup.py', 'install']) + return arg, suffix - return - else: - import CS_Signalling_ERBB_RAS_AKT_petab as model_module - model = model_module.getModel() - solver = model.getSolver() - # TODO - edata = amici.ExpData(model) - edata.setTimepoints([1e8]) - edata.setObservedData([1.0]) - edata.setObservedDataStdDev([1.0]) +def check_results(rdata): + diagnostics = ['numsteps', 'numstepsB', 'numrhsevals', 'numrhsevalsB', + 'numerrtestfails', 'numerrtestfailsB', + 'numnonlinsolvconvfails', 'numnonlinsolvconvfailsB', + 'preeq_cpu_time', 'preeq_cpu_timeB', + 'cpu_time', 'cpu_timeB', + 'posteq_cpu_time', 'posteq_cpu_timeB'] + for d in diagnostics: + print(d, rdata[d]) + assert rdata['status'] == amici.AMICI_SUCCESS + + +def run_import(model_name): + git_dir = os.path.join(os.curdir, 'CS_Signalling_ERBB_RAS_AKT') + if not os.path.exists(git_dir): + subprocess.run([ + 'git', 'clone', '--depth', '1', + 'https://github.com/ICB-DCM/CS_Signalling_ERBB_RAS_AKT'] + ) + os.chdir(os.path.join(os.curdir, 'CS_Signalling_ERBB_RAS_AKT')) + + pp = petab.Problem.from_yaml( + 'FroehlichKes2018/PEtab/FroehlichKes2018.yaml' + ) + petab.lint_problem(pp) + import_model(model_name=model_name, + sbml_model=pp.sbml_model, + condition_table=pp.condition_df, + observable_table=pp.observable_df, + measurement_table=pp.measurement_df, + compile=False, + verbose=True) + + +def compile_model(model_name, model_dir): + if model_name != os.path.basename(model_dir): + shutil.copytree( + os.path.join(os.curdir, 'CS_Signalling_ERBB_RAS_AKT', + model_name), + model_dir + ) + + subprocess.run(['python', 'setup.py', + 'build_ext', f'--build-lib=.', '--force'], + cwd=model_dir) + + +def prepare_simulation(arg, model, solver, edata): if arg == 'forward_simulation': solver.setSensitivityMethod(amici.SensitivityMethod.none) solver.setSensitivityOrder(amici.SensitivityOrder.none) @@ -57,41 +83,60 @@ def main(): solver.setSensitivityMethod(amici.SensitivityMethod.adjoint) solver.setSensitivityOrder(amici.SensitivityOrder.first) elif arg == 'forward_simulation_non_optimal_parameters': - tmpPar = model.getParameters() - model.setParameters([0.1 for _ in tmpPar]) + tmp_par = model.getParameters() + model.setParameters([0.1 for _ in tmp_par]) solver.setSensitivityMethod(amici.SensitivityMethod.none) solver.setSensitivityOrder(amici.SensitivityOrder.none) elif arg == 'adjoint_sensitivities_non_optimal_parameters': - tmpPar = model.getParameters() - model.setParameters([0.1 for _ in tmpPar]) + tmp_par = model.getParameters() + model.setParameters([0.1 for _ in tmp_par]) solver.setSensitivityMethod(amici.SensitivityMethod.adjoint) solver.setSensitivityOrder(amici.SensitivityOrder.first) elif arg == 'forward_steadystate_sensitivities_non_optimal_parameters': - tmpPar = model.getParameters() - model.setParameters([0.1 for _ in tmpPar]) + tmp_par = model.getParameters() + model.setParameters([0.1 for _ in tmp_par]) solver.setSensitivityMethod(amici.SensitivityMethod.forward) solver.setSensitivityOrder(amici.SensitivityOrder.first) edata.setTimepoints([float('inf')]) elif arg == 'adjoint_steadystate_sensitivities_non_optimal_parameters': - tmpPar = model.getParameters() - model.setParameters([0.1 for _ in tmpPar]) + tmp_par = model.getParameters() + model.setParameters([0.1 for _ in tmp_par]) solver.setSensitivityMethod(amici.SensitivityMethod.adjoint) solver.setSensitivityOrder(amici.SensitivityOrder.first) edata.setTimepoints([float('inf')]) else: print("Unknown argument:", arg) sys.exit(1) + + +def main(): + arg, suffix = parse_args() + + model_dir = os.path.join(os.curdir, 'CS_Signalling_ERBB_RAS_AKT', + 'CS_Signalling_ERBB_RAS_AKT_petab' + suffix) + model_name = 'CS_Signalling_ERBB_RAS_AKT_petab' + + if arg == 'import': + run_import(model_name) + return + elif arg == 'compile': + compile_model(model_name, model_dir) + return + else: + model_module = amici.import_model_module(model_name, model_dir) + model = model_module.getModel() + solver = model.getSolver() + # TODO + edata = amici.ExpData(model) + edata.setTimepoints([1e8]) + edata.setObservedData([1.0]) + edata.setObservedDataStdDev([1.0]) + + prepare_simulation(arg, model, solver, edata) + rdata = amici.runAmiciSimulation(model, solver, edata) - diagnostics = ['numsteps', 'numstepsB', 'numrhsevals', 'numrhsevalsB', - 'numerrtestfails', 'numerrtestfailsB', - 'numnonlinsolvconvfails', 'numnonlinsolvconvfailsB', - 'preeq_cpu_time', 'preeq_cpu_timeB', - 'cpu_time', 'cpu_timeB', - 'posteq_cpu_time', 'posteq_cpu_timeB'] - for d in diagnostics: - print(d, rdata[d]) - assert rdata['status'] == amici.AMICI_SUCCESS + check_results(rdata) if __name__ == '__main__': diff --git a/deps/AMICI/tests/petab_test_suite/test_petab_suite.py b/deps/AMICI/tests/petab_test_suite/test_petab_suite.py index f799c2808..73c7a58db 100755 --- a/deps/AMICI/tests/petab_test_suite/test_petab_suite.py +++ b/deps/AMICI/tests/petab_test_suite/test_petab_suite.py @@ -57,11 +57,14 @@ def _test_case(case, model_type): case_dir = os.path.join(petabtests.PYSB_DIR, case) # import petab problem yaml_file = os.path.join(case_dir, petabtests.problem_yaml_name(case)) - problem = PysbPetabProblem.from_yaml(yaml_file) + problem = PysbPetabProblem.from_yaml(yaml_file, + flatten=case.startswith('0006')) else: raise ValueError(f"Unsupported model_type: {model_type}") # compile amici model + if case.startswith('0006') and model_type != "pysb": + petab.flatten_timepoint_specific_output_overrides(problem) model_output_dir = f'amici_models/model_{case}' model = import_petab_problem( problem, model_output_dir=model_output_dir, @@ -83,6 +86,10 @@ def _test_case(case, model_type): gt_chi2 = solution[petabtests.CHI2] gt_llh = solution[petabtests.LLH] gt_simulation_dfs = solution[petabtests.SIMULATION_DFS] + if case.startswith('0006'): + # account for flattening + gt_simulation_dfs[0].loc[:, petab.OBSERVABLE_ID] = ('obs_a__10__c0', + 'obs_a__15__c0') tol_chi2 = solution[petabtests.TOL_CHI2] tol_llh = solution[petabtests.TOL_LLH] tol_simulations = solution[petabtests.TOL_SIMULATIONS] diff --git a/deps/AMICI/tests/testSBMLSuite.py b/deps/AMICI/tests/testSBMLSuite.py index d0c72b19f..9a4c9f648 100755 --- a/deps/AMICI/tests/testSBMLSuite.py +++ b/deps/AMICI/tests/testSBMLSuite.py @@ -19,6 +19,7 @@ import re import shutil import sys +from typing import Tuple, Set import amici import libsbml as sbml @@ -79,6 +80,10 @@ def test_sbml_testsuite_case(test_number, result_path): # simulate model rdata = amici.runAmiciSimulation(model, solver) + if rdata['status'] != amici.AMICI_SUCCESS and test_id in [ + '00748', '00374', '00369' + ]: + raise amici.sbml_import.SBMLException('Simulation Failed') # verify simulated = verify_results(settings, rdata, results, wrapper, @@ -259,11 +264,11 @@ def compile_model(path, test_id, model_dir): os.makedirs(model_dir) model_name = 'SBMLTest' + test_id - wrapper.sbml2amici(model_name, output_dir=model_dir) + wrapper.sbml2amici(model_name, output_dir=model_dir, + generate_sensitivity_code=False) # settings - sys.path.insert(0, model_dir) - model_module = importlib.import_module(model_name) + model_module = amici.import_model_module(model_name, model_dir) model = model_module.getModel() solver = model.getSolver() @@ -306,16 +311,28 @@ def format_test_id(test_id) -> str: return test_str -def get_tags_for_test(test_id): - """Get sbml test suite tags for the given test ID""" +def get_tags_for_test(test_id) -> Tuple[Set[str], Set[str]]: + """Get sbml test suite tags for the given test ID + + Returns: + Tuple of set of strings for componentTags and testTags + """ current_test_path = os.path.join(TEST_PATH, test_id) info_file = os.path.join(current_test_path, f'{test_id}-model.m') with open(info_file) as f: + component_tags = set() + test_tags = set() for line in f: if line.startswith('testTags:'): - res = set(re.split(r'[ ,:]', line[len('testTags:'):].strip())) - res.discard('') - return res - print(f"No testTags found for test case {test_id}.") - return set() + test_tags = set( + re.split(r'[ ,:]', line[len('testTags:'):].strip())) + test_tags.discard('') + if line.startswith('componentTags:'): + component_tags = set( + re.split(r'[ ,:]', line[len('componentTags:'):].strip())) + component_tags.discard('') + if test_tags and component_tags: + return component_tags, test_tags + print(f"No componentTags or testTags found for test case {test_id}.") + return component_tags, test_tags diff --git a/deps/AMICI/version.txt b/deps/AMICI/version.txt index 44ab23e43..c12244635 100644 --- a/deps/AMICI/version.txt +++ b/deps/AMICI/version.txt @@ -1 +1 @@ -0.11.13 +0.11.17 diff --git a/examples/parpeamici/steadystate/CMakeLists.txt b/examples/parpeamici/steadystate/CMakeLists.txt index 49b633f1e..1e7b4dbfb 100644 --- a/examples/parpeamici/steadystate/CMakeLists.txt +++ b/examples/parpeamici/steadystate/CMakeLists.txt @@ -133,18 +133,16 @@ if(${BUILD_TESTING}) add_test (NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME} -c) set(SRC_LIST_CPP - main_test.cpp exampleSteadystateScaledTest.h ${CMAKE_SOURCE_DIR}/tests/parpecommon/testingMisc.cpp steadystateProblem.cpp - ${GTestSrc}/src/gtest-all.cc - ${GMockSrc}/src/gmock-all.cc ) add_executable(${PROJECT_NAME} ${SRC_LIST_CPP}) add_dependencies(${PROJECT_NAME} ${MODEL_NAME}) target_link_libraries(${PROJECT_NAME} parpeamici + gmock_main ${MODEL_LIBRARIES} ${GCOV_LIBRARY} ) diff --git a/examples/parpeamici/steadystate/exampleSteadystateScaledTest.h b/examples/parpeamici/steadystate/exampleSteadystateScaledTest.h index e98eb37ba..73e9f9a0e 100644 --- a/examples/parpeamici/steadystate/exampleSteadystateScaledTest.h +++ b/examples/parpeamici/steadystate/exampleSteadystateScaledTest.h @@ -95,7 +95,7 @@ TEST_F(steadystateProblemTests, testSteadystateMultiCond) { parpe::MultiConditionDataProviderDefault dp(std::move(model), modelNonOwning->getSolver()); - dp.edata_.push_back(amici::ExpData(*modelNonOwning)); + dp.edata_.emplace_back(amici::ExpData(*modelNonOwning)); dp.edata_[0].fixedParameters = modelNonOwning->getFixedParameters(); dp.edata_[0].setObservedData(yExp); dp.edata_[0].setObservedDataStdDev(std::vector(yExp.size(), 1.0)); @@ -126,7 +126,7 @@ TEST_F(steadystateProblemTests, testSteadystateHierarchical) { yScaledExp[offsettedObservableIdx] = offsetExp + yExp[1]; parpe::MultiConditionDataProviderDefault dp(std::move(model), modelNonOwning->getSolver()); // x0? - dp.edata_.push_back(amici::ExpData(*modelNonOwning)); + dp.edata_.emplace_back(amici::ExpData(*modelNonOwning)); dp.edata_[0].fixedParameters = modelNonOwning->getFixedParameters(); dp.edata_[0].setObservedData(yScaledExp); dp.edata_[0].setObservedDataStdDev(std::vector(yExp.size(), 1.0)); diff --git a/examples/parpeamici/steadystate/main_test.cpp b/examples/parpeamici/steadystate/main_test.cpp deleted file mode 100644 index 0db5f422c..000000000 --- a/examples/parpeamici/steadystate/main_test.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "exampleSteadystateScaledTest.h" - -#include - -#include -#include - -int main(int argc, char *argv[]) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/examples/parpeamici/steadystate/test_steadystate.py b/examples/parpeamici/steadystate/test_steadystate.py index 246cbda8c..d1c8a166b 100644 --- a/examples/parpeamici/steadystate/test_steadystate.py +++ b/examples/parpeamici/steadystate/test_steadystate.py @@ -15,6 +15,7 @@ # General setup script_path = os.path.dirname(os.path.abspath(__name__)) # test executables are expected in working directory +# (i.e. working dir is build/examples/parpeamici/steadystate) cwd = os.getcwd() HDF5_FILE = os.path.join( cwd, 'steadystate_scaled-prefix/src/steadystate_scaled/', @@ -22,7 +23,9 @@ HDF5_FILE_TEST = os.path.join( cwd, 'steadystate_scaled-prefix/src/steadystate_scaled/', 'example_data-testset.h5') - +# build directory is expected to be a direct subdirectory of the parPE root dir +parpe_root = os.path.join(script_path, "../../../..") +OPTIM_OPT = os.path.join(parpe_root, "misc/optimizationOptions.py") MPIEXEC = os.environ.get('PARPE_TESTS_MPIEXEC', "mpiexec -n 5 --oversubscribe").split(" ") optim_exe = './example_steadystate_multi' @@ -32,16 +35,20 @@ result_filename = '_rank00000.h5' -def test_nompi_gradient_check(): +@pytest.mark.parametrize("hierarchical", [False, True]) +def test_nompi_gradient_check(hierarchical): """Test gradient check without MPI""" - outdir = 'example_steadystate_multi-test-gradient' + outdir = f'example_steadystate_multi-test-gradient-{int(hierarchical)}' shutil.rmtree(outdir, ignore_errors=True) + subprocess.run([OPTIM_OPT, HDF5_FILE, '-s', 'hierarchicalOptimization', + str(int(hierarchical))], + capture_output=True, check=True, encoding="utf-8") # Gradient check may fail in certain parameter regimes. Therefore, try # multiple times. max_tries = 4 - for i_try in range(max_tries): + for _ in range(max_tries): ret = subprocess.run(f'{optim_exe} -t gradient_check' f' -o {outdir}/ {HDF5_FILE}'.split(' '), capture_output=True, diff --git a/include/parpeamici/amiciSimulationRunner.h b/include/parpeamici/amiciSimulationRunner.h index 0c4fa3bf9..270fb49bf 100644 --- a/include/parpeamici/amiciSimulationRunner.h +++ b/include/parpeamici/amiciSimulationRunner.h @@ -127,7 +127,7 @@ class AmiciSimulationRunner int jobIdx, const std::vector& optimizationParameters, amici::SensitivityOrder sensitivityOrder, - const std::vector& conditionIndices); + const std::vector& conditionIndices) const; #endif std::vector const& optimization_parameters_; diff --git a/include/parpeamici/hierarchicalOptimization.h b/include/parpeamici/hierarchicalOptimization.h index 7df863154..016cf40cb 100644 --- a/include/parpeamici/hierarchicalOptimization.h +++ b/include/parpeamici/hierarchicalOptimization.h @@ -17,7 +17,7 @@ namespace parpe { enum class ErrorModel { normal -}; // TODO logNormal, laplace +}; // TODO logNormal, Laplace class AnalyticalParameterProvider; class AnalyticalParameterHdf5Reader; @@ -87,13 +87,6 @@ class HierarchicalOptimizationWrapper : public GradientFunction using GradientFunction::evaluate; - /** - * @brief See base class - * @param parameters - * @param fval - * @param gradient - * @return - */ FunctionEvaluationStatus evaluate(gsl::span parameters, double& fval, gsl::span gradient, @@ -112,15 +105,15 @@ class HierarchicalOptimizationWrapper : public GradientFunction * @brief Get parameters for initial function evaluation * @return */ - std::vector getDefaultScalingFactors() const; + [[nodiscard]] std::vector getDefaultScalingFactors() const; /** * @brief Get parameters for initial function evaluation * @return */ - std::vector getDefaultOffsetParameters() const; + [[nodiscard]] std::vector getDefaultOffsetParameters() const; - std::vector getDefaultSigmaParameters() const; + [[nodiscard]] std::vector getDefaultSigmaParameters() const; /** * @brief Run simulations with scaling parameters set to 1.0 and collect @@ -130,7 +123,7 @@ class HierarchicalOptimizationWrapper : public GradientFunction * @return Vector of double vectors containing AMICI ReturnData::y (nt x ny, * column-major) */ - std::tuple>, + [[nodiscard]] std::tuple>, std::vector>> getUnscaledModelOutputsAndSigmas( const gsl::span reducedParameters, @@ -142,7 +135,7 @@ class HierarchicalOptimizationWrapper : public GradientFunction * @param modelOutputs Model outputs as provided by getModelOutputs * @return the computed scaling factors */ - std::vector computeAnalyticalScalings( + [[nodiscard]] std::vector computeAnalyticalScalings( std::vector> const& measurements, std::vector> const& modelOutputsUnscaled) const; @@ -155,11 +148,11 @@ class HierarchicalOptimizationWrapper : public GradientFunction * @param modelOutputs Model outputs as provided by getModelOutputs * @return the computed offset parameters */ - std::vector computeAnalyticalOffsets( + [[nodiscard]] std::vector computeAnalyticalOffsets( const std::vector>& measurements, std::vector>& modelOutputsUnscaled) const; - std::vector computeAnalyticalSigmas( + [[nodiscard]] std::vector computeAnalyticalSigmas( std::vector> const& measurements, const std::vector>& modelOutputsScaled) const; @@ -207,25 +200,25 @@ class HierarchicalOptimizationWrapper : public GradientFunction * @brief Get number of parameters the function expects * @return That */ - virtual int numParameters() const override; + [[nodiscard]] int numParameters() const override; - int numProportionalityFactors() const; + [[nodiscard]] int numProportionalityFactors() const; - std::vector const& getProportionalityFactorIndices() const; + [[nodiscard]] std::vector const& getProportionalityFactorIndices() const; - int numOffsetParameters() const; + [[nodiscard]] int numOffsetParameters() const; - int numSigmaParameters() const; + [[nodiscard]] int numSigmaParameters() const; - std::vector const& getOffsetParameterIndices() const; + [[nodiscard]] std::vector const& getOffsetParameterIndices() const; - std::vector const& getSigmaParameterIndices() const; + [[nodiscard]] std::vector const& getSigmaParameterIndices() const; - std::vector getAnalyticalParameterIndices() const; + [[nodiscard]] std::vector getAnalyticalParameterIndices() const; - AmiciSummedGradientFunction* getWrappedFunction() const; + [[nodiscard]] AmiciSummedGradientFunction* getWrappedFunction() const; - std::vector getParameterIds() const override; + [[nodiscard]] std::vector getParameterIds() const override; private: void init(); @@ -247,7 +240,7 @@ class HierarchicalOptimizationWrapper : public GradientFunction /** Total number of conditions used in `fun` */ int numConditions; - /** Total number of observables occuring in `fun` */ + /** Total number of observables occurring in `fun` */ int numObservables; /** Error model to use for computing analytical parameters and negative @@ -258,7 +251,7 @@ class HierarchicalOptimizationWrapper : public GradientFunction /** * @brief The HierarchicalOptimizationProblemWrapper class wraps an - * OptimizationProblem and hides the analytically optimizated parameters (from + * OptimizationProblem and hides the analytically optimized parameters (from * starting point, parameter bounds, ...) * */ @@ -354,8 +347,8 @@ class HierarchicalOptimizationReporter : public OptimizationReporter mutable std::vector cached_full_gradient_; // TODO should override other functions as well // TODO: in all functions, we need to check of the provided parameters or - // functio nvalues match To cached ones, if we want to provide all together - // to downstreams + // function values match To cached ones, if we want to provide all together + // to downstream }; /** @@ -475,32 +468,38 @@ removeInnerParameters(const gsl::span allParameters, allParameters.size() - proportionalityFactorIndices.size() - offsetParameterIndices.size() - sigmaParameterIndices.size()); - int idxOuter = 0; + int nextOuterIdx = 0; for(int idxFull = 0; idxFull < static_cast(allParameters.size()); ++idxFull) { + + // skip if current parameter is scaling/offset/sigma if(std::find(proportionalityFactorIndices.begin(), - proportionalityFactorIndices.end(), idxOuter) + proportionalityFactorIndices.end(), idxFull) != std::end(proportionalityFactorIndices)) continue; + if(std::find(offsetParameterIndices.begin(), - offsetParameterIndices.end(), idxOuter) + offsetParameterIndices.end(), idxFull) != std::end(offsetParameterIndices)) continue; + if(std::find(sigmaParameterIndices.begin(), - sigmaParameterIndices.end(), idxOuter) + sigmaParameterIndices.end(), idxFull) != std::end(sigmaParameterIndices)) continue; - outerParameters[idxOuter] = allParameters[idxFull]; - ++idxOuter; + + // otherwise copy + outerParameters[nextOuterIdx] = allParameters[idxFull]; + ++nextOuterIdx; } - Ensures(idxOuter == static_cast(outerParameters.size())); + Ensures(nextOuterIdx == static_cast(outerParameters.size())); return outerParameters; } /** * @brief From the given parameter vector, extract outer optimization - * parameters, as defined in the file HDF5 file parameterFile + * parameters, as defined in the file HDF5 file `parameterFile` * @param fullParameters * @param parameterFile * @param parameterPath @@ -542,7 +541,7 @@ computeNegLogLikelihood(std::vector const& measurements, /** * @brief If sensitivities are computed w.r.t. analytically computed parameters - * (which is unneccessary), this function checks they are below the given + * (which is unnecessary), this function checks they are below the given * threshold. * @param gradient * @param analyticalIndices diff --git a/include/parpeamici/hierarchicalOptimizationAnalyticalParameterProvider.h b/include/parpeamici/hierarchicalOptimizationAnalyticalParameterProvider.h index d99091087..28c495698 100644 --- a/include/parpeamici/hierarchicalOptimizationAnalyticalParameterProvider.h +++ b/include/parpeamici/hierarchicalOptimizationAnalyticalParameterProvider.h @@ -17,15 +17,15 @@ namespace parpe { class AnalyticalParameterProvider { public: - virtual ~AnalyticalParameterProvider() {} + virtual ~AnalyticalParameterProvider() = default; /** * @brief Get vector of condition indices for which the parameter with the * given index is used. * @param parameterIndex referring to the index in the analytical parameter - * list in the hdf5 file + * list in the HDF5 file * (*not* the optimization parameter index). - * @return Vector of condition indice + * @return Vector of condition indices */ virtual std::vector getConditionsForParameter( int parameterIndex) const = 0; @@ -65,7 +65,7 @@ class AnalyticalParameterProviderDefault : public AnalyticalParameterProvider // TODO private std::vector> conditionsForParameter; std::vector optimizationParameterIndices; - // x[scalingIdx][conditionIdx] -> std::vector of observableIndicies + // x[scalingIdx][conditionIdx] -> std::vector of observableIndices std::vector>> mapping; }; @@ -83,11 +83,11 @@ class AnalyticalParameterHdf5Reader : public AnalyticalParameterProvider /** * @brief AnalyticalParameterHdf5Reader * @param file - * @param scalingParameterIndicesPath location in hdf5 file of the list of + * @param scalingParameterIndicesPath location in HDF5 file of the list of * indices of the analytically determined parameters within the overall * optimization parameters * @param mapPath path of to the dataset with the - * parameter-oberservable-condition mapping + * parameter-observable-condition mapping */ AnalyticalParameterHdf5Reader(const H5::H5File& file, std::string analyticalParameterIndicesPath, @@ -100,9 +100,9 @@ class AnalyticalParameterHdf5Reader : public AnalyticalParameterProvider * @brief Get vector of condition indices for which the parameter with the * given index is used. * @param parameterIndex referring to the index in the analytical parameter - * list in the hdf5 file + * list in the HDF5 file * (*not* the optimization parameter index). - * @return Vector of condition indice + * @return Vector of condition indices */ std::vector getConditionsForParameter( int parameterIndex) const override; @@ -151,7 +151,7 @@ class AnalyticalParameterHdf5Reader : public AnalyticalParameterProvider std::string mapPath; std::string analyticalParameterIndicesPath; - // x[scalingIdx][conditionIdx] -> std::vector of observableIndicies + // x[scalingIdx][conditionIdx] -> std::vector of observableIndices std::vector>> mapping; }; diff --git a/include/parpeamici/multiConditionDataProvider.h b/include/parpeamici/multiConditionDataProvider.h index 44c9a9b6e..cedca9259 100644 --- a/include/parpeamici/multiConditionDataProvider.h +++ b/include/parpeamici/multiConditionDataProvider.h @@ -127,7 +127,8 @@ class MultiConditionDataProviderDefault : public MultiConditionDataProvider /** * @brief Provides the number of conditions for which data is available and * simulations need to be run. - * This is determined from the dimensions of the hdf5MeasurementPath + * This is determined from the dimensions of the + * MultiConditionDataProviderDefault::hdf5MeasurementPath * dataset. * @return Number of conditions */ @@ -348,10 +349,12 @@ class MultiConditionDataProviderHDF5 : public MultiConditionDataProvider /** * @brief Based on the array of optimization parameters, set the simulation - * parameters in the given Model object to the ones for condition index. - * @param conditionIndex - * @param optimizationParams - * @param udata + * parameters in the given Model object to the ones for simulation index. + * @param simulationIdx Index of the simulation condition for which to set + * model parameters. + * @param optimizationParams Problem parameters from which to extract + * simulation parameters. + * @param model Model on which to set parameter values and scale */ void updateSimulationParametersAndScale( int simulationIdx, diff --git a/include/parpeamici/multiConditionProblem.h b/include/parpeamici/multiConditionProblem.h index 805bafcc4..4a9d8a07d 100644 --- a/include/parpeamici/multiConditionProblem.h +++ b/include/parpeamici/multiConditionProblem.h @@ -114,7 +114,7 @@ class AmiciSummedGradientFunction : public SummedGradientFunction { virtual ~AmiciSummedGradientFunction() = default; - virtual FunctionEvaluationStatus evaluate( + FunctionEvaluationStatus evaluate( gsl::span parameters, int dataset, double &fval, @@ -122,7 +122,7 @@ class AmiciSummedGradientFunction : public SummedGradientFunction { Logger *logger, double *cpuTime) const override; - virtual FunctionEvaluationStatus evaluate( + FunctionEvaluationStatus evaluate( gsl::span parameters, std::vector datasets, double &fval, @@ -134,9 +134,9 @@ class AmiciSummedGradientFunction : public SummedGradientFunction { * @brief Number of optimization parameters * @return */ - virtual int numParameters() const override; + [[nodiscard]] int numParameters() const override; - std::vector getParameterIds() const override; + [[nodiscard]] std::vector getParameterIds() const override; /** * @brief Run simulations (no gradient) with given parameters and collect @@ -154,7 +154,7 @@ class AmiciSummedGradientFunction : public SummedGradientFunction { Logger *logger, double *cpuTime) const; - virtual std::vector> getAllMeasurements() const; + [[nodiscard]] virtual std::vector> getAllMeasurements() const; /** * @brief Callback function for LoadBalancer @@ -163,7 +163,7 @@ class AmiciSummedGradientFunction : public SummedGradientFunction { */ virtual void messageHandler(std::vector &buffer, int jobId) const; - virtual amici::ParameterScaling getParameterScaling(int parameterIndex) const; + [[nodiscard]] virtual amici::ParameterScaling getParameterScaling(int parameterIndex) const; /** Include model states in result package */ bool sendStates = false; @@ -188,7 +188,7 @@ class AmiciSummedGradientFunction : public SummedGradientFunction { double *cpuTime) const; /** - * @brief Aggregates loglikelihood received from workers. + * @brief Aggregates log-likelihood received from workers. * @param data Simulation job result * @param negLogLikelihood output argument to which *negative* * log likelihood is added @@ -206,7 +206,7 @@ class AmiciSummedGradientFunction : public SummedGradientFunction { /** - * @brief Aggregates loglikelihood gradient received from workers. + * @brief Aggregates log-likelihood gradient received from workers. * @param conditionIdx * @param simulationGradient log-likelihood gradient from simulation * @param objectiveFunctionGradient output to which *negative* diff --git a/include/parpeamici/optimizationApplication.h b/include/parpeamici/optimizationApplication.h index ba60d16ab..7b4f86781 100644 --- a/include/parpeamici/optimizationApplication.h +++ b/include/parpeamici/optimizationApplication.h @@ -144,7 +144,7 @@ class OptimizationApplication { */ int init(int argc, char **argv); - void runMultiStarts(); + void runMultiStarts() const; protected: // command line option parsing diff --git a/include/parpeamici/simulationResultWriter.h b/include/parpeamici/simulationResultWriter.h index 2d044e8c6..53a18dac9 100644 --- a/include/parpeamici/simulationResultWriter.h +++ b/include/parpeamici/simulationResultWriter.h @@ -55,8 +55,6 @@ class SimulationResultWriter { * @brief Create results datasets. * * Must be called before first call to `save*` - * @param udata - * @param edata * @param numSimulations */ void createDatasets(hsize_t numSimulations); @@ -65,7 +63,6 @@ class SimulationResultWriter { /** * @brief Save results for a single simulation to HDF5 file. - * @param udata * @param edata * @param rdata * @param simulationIdx If >= 0: write results in the selected diff --git a/include/parpeamici/standaloneSimulator.h b/include/parpeamici/standaloneSimulator.h index a01ef5894..dd817f317 100644 --- a/include/parpeamici/standaloneSimulator.h +++ b/include/parpeamici/standaloneSimulator.h @@ -17,7 +17,7 @@ namespace parpe { * ./simulate --at-optimum : use parameters from last iteration of all * multi-start optimization runs * --parameter-matrix : using arbitrary parameters from some matrix - * in hdf5 file + * in HDF5 file * --along-trajectory : use parameters along the optimization * trajectory of all multi-start optimization * runs @@ -34,7 +34,7 @@ class StandaloneSimulator * @param resultPath HDF5 file root group name * @param optimizationParameters Parameters for simulation (results from * hierarchical or standard optimization - * @param loadBalancer LoadBalander instance for distributed memory + * @param loadBalancer LoadBalancer instance for distributed memory * parallel, or nullptr for shared memory parallel or sequential * @param inputFile File with simulation options and data used for * optimization diff --git a/include/parpecommon/functions.h b/include/parpecommon/functions.h index 0e858d80e..199035b11 100644 --- a/include/parpecommon/functions.h +++ b/include/parpecommon/functions.h @@ -74,7 +74,7 @@ class SummedGradientFunction * @param gradient Preallocated space for the gradient of size * dim(parameters). Or gsl::span() for evaluation without gradient. * @param logger Optional Logger instance used for output - * @param cputime Optional output argument to reoprt cpuTime consumed by the + * @param cputime Optional output argument to report cpuTime consumed by the * the function * @return Evaluation status */ @@ -94,7 +94,7 @@ class SummedGradientFunction * @param gradient Preallocated space for the gradient of size * dim(parameters). Or gsl::span() for evaluation without gradient. * @param logger Optional Logger instance used for output - * @param cputime Optional output argument to reoprt cpuTime consumed by the + * @param cputime Optional output argument to report cpuTime consumed by the * the function * @return Evaluation status */ diff --git a/include/parpecommon/misc.h b/include/parpecommon/misc.h index 1b7bd531e..92077d76b 100644 --- a/include/parpecommon/misc.h +++ b/include/parpecommon/misc.h @@ -177,7 +177,7 @@ class InverseUniqueLock }; /** - * @brief Check if a and b are equal to machine precission + * @brief Check if a and b are equal to machine precision * @param a * @param b * @return diff --git a/include/parpeloadbalancer/loadBalancerMaster.h b/include/parpeloadbalancer/loadBalancerMaster.h index fa94f7542..3e5ce9f36 100644 --- a/include/parpeloadbalancer/loadBalancerMaster.h +++ b/include/parpeloadbalancer/loadBalancerMaster.h @@ -94,7 +94,7 @@ class LoadBalancerMaster { void sendTerminationSignalToAllWorkers(); /** - * @brief Retuns whether we are ready to accept jobs (`run` was called, but + * @brief Returns whether we are ready to accept jobs (`run` was called, but * `terminate` was not). * @return true if running, false otherwise */ @@ -204,7 +204,7 @@ class LoadBalancerMaster { std::vector sendRequests; /** Jobs that have been sent to workers. Required for handling replies and - * signalling the client that processing has completed. */ + * signaling the client that processing has completed. */ std::vector sentJobsData; /** Mutex to protect access to `queue`. */ diff --git a/include/parpeloadbalancer/loadBalancerWorker.h b/include/parpeloadbalancer/loadBalancerWorker.h index ee14ba7ac..e60cd972a 100644 --- a/include/parpeloadbalancer/loadBalancerWorker.h +++ b/include/parpeloadbalancer/loadBalancerWorker.h @@ -15,11 +15,11 @@ class LoadBalancerWorker { LoadBalancerWorker() = default; /** - * messageHandler is called by run when a message is received. The - * message is contained in buffer. + * Callback function for when a message is received. + * * @param buffer The message - * @param jobId is a message identifier, unique over the range of MAX_INT - * messages + * @param jobId A message identifier, unique over the range of MAX_INT + * messages. */ using messageHandlerFunc = std::function &buffer, int jobId)>; @@ -27,8 +27,8 @@ class LoadBalancerWorker { private: /** - * @brief waitForAndHandleJobs - * @return true: received termination signal + * @brief Probe for and dispatch the next incoming job + * @return `true` if the termination signal was received, `false` otherwise. */ bool waitForAndHandleJobs(const messageHandlerFunc& messageHandler); }; diff --git a/include/parpeoptimization/localOptimizationDlib.h b/include/parpeoptimization/localOptimizationDlib.h index 18200212f..4e05e5d61 100644 --- a/include/parpeoptimization/localOptimizationDlib.h +++ b/include/parpeoptimization/localOptimizationDlib.h @@ -14,13 +14,14 @@ class OptimizerDlibLineSearch : public Optimizer { * @brief Minimize an objective function given as OptimizationProblem using * dlib line search algorithm * - * TODO: no options are specifyable for the moment + * TODO: no options are specifiable for the moment * * @param problem * @return Returns 0 on success. */ - int optimize(OptimizationProblem *problem) override; + std::tuple > + optimize(OptimizationProblem *problem) override; }; } // namespace parpe diff --git a/include/parpeoptimization/localOptimizationFides.h b/include/parpeoptimization/localOptimizationFides.h new file mode 100644 index 000000000..d78fadb86 --- /dev/null +++ b/include/parpeoptimization/localOptimizationFides.h @@ -0,0 +1,28 @@ +#ifndef LOCAL_OPTIMIZATION_FIDES_H +#define LOCAL_OPTIMIZATION_FIDES_H + +#include +#include + +namespace parpe { + +class OptimizerFides : public Optimizer +{ + public: + OptimizerFides() = default; + + /** + * @brief Minimize an objective function given as OptimizationProblem using + * fides optimizer + * + * @param problem + * @return . + */ + + std::tuple> optimize( + OptimizationProblem* problem) override; +}; + +} // namespace parpe + +#endif diff --git a/include/parpeoptimization/localOptimizationToms611.h b/include/parpeoptimization/localOptimizationToms611.h index 339648924..6db73855c 100644 --- a/include/parpeoptimization/localOptimizationToms611.h +++ b/include/parpeoptimization/localOptimizationToms611.h @@ -13,8 +13,10 @@ class OptimizerToms611TrustRegionSumsl : public Optimizer { /** * @brief Minimize an objective function given as OptimizationProblem using * the `sumsl_` trust-region algorithm from TOMS611 + * (ACM TOMS 9 (1983) 503-524, https://doi.org/10.1145/356056.356066, + * code: http://netlib.org/toms/) * - * TODO: no options are specifyable for the moment + * TODO: no options are specifiable for the moment * * @param problem * @return Returns 0 on success. diff --git a/include/parpeoptimization/minibatchOptimization.h b/include/parpeoptimization/minibatchOptimization.h index 3dfc2ce20..931d61188 100755 --- a/include/parpeoptimization/minibatchOptimization.h +++ b/include/parpeoptimization/minibatchOptimization.h @@ -19,7 +19,7 @@ namespace parpe { /** - * @brief Return status for minibatch optimizer + * @brief Return status for mini-batch optimizer */ enum class minibatchExitStatus { gradientNormConvergence, maxEpochsExceeded, invalidNumber @@ -72,7 +72,7 @@ class MinibatchOptimizationProblem: public OptimizationProblem { }; /** - * @brief learning rate updaters for minibatch optimizers + * @brief learning rate updaters for mini-batch optimizers * * The LearningRateUpdater provides the possibility to reduce the learning rate per epoch * and makes it possible to adapt the learning rate according to success or failure of @@ -119,7 +119,7 @@ class LearningRateUpdater { /** Learning rate, i.e. step size, at the moment of optimization */ double currentLearningRate = 0.0; - /** If an optimization step is not succesful, the learning rate, i.e., step size, will be reduced by this factor */ + /** If an optimization step is not successful, the learning rate, i.e., step size, will be reduced by this factor */ double reductionFactor = 4.0; /** Learning rate, i.e. step size, at the beginning of optimization */ @@ -133,7 +133,7 @@ class LearningRateUpdater { }; /** - * @brief Interface for parameter updaters for minibatch optimizers + * @brief Interface for parameter updaters for mini-batch optimizers */ class ParameterUpdater { public: @@ -157,7 +157,7 @@ class ParameterUpdater { /** If the ODE is repeatedly non-integrable, a cold restart is performed using this method */ virtual void clearCache() = 0; - /** Intialize the parameter updater */ + /** Initialize the parameter updater */ virtual void initialize(unsigned int numParameters) = 0; virtual ~ParameterUpdater() = default; @@ -165,7 +165,7 @@ class ParameterUpdater { }; /** - * @brief Minibatch optimizer: Vanilla SGD Updater + * @brief Mini-batch optimizer: Vanilla SGD Updater * The simplest mini batch algorithm. */ class ParameterUpdaterVanilla: public ParameterUpdater { @@ -187,7 +187,7 @@ class ParameterUpdaterVanilla: public ParameterUpdater { }; /** - * @brief Minibatch optimizer: RMSProp Updater + * @brief Mini-batch optimizer: RMSProp Updater * A so-called adaptive mini batching algorithm without momentum */ class ParameterUpdaterRmsProp: public ParameterUpdater { @@ -212,7 +212,7 @@ class ParameterUpdaterRmsProp: public ParameterUpdater { /** Rate for memorizing gradient norms (between 0 and 1, high rates mean long memory) */ double decayRate = 0.9; - /** Stabilization factor for gradient normalization (avoid deviding by 0) */ + /** Stabilization factor for gradient normalization (avoid dividing by 0) */ double delta = 1e-7; /** Memorized gradient norms (decaying average) from last steps */ @@ -223,7 +223,7 @@ class ParameterUpdaterRmsProp: public ParameterUpdater { }; /** - * @brief Minibatch optimizer: Momentum Updater + * @brief Mini-batch optimizer: Momentum Updater * A classical gradient based optimizer using a vanilla momentum formula */ class ParameterUpdaterMomentum: public ParameterUpdater { @@ -256,7 +256,7 @@ class ParameterUpdaterMomentum: public ParameterUpdater { }; /** - * @brief Minibatch optimizer: Adam Updater + * @brief Mini-batch optimizer: Adam Updater * A momentum-based and so-called adaptive mini batching algorithm */ class ParameterUpdaterAdam: public ParameterUpdater { @@ -284,7 +284,7 @@ class ParameterUpdaterAdam: public ParameterUpdater { /** Rate for memorizing gradient norms (between 0 and 1, high rates mean long memory) */ double decayRateGradientNorm = 0.9; - /** Stabilization factor for gradient normalization (avoid deviding by 0) */ + /** Stabilization factor for gradient normalization (avoid dividing by 0) */ double delta = 1e-7; /** Memorized gradient norms (decaying average) from last steps */ @@ -301,7 +301,7 @@ class ParameterUpdaterAdam: public ParameterUpdater { }; /** - * @brief Minibatch optimizer: Adam Classic Updater + * @brief Mini-batch optimizer: Adam Classic Updater * A momentum-based and so-called adaptive mini batching algorithm, * using the original settings from the literature */ @@ -405,7 +405,7 @@ class MinibatchOptimizer { /** * @brief Minimize the given function using mini-batch gradient descent. * - * @param f Function to minize + * @param f Function to minimize * @param data Full data set on which f will be evaluated * @param initialParameters Starting point for optimization * @param reporter OptimizationReporter instance for tracking progress @@ -467,7 +467,7 @@ class MinibatchOptimizer { batchLogger->logmessage(LOGLVL_DEBUG, ss.str().c_str()); if (status == functionEvaluationFailure) { - // Check, if the interceptor should be used (should alwayss be the case, except for study purpose... + // Check, if the interceptor should be used (should always be the case, except for study purpose... if (interceptor > interceptType::none) status = rescueInterceptor(parameters, oldParameters, gradient, oldGradient, lowerParameterBounds, upperParameterBounds, cost, subsequentFails, @@ -478,7 +478,7 @@ class MinibatchOptimizer { return finish(cost, parameters, minibatchExitStatus::invalidNumber, reporter, batchLogger.get()); } else { - // Cost function evaluation was succeful, so we can increase the step size + // Cost function evaluation was successful, so we can increase the step size subsequentFails = std::max(subsequentFails - 1, 0); learningRateUpdater->increaseLearningRate(); @@ -493,7 +493,7 @@ class MinibatchOptimizer { } - // epoch finished, write the values in hdf5-file + // epoch finished, write the values in HDF5-file if (reporter) reporter->iterationFinished(parameters, cost, gradient); @@ -551,7 +551,7 @@ class MinibatchOptimizer { if (logger) { switch (status) { case minibatchExitStatus::invalidNumber: - logger->logmessage(LOGLVL_ERROR, "Minibatch cost function evaluation failed."); + logger->logmessage(LOGLVL_ERROR, "Mini-batch cost function evaluation failed."); break; case minibatchExitStatus::gradientNormConvergence: logger->logmessage(LOGLVL_INFO, "Convergence: gradientNormThreshold reached."); @@ -576,7 +576,7 @@ class MinibatchOptimizer { * @param oldGradient cost function gradient before last step * @param cost new cost function value after interception * @param subsequentFails number of iterations during rescue interceptor - * @param f Function to minize + * @param f Function to minimize * @param data Full data set on which f will be evaluated * @param logger Logger instance for status messages * @param reporter OptimizationReporter instance for tracking progress @@ -639,7 +639,7 @@ class MinibatchOptimizer { // If nothing helps and no cold restart wanted: cancel optimization if (initialFail or (finalFail and interceptor != interceptType::reduceStepAndRestart)) { - logger->logmessage(LOGLVL_DEBUG, "Failure at intial point of optimization. Stopping."); + logger->logmessage(LOGLVL_DEBUG, "Failure at initial point of optimization. Stopping."); return functionEvaluationFailure; } @@ -658,7 +658,7 @@ class MinibatchOptimizer { } // debug output - ss << ": Interceptor, before new evalaluation: " << std::endl + ss << ": Interceptor, before new evaluation: " << std::endl << " New cost: " << cost << ", new |g|2: " << getVectorNorm(gradient) << ", new LearningRate: " << learningRate @@ -678,7 +678,7 @@ class MinibatchOptimizer { parDifference = getVectorDifference(parameters, oldParameters); // debug output - ss << ": Interceptor, after new evalaluation: " << std::endl + ss << ": Interceptor, after new evaluation: " << std::endl << " New Cost: " << cost << " new |g|2: " << getVectorNorm(gradient) << " new LearningRate: " << learningRate @@ -701,7 +701,7 @@ class MinibatchOptimizer { * @param oldGradient cost function gradient before last step * @param cost new cost function value after interception * @param subsequentFails number of iterations during rescue interceptor - * @param f Function to minize + * @param f Function to minimize * @param data Full data set on which f will be evaluated * @param logger Logger instance for status messages * @param reporter OptimizationReporter instance for tracking progress @@ -740,7 +740,7 @@ class MinibatchOptimizer { parameterUpdater->updateParameters(alpha, iteration, gradient, parameters, lowerParameterBounds, upperParameterBounds); - /* Write new cost funtion value and return */ + /* Write new cost function value and return */ double newCost = NAN; evaluate(f, parameters, datasets, newCost, gsl::span(), logger, reporter); return newCost; @@ -807,9 +807,9 @@ class MinibatchOptimizer { cost1 = evalLineSearch(stepLength); parabola_ss << " Step adaption did not work..." << std::endl; } - parabola_ss << " cost0: " << cost << " (steplength: " << getVectorNorm(parDifference) - << "), cost1: " << cost1 << " (steplength: " << stepLength - << "), cost2: " << cost2 << " (steplength: " << newStepLength + parabola_ss << " cost0: " << cost << " (step length: " << getVectorNorm(parDifference) + << "), cost1: " << cost1 << " (step length: " << stepLength + << "), cost2: " << cost2 << " (step length: " << newStepLength << ") " << std::endl; if (logger) logger->logmessage(LOGLVL_DEBUG, parabola_ss.str().c_str()); @@ -827,9 +827,9 @@ class MinibatchOptimizer { // Debugging output if (logger) { line_ss << " Line-Search: two steps were done, results are: " << std::endl - << " cost0: " << cost << " (steplength: " << getVectorNorm(parDifference) - << "), cost1: " << cost1 << " (steplength: " << stepLength - << "), cost2: " << cost2 << " (steplength: " << newStepLength + << " cost0: " << cost << " (step length: " << getVectorNorm(parDifference) + << "), cost1: " << cost1 << " (step length: " << stepLength + << "), cost2: " << cost2 << " (step length: " << newStepLength << ")" << std::endl; logger->logmessage(LOGLVL_DEBUG, line_ss.str().c_str()); } @@ -861,8 +861,9 @@ class MinibatchOptimizer { } /** - * @brief Perform line search according to interpolation algo by [Dennis and Schnabel, - * Numerical Methods for Unconstrained Optimization and Non-linear Equations, 1993]. + * @brief Perform line search according to interpolation algorithm by + * [Dennis and Schnabel, Numerical Methods for Unconstrained Optimization + * and Non-linear Equations, 1993]. * * @param alpha1 step length of first step * @param alpha2 step length of second step @@ -890,7 +891,7 @@ class MinibatchOptimizer { * * alpha3 = -b + sqrt(b*b - 3*a*dirGradient ) / (3*a) * - * Possibly, we have to iterrate this process. */ + * Possibly, we have to iterate this process. */ /* Declare variables which will be needed outside the loop */ double cost3 = NAN; @@ -960,7 +961,7 @@ void setMinibatchOption(const std::pair &p MinibatchOptimizer* optimizer); /** - * @brief Create and setup a minibatch optimizer according to the given options + * @brief Create and setup a mini-batch optimizer according to the given options * @param options * @return */ diff --git a/include/parpeoptimization/optimizationOptions.h b/include/parpeoptimization/optimizationOptions.h index d8c169942..e3f9fa85b 100644 --- a/include/parpeoptimization/optimizationOptions.h +++ b/include/parpeoptimization/optimizationOptions.h @@ -20,6 +20,7 @@ enum class optimizerName { OPTIMIZER_DLIB, OPTIMIZER_TOMS611, OPTIMIZER_FSQP, + OPTIMIZER_FIDES, OPTIMIZER_MINIBATCH_1 = 10 }; @@ -32,7 +33,7 @@ class OptimizationOptions { OptimizationOptions() = default; /** Optimizer factory method depending on OptimizationOptions::optimizer */ - Optimizer *createOptimizer() const; + std::unique_ptr createOptimizer() const; /** Optimizer to use */ optimizerName optimizer = optimizerName::OPTIMIZER_IPOPT; @@ -86,12 +87,12 @@ class OptimizationOptions { std::map options; }; -Optimizer* optimizerFactory(optimizerName optimizer); +std::unique_ptr optimizerFactory(optimizerName optimizer); /** * @brief Print list of supported optimizers */ -void printAvailableOptimizers(std::string prefix = ""); +void printAvailableOptimizers(const std::string &prefix = ""); } // namespace parpe #endif // OPTIMIZATIONOPTIONS_H diff --git a/include/parpeoptimization/optimizationProblem.h b/include/parpeoptimization/optimizationProblem.h index d2b9094a7..4e52dcda5 100644 --- a/include/parpeoptimization/optimizationProblem.h +++ b/include/parpeoptimization/optimizationProblem.h @@ -46,7 +46,6 @@ class OptimizationReporter: public GradientFunction { /** * @brief Is called just before the optimizer starts. Must be called before * other functions. - * @param numParameters * @param initialParameters * @return Quit optimization? */ @@ -54,9 +53,9 @@ class OptimizationReporter: public GradientFunction { /** * @brief Is called after each iteration except for the last one - * @param numParameters * @param parameters - * @param currentIter + * @param objectiveFunctionValue + * @param objectiveFunctionGradient * @return Quit optimization? */ virtual bool iterationFinished(gsl::span parameters, diff --git a/misc/rebuild_amici.sh b/misc/rebuild_amici.sh index d01a93e5a..0c987128d 100755 --- a/misc/rebuild_amici.sh +++ b/misc/rebuild_amici.sh @@ -27,7 +27,7 @@ rm -f "${amici_dir}/python/sdist/amici/amici.py" rm -f "${amici_dir}/python/sdist/amici/amici_wrap_without_hdf5.cxx" rm -f "${amici_dir}/python/sdist/amici/amici_wrap.cxx" rm -f "${amici_dir}"/python/sdist/amici/_amici.*.so -ls -l ${amici_dir}/python/sdist/amici +ls -l "${amici_dir}/python/sdist/amici" # rebuild "${amici_dir}/scripts/buildAmici.sh" diff --git a/misc/setup_amici_model.sh b/misc/setup_amici_model.sh index 1051db6bb..11301d68e 100755 --- a/misc/setup_amici_model.sh +++ b/misc/setup_amici_model.sh @@ -15,6 +15,7 @@ model_dir="$1" output_dir="$2" template_dir="${script_path}/../templates" model_name=$(basename "${model_dir}") +make_opts="${MAKE_OPTS:-}" if [[ ! -d "${model_dir}" ]]; then echo "ERROR: Model directory ${model_dir} does not exist." @@ -47,4 +48,4 @@ cmake -S "${output_dir}" \ -DParPE_DIR="${script_path}/../build" echo "Building ..." -cmake --build "${output_dir}/build" -- VERBOSE=1 +cmake --build "${output_dir}/build" ${make_opts} -- VERBOSE=1 diff --git a/python/parpe/hdf5_pe_input.py b/python/parpe/hdf5_pe_input.py index e85c85910..c24e57bb9 100644 --- a/python/parpe/hdf5_pe_input.py +++ b/python/parpe/hdf5_pe_input.py @@ -2,6 +2,7 @@ import argparse import logging import sys +from numbers import Number from typing import Any, Collection, Optional, Dict, Tuple import amici @@ -257,7 +258,8 @@ def _generate_simulation_to_optimization_parameter_mapping(self) -> None: # get list of tuple of parameters dicts for all conditions self.parameter_mapping = self.petab_problem \ .get_optimization_to_simulation_parameter_mapping( - warn_unmapped=False, scaled_parameters=False) + warn_unmapped=False, scaled_parameters=False, + allow_timepoint_specific_numeric_noise_parameters=True) variable_par_ids = self.amici_model.getParameterIds() fixed_par_ids = self.amici_model.getFixedParameterIds() @@ -353,7 +355,7 @@ def _set_initial_concentration(condition_id, species_id, self.petab_problem.condition_df.loc[ condition_id, species_id]) - if isinstance(value, float): + if isinstance(value, Number): # numeric initial state par_map[init_par_id] = value scale_map[init_par_id] = ptc.LIN @@ -398,7 +400,7 @@ def _set_initial_concentration(condition_id, species_id, self.petab_problem.condition_df.loc[ preeq_cond_id, species_id]) - if isinstance(value, float): + if isinstance(value, Number): condition_map_sim[init_par_id] = value _set_initial_concentration( preeq_cond_id, species_id, init_par_id, @@ -409,7 +411,7 @@ def _set_initial_concentration(condition_id, species_id, self.petab_problem.condition_df.loc[ sim_cond_id, species_id]) - if not isinstance(value_sim, float) \ + if not isinstance(value_sim, Number) \ or not np.isnan(value_sim): # mark for reinitialization, # unless the value is nan @@ -630,7 +632,8 @@ def _generate_measurement_matrices(self): """ if petab.measurement_table_has_timepoint_specific_mappings( - self.petab_problem.measurement_df): + self.petab_problem.measurement_df, + allow_scalar_numeric_noise_parameters=True): raise RuntimeError("Timepoint-specific overrides are not yet " "supported.") @@ -688,7 +691,7 @@ def write_measurements(self): f' time {row[ptc.TIME]}\n' + str(cur_mes_df)) mes[time_idx, observable_idx] = float(row[ptc.MEASUREMENT]) sigma = to_float_if_float(row[ptc.NOISE_PARAMETERS]) - if isinstance(sigma, float): + if isinstance(sigma, Number): sd[time_idx, observable_idx] = sigma # write to file diff --git a/python/setup.py b/python/setup.py index c0fb03841..5ada124b1 100644 --- a/python/setup.py +++ b/python/setup.py @@ -17,8 +17,8 @@ install_requires=['numpy>=1.18.1', 'termcolor>=1.1.0', 'colorama>=0.4.3', - 'petab>=0.1.14', - 'amici>=0.11.12', + 'petab>=0.1.18', + 'amici>=0.11.15', 'h5py>=3.0.0', 'python-libsbml>=5.17.0', 'snakemake>=5.10.0', diff --git a/src/parpeamici/amiciSimulationRunner.cpp b/src/parpeamici/amiciSimulationRunner.cpp index a1de3100c..1eb3fce55 100644 --- a/src/parpeamici/amiciSimulationRunner.cpp +++ b/src/parpeamici/amiciSimulationRunner.cpp @@ -78,7 +78,7 @@ AmiciSimulationRunner::runDistributedMemory(LoadBalancerMaster* loadBalancer, pthread_mutex_lock(&simulationsMutex); while (numJobsFinished < numJobsTotal) // TODO don't wait for all to // complete; stop early if errors - // occured + // occurred pthread_cond_wait(&simulationsCond, &simulationsMutex); pthread_mutex_unlock(&simulationsMutex); pthread_mutex_destroy(&simulationsMutex); @@ -112,7 +112,7 @@ AmiciSimulationRunner::runSharedMemory(const messageHandlerFunc& messageHandler, for (int simulationIdx = 0; simulationIdx < (signed)condition_indices_.size(); ++simulationIdx) { - // to reuse the parallel code and for debugging we still serialze the + // to reuse the parallel code and for debugging we still serialize the // job data here auto curConditionIndices = std::vector{ simulationIdx }; AmiciWorkPackageSimple work{ optimization_parameters_, @@ -146,7 +146,7 @@ AmiciSimulationRunner::queueSimulation( int jobIdx, std::vector const& optimizationParameters, amici::SensitivityOrder sensitivityOrder, - std::vector const& conditionIndices) + std::vector const& conditionIndices) const { // TODO avoid copy optimizationParameters; reuse;; for const& in work // package need to split into(de)serialize diff --git a/src/parpeamici/hierarchicalOptimization.cpp b/src/parpeamici/hierarchicalOptimization.cpp index f12e66769..dfb569a73 100644 --- a/src/parpeamici/hierarchicalOptimization.cpp +++ b/src/parpeamici/hierarchicalOptimization.cpp @@ -86,7 +86,7 @@ void HierarchicalOptimizationWrapper::init() { if (errorModel != ErrorModel::normal) { - throw ParPEException("Only gaussian noise is supported so far."); + throw ParPEException("Only Gaussian noise is supported so far."); } /* Some functions currently expect these lists to be sorted, therefore @@ -1304,7 +1304,7 @@ HierarchicalOptimizationReporter::iterationFinished( // We don't have the full parameter vector, only the outer // parameters so we can't append them due to different dimension // TODO: save both, outer + combined? can easily save outer + inner - // separetly + // separately std::vector nanParameters(cached_full_parameters_.size(), NAN); diff --git a/src/parpeamici/multiConditionDataProvider.cpp b/src/parpeamici/multiConditionDataProvider.cpp index 6d5ead756..7075a4a4d 100644 --- a/src/parpeamici/multiConditionDataProvider.cpp +++ b/src/parpeamici/multiConditionDataProvider.cpp @@ -63,7 +63,7 @@ int MultiConditionDataProviderHDF5::getNumberOfSimulationConditions() const { // TODO: add additional layer for selection of condition indices (for - // testing and later for minibatch) + // testing and later for mini-batch) // -> won't need different file for testing/validation splits // TODO: cache @@ -378,7 +378,7 @@ MultiConditionDataProviderHDF5::getOptimizationParametersUpperBounds( auto dataset = file_.openDataSet(hdf5_parameter_max_path_); auto dataspace = dataset.getSpace(); - // hdf5ParameterMaxPath dimensions dont match + // hdf5ParameterMaxPath dimensions don't match Expects(dataspace.getSimpleExtentNdims() == 1); hsize_t dim = 0; dataspace.getSimpleExtentDims(&dim); diff --git a/src/parpeamici/optimizationApplication.cpp b/src/parpeamici/optimizationApplication.cpp index 4f7c068da..0e472448b 100644 --- a/src/parpeamici/optimizationApplication.cpp +++ b/src/parpeamici/optimizationApplication.cpp @@ -58,7 +58,7 @@ int OptimizationApplication::init(int argc, char **argv) { return status; } -void OptimizationApplication::runMultiStarts() +void OptimizationApplication::runMultiStarts() const { // TODO: use uniqe_ptr, not ref MultiStartOptimization optimizer(*multiStartOptimizationProblem, true, diff --git a/src/parpecommon/CMakeLists.txt b/src/parpecommon/CMakeLists.txt index f45ca2056..b2860b850 100644 --- a/src/parpecommon/CMakeLists.txt +++ b/src/parpecommon/CMakeLists.txt @@ -28,6 +28,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PUBLIC ${HDF5_LIBRARIES} + PRIVATE stdc++fs ) if(${PARPE_ENABLE_MPI}) diff --git a/src/parpecommon/hdf5Misc.cpp b/src/parpecommon/hdf5Misc.cpp index b0797804d..65173246b 100644 --- a/src/parpecommon/hdf5Misc.cpp +++ b/src/parpecommon/hdf5Misc.cpp @@ -1,3 +1,12 @@ +/** + * Functions for HDF5 I/O + * + * NOTE: Use only `const char*` versions of any HDF5 functions, not the + * `std::string` version. On many systems, HDF5 libraries are still not compiled + * with C++11 support, but use the old C++03 ABI, which will lead to linking + * issues. + */ + #include #include #include @@ -9,7 +18,22 @@ #include #include #include -#include + +#ifdef __has_include +# if __has_include() +# include +using std::filesystem::path; +using std::filesystem::create_directories; +# elif __has_include() +# include +using std::experimental::filesystem::path; +using std::experimental::filesystem::create_directories; +# else +# error "Missing " +# endif +#else +#error "Missing " +#endif #include @@ -82,7 +106,7 @@ void hdf5CreateGroup(const H5::H5File &file, const std::string &groupPath, bool H5::LinkCreatPropList groupCreationPropertyList(groupCreationPropertyListTmp); try { - auto group = file.createGroup(groupPath, groupCreationPropertyList); + auto group = file.createGroup(groupPath.c_str(), groupCreationPropertyList); } catch (H5::Exception const&) { throw(HDF5Exception("Failed to create group in hdf5CreateGroup:" + groupPath)); @@ -106,7 +130,7 @@ void hdf5CreateExtendableDouble2DArray(const H5::H5File &file, H5::DSetCreatPropList dSetCreatPropList; dSetCreatPropList.setChunk(rank, chunkDimensions); - auto dataset = file.createDataSet(datasetPath, H5::PredType::NATIVE_DOUBLE, + auto dataset = file.createDataSet(datasetPath.c_str(), H5::PredType::NATIVE_DOUBLE, dataspace, dSetCreatPropList); } @@ -114,7 +138,7 @@ void hdf5Extend2ndDimensionAndWriteToDouble2DArray(const H5::H5File &file, const { std::lock_guard lock(mutexHdf); - auto dataset = file.openDataSet(datasetPath); + auto dataset = file.openDataSet(datasetPath.c_str()); // check rank auto filespace = dataset.getSpace(); @@ -152,7 +176,7 @@ void hdf5Extend3rdDimensionAndWriteToDouble3DArray(const H5::H5File &file, { std::lock_guard lock(mutexHdf); - auto dataset = file.openDataSet(datasetPath); + auto dataset = file.openDataSet(datasetPath.c_str()); // extend auto filespace = dataset.getSpace(); @@ -187,7 +211,7 @@ void hdf5CreateOrExtendAndWriteToDouble2DArray(const H5::H5File &file, std::string fullDatasetPath = std::string(parentPath) + "/" + datasetName; - if (!file.nameExists(fullDatasetPath)) { + if (!file.nameExists(fullDatasetPath.c_str())) { hdf5CreateExtendableDouble2DArray( file, fullDatasetPath, buffer.size()); } @@ -206,7 +230,7 @@ void hdf5CreateOrExtendAndWriteToDouble3DArray(const H5::H5File &file, std::string fullDatasetPath = std::string(parentPath) + "/" + datasetName; - if (!file.nameExists(fullDatasetPath)) { + if (!file.nameExists(fullDatasetPath.c_str())) { hdf5CreateExtendableDouble3DArray( file, fullDatasetPath, stride1, stride2); } @@ -228,7 +252,7 @@ void hdf5CreateOrExtendAndWriteToInt2DArray(const H5::H5File &file, auto fullDatasetPath = std::string(parentPath) + "/" + datasetName; - if (!file.nameExists(fullDatasetPath)) { + if (!file.nameExists(fullDatasetPath.c_str())) { hdf5CreateExtendableInt2DArray( file, fullDatasetPath, buffer.size()); } @@ -243,7 +267,7 @@ void hdf5Extend2ndDimensionAndWriteToInt2DArray(const H5::H5File &file, { std::lock_guard lock(mutexHdf); - auto dataset = file.openDataSet(datasetPath); + auto dataset = file.openDataSet(datasetPath.c_str()); // extend auto filespace = dataset.getSpace(); @@ -287,7 +311,7 @@ void hdf5CreateExtendableInt2DArray(const H5::H5File &file, datasetCreationProperty.setChunk(rank, chunkDimensions); Expects(H5Tget_size(H5T_NATIVE_INT) == sizeof(int)); - auto dataset = file.createDataSet(datasetPath, H5::PredType::NATIVE_INT, + auto dataset = file.createDataSet(datasetPath.c_str(), H5::PredType::NATIVE_INT, dataspace, datasetCreationProperty); } @@ -311,7 +335,7 @@ void hdf5CreateExtendableDouble3DArray(const H5::H5File &file, H5::DSetCreatPropList datasetCreationProperty; datasetCreationProperty.setChunk(rank, chunkDimensions); - auto dataset = file.createDataSet(datasetPath, H5::PredType::NATIVE_DOUBLE, + auto dataset = file.createDataSet(datasetPath.c_str(), H5::PredType::NATIVE_DOUBLE, dataspace, datasetCreationProperty); } @@ -327,7 +351,7 @@ void hdf5Read2DDoubleHyperslab(const H5::H5File &file, std::lock_guard lock(mutexHdf); - auto dataset = file.openDataSet(path); + auto dataset = file.openDataSet(path.c_str()); auto dataspace = dataset.getSpace(); hsize_t offset[] = {offset0, offset1}; hsize_t count[] = {size0, size1}; @@ -357,7 +381,7 @@ std::vector hdf5Read1DIntegerHyperslab(H5::H5File const& file, { std::lock_guard lock(mutexHdf); - H5::DataSet dataset = file.openDataSet(path); + H5::DataSet dataset = file.openDataSet(path.c_str()); H5::DataSpace filespace = dataset.getSpace(); const int ndims = filespace.getSimpleExtentNdims(); @@ -387,7 +411,7 @@ std::vector hdf5Read2DIntegerHyperslab(const H5::H5File &file, { std::lock_guard lock(mutexHdf); - H5::DataSet dataset = file.openDataSet(path); + H5::DataSet dataset = file.openDataSet(path.c_str()); H5::DataSpace filespace = dataset.getSpace(); const int ndims = filespace.getSimpleExtentNdims(); @@ -432,7 +456,7 @@ void hdf5Read3DDoubleHyperslab(H5::H5File const& file, std::lock_guard lock(mutexHdf); const int rank = 3; - auto dataset = file.openDataSet(path); + auto dataset = file.openDataSet(path.c_str()); auto dataspace = dataset.getSpace(); hsize_t offset[] = {offset0, offset1, offset2}; hsize_t count[] = {size0, size1, size2}; @@ -508,10 +532,10 @@ H5::H5File hdf5CreateFile(const std::string &filename, bool overwrite) { // Create parent folders - std::filesystem::path dirname(filename); + path dirname(filename); dirname.remove_filename(); if(!dirname.empty()) - std::filesystem::create_directories(dirname); + create_directories(dirname); std::lock_guard lock(mutexHdf); @@ -524,7 +548,7 @@ H5::H5File hdf5CreateFile(const std::string &filename, } try { - return H5::H5File(filename, H5F_ACC_TRUNC); + return H5::H5File(filename.c_str(), H5F_ACC_TRUNC); } catch (H5::Exception const& e) { printBacktrace(); throw HDF5Exception("hdf5CreateFile: Failed to create file %s. " @@ -545,7 +569,7 @@ void hdf5GetDatasetDimensions(const H5::H5File &file, std::lock_guard lock(mutexHdf); H5_SAVE_ERROR_HANDLER; - auto dataset = file.openDataSet(path); + auto dataset = file.openDataSet(path.c_str()); auto dataspace = dataset.getSpace(); const int nDimsActual = dataspace.getSimpleExtentNdims(); @@ -611,7 +635,7 @@ void hdf5CreateExtendableString1DArray(const H5::H5File &file, const std::string Expects(H5T_STRING == H5Tget_class(strType.getId()) && H5Tis_variable_str(strType.getId())); - file.createDataSet(datasetPath, strType, + file.createDataSet(datasetPath.c_str(), strType, dataspace, datasetCreationProperty); } @@ -620,7 +644,7 @@ void hdf5ExtendAndWriteToString1DArray(const H5::H5File &file, const std::string { std::lock_guard lock(mutexHdf); - auto dataset = file.openDataSet(datasetPath); + auto dataset = file.openDataSet(datasetPath.c_str()); // extend auto filespace = dataset.getSpace(); @@ -653,7 +677,7 @@ void hdf5CreateOrExtendAndWriteToString1DArray(const H5::H5File &file, std::string fullDatasetPath = std::string(parentPath) + "/" + datasetName; - if (!file.nameExists(fullDatasetPath)) { + if (!file.nameExists(fullDatasetPath.c_str())) { hdf5CreateExtendableString1DArray(file, fullDatasetPath); } @@ -666,7 +690,7 @@ H5::H5File hdf5OpenForReading(const std::string &hdf5Filename) H5_SAVE_ERROR_HANDLER; try { - auto file = H5::H5File(hdf5Filename, H5F_ACC_RDONLY); + auto file = H5::H5File(hdf5Filename.c_str(), H5F_ACC_RDONLY); H5_RESTORE_ERROR_HANDLER; return file; } catch (...) { @@ -690,12 +714,12 @@ H5::H5File hdf5OpenForAppending(const std::string &hdf5Filename) // Open for append or create try { - file = H5::H5File(hdf5Filename, H5F_ACC_RDWR); + file = H5::H5File(hdf5Filename.c_str(), H5F_ACC_RDWR); H5_RESTORE_ERROR_HANDLER; } catch (H5::FileIException const&) { H5_RESTORE_ERROR_HANDLER; // create if doesn't exist - file = H5::H5File(hdf5Filename, H5F_ACC_EXCL); + file = H5::H5File(hdf5Filename.c_str(), H5F_ACC_EXCL); } return file; @@ -705,7 +729,7 @@ std::vector hdf5Read1dStringDataset( H5::H5File const& file, const std::string &datasetPath) { [[maybe_unused]] auto lock = hdf5MutexGetLock(); - auto dataset = file.openDataSet(datasetPath); + auto dataset = file.openDataSet(datasetPath.c_str()); auto filespace = dataset.getSpace(); const int ndims = filespace.getSimpleExtentNdims(); @@ -744,8 +768,8 @@ void hdf5Write1dStringDataset( || !H5Tis_variable_str(tid1.getId()), "String type failure."); hdf5EnsureGroupExists(file, parentPath); - auto dataset = file.createDataSet(parentPath + "/" + datasetPath, - tid1, sid1); + std::string fullpath(parentPath + "/" + datasetPath); + auto dataset = file.createDataSet(fullpath.c_str(), tid1, sid1); // we need character pointers std::vector charPtrBuffer(buffer.size()); diff --git a/src/parpecommon/logging.cpp b/src/parpecommon/logging.cpp index 0d9037998..6a41291b2 100644 --- a/src/parpecommon/logging.cpp +++ b/src/parpecommon/logging.cpp @@ -31,12 +31,10 @@ std::string printfToString(const char *fmt, va_list ap) { ++size; // actual formatting - auto buf = new char[size]; - size = vsnprintf(buf, size, fmt, ap); - std::string str(buf, size); - delete[] buf; + auto buf = std::make_unique(size); + size = vsnprintf(buf.get(), size, fmt, ap); - return str; + return std::string(buf.get(), size); } void logmessage(loglevel lvl, const char *format, ...) diff --git a/src/parpecommon/misc.cpp b/src/parpecommon/misc.cpp index eb1e4989d..32eefa008 100644 --- a/src/parpecommon/misc.cpp +++ b/src/parpecommon/misc.cpp @@ -82,29 +82,32 @@ std::string getBacktrace(int nMaxFrames) void *callstack[nMaxFrames]; int nFrames = backtrace(callstack, nMaxFrames); - char **symbols = backtrace_symbols(callstack, nFrames); - + auto symbols = std::unique_ptr{ + backtrace_symbols(callstack, nFrames), free}; char buf[1024]; + for (int i = 0; i < nFrames; i++) { Dl_info info; if (dladdr(callstack[i], &info) && info.dli_sname) { - char *demangled = nullptr; + auto demangled = + std::unique_ptr{nullptr, free}; int status = -1; if (info.dli_sname[0] == '_') - demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status); - snprintf(buf, sizeof(buf), "%-3d %*p %s + %td\n", - i, int(2 + sizeof(void*) * 2), callstack[i], - status == 0 ? demangled : - info.dli_sname == nullptr ? symbols[i] : info.dli_sname, + demangled.reset( + abi::__cxa_demangle(info.dli_sname,nullptr, nullptr, + &status)); + snprintf(buf, sizeof(buf), "%-3d %*p %s + %td\n", i, + int(2 + sizeof(void*) * 2), callstack[i], + status == 0 ? demangled.get() : + info.dli_sname == nullptr ? + symbols.get()[i] : info.dli_sname, (char *)callstack[i] - (char *)info.dli_saddr); - free(demangled); } else { snprintf(buf, sizeof(buf), "%-3d %*p %s\n", - i, int(2 + sizeof(void*) * 2), callstack[i], symbols[i]); + i, int(2 + sizeof(void*) * 2), callstack[i], symbols.get()[i]); } oss << buf; } - free(symbols); if (nFrames == nMaxFrames) oss << "[truncated]\n"; diff --git a/src/parpecommon/parpeConfig.h.in b/src/parpecommon/parpeConfig.h.in index ffc483176..2fa8b2c31 100644 --- a/src/parpecommon/parpeConfig.h.in +++ b/src/parpecommon/parpeConfig.h.in @@ -2,6 +2,8 @@ #define PARPE_CONFIG_H #cmakedefine PARPE_ENABLE_MPI + +#cmakedefine PARPE_ENABLE_FIDES #cmakedefine PARPE_ENABLE_IPOPT #cmakedefine PARPE_ENABLE_CERES #cmakedefine PARPE_ENABLE_FSQP diff --git a/src/parpeoptimization/CMakeLists.txt b/src/parpeoptimization/CMakeLists.txt index 0316b7dfb..f584d07bc 100644 --- a/src/parpeoptimization/CMakeLists.txt +++ b/src/parpeoptimization/CMakeLists.txt @@ -27,6 +27,14 @@ set(HEADER_LIST add_library(${PROJECT_NAME} ${SRC_LIST}) +if(${PARPE_ENABLE_FIDES}) + target_sources(${PROJECT_NAME} + PRIVATE localOptimizationFides.cpp) + list(APPEND HEADER_LIST + localOptimizationFides.h) + target_link_libraries(${PROJECT_NAME} PUBLIC Fides::fides) +endif(${PARPE_ENABLE_FIDES}) + if(${PARPE_ENABLE_IPOPT}) target_sources(${PROJECT_NAME} PRIVATE localOptimizationIpopt.cpp diff --git a/src/parpeoptimization/localOptimizationDlib.cpp b/src/parpeoptimization/localOptimizationDlib.cpp index d2116fe54..66aa04597 100644 --- a/src/parpeoptimization/localOptimizationDlib.cpp +++ b/src/parpeoptimization/localOptimizationDlib.cpp @@ -1,87 +1,100 @@ -#include -#include "logging.h" -#include "optimizationOptions.h" -#include "optimizationProblem.h" +#include + +#include +#include +#include + #include #include -namespace parpe { - typedef dlib::matrix column_vector; typedef dlib::matrix general_matrix; -column_vector dlibColumnVectorFromDoubleArray(double const *src, int len) { - column_vector colVec(len); - std::copy(src, src + len, colVec.begin()); - return colVec; +namespace gsl { + +template < + typename T, + long num_rows, + long num_cols, + typename mem_manager, + typename layout + > +span make_span(dlib::matrix const& matrix) { + return span(matrix.begin(), matrix.size()); } -int parpe::OptimizerDlibLineSearch::optimize(OptimizationProblem *problem) -{ - int status = 0; - - int numParams = problem->getNumOptimizationParameters(); - column_vector startingPoint = dlibColumnVectorFromDoubleArray(problem->getInitialParameters(), numParams); - column_vector min = dlibColumnVectorFromDoubleArray(problem->getParametersMin(), numParams); - column_vector max = dlibColumnVectorFromDoubleArray(problem->getParametersMax(), numParams); - - clock_t timeBegin = clock(); - clock_t timeIterBegin = clock(); - - double finalFVal = dlib::find_min_box_constrained( - dlib::lbfgs_search_strategy(10), - dlib::objective_delta_stop_strategy( - 1e-9, problem->getOptimizationOptions().maxOptimizerIterations), - [&problem](const column_vector& x){ - // objective function - static __thread int numFunctionCalls = 0; - clock_t timeBegin = clock(); - - double fval = NAN; - problem->evaluateObjectiveFunction(x.begin(), &fval, nullptr); +template < + typename T, + long num_rows, + long num_cols, + typename mem_manager, + typename layout + > +span make_span(dlib::matrix &matrix) { + return span(matrix.begin(), matrix.size()); +} - if(problem->getOptimizationOptions().printToStdout) - std::cout<logObjectiveFunctionEvaluation(x.begin(), fval, nullptr, - numFunctionCalls, wallTime); - return fval; +column_vector dlibColumnVectorFromDoubleArray(double const *src, int len) { + column_vector colVec(len); + std::copy(src, src + len, colVec.begin()); + return colVec; +} - }, - [&problem, &timeIterBegin](const column_vector& x){ - // objective function gradient - static __thread int numFunctionCalls = 0; - clock_t timeBegin = clock(); +std::tuple > +parpe::OptimizerDlibLineSearch::optimize(OptimizationProblem *problem) +{ + int numParams = problem->cost_fun_->numParameters(); - double fVal = NAN; - column_vector fGrad(problem->getNumOptimizationParameters()); - problem->evaluateObjectiveFunction(x.begin(), &fVal, fGrad.begin()); + column_vector startingPoint(numParams); + problem->fillInitialParameters(gsl::make_span(startingPoint)); - if(problem->getOptimizationOptions().printToStdout) - std::cout<<" g"<fillParametersMin(gsl::make_span(startingPoint)); - clock_t timeEnd = clock(); - double wallTime = (double)(timeEnd - timeBegin) / CLOCKS_PER_SEC; -// double wallTimeIter = (double)(timeEnd - timeIterBegin) / CLOCKS_PER_SEC; - timeIterBegin = clock(); + column_vector max(numParams); + problem->fillParametersMax(gsl::make_span(startingPoint)); - problem->logObjectiveFunctionEvaluation(x.begin(), fVal, fGrad.begin(), numFunctionCalls, wallTime); - problem->intermediateFunction( - 0, numFunctionCalls, fVal, 0, 0, 0, 0, 0, 0, 0, 0); - return fGrad; - }, - startingPoint, min, max); - clock_t timeEnd = clock(); - double wallTime = (double)(timeEnd - timeBegin) / CLOCKS_PER_SEC; + auto optimizationController = problem->getReporter(); - problem->logOptimizerFinished(finalFVal, startingPoint.begin(), wallTime, 0); + optimizationController->starting(gsl::make_span(startingPoint)); - return status; + double finalFVal = dlib::find_min_box_constrained( + dlib::lbfgs_search_strategy(10), + dlib::objective_delta_stop_strategy( + 1e-9, problem->getOptimizationOptions().maxOptimizerIterations), + [&optimizationController](const column_vector& x){ + // objective function + double fval = NAN; + optimizationController->evaluate( + gsl::make_span(x), + fval, gsl::span(nullptr, 0)); + + return fval; + + }, + [&optimizationController](const column_vector& x){ + // objective function gradient + + double fVal = NAN; + column_vector fGrad(optimizationController->numParameters()); + optimizationController->evaluate( + gsl::make_span(x), fVal, gsl::make_span(fGrad)); + return fGrad; + }, + startingPoint, min, max); + + optimizationController->finished( + finalFVal, gsl::make_span(startingPoint), 0); + + return std::make_tuple( + 0, finalFVal, + std::vector(startingPoint.begin(), startingPoint.end())); } } // namespace parpe diff --git a/src/parpeoptimization/localOptimizationFides.cpp b/src/parpeoptimization/localOptimizationFides.cpp new file mode 100644 index 000000000..cba2b17ad --- /dev/null +++ b/src/parpeoptimization/localOptimizationFides.cpp @@ -0,0 +1,162 @@ +#include + +#include "parpecommon/logging.h" +#include "parpeoptimization/optimizationOptions.h" +#include "parpeoptimization/optimizationProblem.h" + +#include +#include + +using blaze::columnVector; +using blaze::CustomVector; +using blaze::DynamicVector; +using blaze::unaligned; +using blaze::unpadded; +using UnalignedUnpadded = CustomVector; + +namespace gsl { + +template +auto +make_span(DynamicVector& dv) +{ + return gsl::span(dv.data(), dv.size()); +} + +template +auto +make_span(DynamicVector const& dv) +{ + return gsl::span(dv.data(), dv.size()); +} + +} // namespace gsl + +namespace parpe { + +fides::Options +get_optimization_options(OptimizationOptions const& parpe_options) +{ + fides::Options fides_options; + fides_options.maxiter = parpe_options.maxOptimizerIterations; + + parpe_options.for_each( + [&fides_options](const std::pair& pair, int) { + const std::string& key = pair.first; + const std::string& val = pair.second; + auto &options = fides_options; + if (key == "maxiter") { + options.maxiter = std::stoi(val); + } else if (key == "maxtime") { + options.maxtime = std::chrono::seconds(std::stoi(val)); + } else if (key == "fatol") { + options.fatol = std::stod(val); + } else if (key == "frtol") { + options.frtol = std::stod(val); + } else if (key == "xtol") { + options.xtol = std::stod(val); + } else if (key == "gatol") { + options.gatol = std::stod(val); + } else if (key == "grtol") { + options.grtol = std::stod(val); + } else if (key == "subspace_solver") { + auto result = std::find_if( + fides::subspace_dim_to_str.cbegin(), + fides::subspace_dim_to_str.cend(), + [key](const auto& kv) { return kv.second == key; }); + if (result != fides::subspace_dim_to_str.cend()) + options.subspace_solver = result->first; + else + logmessage(LOGLVL_WARNING, + "Invalid value %s provided for option " + "'subspace_solver'. Ignoring.", + val.c_str()); + } else if (key == "stepback_strategy") { + auto result = std::find_if( + fides::step_back_strategy_str.cbegin(), + fides::step_back_strategy_str.cend(), + [key](const auto& kv) { return kv.second == key; }); + if (result != fides::step_back_strategy_str.cend()) + options.stepback_strategy = result->first; + else + logmessage(LOGLVL_WARNING, + "Invalid value %s provided for option " + "'stepback_strategy'. Ignoring.", + val.c_str()); + } else if (key == "theta_max") { + options.theta_max = std::stoi(val); + } else if (key == "delta_init") { + options.delta_init = std::stoi(val); + } else if (key == "mu") { + options.mu = std::stoi(val); + } else if (key == "eta") { + options.eta = std::stoi(val); + } else if (key == "gamma1") { + options.gamma1 = std::stoi(val); + } else if (key == "gamma2") { + options.gamma2 = std::stoi(val); + } else if (key == "refine_stepback") { + options.refine_stepback = std::stoi(val); + } else { + logmessage(LOGLVL_WARNING, + "Ignoring unknown optimization option %s.", + key.c_str()); + return; + } + + logmessage(LOGLVL_DEBUG, + "Set optimization option %s to %s.", + key.c_str(), + val.c_str()); + }, + 0); + + return fides_options; +} + +std::tuple> +OptimizerFides::optimize(OptimizationProblem* problem) +{ + auto reporter = problem->getReporter(); + auto numParams = + static_cast(problem->cost_fun_->numParameters()); + + DynamicVector x0(numParams); + problem->fillInitialParameters(x0); + + DynamicVector lb(numParams); + problem->fillParametersMin(lb); + + DynamicVector ub(numParams); + problem->fillParametersMax(ub); + + WallTimer optimization_timer; + + auto fun = [&problem](DynamicVector x) { + static __thread int numFunctionCalls = 0; + ++numFunctionCalls; + DynamicVector g(x.size(), NAN); + double fval = NAN; + problem->cost_fun_->evaluate( + gsl::make_span(x), fval, gsl::make_span(g), nullptr, nullptr); + + return std::make_tuple(fval, g, blaze::DynamicMatrix()); + }; + + auto fides_options = + get_optimization_options(problem->getOptimizationOptions()); + // TODO to config + fides::BFGS hessian_approximation; + fides::Optimizer optimizer( + fun, lb, ub, fides_options, &hessian_approximation); + + reporter->starting(x0); + auto [fval, x, grad, hess] = optimizer.minimize(x0); + reporter->finished(fval, x, static_cast(optimizer.exit_flag_)); + + return std::make_tuple(static_cast(optimizer.exit_flag_) <= 0, + fval, + std::vector(x.begin(), x.end())); +} + +} // namespace parpe diff --git a/src/parpeoptimization/optimizationOptions.cpp b/src/parpeoptimization/optimizationOptions.cpp index 57cbf34c9..455284a2e 100644 --- a/src/parpeoptimization/optimizationOptions.cpp +++ b/src/parpeoptimization/optimizationOptions.cpp @@ -5,6 +5,10 @@ #include #endif +#ifdef PARPE_ENABLE_FIDES +#include +#endif + #ifdef PARPE_ENABLE_IPOPT #include #endif @@ -79,7 +83,7 @@ void optimizationOptionsFromAttribute(H5::H5Object& loc, } } -Optimizer *OptimizationOptions::createOptimizer() const { +std::unique_ptr OptimizationOptions::createOptimizer() const { return optimizerFactory(optimizer); } @@ -127,6 +131,9 @@ std::unique_ptr OptimizationOptions::fromHDF5(const H5::H5F std::string optimizerPath; switch(o->optimizer) { + case optimizerName::OPTIMIZER_FIDES: + optimizerPath = std::string(hdf5path) + "/fides"; + break; case optimizerName::OPTIMIZER_CERES: optimizerPath = std::string(hdf5path) + "/ceres"; break; @@ -258,55 +265,72 @@ void OptimizationOptions::setOption(const std::string& key, std::string value) options[key] = std::move(value); } -Optimizer* optimizerFactory(optimizerName optimizer) +std::unique_ptr optimizerFactory(optimizerName optimizer) { switch (optimizer) { + case optimizerName::OPTIMIZER_FIDES: +#ifdef PARPE_ENABLE_FIDES + return std::make_unique(); +#else + return nullptr; +#endif case optimizerName::OPTIMIZER_IPOPT: #ifdef PARPE_ENABLE_IPOPT - return new OptimizerIpOpt(); + return std::make_unique(); #else return nullptr; #endif case optimizerName::OPTIMIZER_CERES: #ifdef PARPE_ENABLE_CERES - return new OptimizerCeres(); + return std::make_unique(); #else return nullptr; #endif case optimizerName::OPTIMIZER_DLIB: #ifdef PARPE_ENABLE_DLIB - return new OptimizerDlibLineSearch(); + return std::make_unique(); #else return nullptr; #endif case optimizerName::OPTIMIZER_TOMS611: #ifdef PARPE_ENABLE_TOMS611 - return new OptimizerToms611TrustRegionSumsl(); + return std::make_unique(); #else return nullptr; #endif case optimizerName::OPTIMIZER_FSQP: #ifdef PARPE_ENABLE_FSQP - return new OptimizerFsqp(); + return std::make_unique(); #else return nullptr; #endif case optimizerName::OPTIMIZER_MINIBATCH_1: throw ParPEException("optimizerFactory() cannot be used with " - "minibatch optimizer."); + "mini-batch optimizer."); } return nullptr; } -void printAvailableOptimizers(std::string prefix) +void printAvailableOptimizers(std::string const& prefix) { optimizerName optimizer {optimizerName::OPTIMIZER_IPOPT}; // Note: Keep fall-through switch statement, so compiler will warn us about // any addition to optimizerName switch (optimizer) { + case optimizerName::OPTIMIZER_FIDES: +#ifdef PARPE_ENABLE_FIDES + std::cout<(optimizerName::OPTIMIZER_FIDES) + <<" enabled\n"; +#else + std::cout<(optimizerName::OPTIMIZER_FIDES) + <<" disabled\n"; +#endif + [[fallthrough]]; case optimizerName::OPTIMIZER_IPOPT: #ifdef PARPE_ENABLE_IPOPT std::cout< -TEST(simulationWorkerAmici, testSerializeResultPackageMessage) +TEST(SimulationWorkerAmici, SerializeResultPackageMessage) { parpe::AmiciSimulationRunner::AmiciResultPackageSimple results = { 1.1, diff --git a/tests/parpeamici/hierarchicalOptimizationTest.h b/tests/parpeamici/hierarchicalOptimizationTest.cpp similarity index 96% rename from tests/parpeamici/hierarchicalOptimizationTest.h rename to tests/parpeamici/hierarchicalOptimizationTest.cpp index d59108f40..f0f2435a9 100644 --- a/tests/parpeamici/hierarchicalOptimizationTest.h +++ b/tests/parpeamici/hierarchicalOptimizationTest.cpp @@ -24,7 +24,7 @@ using ::testing::ReturnRefOfCopy; using ::testing::SetArgReferee; using ::testing::DoAll; -TEST(hierarchicalOptimization1, reader) { +TEST(HierarchicalOptimization1, Reader) { // mappingToObservable = np.array([[ 0, 1, 0], [ 0, 2, 0], [ 1, 1, 1], [1, 2, 1], [1, 3, 1]]) parpe::AnalyticalParameterHdf5Reader r(H5::H5File(TESTFILE, H5F_ACC_RDONLY), @@ -90,7 +90,7 @@ class AmiciSummedGradientFunctionMock : public parpe::AmiciSummedGradientFunctio }; -class hierarchicalOptimization : public ::testing::Test { +class HierarchicalOptimization : public ::testing::Test { protected: int numParameters_ = 4; @@ -126,7 +126,7 @@ class hierarchicalOptimization : public ::testing::Test { -TEST_F(hierarchicalOptimization, hierarchicalOptimization) { +TEST_F(HierarchicalOptimization, HierarchicalOptimization) { auto funUnqiue = std::make_unique(); auto fun = funUnqiue.get(); ON_CALL(*fun, numParameters()).WillByDefault(Return(numParameters_)); @@ -229,7 +229,7 @@ TEST_F(hierarchicalOptimization, hierarchicalOptimization) { EXPECT_EQ(2, hierarchicalOptimizationWrapper.numParameters()); } -TEST_F(hierarchicalOptimization, testNoAnalyticalParameters) { +TEST_F(HierarchicalOptimization, NoAnalyticalParameters) { // Should only call fun::evaluate, nothing else // setup @@ -262,7 +262,7 @@ TEST_F(hierarchicalOptimization, testNoAnalyticalParameters) { } -TEST_F(hierarchicalOptimization, testComputeAnalyticalScalings) { +TEST_F(HierarchicalOptimization, ComputeAnalyticalScalings) { /* data * measurement = data * 10 * check scaling = 10 @@ -325,7 +325,7 @@ TEST_F(hierarchicalOptimization, testComputeAnalyticalScalings) { } -TEST_F(hierarchicalOptimization, testComputeAnalyticalOffsets) { +TEST_F(HierarchicalOptimization, ComputeAnalyticalOffsets) { /* data * measurement = data + 10 * check offset = 10 @@ -370,7 +370,7 @@ TEST_F(hierarchicalOptimization, testComputeAnalyticalOffsets) { EXPECT_EQ(1.0, scaledOffset2); } -TEST_F(hierarchicalOptimization, applyOptimalScaling) { +TEST_F(HierarchicalOptimization, ApplyOptimalScaling) { constexpr int numObservables = 2; // constexpr int numTimepoints = 2; constexpr int scalingIdx = 0; @@ -398,7 +398,7 @@ TEST_F(hierarchicalOptimization, applyOptimalScaling) { } -TEST_F(hierarchicalOptimization, applyOptimalOffset) { +TEST_F(HierarchicalOptimization, ApplyOptimalOffset) { constexpr int numObservables = 2; // constexpr int numTimepoints = 2; constexpr int offsetIdx = 0; @@ -425,7 +425,7 @@ TEST_F(hierarchicalOptimization, applyOptimalOffset) { } -TEST_F(hierarchicalOptimization, testScaling) { +TEST_F(HierarchicalOptimization, Scaling) { EXPECT_EQ(42.0, amici::getUnscaledParameter(42.0, amici::ParameterScaling::none)); EXPECT_EQ(42.0, @@ -444,7 +444,7 @@ TEST_F(hierarchicalOptimization, testScaling) { amici::ParameterScaling::ln)); } -TEST(hierarchicalOptimization1, spliceParameters) { +TEST(HierarchicalOptimization1, SpliceParameters) { const std::vector fullParametersExp {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0}; @@ -466,7 +466,7 @@ TEST(hierarchicalOptimization1, spliceParameters) { EXPECT_EQ(fullParametersExp, fullParametersAct); } -TEST(hierarchicalOptimization1, spliceParametersNothingToDo) { +TEST(HierarchicalOptimization1, SpliceParametersNothingToDo) { const std::vector fullParametersExp {0.0, 1.0, 2.0}; const std::vector reducedParameters {0.0, 1.0, 2.0}; @@ -489,7 +489,7 @@ TEST(hierarchicalOptimization1, spliceParametersNothingToDo) { } -TEST(hierarchicalOptimization1, fillFilteredParams) { +TEST(HierarchicalOptimization1, FillFilteredParams) { const std::vector resultExp {1.0, 2.0, 3.0, 4.0, 5.0}; const std::vector valuesToFilter {9.0, 1.0, 2.0, 9.0, 9.0, 3.0, 4.0, 5.0, 9.0}; @@ -504,7 +504,7 @@ TEST(hierarchicalOptimization1, fillFilteredParams) { } -TEST_F(hierarchicalOptimization, testWrappedFunIsCalledWithGradient) { +TEST_F(HierarchicalOptimization, WrappedFunIsCalledWithGradient) { // setup auto fun = std::make_unique(); auto funNonOwning = fun.get(); @@ -577,7 +577,7 @@ TEST_F(hierarchicalOptimization, testWrappedFunIsCalledWithGradient) { hierarchicalWrapper.evaluate(parameters, fval, gsl::span(), nullptr, nullptr); } -TEST(hierarchicalOptimization1, likelihoodOfMatchingData) { +TEST(HierarchicalOptimization1, LikelihoodOfMatchingData) { const std::vector data {1.0, 2.0, 3.0}; const std::vector sigmas {1.0, 1.0, 1.0}; @@ -590,7 +590,7 @@ TEST(hierarchicalOptimization1, likelihoodOfMatchingData) { } -TEST_F(hierarchicalOptimization, problemWrapper) { +TEST_F(HierarchicalOptimization, ProblemWrapper) { //std::unique_ptr problem(new parpe::QuadraticTestProblem()); //auto hCost = std::make_unique(); //auto wrappedFun = dynamic_cast*>(wrappedProblem->costFun.get()); diff --git a/tests/parpeamici/main.cpp b/tests/parpeamici/main.cpp deleted file mode 100644 index 36e8eee07..000000000 --- a/tests/parpeamici/main.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "amiciSimulationRunnerTest.h" -#include "multiConditionDataProviderTest.h" -#include "multiConditionProblemTest.h" -#include "simulationResultWriterTest.h" -#include "hierarchicalOptimizationTest.h" - -#include - -#include -#include - -int main(int argc, char *argv[]) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/tests/parpeamici/multiConditionDataProviderTest.h b/tests/parpeamici/multiConditionDataProviderTest.cpp similarity index 100% rename from tests/parpeamici/multiConditionDataProviderTest.h rename to tests/parpeamici/multiConditionDataProviderTest.cpp diff --git a/tests/parpeamici/multiConditionProblemTest.h b/tests/parpeamici/multiConditionProblemTest.cpp similarity index 100% rename from tests/parpeamici/multiConditionProblemTest.h rename to tests/parpeamici/multiConditionProblemTest.cpp diff --git a/tests/parpeamici/simulationResultWriterTest.h b/tests/parpeamici/simulationResultWriterTest.cpp similarity index 95% rename from tests/parpeamici/simulationResultWriterTest.h rename to tests/parpeamici/simulationResultWriterTest.cpp index 3ab82d990..7ba3f8e4c 100644 --- a/tests/parpeamici/simulationResultWriterTest.h +++ b/tests/parpeamici/simulationResultWriterTest.cpp @@ -14,7 +14,7 @@ #include -TEST(simulationResultWriter, testResultWriter) { +TEST(SimulationResultWriter, ResultWriter) { // setup ResultWriter const char* tmpName = "parpeTest_testResultWriter.h5"; auto _ = gsl::finally([tmpName] { remove(tmpName); }); @@ -45,7 +45,7 @@ TEST(simulationResultWriter, testResultWriter) { std::vector(), amici::SecondOrderMode::none, amici::SensitivityOrder::none, amici::SensitivityMethod::none, amici::RDataReporting::full, - true); + true, true, 50); std::iota(rdata.x.begin(), rdata.x.end(), 0); rdata.llh = 1.2345; rdata.y.resize(measurements.size()); @@ -74,7 +74,7 @@ TEST(simulationResultWriter, testResultWriter) { parpe::checkEqualArray(measurements.data(), yMesAct.data(), yMesAct.size(), 1e-16, 1e-16); } -TEST(simulationResultWriter, testResultWriterNewExistingFile) { +TEST(SimulationResultWriter, ResultWriterNewExistingFile) { const char* tmpName = "parpeTest_testResultWriterNewExistingFile.h5"; auto _ = gsl::finally([tmpName] { remove(tmpName); }); diff --git a/tests/parpecommon/CMakeLists.txt b/tests/parpecommon/CMakeLists.txt index 1413a2bdf..cef64daa8 100644 --- a/tests/parpecommon/CMakeLists.txt +++ b/tests/parpecommon/CMakeLists.txt @@ -1,12 +1,9 @@ project(unittests_common) set(SRC_LIST - main.cpp - commonTests.h - hdf5MiscTests.h + commonTests.cpp + hdf5MiscTests.cpp ${CMAKE_SOURCE_DIR}/tests/parpecommon/testingMisc.cpp - ${GTestSrc}/src/gtest-all.cc - ${GMockSrc}/src/gmock-all.cc ) add_executable(${PROJECT_NAME} ${SRC_LIST}) @@ -14,6 +11,7 @@ add_executable(${PROJECT_NAME} ${SRC_LIST}) target_link_libraries(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT} parpecommon + gtest_main ${GCOV_LIBRARY} ) diff --git a/tests/parpecommon/commonTests.h b/tests/parpecommon/commonTests.cpp similarity index 90% rename from tests/parpecommon/commonTests.h rename to tests/parpecommon/commonTests.cpp index ce6a22ee3..64b7fba13 100644 --- a/tests/parpecommon/commonTests.h +++ b/tests/parpecommon/commonTests.cpp @@ -18,11 +18,11 @@ using namespace parpe; -TEST(testingMisc, testTenToMinusInf) { +TEST(Testing, TenToMinusInf) { ASSERT_EQ(0.0, pow(10, -INFINITY)); } -TEST(testingMisc, testWithinTolerance) { +TEST(Testing, WithinTolerance) { captureStreamToString([](){ double atol = 0.1; double rtol = 0.1; @@ -43,7 +43,7 @@ TEST(testingMisc, testWithinTolerance) { }, stderr, STDERR_FILENO); } -TEST(testingMisc, testCheckEqualArray) { +TEST(Testing, CheckEqualArray) { const double expected[] = {1.0, 2.0, 3.0}; const double actual[] = {1.0, 2.0, 3.0}; @@ -51,7 +51,7 @@ TEST(testingMisc, testCheckEqualArray) { checkEqualArray(nullptr, nullptr, 3, 1e-16, 1e-16); } -TEST(testingMisc, testRandInt) { +TEST(Testing, RandInt) { const int numTests = 100; const int min = -1; const int max = 1; @@ -62,14 +62,14 @@ TEST(testingMisc, testRandInt) { } } -TEST(commonMisc, testBacktrace) { +TEST(Common, Backtrace) { std::string output = captureStreamToString([]() { parpe::printBacktrace(5); }, stderr, STDERR_FILENO); EXPECT_TRUE(100 < output.size()); } -TEST(commonMisc, testRandDouble) { +TEST(Common, RandDouble) { const int numTests = 100; const double min = -1.0; const double max = 1.0; @@ -80,7 +80,7 @@ TEST(commonMisc, testRandDouble) { } } -TEST(commonMisc, testFillArrayRandomDoubleSameInterval) { +TEST(Common, FillArrayRandomDoubleSameInterval) { const int numTests = 100; const double min = -1.0; const double max = 1.0; @@ -93,7 +93,7 @@ TEST(commonMisc, testFillArrayRandomDoubleSameInterval) { } } -TEST(commonMisc, testFillArrayRandomDoubleIndividualInterval) { +TEST(Common, FillArrayRandomDoubleIndividualInterval) { const int numTests = 100; const double min[numTests] = {-1.0, 0.0, 1.0}; const double max[numTests] = {-0.5, 0.5, 1.5}; @@ -108,25 +108,25 @@ TEST(commonMisc, testFillArrayRandomDoubleIndividualInterval) { #ifdef PARPE_ENABLE_MPI -TEST(commonMisc, testMpi) { +TEST(Common, Mpi) { // Before MPI initialized EXPECT_EQ(-1, parpe::getMpiRank()); EXPECT_EQ(-1, parpe::getMpiCommSize()); // MPI initialized - MPI_Init(0, nullptr); + MPI_Init(nullptr, nullptr); EXPECT_EQ(0, parpe::getMpiRank()); EXPECT_EQ(1, parpe::getMpiCommSize()); MPI_Finalize(); - // Should not make invalid calls after mpi_finalize + // Should not make invalid calls after MPI_Finalize EXPECT_EQ(-1, parpe::getMpiRank()); EXPECT_EQ(-1, parpe::getMpiCommSize()); } #endif -TEST(commonMisc, runInParallelAndWaitForFinish) { +TEST(Common, RunInParallelAndWaitForFinish) { captureStreamToString([](){ const int numThreads = 15; void* args[numThreads]; @@ -136,7 +136,7 @@ TEST(commonMisc, runInParallelAndWaitForFinish) { }, stdout); } -TEST(commonMisc, strFormatCurrentLocaltime) { +TEST(Common, StrFormatCurrentLocaltime) { int buflen = 10; char buf[buflen]; parpe::strFormatCurrentLocaltime(gsl::make_span(buf, buflen), "abc"); @@ -144,13 +144,13 @@ TEST(commonMisc, strFormatCurrentLocaltime) { } -TEST(logging, printDebugInfoAndWait) { +TEST(Logging, PrintDebugInfoAndWait) { captureStreamToString([](){ parpe::printDebugInfoAndWait(0); }, stdout); } -TEST(logging, misc) { +TEST(Logging, MessageIsPrinted) { captureStreamToString([](){ parpe::warning("bla"); parpe::error("bla"); @@ -158,7 +158,7 @@ TEST(logging, misc) { }, stdout); } -TEST(logging, printMPIInfo) { +TEST(Logging, PrintMPIInfo) { std::string s = captureStreamToString([](){ parpe::printMPIInfo(); }, stdout); @@ -166,7 +166,7 @@ TEST(logging, printMPIInfo) { EXPECT_TRUE(s.size() > 20); } -TEST(logging, logProcessStats) { +TEST(Logging, LogProcessStats) { std::string s = captureStreamToString([](){ parpe::logProcessStats(); }, stdout); @@ -178,7 +178,7 @@ TEST(logging, logProcessStats) { #include #include -TEST(costFunction, mseZero) { +TEST(CostFunction, MseZero) { parpe::MeanSquaredError mse; std::vector label = {1.0, 1.0}; std::vector prediction = {1.0, 1.0}; @@ -203,7 +203,7 @@ TEST(costFunction, mseZero) { } -TEST(costFunction, mseNonzero) { +TEST(CostFunction, MseNonzero) { parpe::MeanSquaredError mse; std::vector label = {1.0, 1.0}; std::vector prediction = {1.0, 2.0}; @@ -228,7 +228,7 @@ TEST(costFunction, mseNonzero) { } -TEST(costFunction, linearModel) { +TEST(CostFunction, LinearModel) { std::vector parameters = { 3.0, 2.0 }; // x = 3.0, b = 2.0 std::vector> features = { { 4.0 } }; // y = A x + b = 4.0 * 3.0 + 2.0 = 14.0 @@ -250,7 +250,7 @@ TEST(costFunction, linearModel) { EXPECT_TRUE(gradExp == gradAct); } -TEST(costFunction, linearModel2) { +TEST(CostFunction, LinearModel2) { std::vector parameters = { 3.0, 1.0, 2.0 }; std::vector> features = { { 4.0, 1.0 } }; // y = A x + b = 4.0 * 3.0 + 1.0*1.0 + 2.0 = 15.0 @@ -272,7 +272,7 @@ TEST(costFunction, linearModel2) { EXPECT_TRUE(gradExp == gradAct); } -TEST(costFunction, linearModel3) { +TEST(CostFunction, LinearModel3) { std::vector parameters = { 3.0, 1.0, 2.0 }; std::vector> features = { { 4.0, 1.0 }, { 8.0, 2.0 }}; // y = A x + b = 4.0 * 3.0 + 1.0*1.0 + 2.0 = 15.0 diff --git a/tests/parpecommon/hdf5MiscTests.h b/tests/parpecommon/hdf5MiscTests.cpp similarity index 79% rename from tests/parpecommon/hdf5MiscTests.h rename to tests/parpecommon/hdf5MiscTests.cpp index 4bd88471d..06e2dfff0 100644 --- a/tests/parpecommon/hdf5MiscTests.h +++ b/tests/parpecommon/hdf5MiscTests.cpp @@ -7,7 +7,7 @@ #include #include -class hdf5Misc : public ::testing::Test { +class HDF5 : public ::testing::Test { protected: void SetUp() override { @@ -29,24 +29,24 @@ class hdf5Misc : public ::testing::Test { -TEST_F(hdf5Misc, testOpenExistingFileNoOverwrite) { +TEST_F(HDF5, OpenExistingFileNoOverwrite) { EXPECT_THROW(parpe::hdf5CreateFile(tempFileName, false), parpe::HDF5Exception); } -TEST_F(hdf5Misc, testOpenExistingFileOverwrite) { +TEST_F(HDF5, OpenExistingFileOverwrite) { file.close(); file = parpe::hdf5CreateFile(tempFileName, true); } -TEST_F(hdf5Misc, testMutexGetLock) { +TEST_F(HDF5, MutexGetLock) { parpe::hdf5MutexGetLock(); } -TEST_F(hdf5Misc, testErrorStackWalker) { +TEST_F(HDF5, ErrorStackWalker) { H5_SAVE_ERROR_HANDLER; // provoke error by asking to truncate a file that is already open @@ -65,7 +65,7 @@ TEST_F(hdf5Misc, testErrorStackWalker) { } -TEST_F(hdf5Misc, testCreateGroup) { +TEST_F(HDF5, CreateGroup) { const char *groupName = "/test"; EXPECT_FALSE(parpe::hdf5GroupExists(file, groupName)); @@ -76,7 +76,7 @@ TEST_F(hdf5Misc, testCreateGroup) { } -TEST_F(hdf5Misc, testCreateExistingGroup) { +TEST_F(HDF5, CreateExistingGroup) { parpe::hdf5CreateGroup(file, "/test", false); H5_SAVE_ERROR_HANDLER; @@ -86,7 +86,7 @@ TEST_F(hdf5Misc, testCreateExistingGroup) { } -TEST_F(hdf5Misc, testEnsureGroupExists) { +TEST_F(HDF5, EnsureGroupExists) { const char *groupName = "/test"; EXPECT_FALSE(parpe::hdf5GroupExists(file, groupName)); @@ -98,7 +98,7 @@ TEST_F(hdf5Misc, testEnsureGroupExists) { parpe::hdf5EnsureGroupExists(file, groupName); } -TEST_F(hdf5Misc, testStringAttribute) { +TEST_F(HDF5, StringAttribute) { const char *groupName = "/"; const char *attrName = "testA"; const char *expAttrValue = "adsf"; @@ -121,7 +121,7 @@ TEST_F(hdf5Misc, testStringAttribute) { } -TEST_F(hdf5Misc, testDatasetDimensions) { +TEST_F(HDF5, DatasetDimensions) { const char datasetName[] = "bla"; const int rank = 3; const hsize_t dims[rank] = {1,2,3}; @@ -146,16 +146,3 @@ TEST_F(hdf5Misc, testDatasetDimensions) { EXPECT_EQ((signed)dims[2], d2); EXPECT_EQ(0, d3); } - -// TODO: -// hdf5CreateExtendableDouble2DArray -// hdf5CreateOrExtendAndWriteToDouble2DArray -// hdf5CreateOrExtendAndWriteToDouble3DArray -// hdf5CreateOrExtendAndWriteToInt2DArray -// hdf5CreateExtendableInt2DArray -// hdf5CreateExtendableDouble3DArray -// hdf5Extend2ndDimensionAndWriteToDouble2DArray -// hdf5Extend3rdDimensionAndWriteToDouble3DArray -// hdf5Extend2ndDimensionAndWriteToInt2DArray -// hdf5Read2DDoubleHyperslab -// hdf5Read3DDoubleHyperslab diff --git a/tests/parpecommon/main.cpp b/tests/parpecommon/main.cpp deleted file mode 100644 index a11775358..000000000 --- a/tests/parpecommon/main.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "commonTests.h" -#include "hdf5MiscTests.h" - -#include - -#include -#include - -int main(int argc, char *argv[]) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/tests/parpeloadbalancer/CMakeLists.txt b/tests/parpeloadbalancer/CMakeLists.txt index 2c61f7799..461f3ec9e 100644 --- a/tests/parpeloadbalancer/CMakeLists.txt +++ b/tests/parpeloadbalancer/CMakeLists.txt @@ -3,10 +3,7 @@ project(unittests_loadbalancer) add_test (NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME} -c) set(SRC_LIST - main.cpp - loadBalancerMasterTest.h - ${GTestSrc}/src/gtest-all.cc - ${GMockSrc}/src/gmock-all.cc + loadBalancerMasterTest.cpp ) add_executable(${PROJECT_NAME} ${SRC_LIST}) @@ -14,5 +11,6 @@ add_executable(${PROJECT_NAME} ${SRC_LIST}) target_link_libraries(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT} parpeloadbalancer + gmock_main ${GCOV_LIBRARY} ) diff --git a/tests/parpeloadbalancer/loadBalancerMasterTest.h b/tests/parpeloadbalancer/loadBalancerMasterTest.cpp similarity index 92% rename from tests/parpeloadbalancer/loadBalancerMasterTest.h rename to tests/parpeloadbalancer/loadBalancerMasterTest.cpp index 5ef5f8b7d..efbebc3c2 100644 --- a/tests/parpeloadbalancer/loadBalancerMasterTest.h +++ b/tests/parpeloadbalancer/loadBalancerMasterTest.cpp @@ -51,7 +51,7 @@ class MockMPI { } }; -class queuemaster : public ::testing::Test { +class LoadBalancer : public ::testing::Test { protected: MockMPI mockMpi; @@ -60,7 +60,7 @@ class queuemaster : public ::testing::Test { #include -TEST_F(queuemaster, test_queueinit) { +TEST_F(LoadBalancer, QueueInited) { EXPECT_CALL(mockMpi, MPI_Comm_size(_, _)).Times(1); // Can happen or not, depending on how quick it's terminated // mock().expectOneCall("MPI_Testany"); @@ -71,7 +71,7 @@ TEST_F(queuemaster, test_queueinit) { lbm.terminate(); } -TEST_F(queuemaster, test_queue) { +TEST_F(LoadBalancer, Queues) { EXPECT_CALL(mockMpi, MPI_Comm_size(_, _)).Times(1); parpe::LoadBalancerMaster lbm; lbm.run(); @@ -89,7 +89,7 @@ TEST_F(queuemaster, test_queue) { lbm.terminate(); } -TEST_F(queuemaster, test_terminateMasterQueue_noInit) { +TEST_F(LoadBalancer, TerminateMasterWithoutInitSucceeds) { // terminate uninitialized masterQueue should not fail parpe::LoadBalancerMaster lbm; lbm.terminate(); diff --git a/tests/parpeloadbalancer/main.cpp b/tests/parpeloadbalancer/main.cpp deleted file mode 100644 index 752b7ec70..000000000 --- a/tests/parpeloadbalancer/main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "loadBalancerMasterTest.h" - -#include -#include -#include - -int main(int argc, char *argv[]) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/tests/parpeoptimization/CMakeLists.txt b/tests/parpeoptimization/CMakeLists.txt index 58877fe10..12b9edff9 100644 --- a/tests/parpeoptimization/CMakeLists.txt +++ b/tests/parpeoptimization/CMakeLists.txt @@ -3,18 +3,13 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) project(unittests_optimization) set(SRC_LIST_CPP - main.cpp ../parpecommon/testingMisc.cpp quadraticTestProblem.cpp - multiStartOptimizationTest.h - minibatchOptimizationTest.h - optimizationResultWriterTest.h - optimizationOptionsTest.h - optimizationProblemTest.h - localOptimizationIpoptTest.h - localOptimizationCeresTest.h - ${GTestSrc}/src/gtest-all.cc - ${GMockSrc}/src/gmock-all.cc + multiStartOptimizationTest.cpp + minibatchOptimizationTest.cpp + optimizationResultWriterTest.cpp + optimizationOptionsTest.cpp + optimizationProblemTest.cpp ) add_executable(${PROJECT_NAME} ${SRC_LIST_CPP}) @@ -22,14 +17,34 @@ add_executable(${PROJECT_NAME} ${SRC_LIST_CPP}) target_link_libraries(${PROJECT_NAME} parpeoptimization parpecommon + gmock_main ${GCOV_LIBRARY} ) +if(${PARPE_ENABLE_FIDES}) + target_sources(${PROJECT_NAME} + PRIVATE localOptimizationFidesTest.cpp) +endif() + +if(${PARPE_ENABLE_IPOPT}) + target_sources(${PROJECT_NAME} + PRIVATE localOptimizationIpoptTest.cpp) +endif() + +if(${PARPE_ENABLE_CERES}) + target_sources(${PROJECT_NAME} + PRIVATE localOptimizationCeresTest.cpp) +endif() + if(${PARPE_ENABLE_TOMS611}) + target_sources(${PROJECT_NAME} + PRIVATE localOptimizationToms611Test.cpp) target_link_libraries(${PROJECT_NAME} toms611) endif(${PARPE_ENABLE_TOMS611}) if(${PARPE_ENABLE_FSQP}) + target_sources(${PROJECT_NAME} + PRIVATE localOptimizationFsqpTest.cpp) target_link_libraries(${PROJECT_NAME} fsqp) endif(${PARPE_ENABLE_FSQP}) diff --git a/tests/parpeoptimization/localOptimizationCeresTest.h b/tests/parpeoptimization/localOptimizationCeresTest.cpp similarity index 96% rename from tests/parpeoptimization/localOptimizationCeresTest.h rename to tests/parpeoptimization/localOptimizationCeresTest.cpp index d73bbdad0..07c832db1 100644 --- a/tests/parpeoptimization/localOptimizationCeresTest.h +++ b/tests/parpeoptimization/localOptimizationCeresTest.cpp @@ -15,7 +15,7 @@ using ::testing::Ne; using ::testing::AtLeast; -TEST(localOptimizationCeres, testOptimization) { +TEST(LocalOptimizationCeres, Optimization) { parpe::QuadraticTestProblem problem; EXPECT_CALL(*problem.reporter, starting(_)); @@ -47,7 +47,7 @@ TEST(localOptimizationCeres, testOptimization) { #if (CERES_VERSION_MAJOR < 1 && CERES_VERSION_MINOR < 13) IGNORE_TEST(localOptimizationCeres, testReporterCalled) { #else -TEST(localOptimizationCeres, testReporterCalled) { +TEST(LocalOptimizationCeres, IsReporterCalled) { #endif parpe::QuadraticTestProblem problem; auto o = problem.getOptimizationOptions(); diff --git a/tests/parpeoptimization/localOptimizationFidesTest.cpp b/tests/parpeoptimization/localOptimizationFidesTest.cpp new file mode 100644 index 000000000..d41d9b34c --- /dev/null +++ b/tests/parpeoptimization/localOptimizationFidesTest.cpp @@ -0,0 +1,61 @@ +#include + +#include +#include + +#include "../parpecommon/testingMisc.h" +#include "quadraticTestProblem.h" + +#include + +using ::testing::_; +using ::testing::AtLeast; +using ::testing::Eq; +using ::testing::Ne; + +TEST(LocalOptimizationFides, FindsOptimum) +{ + parpe::QuadraticTestProblem problem; + + // should trigger termination + auto fatol = 1e-12; + + // should not trigger termination + auto xtol = 1e-16; + auto frtol = 0.0; + auto gatol = -1.0; + auto grtol = -1.0; + + + auto optimization_options = problem.getOptimizationOptions(); + optimization_options.setOption("xtol", xtol); + optimization_options.setOption("fatol", fatol); + optimization_options.setOption("frtol", frtol); + optimization_options.setOption("gatol", gatol); + optimization_options.setOption("grtol", grtol); + optimization_options.setOption("maxiter", 25); + problem.setOptimizationOptions(optimization_options); + + EXPECT_CALL(*problem.reporter, starting(_)); + EXPECT_CALL(*problem.reporter, + finished(_, _, static_cast(fides::ExitStatus::ftol))); + + // No calls without gradient + EXPECT_CALL(*dynamic_cast( + problem.cost_fun_.get()), + evaluate_impl(_, _, Eq(gsl::span()), _, _)) + .Times(0); + // At least one gradient evaluation + EXPECT_CALL(*dynamic_cast( + problem.cost_fun_.get()), + evaluate_impl(_, _, Ne(gsl::span()), _, _)) + .Times(AtLeast(1)); + + parpe::OptimizerFides optimizer; + auto [status, fval, parameters]= optimizer.optimize(&problem); + + // check status, cost, parameter + EXPECT_EQ(0, status); + EXPECT_NEAR(42.0, fval, fatol * 10.0); + EXPECT_NEAR(-1.0, parameters.at(0), 1e-6); +} diff --git a/tests/parpeoptimization/localOptimizationIpoptTest.h b/tests/parpeoptimization/localOptimizationIpoptTest.cpp similarity index 100% rename from tests/parpeoptimization/localOptimizationIpoptTest.h rename to tests/parpeoptimization/localOptimizationIpoptTest.cpp diff --git a/tests/parpeoptimization/main.cpp b/tests/parpeoptimization/main.cpp index aea340cf0..f0b2ee417 100644 --- a/tests/parpeoptimization/main.cpp +++ b/tests/parpeoptimization/main.cpp @@ -10,6 +10,10 @@ #include "localOptimizationIpoptTest.h" #endif +#ifdef PARPE_ENABLE_FIDES +#include "localOptimizationFidesTest.h" +#endif + #ifdef PARPE_ENABLE_CERES #include "localOptimizationCeresTest.h" #endif diff --git a/tests/parpeoptimization/minibatchOptimizationTest.h b/tests/parpeoptimization/minibatchOptimizationTest.cpp similarity index 91% rename from tests/parpeoptimization/minibatchOptimizationTest.h rename to tests/parpeoptimization/minibatchOptimizationTest.cpp index 955609e9d..fe8b12d99 100644 --- a/tests/parpeoptimization/minibatchOptimizationTest.h +++ b/tests/parpeoptimization/minibatchOptimizationTest.cpp @@ -14,7 +14,7 @@ #include -TEST(minibatchOptimization, getBatches) { +TEST(MinibatchOptimization, CreatesBatches) { int numElements = 10; std::vector input(numElements); @@ -41,7 +41,7 @@ TEST(minibatchOptimization, getBatches) { EXPECT_TRUE(std::vector(input.begin() + batchSize, input.end()) == batchesAct[1]); } -TEST(minibatchOptimization, updateParameters) { +TEST(MinibatchOptimization, UpdatesParameters) { // Test whether the most simple parameter updater works reliably std::vector gradient {3.0, 4.0}; std::vector parameters {2.0, 3.0}; @@ -71,7 +71,7 @@ TEST(minibatchOptimization, updateParameters) { -class minibatchOptimizationLinearModel : public ::testing::Test { +class MinibatchOptimizationLinearModel : public ::testing::Test { protected: void SetUp() override { @@ -137,7 +137,7 @@ class minibatchOptimizationLinearModel : public ::testing::Test { }; -TEST_F(minibatchOptimizationLinearModel, testCostWithTrueParametersIsZeroIndivdually) { +TEST_F(MinibatchOptimizationLinearModel, CostWithTrueParametersIsZeroIndivdually) { // verify cost gradient with true parameters is 0 auto lm2 = getLinearModelMSE(); double mse = NAN; @@ -149,7 +149,7 @@ TEST_F(minibatchOptimizationLinearModel, testCostWithTrueParametersIsZeroIndivdu } } -TEST_F(minibatchOptimizationLinearModel, testCostWithTrueParametersIsZeroFull) { +TEST_F(MinibatchOptimizationLinearModel, CostWithTrueParametersIsZeroFull) { // verify cost gradient with true parameters is 0 auto lm2 = getLinearModelMSE(); double mse = NAN; @@ -159,7 +159,7 @@ TEST_F(minibatchOptimizationLinearModel, testCostWithTrueParametersIsZeroFull) { EXPECT_TRUE(std::vector(trueParameters.size(), 0.0) == gradient); } -TEST_F(minibatchOptimizationLinearModel, testMinibatchSucceedFromOptimum) { +TEST_F(MinibatchOptimizationLinearModel, MinibatchSucceedFromOptimum) { // verify optimization succeeds with true parameters auto lm2 = getLinearModelMSE(); parpe::MinibatchOptimizer mb; @@ -172,19 +172,19 @@ TEST_F(minibatchOptimizationLinearModel, testMinibatchSucceedFromOptimum) { EXPECT_TRUE(trueParameters == std::get<2>(result)); } -TEST_F(minibatchOptimizationLinearModel, linearModelCheckCostGradient) { +TEST_F(MinibatchOptimizationLinearModel, LinearModelCheckCostGradient) { // use gradient checker auto p = getOptimizationProblem(); for(int i = 0; i < 10; ++i) - parpe::optimizationProblemGradientCheck(p.get(), 10, 1e-1); + parpe::optimizationProblemGradientCheck(p.get(), 10, 1e-1); // TODO: check results automatically } #ifdef PARPE_ENABLE_IPOPT #include -TEST_F(minibatchOptimizationLinearModel, linearModelTestBatchOptimizerSucceeds) { +TEST_F(MinibatchOptimizationLinearModel, linearModelDoesBatchOptimizerSucceed) { // test batch optimizer auto p = getOptimizationProblem(); @@ -201,7 +201,7 @@ TEST_F(minibatchOptimizationLinearModel, linearModelTestBatchOptimizerSucceeds) } #endif -TEST_F(minibatchOptimizationLinearModel, linearModel) { +TEST_F(MinibatchOptimizationLinearModel, LinearModel) { // optimization/tests/unittests_optimization -sg minibatchOptimizationLinearModel -sn linearModel std::cout<<"True parameters "< ignore diff --git a/tests/parpeoptimization/optimizationOptionsTest.h b/tests/parpeoptimization/optimizationOptionsTest.cpp similarity index 92% rename from tests/parpeoptimization/optimizationOptionsTest.h rename to tests/parpeoptimization/optimizationOptionsTest.cpp index 188cd1acd..a05c65b06 100644 --- a/tests/parpeoptimization/optimizationOptionsTest.h +++ b/tests/parpeoptimization/optimizationOptionsTest.cpp @@ -27,7 +27,7 @@ void setCeresOption(const std::pair &pair, #endif -TEST(optimizationOptions, setGetOptionStr) { +TEST(OptimizationOptions, setGetOptionStr) { parpe::OptimizationOptions o; std::string key = "str"; std::string expVal = "testStr"; @@ -37,7 +37,7 @@ TEST(optimizationOptions, setGetOptionStr) { EXPECT_EQ(expVal, actVal); } -TEST(optimizationOptions, setGetOptionInt) { +TEST(OptimizationOptions, setGetOptionInt) { parpe::OptimizationOptions o; std::string key = "str"; double expVal = 1.23; @@ -47,7 +47,7 @@ TEST(optimizationOptions, setGetOptionInt) { EXPECT_NEAR(expVal, actVal, 1e-15); } -TEST(optimizationOptions, setGetOptionDouble) { +TEST(OptimizationOptions, setGetOptionDouble) { parpe::OptimizationOptions o; std::string key = "str"; auto expVal = 123; @@ -58,14 +58,14 @@ TEST(optimizationOptions, setGetOptionDouble) { } -TEST(optimizationOptions, getNonExistingOption) { +TEST(OptimizationOptions, getNonExistingOption) { parpe::OptimizationOptions o; EXPECT_THROW(o.getIntOption("missingKey"), std::invalid_argument); } #ifdef PARPE_ENABLE_IPOPT -TEST(optimizationOptions, setIpOptOptions) { +TEST(OptimizationOptions, setIpOptOptions) { std::string key = "max_iter"; int expVal = 10; @@ -84,7 +84,7 @@ TEST(optimizationOptions, setIpOptOptions) { #endif #ifdef PARPE_ENABLE_CERES -TEST(optimizationOptions, setCeresOptions) { +TEST(OptimizationOptions, setCeresOptions) { std::string key = "max_num_iterations"; int expVal = 10; @@ -103,7 +103,7 @@ TEST(optimizationOptions, setCeresOptions) { } #endif -TEST(optimizationOptions, fromHDF5) { +TEST(OptimizationOptions, fromHDF5) { const char* tmpName = "parpeTest_fromHDF5.h5"; auto _ = gsl::finally([tmpName] { remove(tmpName); }); diff --git a/tests/parpeoptimization/optimizationProblemTest.h b/tests/parpeoptimization/optimizationProblemTest.cpp similarity index 95% rename from tests/parpeoptimization/optimizationProblemTest.h rename to tests/parpeoptimization/optimizationProblemTest.cpp index a00744e35..942373093 100644 --- a/tests/parpeoptimization/optimizationProblemTest.h +++ b/tests/parpeoptimization/optimizationProblemTest.cpp @@ -94,7 +94,7 @@ class SummedGradientFunctionLinearModelTest }; -TEST(optimizationProblem, quadraticTestFunction) { +TEST(OptimizationProblem, quadraticTestFunction) { // Test QuadraticGradientFunction for f(-1) = 42 parpe::QuadraticGradientFunction f {}; double parameter = -1; @@ -112,7 +112,7 @@ TEST(optimizationProblem, quadraticTestFunction) { -TEST(optimizationProblem, gradientChecker) { +TEST(OptimizationProblem, gradientChecker) { parpe::QuadraticTestProblem problem {}; constexpr int numParameterIndices {1}; int parameterIndices[numParameterIndices] {0}; @@ -124,7 +124,7 @@ TEST(optimizationProblem, gradientChecker) { } -TEST(optimizationProblem, linearModel) { +TEST(OptimizationProblem, linearModel) { // Test if the linear model produces correct results SummedGradientFunctionLinearModelTest model; @@ -145,7 +145,7 @@ TEST(optimizationProblem, linearModel) { } -TEST(optimizationProblem, linearModelToGradientFun) { +TEST(OptimizationProblem, linearModelToGradientFun) { // Test that the SummedGradientFunction <-> GradientFunction Adapter works // with the linear model std::vector dataset {2.0, 3.0}; @@ -166,7 +166,7 @@ TEST(optimizationProblem, linearModelToGradientFun) { #ifdef PARPE_ENABLE_IPOPT -TEST(optimizationProblem, linearModelToGradientFunOptimization) { +TEST(OptimizationProblem, linearModelToGradientFunOptimization) { // create optimization problem for the linear model // does not do anything meaningful yet std::vector dataset {2.0, 3.0}; diff --git a/tests/parpeoptimization/optimizationResultWriterTest.h b/tests/parpeoptimization/optimizationResultWriterTest.cpp similarity index 95% rename from tests/parpeoptimization/optimizationResultWriterTest.h rename to tests/parpeoptimization/optimizationResultWriterTest.cpp index 2f05edbd7..f6f9f6544 100644 --- a/tests/parpeoptimization/optimizationResultWriterTest.h +++ b/tests/parpeoptimization/optimizationResultWriterTest.cpp @@ -6,7 +6,7 @@ #include #include -TEST(optimizationResultWriter, testResultWriter) { +TEST(OptimizationResultWriter, ResultWriter) { const char* tmpFilename = "deleteme.h5"; parpe::OptimizationResultWriter w(tmpFilename, true, "/bla/"); diff --git a/tests/parpeoptimization/quadraticTestProblem.cpp b/tests/parpeoptimization/quadraticTestProblem.cpp index 213c820b7..5b212697a 100644 --- a/tests/parpeoptimization/quadraticTestProblem.cpp +++ b/tests/parpeoptimization/quadraticTestProblem.cpp @@ -14,8 +14,9 @@ namespace parpe { QuadraticTestProblem::QuadraticTestProblem(std::unique_ptr logger) : OptimizationProblem( - std::unique_ptr( - new NiceMock()), std::move(logger)) { + std::make_unique>(), + std::move(logger) + ) { auto options = getOptimizationOptions(); options.maxOptimizerIterations = 12; @@ -30,7 +31,6 @@ QuadraticTestProblem::QuadraticTestProblem(std::unique_ptr logger) void QuadraticTestProblem::fillParametersMin(gsl::span buffer) const { buffer[0] = -1e5; - } void QuadraticTestProblem::fillParametersMax(gsl::span buffer) const @@ -49,9 +49,8 @@ QuadraticOptimizationMultiStartProblem::getLocalProblem( int multiStartIndex) const { auto loggerPrefix = std::string("[start ") + std::to_string(multiStartIndex) + "]"; - auto p = std::unique_ptr( - new QuadraticTestProblem( - std::make_unique(loggerPrefix))); + auto p = std::make_unique( + std::make_unique(loggerPrefix)); p->setOptimizationOptions(options); return p; } diff --git a/tests/parpeoptimization/quadraticTestProblem.h b/tests/parpeoptimization/quadraticTestProblem.h index 77830b2df..cccd76438 100644 --- a/tests/parpeoptimization/quadraticTestProblem.h +++ b/tests/parpeoptimization/quadraticTestProblem.h @@ -146,7 +146,7 @@ class QuadraticGradientFunctionMock : public GradientFunction { class QuadraticTestProblem : public OptimizationProblem { public: - QuadraticTestProblem(std::unique_ptr logger = std::make_unique()); + explicit QuadraticTestProblem(std::unique_ptr logger = std::make_unique()); void fillParametersMin(gsl::span buffer) const override; void fillParametersMax(gsl::span buffer) const override; diff --git a/tests/petab-test-suite/test_petab_test_suite.py b/tests/petab-test-suite/test_petab_test_suite.py index 453dfe48b..ef16c6352 100755 --- a/tests/petab-test-suite/test_petab_test_suite.py +++ b/tests/petab-test-suite/test_petab_test_suite.py @@ -27,7 +27,7 @@ def test_case(case: Union[int, str]) -> None: _test_case(case) except Exception as e: if isinstance(e, NotImplementedError) \ - or "Timepoint-specific parameter overrides" in str(e): + or "models with timepoint specific mappings" in str(e): logger.info(f"Case {case} expectedly failed. " "Required functionality is not yet " f"implemented: {e}") @@ -75,6 +75,7 @@ def _test_case(case: Union[int, str]) -> None: # create amici model from PEtab cmd = ['amici_import_petab', '-y', yaml_file, '-o', amici_model_dir, '-n', model_name] + print(" ".join(cmd)) check_run(cmd) # must not exist when calling setup_amici_model.sh @@ -84,20 +85,23 @@ def _test_case(case: Union[int, str]) -> None: # set up for parPE cmd = [os.path.join(parpe_dir, 'misc', 'setup_amici_model.sh'), amici_model_dir, parpe_model_dir] + print(" ".join(cmd)) check_run(cmd) # create input hdf5 file cmd = ['parpe_petab_to_hdf5', '-y', yaml_file, '-d', amici_model_dir, '-n', model_name, '-o', hdf5_input] + print(" ".join(cmd)) check_run(cmd) # simulate model using nominal parameters cmd = [os.path.join(parpe_model_dir, 'build', f'simulateNominal_{model_name}'), hdf5_input, hdf5_output] + print(" ".join(cmd)) ret = check_run(cmd) - print(' '.join(cmd)) + # check output g = re.search(r'Likelihood: (\d+\.\d+)', ret.stdout).group(0) llh_actual = - float(g.split(' ')[1])