-
Notifications
You must be signed in to change notification settings - Fork 0
/
compute_subject_functional_connectivity.py
199 lines (172 loc) · 6.92 KB
/
compute_subject_functional_connectivity.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
from pathlib import Path
import pandas as pd
from typing import Optional, Union
import numpy as np
from datetime import datetime
from compute_functional_connectivity import (
compute_functional_connectivity,
compute_one_to_all_connectivity,
visualize_fc_data,
)
def process_subject_functional(args):
"""
Processes a single subject: loads pre-extracted timeseries, computes connectivity,
saves the connectivity matrix, and optionally, visualizes the matrix.
Args:
args (tuple): Contains the following:
subject_id (str): Subject ID.
output_dir (Path): Path to the directory where output data is saved.
root_directory (Path): Root directory for the timeseries data.
selected_rois_csv (Path): Path to the selected ROIs CSV.
roi_column_name (str): Name of the column containing ROI names.
subjects (list): List of all subjects to be processed.
error_log_path (Path): Path to the error log file.
one_timeseries_index (Optional[Union[int, str]]): Index or name of the ROI to focus on (optional).
roi_names (list): List of all ROI names.
Raises:
FileNotFoundError: If the timeseries file is not found.
Exception: If an error occurs while loading the timeseries data
"""
(
subject_id,
output_dir,
root_directory,
selected_rois_csv,
roi_column_name,
subjects,
error_log_path,
one_timeseries_index,
roi_names,
) = args
timeseries_file = root_directory / f"{subject_id}_timeseries.csv"
# Load extracted timeseries
print(f"--- Processing subject: {subject_id} ---")
print("Reading extracted timeseries...")
try:
timeseries = np.loadtxt(timeseries_file, delimiter=",")
print("Timeseries loaded")
except FileNotFoundError:
print(f"Timeseries file not found: {timeseries_file}")
return
except Exception as e:
print(f"Error loading timeseries: {e}")
with open(error_log_path, "a") as f:
f.write(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"Error loading timeseries for subject {subject_id}:\n")
f.write(f"{str(e)}\n\n")
return
if timeseries is None or timeseries.size == 0:
print(f"No valid timeseries loaded for subject {subject_id}")
return
# Compute functional connectivity
connectivity_matrix, fisher_z_matrix = compute_functional_connectivity(
subject_id=subject_id,
timeseries=timeseries,
output_dir=output_dir,
selected_rois_csv=selected_rois_csv,
roi_column_name=roi_column_name,
subjects=subjects,
)
# Conditionally compute one-to-all connectivity
if one_timeseries_index is not None:
compute_one_to_all_connectivity(
subject_id=subject_id,
connectivity_matrix=connectivity_matrix,
fisher_z_matrix=fisher_z_matrix,
output_dir=output_dir,
one_timeseries_index=one_timeseries_index,
roi_names=roi_names,
subjects=subjects,
)
# Visualize data if you would like by uncommenting the line below
# visualize_fc_data(subject_id, connectivity_matrix)
print(f"Processing completed for subject: {subject_id}")
def main(
todo_path: Union[str, Path],
output_dir: Union[str, Path],
root_directory: Union[str, Path],
selected_rois_csv: Path,
roi_column_name: str,
one_timeseries_index: Optional[Union[int, str]] = None,
):
"""
Main function to run the script.
This function reads the pre-extracted timeseries data for each subject,
computes the functional connectivity matrices for all subjects.
Args:
todo_path (Union[str, Path]): Path to the todo file with subject IDs to be processed.
output_dir (Union[str, Path]): Path where processed data will be output.
root_directory (Union[str, Path]): Root directory for the timeseries data.
selected_rois_csv (Path): Path to the selected ROIs CSV.
roi_column_name (str): Name of the column containing ROI names.
one_timeseries_index (Optional[Union[int, str]]): Index or name of the ROI to focus on for one-to-all connectivity (optional).
Raises:
FileNotFoundError: If the selected ROIs file is not found.
KeyError: If the specified column name is not found in the selected ROIs file
"""
output_dir = Path(output_dir)
root_directory = Path(root_directory)
todo_path = Path(todo_path)
error_log_path = output_dir / "error_log.txt" # Define error log path
# Ensure output directory exists
output_dir.mkdir(parents=True, exist_ok=True)
try:
todo_df = pd.read_csv(todo_path)
todo = todo_df["todo"].tolist()
except Exception as e:
print(f"Error reading CSV file: {e}")
return
print(f"Number of subjects to process: {len(todo)}")
# Read and define roi_names
try:
selected_rois_df = pd.read_csv(selected_rois_csv, index_col=0)
roi_names = selected_rois_df[roi_column_name].values.tolist()
except FileNotFoundError:
print(f"Selected ROIs file not found at: {selected_rois_csv}")
return
except KeyError:
print(
f"'{roi_column_name}' column not found in the selected ROIs file: {selected_rois_csv}"
)
return
# Map ROI names to the corresponding index
if isinstance(one_timeseries_index, str):
if one_timeseries_index in roi_names:
one_timeseries_index = roi_names.index(one_timeseries_index)
else:
print(f"ROI name '{one_timeseries_index}' not found in ROI names list.")
return
subjects = todo # Assign subjects list
args = [
(
subject,
output_dir,
root_directory,
selected_rois_csv,
roi_column_name,
subjects,
error_log_path,
one_timeseries_index,
roi_names,
)
for subject in todo
]
for arg in args:
process_subject_functional(arg)
if __name__ == "__main__":
todo_file = Path("/home/rachel/Desktop/fMRI Analysis/todo.csv")
root_directory = Path("/home/rachel/Desktop/fMRI Analysis/DK76/timeseries")
output_directory = Path(
"/home/rachel/Desktop/fMRI Analysis/DK76/connectivity_matrices"
)
selected_rois_csv = Path("/home/rachel/Desktop/fMRI Analysis/selected_rois.csv")
roi_column_name = "LabelName"
main(
todo_path=todo_file,
output_dir=output_directory,
root_directory=root_directory,
selected_rois_csv=selected_rois_csv,
roi_column_name=roi_column_name,
# one_timeseries_index=None, # Unomment this line and comment the line below to not compute one-to-all connectivity
one_timeseries_index="Right-Hippocampus", # Specify the name or index of the ROI you want to focus on
)