def _calculate_residual(self, label: str, dataset_model: DatasetModel): self._group._reduced_clps[label] = [] self._group._clps[label] = [] self._group._weighted_residuals[label] = [] self._group._residuals[label] = [] data = dataset_model.get_data() global_axis = dataset_model.get_global_axis() for i, index in enumerate(global_axis): reduced_clp_labels, reduced_matrix = ( self._group.reduced_matrices[label][i] if dataset_model.is_index_dependent() else self._group.reduced_matrices[label]) if not dataset_model.is_index_dependent(): reduced_matrix = reduced_matrix.copy() if dataset_model.scale is not None: reduced_matrix *= dataset_model.scale weight = dataset_model.get_weight() if weight is not None: apply_weight(reduced_matrix, weight[:, i]) reduced_clps, residual = self._group._residual_function( reduced_matrix, data[:, i]) self._group._reduced_clps[label].append(reduced_clps) clp_labels = self._get_clp_labels(label, i) self._group._clps[label].append( retrieve_clps( self._group.model, self._group.parameters, clp_labels, reduced_clp_labels, reduced_clps, index, )) self._group._weighted_residuals[label].append(residual) if weight is not None: self._group._residuals[label].append(residual / weight[:, i]) else: self._group._residuals[label].append(residual) clp_labels = self._get_clp_labels(label) additional_penalty = calculate_clp_penalties( self._group.model, self._group.parameters, clp_labels, self._group._clps[label], global_axis, self._group.dataset_models, ) if additional_penalty.size != 0: self._group._additional_penalty.append(additional_penalty)
def _calculate_full_model_residual(self, label: str, dataset_model: DatasetModel): model_matrix = self._group.matrices[label] global_matrix = self.global_matrices[label].matrix if dataset_model.is_index_dependent(): matrix = np.concatenate([ np.kron(global_matrix[i, :], model_matrix[i].matrix) for i in range(global_matrix.shape[0]) ]) else: matrix = np.kron(global_matrix, model_matrix.matrix) weight = self._flattened_weights.get(label) if weight is not None: apply_weight(matrix, weight) data = self._flattened_data[label] ( self._group._clps[label], self._group._weighted_residuals[label], ) = self._group._residual_function(matrix, data) self._group._residuals[label] = self._group._weighted_residuals[label] if weight is not None: self._group._residuals[label] /= weight
def finalize_data( self, dataset_model: DatasetModel, dataset: xr.Dataset, is_full_model: bool = False, as_global: bool = False, ): if not is_full_model: global_dimension = dataset_model.get_global_dimension() model_dimension = dataset_model.get_model_dimension() dataset.coords["coherent_artifact_order"] = np.arange( 1, self.order + 1) response_dimensions = (model_dimension, "coherent_artifact_order") if dataset_model.is_index_dependent() is True: response_dimensions = (global_dimension, *response_dimensions) dataset["coherent_artifact_response"] = ( response_dimensions, dataset.matrix.sel(clp_label=self.compartments()).values, ) dataset["coherent_artifact_associated_spectra"] = ( (global_dimension, "coherent_artifact_order"), dataset.clp.sel(clp_label=self.compartments()).values, ) retrieve_irf(dataset_model, dataset, dataset_model.get_global_dimension())
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