diff --git a/rabies/analysis_pkg/analysis_functions.py b/rabies/analysis_pkg/analysis_functions.py index 30d44181..4da4d8f2 100644 --- a/rabies/analysis_pkg/analysis_functions.py +++ b/rabies/analysis_pkg/analysis_functions.py @@ -217,6 +217,14 @@ class ComplementaryPCA(BaseInterface): output_spec = ComplementaryPCAOutputSpec def _run_interface(self, runtime): + """ + Run Complementary Principal Component Analysis (CPCA) on BOLD fMRI data using provided priors and parameters. + + Loads preprocessed BOLD data and prior spatial maps, applies CPCA modeling to extract prior and extra spatial/temporal components, generates component figures, and saves results as NIfTI images and CSV files. Output files and report folder are set as attributes for downstream workflow use. + + Returns: + runtime: The updated runtime object after processing. + """ import os import numpy as np import pandas as pd @@ -298,6 +306,9 @@ def _run_interface(self, runtime): return runtime def _list_outputs(self): + """ + Return a dictionary mapping output names to their corresponding file paths or report folder for the ComplementaryPCA interface. + """ return {'CPCA_prior_timecourse_csv': getattr(self, 'CPCA_prior_timecourse_csv'), 'CPCA_extra_timecourse_csv': getattr(self, 'CPCA_extra_timecourse_csv'), 'CPCA_prior_filename': getattr(self, 'CPCA_prior_filename'), diff --git a/rabies/analysis_pkg/analysis_math.py b/rabies/analysis_pkg/analysis_math.py index a8b72bea..78c76720 100644 --- a/rabies/analysis_pkg/analysis_math.py +++ b/rabies/analysis_pkg/analysis_math.py @@ -58,6 +58,19 @@ def dual_regression(all_IC_vectors, timeseries): ### The fMRI timeseries aren't assumed theoretically to be spatially centered, and ### this measure would be removing global signal variations which we are interested in. ### Thus we prefer to avoid this step here, despite modelling limitations. + """ + Perform dual regression to decompose timeseries data into spatial weights and component timecourses using provided independent component vectors. + + Parameters: + all_IC_vectors (ndarray): Array of independent component spatial maps (components x voxels). + timeseries (ndarray): Array of observed timeseries data (voxels x timepoints). + + Returns: + dict: Dictionary containing: + 'C' (ndarray): Component timecourses (components x timepoints), variance-normalized. + 'W' (ndarray): Spatial weights (voxels x components), variance-normalized. + 'S' (ndarray): Scaling factors for each component. + """ X = all_IC_vectors.T Y = timeseries.T # for one given volume, it's values can be expressed through a linear combination of the components diff --git a/rabies/analysis_pkg/analysis_wf.py b/rabies/analysis_pkg/analysis_wf.py index 371376fe..f32aa890 100644 --- a/rabies/analysis_pkg/analysis_wf.py +++ b/rabies/analysis_pkg/analysis_wf.py @@ -9,6 +9,22 @@ def init_analysis_wf(opts, commonspace_cr=False, name="analysis_wf"): + """ + Initialize and configure a Nipype workflow for neuroimaging data analysis based on specified options. + + This function constructs a modular workflow that conditionally includes analysis steps such as seed-based functional connectivity, dual regression ICA, group ICA, complementary PCA, and functional connectivity matrix computation. The workflow manages subject- and group-level inputs, enforces prerequisites for certain analyses, and aggregates outputs for downstream processing. + + Parameters: + opts: Configuration object containing analysis options and parameters. + commonspace_cr (bool): Indicates if confound regression outputs are in common space. Required for seed-based FC and group ICA. + name (str): Name assigned to the workflow. + + Returns: + workflow: A Nipype Workflow object with nodes and connections reflecting the requested analyses. + + Raises: + ValueError: If seed-based FC or group ICA is requested without common space confound regression outputs, or if any specified seed file does not exist. + """ workflow = pe.Workflow(name=name) subject_inputnode = pe.Node(niu.IdentityInterface( fields=['dict_file', 'token']), name='subject_inputnode') diff --git a/rabies/analysis_pkg/cpca/modeling.py b/rabies/analysis_pkg/cpca/modeling.py index 534def4e..f78d52d0 100644 --- a/rabies/analysis_pkg/cpca/modeling.py +++ b/rabies/analysis_pkg/cpca/modeling.py @@ -5,9 +5,23 @@ def spatial_cpca(X, q=1, c_init=None, W_prior=None, tol=1e-6, max_iter=200, verbose=1): - ''' - Derives spatially orthogonal complementary components (first step of CPCA, i.e. spatial CPCA) - ''' + """ + Extracts spatially orthogonal complementary components from a data matrix using the first step of Complementary Principal Component Analysis (CPCA). + + Parameters: + X (ndarray): Data matrix of shape (time points, voxels). + q (int, optional): Number of spatial components to extract. Default is 1. + c_init (ndarray, optional): Initial spatial weights matrix of shape (voxels, components). If None, initialized randomly. + W_prior (ndarray, optional): Prior temporal weights matrix of shape (time points, components). If None, set to zeros. + tol (float, optional): Convergence tolerance. Default is 1e-6. + max_iter (int, optional): Maximum number of iterations. Default is 200. + verbose (int, optional): Verbosity level for logging progress. + + Returns: + Cs (ndarray): Extracted spatial components (voxels × q). + Ws (ndarray): Corresponding temporal components (time points × q). + C_ (ndarray): Combined components matrix after update. + """ # X: time by voxel matrix # c_init: can specify an voxel by component number matrix for initiating weights @@ -49,9 +63,27 @@ def spatial_cpca(X, q=1, c_init=None, W_prior=None, tol=1e-6, max_iter=200, verb return Cs,Ws,C_ def cpca(X, C_prior, sequence = ['s','s','s','s'], verbose=False): - ''' - CPCA algorithm: 1) spatial CPCA, 2) temporal CPCA with Wt correction, 3) derive final model - ''' + """ + Performs Complementary Principal Component Analysis (CPCA) to extract spatial and temporal components from a data matrix. + + This function iteratively derives spatial and temporal components according to a specified sequence, applies temporal correction to ensure orthogonality, normalizes component weights, and computes the final component matrices. + + Parameters: + X (ndarray): Data matrix of shape (time points, voxels). + C_prior (ndarray): Prior spatial components matrix. + sequence (list of str, optional): List indicating the order and type of components to extract ('s' for spatial, 't' for temporal). Default is four spatial components. + verbose (bool, optional): If True, prints progress information. + + Returns: + Cnet (ndarray): Corrected prior spatial components. + Wnet (ndarray): Corrected prior spatial weights. + Cs (ndarray): Extracted spatial components. + Ws (ndarray): Extracted spatial weights. + Ct (ndarray): Extracted temporal components. + Wt (ndarray): Extracted temporal weights. + C (ndarray): Final combined component matrix. + W (ndarray): Final combined weights matrix. + """ q=1 # one component is derived at a time to have deterministic outputs @@ -99,9 +131,25 @@ def cpca(X, C_prior, sequence = ['s','s','s','s'], verbose=False): def cpca_quick(X, C_prior, sequence = ['s','s','s','s'], tol=1e-10, verbose=False): - ''' - CPCA algorithm, but X is residualized for each spatial CPCA component to speed up convergence for next iterations - ''' + """ + Performs CPCA with accelerated convergence by residualizing the data matrix after each spatial component extraction. + + This function iteratively extracts spatial components from the data matrix, subtracting each extracted component's contribution before the next iteration. After all components are derived according to the specified sequence, temporal correction and normalization are applied to the resulting weights and components. + + Parameters: + sequence (list of str): Specifies the order and type of components to extract ('s' for spatial, 't' for temporal). + tol (float): Convergence tolerance for spatial CPCA steps. + + Returns: + Cnet (ndarray): Corrected prior spatial components. + Wnet (ndarray): Corrected prior spatial weights. + Cs (ndarray): Extracted spatial components. + Ws (ndarray): Extracted spatial weights. + Ct (ndarray): Extracted temporal components. + Wt (ndarray): Extracted temporal weights. + C (ndarray): Final combined component matrix. + W (ndarray): Final combined weight matrix. + """ q=1 # one component is derived at a time to have deterministic outputs @@ -153,9 +201,31 @@ def cpca_quick(X, C_prior, sequence = ['s','s','s','s'], tol=1e-10, verbose=Fals def cpca_auto(X, C_prior, N_max, Wt_n='n', min_prior_sim=None, Dc_W_thresh=None, Dc_C_thresh=None): - ''' - Conduct CPCA with automated estimation of n*. Wt_n sets a maximum for how many components are used for temporal CPCA. - ''' + """ + Performs automated Complementary Principal Component Analysis (CPCA) with estimation of the optimal number of spatial components. + + This function runs CPCA with up to `N_max` spatial components, uses a fitting report to determine the optimal number of components, and constructs the final model accordingly. The number of temporal components used can be limited by `Wt_n`. Returns the corrected prior components and weights, spatial and temporal components and weights, final combined matrices, and diagnostic figures. + + Parameters: + X (np.ndarray): Data matrix (time points × voxels). + C_prior (np.ndarray): Prior spatial components matrix. + N_max (int): Maximum number of spatial components to consider. + Wt_n (int or 'n', optional): Maximum number of temporal components to use; if 'n', uses all available. + min_prior_sim (float, optional): Minimum similarity threshold for prior components in the fitting report. + Dc_W_thresh (float, optional): Threshold for temporal component diagnostics. + Dc_C_thresh (float, optional): Threshold for spatial component diagnostics. + + Returns: + Cnet (np.ndarray): Corrected prior spatial components. + Wnet (np.ndarray): Corrected prior weights. + Cs (np.ndarray): Derived spatial components. + Ws (np.ndarray): Derived spatial weights. + Ct (np.ndarray): Derived temporal components. + Wt (np.ndarray): Derived temporal weights. + C (np.ndarray): Final combined components matrix. + W (np.ndarray): Final combined weights matrix. + fig_list (list): List of diagnostic figures from the fitting report. + """ if Wt_n=='n': Wt_n = N_max diff --git a/rabies/analysis_pkg/cpca/report.py b/rabies/analysis_pkg/cpca/report.py index 3e96a973..1c36e16c 100644 --- a/rabies/analysis_pkg/cpca/report.py +++ b/rabies/analysis_pkg/cpca/report.py @@ -5,6 +5,14 @@ def cosine_similarity(X,Y=None): # estimate cosine similarity across the columns of X and Y combined + """ + Compute the cosine similarity matrix between columns of one or two input arrays. + + If only X is provided, returns the cosine similarity among columns of X. If Y is provided, computes similarities among all columns of X and Y combined. + + Returns: + Sc (ndarray): Square matrix of cosine similarities between columns. + """ if Y is None: arr = X.copy() else: @@ -15,12 +23,20 @@ def cosine_similarity(X,Y=None): def gen_report(X,C_prior, Cs, min_prior_sim=None, Dc_W_thresh=None, Dc_C_thresh=None): - ''' - Generate CPCA fitting report, and derive an optimal value for n* using minimal - prior similarity threshold, and/or thresholds on Dc_Wnet and/or Dc_Cnet. - If min_prior_sim=None, Dc_t_thresh=None, and Dc_s_thresh=None, then n_optim_idx - will be None (no optimal n* is derived). - ''' + """ + Generates a CPCA fitting report and determines the optimal number of components based on similarity and distance thresholds. + + Evaluates the CPCA fit using provided data and prior components, computes relevant metrics, and produces diagnostic plots. The optimal component count is selected according to user-specified thresholds for minimal prior similarity and cosine distances of spatial and temporal components. Returns the optimal index and a list of diagnostic figure objects. + + Parameters: + min_prior_sim (float, optional): Minimum acceptable similarity to prior components for selecting the optimal component count. + Dc_W_thresh (float, optional): Cosine distance threshold for temporal components. + Dc_C_thresh (float, optional): Cosine distance threshold for spatial components. + + Returns: + n_optim_idx (int or None): Index of the optimal number of components, or None if no thresholds are provided or met. + fig_list (list): List of matplotlib figure objects containing diagnostic plots. + """ # generate the fitting report Snet_s_l,Snet_t_l,prior_sim_l,Dc_Cnet,Dc_Wnet,R2_s,R2_t = evaluate_fit(X,C_prior,Cs) @@ -37,6 +53,25 @@ def gen_report(X,C_prior, Cs, min_prior_sim=None, Dc_W_thresh=None, Dc_C_thresh= def evaluate_fit(X,C_prior,Cs): + """ + Evaluate the quality of CPCA fitting across a range of component counts. + + For each number of added candidate components, computes spatial and temporal network amplitudes, similarity to prior components, cosine distances between consecutive iterations for spatial and temporal components, and redundancy metrics (R2) for orthogonal and non-orthogonal CPCA. Returns lists and arrays of these metrics for further analysis and reporting. + + Parameters: + X (ndarray): Data matrix to be decomposed. + C_prior (ndarray): Matrix of prior spatial components. + Cs (ndarray): Matrix of candidate spatial components. + + Returns: + Snet_s_l (list): Spatial network amplitudes for orthogonal CPCA at each iteration. + Snet_t_l (list): Spatial network amplitudes for non-orthogonal CPCA at each iteration. + prior_sim_l (list): Cosine similarities between estimated and prior components at each iteration. + Dc_Cnet (ndarray): Cosine distances between consecutive spatial component estimates. + Dc_Wnet (ndarray): Cosine distances between consecutive temporal component estimates. + R2_s (ndarray): Redundancy (variance explained) for orthogonal CPCA at each iteration. + R2_t (ndarray): Redundancy (variance explained) for non-orthogonal CPCA at each iteration. + """ n_prior = C_prior.shape[1] N = Cs.shape[1] C_prior_ = np.concatenate((C_prior, Cs),axis=1) # expand prior @@ -127,6 +162,15 @@ def evaluate_fit(X,C_prior,Cs): def optim_n(prior_sim_l,min_prior_sim,Dc_Cnet,Dc_Wnet,Dc_W_thresh,Dc_C_thresh): + """ + Determine the optimal number of components based on prior similarity and cosine distance thresholds. + + Parameters: + prior_sim_l (array-like): Sequence of prior similarity values for each iteration. + + Returns: + optim_idx (int or None): The index corresponding to the optimal number of components, or None if no thresholds are provided or met. + """ if (min_prior_sim is None) and (Dc_W_thresh is None) and (Dc_C_thresh is None): return None @@ -164,7 +208,30 @@ def optim_n(prior_sim_l,min_prior_sim,Dc_Cnet,Dc_Wnet,Dc_W_thresh,Dc_C_thresh): def plot_report(n_prior,N_max,n_optim_idx,min_prior_sim,Dc_W_thresh,Dc_C_thresh,prior_sim_l, Snet_s_l,Snet_t_l,Dc_Cnet,Dc_Wnet,R2_s,R2_t): - fig_list = [] + """ + Generate diagnostic plots for each prior component to visualize CPCA fitting metrics. + + For each prior component, creates a 2x2 grid of plots showing network amplitude, prior similarity, component change via cosine distance, and redundancy metrics. Thresholds and the optimal component count are marked if provided. + + Parameters: + n_prior (int): Number of prior components. + N_max (int): Maximum number of CPCA components considered. + n_optim_idx (int or None): Index of the optimal number of components, if determined. + min_prior_sim (float or None): Threshold for minimal prior similarity, if specified. + Dc_W_thresh (float or None): Cosine distance threshold for timecourse components, if specified. + Dc_C_thresh (float or None): Cosine distance threshold for spatial components, if specified. + prior_sim_l (ndarray): Array of prior similarity values across component counts. + Snet_s_l (ndarray): Array of spatial network amplitudes for orthogonal CPCA. + Snet_t_l (ndarray): Array of temporal network amplitudes for non-orthogonal CPCA. + Dc_Cnet (ndarray): Array of cosine distances for spatial components. + Dc_Wnet (ndarray): Array of cosine distances for timecourse components. + R2_s (ndarray): Redundancy metrics for orthogonal CPCA. + R2_t (ndarray): Redundancy metrics for non-orthogonal CPCA. + + Returns: + fig_list (list): List of matplotlib Figure objects, one per prior component. + """ + fig_list = [] for prior_idx in range(n_prior): fig,axes = plt.subplots(2,2, figsize=(8,8), constrained_layout=True) diff --git a/rabies/analysis_pkg/diagnosis_pkg/diagnosis_functions.py b/rabies/analysis_pkg/diagnosis_pkg/diagnosis_functions.py index de0fc8a6..8ca6eca8 100644 --- a/rabies/analysis_pkg/diagnosis_pkg/diagnosis_functions.py +++ b/rabies/analysis_pkg/diagnosis_pkg/diagnosis_functions.py @@ -39,6 +39,19 @@ def resample_mask(in_file, ref_file): def process_data(data_dict, analysis_dict, prior_bold_idx, prior_confound_idx): + """ + Extracts and organizes temporal and spatial features from fMRI timeseries and associated analysis data. + + This function processes subject-level neuroimaging data to compute and aggregate a variety of temporal and spatial metrics, including motion parameters, regional timecourses, dual regression and CPCA network features, and seed-based correlation results. The output consists of two dictionaries containing all relevant features for downstream analysis or quality control. + + Parameters: + prior_bold_idx (array-like): Indices specifying which components are considered BOLD-related. + prior_confound_idx (array-like): Indices specifying which components are considered confounds. + + Returns: + temporal_info (dict): Dictionary containing temporal features such as motion traces, regional timecourses, and network timecourses. + spatial_info (dict): Dictionary containing spatial features such as network maps, variance explained, and global signal metrics. + """ temporal_info = {} spatial_info = {} temporal_info['name_source'] = data_dict['name_source'] @@ -137,6 +150,14 @@ def process_data(data_dict, analysis_dict, prior_bold_idx, prior_confound_idx): def temporal_external_formating(temporal_info): + """ + Export selected temporal metrics to a CSV file after removing large array entries. + + Removes detailed timecourse arrays from the input dictionary, then saves the remaining temporal summary information to a CSV file named after the source data. Returns the path to the generated CSV file. + + Returns: + temporal_info_csv (str): Absolute path to the saved CSV file containing temporal summary metrics. + """ import os import pandas as pd import pathlib # Better path manipulation @@ -251,6 +272,21 @@ def plot_freqs(ax,timeseries, TR): def scan_diagnosis(data_dict, temporal_info, spatial_info, regional_grayplot=False): + """ + Generate comprehensive quality control (QC) figures for a subject's fMRI data, visualizing temporal and spatial features. + + Creates two matplotlib figures: the first displays timeseries diagnostics including frequency spectrum, grayplot, motion parameters, framewise displacement (FD), DVARS, regional amplitudes, and network timecourse amplitudes; the second shows spatial maps such as template, temporal and predicted standard deviation, variance explained, global signal covariance, and network component maps (DR, SBC, CPCA) with thresholded overlays. + + Parameters: + data_dict (dict): Dictionary containing subject data, including timeseries, template, mask, and motion parameters. + temporal_info (dict): Dictionary of extracted temporal features and metrics. + spatial_info (dict): Dictionary of extracted spatial features and network maps. + regional_grayplot (bool, optional): If True, displays a regionally segmented grayplot (currently disabled). + + Returns: + fig (matplotlib.figure.Figure): Figure with temporal QC plots. + fig2 (matplotlib.figure.Figure): Figure with spatial maps and network overlays. + """ timeseries = data_dict['timeseries'] template_file = data_dict['template_file'] CR_data_dict = data_dict['CR_data_dict'] diff --git a/rabies/analysis_pkg/diagnosis_pkg/diagnosis_wf.py b/rabies/analysis_pkg/diagnosis_pkg/diagnosis_wf.py index f7e7e849..f7cedcab 100644 --- a/rabies/analysis_pkg/diagnosis_pkg/diagnosis_wf.py +++ b/rabies/analysis_pkg/diagnosis_pkg/diagnosis_wf.py @@ -9,6 +9,21 @@ def init_diagnosis_wf(analysis_opts, commonspace_bold, preprocess_opts, split_name_list, name="diagnosis_wf"): + """ + Initializes a Nipype workflow for scan-level and dataset-level neuroimaging diagnosis analysis. + + This workflow integrates multiple processing nodes to perform diagnostic analyses on individual scans and, when sufficient data is available, on the dataset as a whole. It conditionally configures group-level diagnosis based on the presence of BOLD data in common space or a BOLD-only preprocessing flag, and the number of scans provided. + + Parameters: + analysis_opts: Analysis configuration options, including indices, thresholds, and figure format. + commonspace_bold (bool): Indicates if BOLD data is in common anatomical space. + preprocess_opts: Preprocessing options, including anatomical template and BOLD-only flag. + split_name_list (list): List of scan names used to determine dataset size. + name (str, optional): Name for the workflow. Defaults to "diagnosis_wf". + + Returns: + workflow: A Nipype Workflow object configured for neuroimaging diagnosis analysis. + """ workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface( fields=['dict_file', 'analysis_dict']), name='inputnode') @@ -73,6 +88,19 @@ def init_diagnosis_wf(analysis_opts, commonspace_bold, preprocess_opts, split_na if (commonspace_bold or preprocess_opts.bold_only) and not len(split_name_list)<3: def prep_scan_data(dict_file, spatial_info, temporal_info): + """ + Extracts and organizes diagnostic data from input files for a single scan. + + Loads a pickled dictionary from the specified file and combines selected spatial and temporal diagnostic metrics, confound and network timecourses, quality control measures, and metadata into a single dictionary for downstream dataset-level analysis. + + Parameters: + dict_file (str): Path to the pickled dictionary file containing scan metadata and QC metrics. + spatial_info (dict): Dictionary of spatial diagnostic results for the scan. + temporal_info (dict): Dictionary of temporal diagnostic results for the scan. + + Returns: + dict: Aggregated scan data including spatial and temporal metrics, timecourses, QC measures, and metadata. + """ import pickle with open(dict_file, 'rb') as handle: data_dict = pickle.load(handle) diff --git a/rabies/analysis_pkg/diagnosis_pkg/interfaces.py b/rabies/analysis_pkg/diagnosis_pkg/interfaces.py index 6d249992..e14c4ebe 100644 --- a/rabies/analysis_pkg/diagnosis_pkg/interfaces.py +++ b/rabies/analysis_pkg/diagnosis_pkg/interfaces.py @@ -185,6 +185,13 @@ class DatasetDiagnosis(BaseInterface): output_spec = DatasetDiagnosisOutputSpec def _run_interface(self, runtime): + """ + Performs group-level quality control analysis by aggregating and evaluating spatial and temporal features across multiple neuroimaging scans. + + This method computes group statistics, detects outliers, and generates quality control (QC) figures and CSV reports for different network types (DR, CPCA, SBC). It supports both parametric and non-parametric analyses, applies user-defined or default QC thresholds, and handles group priors or external prior maps as needed. The results are saved in structured output directories for further review. + + If fewer than three scans are provided, the analysis is skipped and a warning is logged. + """ import pathlib import matplotlib.pyplot as plt from rabies.utils import flatten_list diff --git a/rabies/analysis_pkg/main_wf.py b/rabies/analysis_pkg/main_wf.py index d7cc2014..f60a5ae4 100644 --- a/rabies/analysis_pkg/main_wf.py +++ b/rabies/analysis_pkg/main_wf.py @@ -11,6 +11,22 @@ def init_main_analysis_wf(preprocess_opts, cr_opts, analysis_opts): + """ + Initialize the main Nipype workflow for neuroimaging analysis, integrating confound correction outputs, data preparation, analysis, and optional diagnostic workflows. + + This function constructs a Nipype workflow that: + - Loads confound correction outputs and filters BOLD scan splits based on inclusion/exclusion criteria. + - Prepares subject-specific and group-level data nodes for analysis. + - Initializes and connects the main analysis workflow, handling both native and common space processing. + - Sets up data sinks for saving analysis and diagnostic outputs. + - Optionally initializes and connects a diagnostic workflow if enabled, packaging relevant analysis outputs for further quality control. + + Raises: + ValueError: If no confound correction outputs are found or if required prior maps are missing. + + Returns: + workflow: The fully constructed Nipype workflow ready for execution. + """ workflow = pe.Workflow(name='analysis_main_wf') conf_output = os.path.abspath(str(analysis_opts.confound_correction_out)) @@ -176,6 +192,12 @@ def read_dict(split_dict, split_name, target_list): if analysis_opts.data_diagnosis: def prep_analysis_dict(seed_map_files, seed_timecourse_csv, dual_regression_nii, dual_regression_timecourse_csv, CPCA_prior_timecourse_csv, CPCA_extra_timecourse_csv, CPCA_prior_filename, CPCA_extra_filename): + """ + Package analysis output file paths into a dictionary for downstream processing. + + Returns: + dict: Dictionary containing file paths for seed-based, dual regression, and CPCA analysis outputs. + """ return {'seed_map_files':seed_map_files, 'seed_timecourse_csv':seed_timecourse_csv, 'dual_regression_nii':dual_regression_nii, 'dual_regression_timecourse_csv':dual_regression_timecourse_csv, 'CPCA_prior_timecourse_csv':CPCA_prior_timecourse_csv, 'CPCA_extra_timecourse_csv':CPCA_extra_timecourse_csv, 'CPCA_prior_filename':CPCA_prior_filename, 'CPCA_extra_filename':CPCA_extra_filename} diff --git a/rabies/parser.py b/rabies/parser.py index 7496f218..c58c2b0e 100644 --- a/rabies/parser.py +++ b/rabies/parser.py @@ -10,7 +10,14 @@ def get_parser(): - """Build parser object""" + """ + Constructs and returns an argparse.ArgumentParser configured for the RABIES rodent fMRI processing pipeline. + + The parser supports three main subcommands—preprocess, confound_correction, and analysis—each with comprehensive argument groups for their respective processing stages. Options include parallel execution, memory management, input/output directories, BIDS filtering, registration and resampling strategies, slice timing correction, confound correction methods, quality control thresholds, and multiple analysis modalities such as seed-based connectivity, group ICA, dual regression, and CPCA. + + Returns: + argparse.ArgumentParser: Configured parser for RABIES CLI usage. + """ parser = argparse.ArgumentParser( description= "RABIES performs multiple stages of rodent fMRI image processing, including preprocessing, \n" @@ -1023,6 +1030,14 @@ def get_parser(): def read_parser(parser, args): + """ + Parse and validate command-line arguments for the specified RABIES processing stage. + + Depending on the selected stage ('preprocess', 'confound_correction', or 'analysis'), this function processes and validates complex options, including parsing key-value string arguments into dictionaries, loading JSON filters, and enforcing logical consistency among related options. Returns the fully parsed and validated options object. + + Returns: + opts: Namespace object containing parsed and validated command-line arguments for the selected RABIES stage. + """ if args is None: opts = parser.parse_args() else: @@ -1149,6 +1164,20 @@ def parse_argument(opt, key_value_pairs, defaults, name): def parse_scan_QC_thresholds(opt): # we must add "" around each key manually, as they are not encoded from the parser + """ + Parse and validate the scan quality control thresholds string for analysis. + + Converts a string representation of a nested dictionary specifying scan QC thresholds into a validated Python dictionary. Ensures correct syntax, key names, value types, and logical consistency for the 'SBC', 'DR', and 'CPCA' analysis types. + + Parameters: + opt (str): String representing the scan QC thresholds, with keys and values for each analysis type. + + Returns: + dict: A validated dictionary mapping analysis types to their QC threshold specifications. + + Raises: + ValueError: If the input string is malformed, contains invalid keys, or specifies values with incorrect types or logical inconsistencies. + """ for key in ['SBC','DR','CPCA','Dice','Conf','Amp']: s='' for s_ in opt.split(key): diff --git a/scripts/generate_graph.py b/scripts/generate_graph.py index 8e705e21..ba5c15ff 100644 --- a/scripts/generate_graph.py +++ b/scripts/generate_graph.py @@ -1,4 +1,3 @@ - import os import pickle import SimpleITK as sitk @@ -15,6 +14,17 @@ def execute_workflow(args=None): # generates the parser CLI and execute the workflow based on specified parameters. + """ + Prepare and configure a RABIES workflow based on command-line arguments. + + Parses CLI arguments, validates output directory paths, initializes logging, verifies template installation, checks for incompatible inclusion/exclusion parameters, and sets up the specified workflow stage (preprocess, confound correction, or analysis). Saves the modified CLI options as a pickle file and returns the prepared workflow object. + + Parameters: + args (list, optional): List of command-line arguments to override sys.argv. If None, uses sys.argv. + + Returns: + workflow: The configured workflow object ready for execution. + """ parser = get_parser() opts = read_parser(parser, args)