diff --git a/glotaran/builtin/megacomplexes/decay/__init__.py b/glotaran/builtin/megacomplexes/decay/__init__.py index ebdec4a97..837cb3c09 100644 --- a/glotaran/builtin/megacomplexes/decay/__init__.py +++ b/glotaran/builtin/megacomplexes/decay/__init__.py @@ -1,4 +1,7 @@ from glotaran.builtin.megacomplexes.decay.decay_megacomplex import DecayMegacomplex +from glotaran.builtin.megacomplexes.decay.decay_parallel_megacomplex import ( + DecayParallelMegacomplex, +) from glotaran.builtin.megacomplexes.decay.decay_sequential_megacomplex import ( DecaySequentialMegacomplex, ) diff --git a/glotaran/builtin/megacomplexes/decay/decay_parallel_megacomplex.py b/glotaran/builtin/megacomplexes/decay/decay_parallel_megacomplex.py new file mode 100644 index 000000000..ee073e8b7 --- /dev/null +++ b/glotaran/builtin/megacomplexes/decay/decay_parallel_megacomplex.py @@ -0,0 +1,40 @@ +"""This package contains the decay megacomplex item.""" +from __future__ import annotations + +from typing import List + +import numpy as np + +from glotaran.builtin.megacomplexes.decay.decay_megacomplex_base import DecayMegacomplexBase +from glotaran.builtin.megacomplexes.decay.irf import Irf +from glotaran.builtin.megacomplexes.decay.k_matrix import KMatrix +from glotaran.model import DatasetModel +from glotaran.model import megacomplex +from glotaran.parameter import Parameter + + +@megacomplex( + dimension="time", + properties={ + "compartments": List[str], + "rates": List[Parameter], + }, + dataset_model_items={ + "irf": {"type": Irf, "allow_none": True}, + }, + register_as="decay-parallel", +) +class DecayParallelMegacomplex(DecayMegacomplexBase): + def get_compartments(self, dataset_model: DatasetModel) -> list[str]: + return self.compartments + + def get_initial_concentration(self, dataset_model: DatasetModel) -> np.ndarray: + return np.ones((len(self.compartments)), dtype=np.float64) + + def get_k_matrix(self) -> KMatrix: + size = len(self.compartments) + k_matrix = KMatrix() + k_matrix.matrix = { + (self.compartments[i], self.compartments[i]): self.rates[i] for i in range(size) + } + return k_matrix diff --git a/glotaran/builtin/megacomplexes/decay/test/test_decay_megacomplex.py b/glotaran/builtin/megacomplexes/decay/test/test_decay_megacomplex.py index bb18ef268..c28be4477 100644 --- a/glotaran/builtin/megacomplexes/decay/test/test_decay_megacomplex.py +++ b/glotaran/builtin/megacomplexes/decay/test/test_decay_megacomplex.py @@ -9,7 +9,6 @@ from glotaran.model import Model from glotaran.parameter import ParameterGroup from glotaran.project import Scheme -from glotaran.testing.model_generators import SimpleModelGenerator def _create_gaussian_clp(labels, amplitudes, centers, widths, axis): @@ -124,15 +123,56 @@ class OneComponentOneChannelGaussianIrf: class ThreeComponentParallel: - generator = SimpleModelGenerator( - rates=[300e-3, 500e-4, 700e-5], - irf={"center": 1.3, "width": 7.8}, - k_matrix="parallel", + model = DecayModel.from_dict( + { + "megacomplex": { + "mc1": { + "type": "decay-parallel", + "compartments": ["s1", "s2", "s3"], + "rates": [ + "kinetic.1", + "kinetic.2", + "kinetic.3", + ], + }, + }, + "irf": { + "irf1": { + "type": "multi-gaussian", + "center": ["irf.center"], + "width": ["irf.width"], + }, + }, + "dataset": { + "dataset1": { + "irf": "irf1", + "megacomplex": ["mc1"], + }, + }, + } ) - model, initial_parameters = generator.model_and_parameters - generator.rates = [301e-3, 502e-4, 705e-5] - wanted_parameters = generator.parameters + initial_parameters = ParameterGroup.from_dict( + { + "kinetic": [ + ["1", 501e-3], + ["2", 202e-4], + ["3", 105e-5], + {"non-negative": True}, + ], + "irf": [["center", 1.3], ["width", 7.8]], + } + ) + wanted_parameters = ParameterGroup.from_dict( + { + "kinetic": [ + ["1", 501e-3], + ["2", 202e-4], + ["3", 105e-5], + ], + "irf": [["center", 1.3], ["width", 7.8]], + } + ) time = np.arange(-10, 100, 1.5) pixel = np.arange(600, 750, 10)