WIP: [MARKER]: Support FunctionalConnectivityLagged #435

Closed
synchon wants to merge 10 commits from feat/functional-connectivity-lagged into main
synchon commented 2025-03-11 10:28:53 +00:00 (Migrated from github.com)

Which marker do you want to include?

  1. Compute Cross-Correlation:

For two time series X(t) and Y(t) from different brain regions:
CCF(τ)=∑tX(t)Y(t+τ)
CCF(τ)=t∑​X(t)Y(t+τ)

where τ represents a time lag (positive or negative shifts).

Compute cross-correlation for each ROI pair across a range of time lags τ (e.g., -10s to +10s).
The peak of the cross-correlation function indicates the optimal time lag (e.g., if peak at τ = 2s, Y lags behind X by 2s).

  1. Construct a Lag-Based Functional Connectivity Matrix:

Identify the lag at which cross-correlation is maximal.
Store the peak correlation value and associated lag for each ROI pair.
Construct:

  • A functional connectivity matrix (correlation values).
  • A lag matrix (time lags at which correlation is maximal).

Is there any publication or available code?

https://pmc.ncbi.nlm.nih.gov/articles/PMC4097876

Do you have a sample code that implements this outside of junifer?

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import correlate

# Simulated fMRI data (example: 10 ROIs, 300 time points)
np.random.seed(42)
n_rois = 10
n_timepoints = 300
fmri_data = np.random.rand(n_rois, n_timepoints)  # Replace with real fMRI signals

# Define time lag range (e.g., -10 to +10 time points)
max_lag = 10
lags = np.arange(-max_lag, max_lag + 1)

# Initialize matrices
fc_matrix = np.zeros((n_rois, n_rois))  # Functional connectivity matrix
lag_matrix = np.zeros((n_rois, n_rois))  # Lag matrix

