def simulate_global_model( dataset_model: DatasetModel, parameters: ParameterGroup, clp: xr.DataArray = None, ): """Simulates a global model.""" # TODO: implement full model clp if clp is not None: raise NotImplementedError( "Simulation of full models with clp is not supported yet.") if any( m.index_dependent(dataset_model) for m in dataset_model.global_megacomplex): raise ValueError( "Index dependent models for global dimension are not supported.") global_matrix = calculate_matrix(dataset_model, {}, as_global_model=True) global_clp_labels = global_matrix.clp_labels global_matrix = xr.DataArray( global_matrix.matrix.T, coords=[ ("clp_label", global_clp_labels), (dataset_model.get_global_dimension(), dataset_model.get_global_axis()), ], ) return simulate_clp( dataset_model, parameters, global_matrix, )
def calculate_index_independent_matrices( self, ) -> tuple[dict[str, CalculatedMatrix], dict[str, CalculatedMatrix], ]: """Calculates the index independent model matrices.""" self._group._matrices = {} self._group._reduced_matrices = {} self._group_clp_labels = {} for label, dataset_model in self._group.dataset_models.items(): self._group._matrices[label] = calculate_matrix( dataset_model, {}, ) self._group_clp_labels[label] = self._group._matrices[ label].clp_labels self._group._reduced_matrices[label] = reduce_matrix( self._group._matrices[label], self._group.model, self._group.parameters, None, ) for group_label, group in self.groups.items(): if group_label not in self._group._matrices: self._group._reduced_matrices[group_label] = combine_matrices( [self._group._reduced_matrices[label] for label in group]) group_clp_labels = [] for label in group: for clp_label in self._group._matrices[label].clp_labels: if clp_label not in group_clp_labels: group_clp_labels.append(clp_label) self._group_clp_labels[group_label] = group_clp_labels return self._group._matrices, self._group._reduced_matrices
def _calculate_index_independent_matrix(self, label: str, dataset_model: DatasetModel): matrix = calculate_matrix(dataset_model, {}) self._group._matrices[label] = matrix if not dataset_model.has_global_model(): reduced_matrix = reduce_matrix(matrix, self._group.model, self._group.parameters, None) self._group._reduced_matrices[label] = reduced_matrix
def simulate_clp( dataset_model: DatasetModel, parameters: ParameterGroup, clp: xr.DataArray, ): if "clp_label" not in clp.coords: raise ValueError("Missing coordinate 'clp_label' in clp.") global_dimension = next(dim for dim in clp.coords if dim != "clp_label") global_axis = clp.coords[global_dimension] matrices = ([ calculate_matrix( dataset_model, {global_dimension: index}, ) for index, _ in enumerate(global_axis) ] if dataset_model.is_index_dependent() else calculate_matrix( dataset_model, {})) model_dimension = dataset_model.get_model_dimension() model_axis = dataset_model.get_coordinates()[model_dimension] result = xr.DataArray( data=0.0, coords=[ (model_dimension, model_axis.data), (global_dimension, global_axis.data), ], ) result = result.to_dataset(name="data") for i in range(global_axis.size): index_matrix = matrices[i] if dataset_model.is_index_dependent( ) else matrices result.data[:, i] = np.dot( index_matrix.matrix, clp.isel({ global_dimension: i }).sel({"clp_label": index_matrix.clp_labels}), ) return result
def _calculate_index_dependent_matrix(self, label: str, dataset_model: DatasetModel): self._group._matrices[label] = [] self._group._reduced_matrices[label] = [] for i, index in enumerate(dataset_model.get_global_axis()): matrix = calculate_matrix( dataset_model, {dataset_model.get_global_dimension(): i}, ) self._group._matrices[label].append(matrix) if not dataset_model.has_global_model(): reduced_matrix = reduce_matrix(matrix, self._group.model, self._group.parameters, index) self._group._reduced_matrices[label].append(reduced_matrix)
def calculate_group( group_model: DatasetIndexModelGroup, dataset_models: dict[str, DatasetModel] ) -> tuple[list[CalculatedMatrix], list[str], CalculatedMatrix]: matrices = [ calculate_matrix( dataset_models[dataset_index_model.label], dataset_index_model.indices, ) for dataset_index_model in group_model.dataset_models ] global_index = group_model.dataset_models[0].indices[ self._global_dimension] global_index = group_model.dataset_models[0].axis[ self._global_dimension][global_index] combined_matrix = combine_matrices(matrices) group_clp_labels = combined_matrix.clp_labels reduced_matrix = reduce_matrix(combined_matrix, self._group.model, self._group.parameters, global_index) return matrices, group_clp_labels, reduced_matrix
def test_coherent_artifact(spectral_dependence: str): model_dict = { "initial_concentration": { "j1": {"compartments": ["s1"], "parameters": ["irf_center"]}, }, "megacomplex": { "mc1": {"type": "decay", "k_matrix": ["k1"]}, "mc2": {"type": "coherent-artifact", "order": 3}, }, "k_matrix": { "k1": { "matrix": { ("s1", "s1"): "rate", } } }, "irf": { "irf1": { "type": "spectral-multi-gaussian", "center": ["irf_center"], "width": ["irf_width"], }, }, "dataset": { "dataset1": { "initial_concentration": "j1", "megacomplex": ["mc1", "mc2"], "irf": "irf1", }, }, } parameter_list = [ ["rate", 101e-4], ["irf_center", 10, {"vary": False, "non-negative": False}], ["irf_width", 20, {"vary": False, "non-negative": False}], ] irf_spec = model_dict["irf"]["irf1"] if spectral_dependence == "dispersed": irf_spec["dispersion_center"] = "irf_dispc" irf_spec["center_dispersion"] = ["irf_disp1", "irf_disp2"] parameter_list += [ ["irf_dispc", 300, {"vary": False, "non-negative": False}], ["irf_disp1", 0.01, {"vary": False, "non-negative": False}], ["irf_disp2", 0.001, {"vary": False, "non-negative": False}], ] elif spectral_dependence == "shifted": irf_spec["shift"] = ["irf_shift1", "irf_shift2", "irf_shift3"] parameter_list += [ ["irf_shift1", -2], ["irf_shift2", 0], ["irf_shift3", 2], ] model = Model.from_dict( model_dict.copy(), megacomplex_types={ "decay": DecayMegacomplex, "coherent-artifact": CoherentArtifactMegacomplex, }, ) parameters = ParameterGroup.from_list(parameter_list) time = np.arange(0, 50, 1.5) spectral = np.asarray([200, 300, 400]) coords = {"time": time, "spectral": spectral} dataset_model = model.dataset["dataset1"].fill(model, parameters) dataset_model.overwrite_global_dimension("spectral") dataset_model.set_coordinates(coords) matrix = calculate_matrix(dataset_model, {"spectral": 1}) compartments = matrix.clp_labels print(compartments) assert len(compartments) == 4 for i in range(1, 4): assert compartments[i] == f"coherent_artifact_{i}" assert matrix.matrix.shape == (time.size, 4) clp = xr.DataArray( np.ones((3, 4)), coords=[ ("spectral", spectral), ( "clp_label", [ "s1", "coherent_artifact_1", "coherent_artifact_2", "coherent_artifact_3", ], ), ], ) axis = {"time": time, "spectral": clp.spectral} data = simulate(model, "dataset1", parameters, axis, clp) dataset = {"dataset1": data} scheme = Scheme( model=model, parameters=parameters, data=dataset, maximum_number_function_evaluations=20 ) result = optimize(scheme) print(result.optimized_parameters) for label, param in result.optimized_parameters.all(): assert np.allclose(param.value, parameters.get(label).value, rtol=1e-8) resultdata = result.data["dataset1"] assert np.array_equal(data.time, resultdata.time) assert np.array_equal(data.spectral, resultdata.spectral) assert data.data.shape == resultdata.data.shape assert data.data.shape == resultdata.fitted_data.shape assert np.allclose(data.data, resultdata.fitted_data) assert "coherent_artifact_response" in resultdata if spectral_dependence == "none": assert resultdata["coherent_artifact_response"].shape == (time.size, 3) else: assert resultdata["coherent_artifact_response"].shape == (spectral.size, time.size, 3) assert "coherent_artifact_associated_spectra" in resultdata assert resultdata["coherent_artifact_associated_spectra"].shape == (3, 3)
def _calculate_global_matrix(self, label: str, dataset_model: DatasetModel): matrix = calculate_matrix(dataset_model, {}, as_global_model=True) self._global_matrices[label] = matrix
class OneCompartmentModelInvertedAxis: decay_model = DecayModel.from_dict({ "initial_concentration": { "j1": { "compartments": ["s1"], "parameters": ["2"] }, }, "megacomplex": { "mc1": { "k_matrix": ["k1"] }, }, "k_matrix": { "k1": { "matrix": { ("s1", "s1"): "1", } } }, "dataset": { "dataset1": { "initial_concentration": "j1", "megacomplex": ["mc1"], }, }, }) decay_parameters = ParameterGroup.from_list( [101e-4, [1, { "vary": False, "non-negative": False }]]) spectral_model = SpectralModel.from_dict({ "megacomplex": { "mc1": { "shape": { "s1": "sh1" } }, }, "shape": { "sh1": { "type": "gaussian", "amplitude": "1", "location": "2", "width": "3", } }, "dataset": { "dataset1": { "megacomplex": ["mc1"], "spectral_axis_scale": 1e7, "spectral_axis_inverted": True, }, }, }) spectral_parameters = ParameterGroup.from_list([7, 1e7 / 10000, 800, -1]) time = np.arange(-10, 50, 1.5) spectral = np.arange(5000, 15000, 20) axis = {"time": time, "spectral": spectral} decay_dataset_model = decay_model.dataset["dataset1"].fill( decay_model, decay_parameters) decay_dataset_model.overwrite_global_dimension("spectral") decay_dataset_model.set_coordinates(axis) matrix = calculate_matrix(decay_dataset_model, {}) decay_compartments = matrix.clp_labels clp = xr.DataArray(matrix.matrix, coords=[("time", time), ("clp_label", decay_compartments)])
class ThreeCompartmentModel: decay_model = DecayModel.from_dict({ "initial_concentration": { "j1": { "compartments": ["s1", "s2", "s3"], "parameters": ["4", "4", "4"] }, }, "megacomplex": { "mc1": { "k_matrix": ["k1"] }, }, "k_matrix": { "k1": { "matrix": { ("s1", "s1"): "1", ("s2", "s2"): "2", ("s3", "s3"): "3", } } }, "dataset": { "dataset1": { "initial_concentration": "j1", "megacomplex": ["mc1"], }, }, }) decay_parameters = ParameterGroup.from_list( [101e-4, 101e-5, 101e-6, [1, { "vary": False, "non-negative": False }]]) spectral_model = SpectralModel.from_dict({ "megacomplex": { "mc1": { "shape": { "s1": "sh1", "s2": "sh2", "s3": "sh3", } }, }, "shape": { "sh1": { "type": "gaussian", "amplitude": "1", "location": "2", "width": "3", }, "sh2": { "type": "gaussian", "amplitude": "4", "location": "5", "width": "6", }, "sh3": { "type": "gaussian", "amplitude": "7", "location": "8", "width": "9", }, }, "dataset": { "dataset1": { "megacomplex": ["mc1"], }, }, }) spectral_parameters = ParameterGroup.from_list([ 7, 450, 80, 20, 550, 50, 10, 580, 10, ]) time = np.arange(-10, 50, 1.5) spectral = np.arange(400, 600, 5) axis = {"time": time, "spectral": spectral} decay_dataset_model = decay_model.dataset["dataset1"].fill( decay_model, decay_parameters) decay_dataset_model.overwrite_global_dimension("spectral") decay_dataset_model.set_coordinates(axis) matrix = calculate_matrix(decay_dataset_model, {}) decay_compartments = matrix.clp_labels clp = xr.DataArray(matrix.matrix, coords=[("time", time), ("clp_label", decay_compartments)])
def test_baseline(): model = Model.from_dict( { "initial_concentration": { "j1": { "compartments": ["s1"], "parameters": ["2"] }, }, "megacomplex": { "mc1": { "type": "decay", "k_matrix": ["k1"] }, "mc2": { "type": "baseline", "dimension": "time" }, }, "k_matrix": { "k1": { "matrix": { ("s1", "s1"): "1", } } }, "dataset": { "dataset1": { "initial_concentration": "j1", "megacomplex": ["mc1", "mc2"], }, }, }, megacomplex_types={ "decay": DecayMegacomplex, "baseline": BaselineMegacomplex }, ) parameter = ParameterGroup.from_list([ 101e-4, [1, { "vary": False, "non-negative": False }], [42, { "vary": False, "non-negative": False }], ]) time = np.asarray(np.arange(0, 50, 1.5)) pixel = np.asarray([0]) coords = {"time": time, "pixel": pixel} dataset_model = model.dataset["dataset1"].fill(model, parameter) dataset_model.overwrite_global_dimension("pixel") dataset_model.set_coordinates(coords) matrix = calculate_matrix(dataset_model, {}) compartments = matrix.clp_labels assert len(compartments) == 2 assert "dataset1_baseline" in compartments assert matrix.matrix.shape == (time.size, 2) assert np.all(matrix.matrix[:, 1] == 1)