PCAGuidedIdifFitterBase ============================================================= .. py:class:: petpal.input_function.pca_guided_idif.PCAGuidedIdifFitterBase(input_image_path: str, mask_image_path: str, output_tac_path: str, num_pca_components: int, pca_comp_filter_min_value: float, pca_comp_threshold: float, verbose: bool) Bases: :py:obj:`PCAGuidedIdifBase` Base class for calculating the PCA-guided IDIF by fitting to find the best voxels This class extends :class:`~.PCAGuidedIdifBase` and provides a framework for applying optimizations and heuristics (e.g., voxel count, peak sharpness, and smoothness) to filter and refine the targeted voxel selection for IDIF estimation. .. rubric:: Notes This class provides a foundation for subclasses to customize voxel filtering and optimization strategies by overriding the static methods for term functions. See :class:`~.PCAGuidedIdifFitter` for a concrete implementation example. Initializes the PCA-guided IDIF fitter base-class. :param input_image_path: Path to the dynamic input image. :type input_image_path: str :param mask_image_path: Path to the mask image used to select the region of interest. :type mask_image_path: str :param output_tac_path: Path where the output TAC data will be saved. :type output_tac_path: str :param num_pca_components: Number of PCA components to compute. :type num_pca_components: int :param pca_comp_filter_min_value: Minimum value for filtering PCA components. :type pca_comp_filter_min_value: float :param pca_comp_threshold: Threshold for filtering PCA components. :type pca_comp_threshold: float :param verbose: Whether to enable detailed diagnostic output. :type verbose: bool Side Effects: - Initializes several fitting-related attributes (e.g., `alpha`, `beta`, `_fitting_params`). - Calculates PCA filtering flags and signs based on the passed thresholds. .. py:property:: pca_comp_filter_flag_threshold :type: float .. py:property:: pca_comp_filter_min_val :type: float .. py:method:: get_pca_component_filter_flags(pca_components: numpy.ndarray, comp_min_val: float = 0.0, threshold: float = 0.1) -> numpy.ndarray[bool] :staticmethod: Generates filtering flags for PCA components based on their contribution. Given the `comp_min_val`, we check how many of the time-points of the PCA components are above the threshold, then `threshold` determines if the component contributes with ``>`` (if the fraction of higher points is above the threshold) or ``<`` (if the fraction of higher points is below the threshold). :param pca_components: Array of PCA components for evaluation. :type pca_components: np.ndarray :param comp_min_val: Minimum value for PCA components to contribute positively. :type comp_min_val: float :param threshold: Threshold for rejecting components with insufficient contributions. :type threshold: float :returns: *np.ndarray[bool]* -- Boolean flags indicating whether a PCA filters less than, or greater than. .. py:method:: get_pca_filter_signs_from_flags(pca_component_filter_flags: numpy.ndarray[bool]) -> list[str] :staticmethod: Derives signs ('>' or '<') for PCA components based on their filtering flags. .. seealso:: :meth:`get_pca_component_filter_flags` :param pca_component_filter_flags: Filtering flags for PCA components. :type pca_component_filter_flags: np.ndarray[bool] :returns: *list[str]* -- List of signs corresponding to the filter flags. .. py:method:: _voxel_term_func(voxel_nums: float) -> float :staticmethod: :abstractmethod: Abstract method for computing the voxel-number term for the optimization function. :param voxel_nums: Number of valid voxels contributing to the TACs. :type voxel_nums: float :returns: *float* -- Calculated voxel term. .. py:method:: _noise_term_func(tac_stderrs: numpy.ndarray[float]) -> float :staticmethod: :abstractmethod: Abstract method for computing the noise term for the optimization function. :param tac_stderrs: Standard deviations of TACs from voxel data. :type tac_stderrs: np.ndarray[float] :returns: *float* -- Calculated noise term. .. py:method:: _smoothness_term_func(tac_values: numpy.ndarray[float]) -> float :staticmethod: :abstractmethod: Abstract method for computing the smoothness term for the optimization function. :param tac_values: Mean values of TACs from voxel data. :type tac_values: np.ndarray[float] :returns: *float* -- Calculated smoothness term. .. py:method:: _peak_term_func(tac_peak_ratio: float) -> float :staticmethod: :abstractmethod: Abstract method for computing the peak term for the optimization function. :param tac_peak_ratio: Ratio of the voxel TAC peak to the peak of the mask average :type tac_peak_ratio: float :returns: *float* -- Calculated peak term. .. py:method:: _generate_quantile_params(num_components: int = 3, value: float = 0.5, lower: float = 0.0001, upper: float = 0.999) -> lmfit.Parameters :staticmethod: Generates initial fitting quantile parameters for determining voxel filters. :param num_components: The number of PCA components to generate parameters for. :type num_components: int :param value: Default value for each quantile parameter (e.g., median = 0.5). :type value: float :param lower: Lower bound for the quantile parameter (default is 1e-4). :type lower: float :param upper: Upper bound for the quantile parameter (default is 0.999). :type upper: float :returns: *lmfit.Parameters* -- A parameter set with quantile values for each PCA component. .. py:method:: calculate_voxel_mask_from_quantiles(params: lmfit.Parameters, pca_values_per_voxel: numpy.ndarray, quantile_flags: numpy.ndarray[bool]) -> numpy.ndarray[bool] :staticmethod: Calculates a mask to identify selected voxels based on quantile thresholds. Given the passed in quantile `params`, we check if the value of the principal component for a voxel is above the quantile threshold, then `quantile_flags` is used to flip the signs of the components which should be lower than. For each voxel, the boolean product is calculated to determine if the voxel should be a part of the mask or not. Only voxels where every PC is above (or below) the quantile thresholds in `params` are included in the mask. :param params: Quantile parameters for each PCA component. :type params: lmfit.Parameters :param pca_values_per_voxel: PCA values for every voxel. :type pca_values_per_voxel: np.ndarray :param quantile_flags: Filtering flags for quantile-based masking. :type quantile_flags: np.ndarray[bool] :returns: *np.ndarray[bool]* -- Mask identifying selected voxels passing the quantile criteria. .. py:method:: calculate_filter_flags_and_signs(comp_min_val: float, threshold: float) Updates PCA filter flags and their respective signs based on component values. :param comp_min_val: Minimum acceptable value for filtering PCA components. :type comp_min_val: float :param threshold: Threshold percentage for filtering components. :type threshold: float Side Effects: - Updates the `pca_filter_flags` attribute with new flags for indicating filtered components. - Updates the `filter_signs` attribute with the corresponding value comparison signs based on the flags. .. py:method:: residual(params: lmfit.Parameters, pca_values_per_voxel: numpy.ndarray[float], quantile_flags: numpy.ndarray[bool], voxel_tacs: numpy.ndarray, alpha: float, beta: float) -> float Calculates the residual (objective function) for optimization. The residual has the following terms: .. math:: \mathcal{L} = \mathrm{VoxelTerm} + \mathrm{NoiseTerm} + (\alpha\cdot\mathrm{PeakTerm}) + (\beta\cdot\mathrm{SmoothnessTerm}) :param params: Parameters for the optimization. :type params: lmfit.Parameters :param pca_values_per_voxel: PCA values for each voxel. :type pca_values_per_voxel: np.ndarray[float] :param quantile_flags: Flags indicating quantile filtering. :type quantile_flags: np.ndarray[bool] :param voxel_tacs: TACs for valid voxels. :type voxel_tacs: np.ndarray :param alpha: Weight for the peak term. :type alpha: float :param beta: Weight for the smoothness term. :type beta: float :returns: *float* -- Residual value. .. py:method:: run(alpha: float, beta: float, method: str = 'ampgo', **method_kwargs) Runs the PCA-guided IDIF fitting process using optimization. :param alpha: Weight for the peak term in the optimization. :type alpha: float :param beta: Weight for the smoothness term in the optimization. :type beta: float :param method: Optimization method to use (default is 'ampgo'). :type method: str :param \*\*method_kwargs: Additional keyword arguments for the optimizer. Side Effects: - Updates optimization-related attributes (e.g., `fit_result`, `fit_quantiles`). - Updates `selected_voxels_mask` with the best voxel subset. - Marks `analysis_has_run` as True. .. rubric:: Notes The `run` method uses the residual function as the target for minimization. .. py:method:: __call__(alpha: float, beta: float, method: str, **meth_kwargs) -> None Callable interface for running the fitting process and saving results. :param alpha: Weight for the peak term in the optimization. :type alpha: float :param beta: Weight for the smoothness term in the optimization. :type beta: float :param method: Optimization method to use. :type method: str :param \*\*method_kwargs: Additional keyword arguments for the optimizer. Side Effects: - Executes the analysis and saves the resulting TAC data to the output file. .. py:method:: perform_temporal_pca() Performs PCA decomposition on the dynamic image data within the specified mask. This method applies temporal PCA analysis on the input dynamic image constrained to the region defined by the mask. The resulting PCA object and fitted data are stored as attributes for subsequent processing. Uses :func:`~.extract_roi_voxel_tacs_from_image_using_mask` Attributes Updated: - `pca_obj` - `pca_fit` :raises ValueError: If PCA analysis fails during execution. .. py:method:: rescale_tacs(rescale_constant: float = CONVERT_kBq_to_mCi_) -> None Rescales the time-activity curves (TACs) and associated data by a constant factor. This method uniformly rescales voxel-level TACs, IDIF values, PCA outputs, and other TAC-associated metrics using the specified constant. The default value corresponds to a pre-defined scaling factor to convert units between kilobecquerels and millicuries. :param rescale_constant: The constant factor used for rescaling. Must be greater than zero. Default is 37000.0. :type rescale_constant: float Attributes Updated: - `mask_voxel_tacs` - `mask_avg` - `mask_std` - `mask_peak_val` - `idif_vals` - `idif_errs` - `prj_idif_vals` - `prj_idif_errs` - `selected_voxels_tacs` - `selected_voxels_prj_tacs` :raises AssertionError: If the `rescale_constant` is not greater than 0. .. py:method:: save() Saves the computed IDIF and related metrics to a file. This method exports the time-activity curves (TACs) and other analysis results into a tab-delimited text file. The file will include time points, IDIF values, errors, PCA-projected metrics, and mask-derived averages, along with their associated standard deviations. The output file is saved at the path specified in the `output_tac_path` attribute. :raises AssertionError: If the analysis has not been run prior to calling this method. Output Format: The saved text file will have the following tab-delimited columns: - time: Time in minutes. - idif: IDIF values. - d_idif: Errors (standard deviations) for IDIF. - prj_idif: PCA-projected IDIF values. - d_prj_idif: Errors (standard deviations) for PCA-projected IDIF values. - mask: Mean voxel activity in the mask. - d_mask: Standard deviation of voxel activity in the mask. .. py:method:: calculate_tacs_from_mask() -> None Calculates Time-Activity Curves (TACs) and IDIF-related metrics from the selected voxel mask. This method processes the data from selected voxels within a previously defined mask and computes key metrics such as mean IDIF values, standard deviations, PCA-projected values, and their respective errors. It utilizes PCA transformations to refine the IDIF and ensure consistency with the voxel data. Side Effects: idif_vals (np.ndarray): Mean IDIF values calculated from the selected voxel TACs. idif_errs (np.ndarray): Standard deviations of the IDIF values derived from selected voxels. prj_idif_vals (np.ndarray): Mean PCA-projected IDIF values, with negative values set to zero. prj_idif_errs (np.ndarray): Standard deviations for the PCA-projected IDIF values. :raises AssertionError: If the analysis has not been previously performed (i.e., `.run()` was not called). .. rubric:: Notes - Negative PCA-projected IDIF values are set to zero since negative values are non-physical. .. py:property:: idif_tac Get the calculated IDIF TAC :returns: *TimeActivityCurve* -- TAC object with (times, idif_vals) .. seealso:: :class:`~.TimeActivityCurve` .. py:property:: idif_tac_werr Get the calculated IDIF TAC with the standard deviations :returns: *TimeActivityCurve* -- TAC object with (times, idif_vals, idif_stderrs) .. seealso:: :class:`~.TimeActivityCurve` .. py:property:: prj_idif_tac Get the calculated PCA-projected IDIF TAC :returns: *TimeActivityCurve* -- TAC object with (times, projected_idif_vals) .. seealso:: :class:`~.TimeActivityCurve` .. py:property:: prj_idif_tac_werr Get the calculated PCA-projected IDIF TAC with the standard deviations :returns: *TimeActivityCurve* -- TAC object with (times, projected_idif_vals, projected_idif_stderrs) .. seealso:: :class:`~.TimeActivityCurve`