# Compute cross-correlation for each ROI pair
for i in range(n_rois):
    for j in range(n_rois):
        if i != j:
            # Compute cross-correlation
            ccf = correlate(fmri_data[i], fmri_data[j], mode='full', method='auto')
            ccf = ccf[len(ccf)//2 - max_lag : len(ccf)//2 + max_lag + 1]  # Limit lag range
            
            # Find peak correlation & corresponding lag
            peak_idx = np.argmax(np.abs(ccf))  # Peak correlation index
            peak_corr = ccf[peak_idx]  # Peak correlation value
            peak_lag = lags[peak_idx]  # Corresponding lag
            
            # Store in matrices
            fc_matrix[i, j] = peak_corr
            lag_matrix[i, j] = peak_lag

# Plot Functional Connectivity Matrix
plt.figure(figsize=(8,6))
plt.imshow(fc_matrix, cmap='coolwarm', aspect='auto')
plt.colorbar(label="Peak Cross-Correlation")
plt.title("Functional Connectivity Matrix")
plt.xlabel("ROI")
plt.ylabel("ROI")
plt.show()

# Plot Lag Matrix
plt.figure(figsize=(8,6))
plt.imshow(lag_matrix, cmap='jet', aspect='auto')
plt.colorbar(label="Lag (Time Points)")
plt.title("Lag Matrix")
plt.xlabel("ROI")
plt.ylabel("ROI")
plt.show()

Anything else to say?

No response

### Which marker do you want to include? 1. Compute Cross-Correlation: For two time series X(t) and Y(t) from different brain regions: CCF(τ)=∑tX(t)Y(t+τ) CCF(τ)=t∑​X(t)Y(t+τ) where τ represents a time lag (positive or negative shifts). Compute cross-correlation for each ROI pair across a range of time lags τ (e.g., -10s to +10s). The peak of the cross-correlation function indicates the optimal time lag (e.g., if peak at τ = 2s, Y lags behind X by 2s). 2. Construct a Lag-Based Functional Connectivity Matrix: Identify the lag at which cross-correlation is maximal. Store the peak correlation value and associated lag for each ROI pair. Construct: - A functional connectivity matrix (correlation values). - A lag matrix (time lags at which correlation is maximal). ### Is there any publication or available code? https://pmc.ncbi.nlm.nih.gov/articles/PMC4097876 ### Do you have a sample code that implements this outside of junifer? ```shell import numpy as np import matplotlib.pyplot as plt from scipy.signal import correlate # Simulated fMRI data (example: 10 ROIs, 300 time points) np.random.seed(42) n_rois = 10 n_timepoints = 300 fmri_data = np.random.rand(n_rois, n_timepoints) # Replace with real fMRI signals # Define time lag range (e.g., -10 to +10 time points) max_lag = 10 lags = np.arange(-max_lag, max_lag + 1) # Initialize matrices fc_matrix = np.zeros((n_rois, n_rois)) # Functional connectivity matrix lag_matrix = np.zeros((n_rois, n_rois)) # Lag matrix # Compute cross-correlation for each ROI pair for i in range(n_rois): for j in range(n_rois): if i != j: # Compute cross-correlation ccf = correlate(fmri_data[i], fmri_data[j], mode='full', method='auto') ccf = ccf[len(ccf)//2 - max_lag : len(ccf)//2 + max_lag + 1] # Limit lag range # Find peak correlation & corresponding lag peak_idx = np.argmax(np.abs(ccf)) # Peak correlation index peak_corr = ccf[peak_idx] # Peak correlation value peak_lag = lags[peak_idx] # Corresponding lag # Store in matrices fc_matrix[i, j] = peak_corr lag_matrix[i, j] = peak_lag # Plot Functional Connectivity Matrix plt.figure(figsize=(8,6)) plt.imshow(fc_matrix, cmap='coolwarm', aspect='auto') plt.colorbar(label="Peak Cross-Correlation") plt.title("Functional Connectivity Matrix") plt.xlabel("ROI") plt.ylabel("ROI") plt.show() # Plot Lag Matrix plt.figure(figsize=(8,6)) plt.imshow(lag_matrix, cmap='jet', aspect='auto') plt.colorbar(label="Lag (Time Points)") plt.title("Lag Matrix") plt.xlabel("ROI") plt.ylabel("ROI") plt.show() ``` ### Anything else to say? _No response_
codecov[bot] commented 2025-03-11 11:02:26 +00:00 (Migrated from github.com)

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.09%. Comparing base (e8a99eb) to head (6aed916).
⚠️ Report is 288 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #435   +/-   ##
=======================================
  Coverage   91.09%   91.09%           
=======================================
  Files         134      134           
  Lines        5422     5422           
  Branches      903      903           
=======================================
  Hits         4939     4939           
  Misses        309      309           
  Partials      174      174           
Flag Coverage Δ
docs 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
junifer/pipeline/pipeline_component_registry.py 94.64% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
## [Codecov](https://app.codecov.io/gh/juaml/junifer/pull/435?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=juaml) Report :white_check_mark: All modified and coverable lines are covered by tests. :white_check_mark: Project coverage is 91.09%. Comparing base ([`e8a99eb`](https://app.codecov.io/gh/juaml/junifer/commit/e8a99eb0e63858306a78c87d10c5d0ed797328e4?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=juaml)) to head ([`6aed916`](https://app.codecov.io/gh/juaml/junifer/commit/6aed9164f5228d9de2cba32613e2d7ec050a32f7?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=juaml)). :warning: Report is 288 commits behind head on main. <details><summary>Additional details and impacted files</summary> [![Impacted file tree graph](https://app.codecov.io/gh/juaml/junifer/pull/435/graphs/tree.svg?width=650&height=150&src=pr&token=5H21JuZXMw&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=juaml)](https://app.codecov.io/gh/juaml/junifer/pull/435?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=juaml) ```diff @@ Coverage Diff @@ ## main #435 +/- ## ======================================= Coverage 91.09% 91.09% ======================================= Files 134 134 Lines 5422 5422 Branches 903 903 ======================================= Hits 4939 4939 Misses 309 309 Partials 174 174 ``` | [Flag](https://app.codecov.io/gh/juaml/junifer/pull/435/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=juaml) | Coverage Δ | | |---|---|---| | [docs](https://app.codecov.io/gh/juaml/junifer/pull/435/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=juaml) | `100.00% <ø> (ø)` | | Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=juaml#carryforward-flags-in-the-pull-request-comment) to find out more. | [Files with missing lines](https://app.codecov.io/gh/juaml/junifer/pull/435?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=juaml) | Coverage Δ | | |---|---|---| | [junifer/pipeline/pipeline\_component\_registry.py](https://app.codecov.io/gh/juaml/junifer/pull/435?src=pr&el=tree&filepath=junifer%2Fpipeline%2Fpipeline_component_registry.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=juaml#diff-anVuaWZlci9waXBlbGluZS9waXBlbGluZV9jb21wb25lbnRfcmVnaXN0cnkucHk=) | `94.64% <ø> (ø)` | | </details> <details><summary> :rocket: New features to boost your workflow: </summary> - :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems. </details>
github-actions[bot] commented 2025-03-11 11:10:41 +00:00 (Migrated from github.com)
PR Preview Action v1.6.1

🚀 View preview at
https://juaml.github.io/junifer/pr-preview/pr-435/

Built to branch gh-pages at 2025-05-09 12:45 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

[PR Preview Action](https://github.com/rossjrw/pr-preview-action) v1.6.1 :---: | <p></p> :rocket: View preview at <br> https://juaml.github.io/junifer/pr-preview/pr-435/ <br><br> | <h6>Built to branch [`gh-pages`](https://github.com/juaml/junifer/tree/gh-pages) at 2025-05-09 12:45 UTC. <br> Preview will be ready when the [GitHub Pages deployment](https://github.com/juaml/junifer/deployments) is complete. <br><br> </h6> <!-- Sticky Pull Request Commentpr-preview -->

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
juaml/junifer!435
No description provided.