:py:mod:`cubnm.utils`
####################

.. py:module:: cubnm.utils

.. autoapi-nested-parse::

   Utility functions




.. autoapisummary::

   cubnm.utils.cdf_2d_2d_right
   cubnm.utils.avail_gpus
   cubnm.utils.is_jupyter
   cubnm.utils.get_bw_params
   cubnm.utils.calculate_fc
   cubnm.utils.calculate_fcd
   cubnm.utils.fcd_ks_device
   cubnm.utils.fc_corr_device



.. autoapisummary::

   cubnm.utils.has_cupy


.. py:data:: has_cupy
   :value: True

   

.. py:function:: cdf_2d_2d_right(A_sorted, x_values, out)

   CUDA kernel for calculating CDF of matching rows in 2D arrays.
   For each row i, performs searchsorted (right-sided) of 
   x_values[i] in A_sorted[i] divided by the length of A_sorted[i]
   resulting in empirical CDF of A_sorted[i] at x_values[i].
   Each row of A_sorted[i] must be sorted in ascending order.

   Parameters
   ----------
   A_sorted : `obj`:cp.ndarray
       2D array of sorted values. Shape: (n_rows, m)
   x_values : `obj`:cp.ndarray
       2D array of values to calculate CDF for. Shape: (n_rows, k)
   out : `obj`:cp.ndarray
       2D array to store the CDF values. Shape: (n_rows, k)


.. py:function:: avail_gpus()

   Get the number of available GPUs

   Returns
   -------
   :obj:`int`
       Number of available GPUs


.. py:function:: is_jupyter()

   This function checks if the current environment is a Jupyter notebook.

   Returns:
       bool: True if the current environment is a Jupyter notebook, False otherwise.


.. py:function:: get_bw_params(src)

   Get Balloon-Windkessel model parameters

   Parameters
   ----------
   src: {'friston2003', 'heinzle2016-3T'}
       - 'friston2003': Friston et al. 2003
       - 'heinzle2016-3T': Heinzle et al. 2016, 3T parameters

   Returns
   -------
   :obj:`dict`
       Balloon-Windkessel model parameters


.. py:function:: calculate_fc(bold, exc_interhemispheric=False, return_tril=True)

   Calculates functional connectivity matrix

   Parameters
   ---------
   bold: :obj:`np.ndarray`
       cleaned and parcellated empirical BOLD time series. Shape: (nodes, volumes)
       Motion outliers should either be excluded or replaced with zeros.
   exc_interhemispheric: :obj:`bool`, optional
       exclude interhemispheric connections
   return_tril: :obj:`bool`, optional
       return only the lower triangular part of the FCD matrix

   Returns
   -------
   fc: :obj:`np.ndarray`
       FC dynamics matrix. 
       Shape: (nodes, nodes) or (n_node_pairs,)
       if return_tril is True


.. py:function:: calculate_fcd(bold, window_size, window_step, drop_edges=True, outlier_threshold=0.5, exc_interhemispheric=False, return_tril=True, return_dfc=False)

   Calculates functional connectivity dynamics matrix
   and dynamic functional connectivity matrices

   Parameters
   ---------
   bold: :obj:`np.ndarray`
       cleaned and parcellated empirical BOLD time series. Shape: (nodes, volumes)
       Motion outliers should either be excluded (not recommended as it disrupts
       the temporal structure) or replaced with zeros.
   window_size: :obj:`int`, optional
       dynamic FC window size (in TR)
       Must be even. The actual window size is +1 (including center).
   window_step: :obj:`int`, optional
       dynamic FC window step (in TR)
   drop_edges: :obj:`bool`, optional
       drop edge windows which have less than window_size volumes
   outlier_threshold: :obj:`float`, optional
       threshold for the proportion of motion outliers in a window
       that would lead to discarding the window
   exc_interhemispheric: :obj:`bool`, optional
       exclude interhemispheric connections
   return_tril: :obj:`bool`, optional
       return only the lower triangular part of the FCD matrix
   return_dfc: :obj:`bool`, optional
       return dynamic FCs as well

   Returns
   -------
   fcd_matrix: :obj:`np.ndarray`
       FC dynamics matrix. 
       Shape: (n_windows, n_windows) or (n_window_pairs,)
       if return_tril is True
   window_fcs: :obj:`np.ndarray`
       dynamic FCs. Shape: (nodes, nodes, n_windows)
       Returned only if return_dfc is True


.. py:function:: fcd_ks_device(sim_fcd_trils, emp_fcd_tril, usable_mem=None)

   Calculates Kolmogorov-Smirnov distance of provided simulated FCDs
   to the empirical FCD on GPU. The calculation will be done in batches
   depending on the available GPU memory (`usable_mem`) and the memory
   required for each simulation.

   Parameters
   ----------
   sim_fcd_trils : :obj:`cp.ndarray`
       2D array of simulated FCDs. Shape: (n_simulations, m1)
   emp_fcd_tril : :obj:`cp.ndarray`
       1D array of empirical FCD. Shape: (m2)
   usable_mem : :obj:`int`, optional
       available GPU memory in bytes
       If not provided, 80% of the free GPU memory will be used.

   Returns
   -------
   ks : :obj:`np.ndarray`
       Kolmogorov-Smirnov distances. Shape: (n_simulations,)


.. py:function:: fc_corr_device(sim_fc_trils, emp_fc_tril, usable_mem=None)

   Calculates Pearson correlation between simulated FCs and empirical FCs
   on GPU. The calculation will be done in batches depending on the available
   GPU memory (`usable_mem`) and the memory required for each simulation.

   Parameters
   ----------
   sim_fc_trils : :obj:`cp.ndarray`
       2D array of simulated FCs. Shape: (n_simulations, n_pairs)
   emp_fc_tril : :obj:`cp.ndarray`
       1D array of empirical FC. Shape: (n_pairs)
   usable_mem : :obj:`int`, optional
       available GPU memory in bytes
       If not provided, 80% of the free GPU memory will be used.

   Returns
   -------
   fc_corr : :obj:`np.ndarray`
       Pearson correlation coefficients. Shape: (n_simulations,)


