Skip to content

Commit

Permalink
Changed megacomplex scale application and definition.
Browse files Browse the repository at this point in the history
Megacomplex scales are now a property of the dataset_descriptor. They
are defined per dataset per megacomplex.

Fixes glotaran#606
  • Loading branch information
joernweissenborn committed Mar 26, 2021
1 parent eaa427b commit c42a9c1
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 24 deletions.
2 changes: 1 addition & 1 deletion glotaran/builtin/io/yml/test/test_model_spec_kinetic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ megacomplex:
k_matrix: [km1] # A megacomplex has one or more k-matrices
cmplx2:
k_matrix: [km2]
cmplx3: [[km3], None]
cmplx3: [[km3]]

spectral_constraints:
- type: zero
Expand Down
13 changes: 2 additions & 11 deletions glotaran/builtin/models/kinetic_image/initial_concentration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import numpy as np

from glotaran.model import DatasetDescriptor
from glotaran.model import model_attribute
from glotaran.parameter import Parameter

Expand All @@ -22,16 +21,8 @@ class InitialConcentration:
"""An initial concentration describes the population of the compartments at
the beginning of an experiment."""

def normalized(self, dataset: DatasetDescriptor) -> InitialConcentration:
parameters = self.parameters
for megacomplex in dataset.megacomplex:
scale = [
megacomplex.scale
if c in megacomplex.involved_compartments and megacomplex.scale
else 1
for c in self.compartments
]
parameters = np.multiply(parameters, scale)
def normalized(self) -> InitialConcentration:
parameters = np.array(self.parameters)
idx = [c not in self.exclude_from_normalize for c in self.compartments]
parameters[idx] /= np.sum(parameters[idx])
new = copy.deepcopy(self)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,38 @@
}
)
class KineticImageDatasetDescriptor(DatasetDescriptor):
def get_k_matrices(self):
return [mat for mat in [cmplx.full_k_matrix() for cmplx in self.megacomplex] if mat]
def get_megacomplex_k_matrices(self):
scales = (
[
self.megacomplex_scale[i]
for i in [
i
for i, megacomplex in enumerate(self.megacomplex)
if megacomplex.has_k_matrix()
]
]
if self.megacomplex_scale is not None
else None
)

matrices = [
matrix
for matrix in [
megacomplex.full_k_matrix()
for megacomplex in self.megacomplex
if megacomplex.has_k_matrix()
]
]

return scales, matrices

def has_k_matrix(self):
_, matrices = self.get_megacomplex_k_matrices()
return len(matrices) != 0

def compartments(self):
compartments = []
for k in self.get_k_matrices():
_, k_matrices = self.get_megacomplex_k_matrices()
for k in k_matrices:
compartments += k.involved_compartments()
return list(set(compartments))
9 changes: 6 additions & 3 deletions glotaran/builtin/models/kinetic_image/kinetic_image_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def kinetic_matrix(

compartments = None
matrix = None
k_matrices = dataset_descriptor.get_k_matrices()
megacomplex_scales, k_matrices = dataset_descriptor.get_megacomplex_k_matrices()

if len(k_matrices) == 0:
return (None, None)
Expand All @@ -29,9 +29,9 @@ def kinetic_matrix(
raise Exception(
f'No initial concentration specified in dataset "{dataset_descriptor.label}"'
)
initial_concentration = dataset_descriptor.initial_concentration.normalized(dataset_descriptor)
initial_concentration = dataset_descriptor.initial_concentration.normalized()

for k_matrix in k_matrices:
for i, k_matrix in enumerate(k_matrices):

if k_matrix is None:
continue
Expand All @@ -46,6 +46,9 @@ def kinetic_matrix(
matrix_implementation,
)

if megacomplex_scales is not None:
this_matrix *= megacomplex_scales[i]

if matrix is None:
compartments = this_compartments
matrix = this_matrix
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
from typing import List

from glotaran.model import model_attribute
from glotaran.parameter import Parameter


@model_attribute(
properties={
"k_matrix": {"type": List[str], "default": []},
"scale": {"type": Parameter, "allow_none": True},
}
)
class KineticImageMegacomplex:
"""A Megacomplex with one or more K-Matrices."""

def has_k_matrix(self) -> bool:
return len(self.k_matrix) != 0

def full_k_matrix(self, model=None):
full_k_matrix = None
for k_matrix in self.k_matrix:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ def finalize_kinetic_image_result(model, problem: Problem, data: dict[str, xr.Da
for label, dataset in data.items():

dataset_descriptor = problem.filled_dataset_descriptors[label]
if not dataset_descriptor.get_k_matrices():

if not dataset_descriptor.has_k_matrix():
continue

retrieve_species_assocatiated_data(problem.model, dataset, dataset_descriptor, "images")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def finalize_kinetic_spectrum_result(model, problem: Problem, data: dict[str, xr
for label, dataset in data.items():

dataset_descriptor = problem.filled_dataset_descriptors[label]
if not dataset_descriptor.get_k_matrices():
if not dataset_descriptor.has_k_matrix():
continue

retrieve_species_assocatiated_data(problem.model, dataset, dataset_descriptor, "spectra")
Expand Down
1 change: 1 addition & 0 deletions glotaran/model/dataset_descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@model_attribute(
properties={
"megacomplex": List[str],
"megacomplex_scale": {"type": List[Parameter], "default": None, "allow_none": True},
"scale": {"type": Parameter, "default": None, "allow_none": True},
}
)
Expand Down
4 changes: 2 additions & 2 deletions glotaran/model/test/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def model():
"megacomplex": ["m1", "m2"],
"scale": "scale_1",
},
"dataset2": [["m2"], "scale_2"],
"dataset2": [["m2"], ["bar"], "scale_2"],
},
}
return MockModel.from_dict(d)
Expand All @@ -98,7 +98,7 @@ def model_error():
"megacomplex": ["N1", "N2"],
"scale": "scale_1",
},
"dataset2": [["mrX"], "scale_3"],
"dataset2": [["mrX"], ["bar"], "scale_3"],
},
}
return MockModel.from_dict(d)
Expand Down

0 comments on commit c42a9c1

Please sign in to comment.