diff --git a/_images/index_51_0.png b/_images/index_51_0.png deleted file mode 100644 index aefefe9..0000000 Binary files a/_images/index_51_0.png and /dev/null differ diff --git a/index.html b/index.html index 0a1f0a1..c98a145 100644 --- a/index.html +++ b/index.html @@ -368,8 +368,7 @@
path_data = os.getcwd()
-print(f"path_data: {path_data}")
+print(f"path_data: {path_data}")
path_labels = os.path.join(path_data, "derivatives", "labels")
path_qc = os.path.join(path_data, "qc")
shim_modes = ["CP", "patient", "volume", "phase", "CoV", "target", "SAReff"]
@@ -392,7 +391,7 @@ 5 | Process anat/T2starw (GRE)
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
for subject in subjects:
os.chdir(os.path.join(path_data, subject, "anat"))
# The "CoV" RF shimming scenario was chosen as the segmentation baseline due to the more homogeneous signal intensity in the I-->S direction, which results in a better segmentation peformance in the C7-T2 region
@@ -415,7 +414,7 @@ 5 | Process anat/T2starw (GRE)https://github.com/shimming-toolbox/rf-shimming-7t/issues/67.
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
for subject in subjects:
os.chdir(os.path.join(path_data, subject, "anat"))
fname_manual_seg = os.path.join(path_labels, subject, "anat", f"{subject}_acq-CoV_T2starw_label-CSF_seg.nii.gz")
@@ -435,7 +434,7 @@ 5 | Process anat/T2starw (GRE)
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
for subject in subjects:
os.chdir(os.path.join(path_data, subject, "anat"))
!sct_crop_image -i {subject}_acq-CoV_T2starw.nii.gz -m {subject}_acq-CoV_T2starw_seg.nii.gz -dilate 20x20x0 -o {subject}_acq-CoV_T2starw_crop.nii.gz
@@ -449,7 +448,7 @@ 5 | Process anat/T2starw (GRE)
# Given the low resolution of the GRE scan, the automatic detection of C2-C3 disc is unreliable. Therefore we need to use the manual disc labels that are part of the dataset.
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
for subject in subjects:
os.chdir(os.path.join(path_data, subject, "anat"))
fname_label_discs = os.path.join(path_data, "derivatives", "labels", subject, "anat", f"{subject}_acq-CoV_T2starw_label-discs_dseg.nii.gz")
@@ -463,7 +462,7 @@ 5 | Process anat/T2starw (GRE)
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
for subject in subjects:
os.chdir(os.path.join(path_data, subject, "anat"))
for shim_mode in shim_modes:
@@ -477,7 +476,7 @@ 5 | Process anat/T2starw (GRE)
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
for subject in subjects:
os.chdir(os.path.join(path_data, subject, "anat"))
for shim_mode in shim_modes:
@@ -527,6 +526,15 @@ 5 | Process anat/T2starw (GRE)# Number of subjects determines the number of rows in the subplot
n_rows = len(subjects)
+# Create a figure with multiple subplots
+fig, axes = plt.subplots(n_rows, 1, figsize=(10, 6 * n_rows))
+font_size = 18
+line_width = 3
+
+# Check if axes is an array or a single object
+if n_rows == 1:
+ axes = [axes]
+
# Data storage for statistics
data_stats = []
@@ -535,7 +543,7 @@ 5 | Process anat/T2starw (GRE)# Iterate over each subject and create a subplot
for i, subject in enumerate(subjects):
-
+ ax = axes[i]
t2_data_plotly[subject]={}
for shim_mode in shim_modes:
# Initialize list to collect data for this shim method
@@ -569,12 +577,43 @@ 5 | Process anat/T2starw (GRE)if method_data:
t2_data_plotly[subject][shim_mode]=method_data
+ # Plotting each file's data separately
+ for resampled_data in method_data:
+ ax.plot(x_grid, resampled_data, label=f"{shim_mode}", linewidth=line_width)
+
# Compute stats on the non-resampled data (to avoid interpolation errors)
mean_data = np.mean(data_sc_csf_ratio)
sd_data = np.std(data_sc_csf_ratio)
data_stats.append([subject, shim_mode, mean_data, sd_data])
else:
t2_data_plotly[subject][shim_mode]=None
+
+ # Set x-ticks and labels for the bottom subplot
+ if i == n_rows - 1: # Check if it's the last subplot
+ # Create a secondary axis for vertebral level labels
+ secax = ax.secondary_xaxis('bottom')
+ secax.set_xticks(label_positions)
+ secax.set_xticklabels(vertebral_levels, fontsize=font_size-4)
+ secax.tick_params(axis='x', which='major', length=0) # Hide tick marks
+
+ ax.set_xticks(custom_xticks)
+ ax.set_xticklabels([''] * len(custom_xticks))
+ ax.tick_params(axis='x', which='major', length=0) # Hide tick marks for the primary axis
+
+ ax.set_title(f'{subject}', fontsize=font_size)
+ ax.set_ylabel('CSF/Cord T2starw signal ratio', fontsize=font_size)
+ ax.tick_params(axis='y', which='major', labelsize=font_size-4)
+
+ # Add legend only to the first subplot
+ if i == 0:
+ ax.legend(fontsize=font_size)
+
+ ax.grid(True)
+
+# Adjust the layout so labels and titles do not overlap
+plt.tight_layout()
+plt.savefig(os.path.join(path_results, 'fig_gre_csf-sc_ratio.png'), dpi=300, format='png')
+plt.show()
@@ -646,41 +685,6 @@ 5 | Process anat/T2starw (GRE)
- Anova
-=======================================
- F Value Num DF Den DF Pr > F
----------------------------------------
-Shim_Mode 9.0936 6.0000 24.0000 0.0000
-=======================================
-
-
-Paired t-tests:
- Pair P-Value Adjusted P-Value
-0 (CP, patient) 0.005972 0.025083
-1 (CP, volume) 0.075373 0.131902
-2 (CP, phase) 0.011296 0.033889
-3 (CP, CoV) 0.000156 0.003279
-4 (CP, target) 0.030643 0.080437
-5 (CP, SAReff) 0.197466 0.276452
-6 (patient, volume) 0.205065 0.269148
-7 (patient, phase) 0.296440 0.366191
-8 (patient, CoV) 0.001437 0.010061
-9 (patient, target) 0.154750 0.232125
-10 (patient, SAReff) 0.031202 0.072804
-11 (volume, phase) 0.413730 0.457281
-12 (volume, CoV) 0.404085 0.471432
-13 (volume, target) 0.552388 0.552388
-14 (volume, SAReff) 0.075590 0.122108
-15 (phase, CoV) 0.009898 0.034641
-16 (phase, target) 0.496343 0.521160
-17 (phase, SAReff) 0.005612 0.029461
-18 (CoV, target) 0.043267 0.082600
-19 (CoV, SAReff) 0.001394 0.014638
-20 (target, SAReff) 0.036743 0.077159
-
-
-
@@ -688,7 +692,7 @@ 6 | Process fmap/TFL (flip angle maps)Register TFL flip angle maps to the GRE scan ⏳
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
for subject in subjects:
os.chdir(os.path.join(path_data, subject, "fmap"))
for shim_mode in shim_modes:
@@ -700,7 +704,7 @@ 6 | Process fmap/TFL (flip angle maps)Warping spinal cord segmentation and vertebral level to each flip angle map
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
for subject in subjects:
os.chdir(os.path.join(path_data, subject, "fmap"))
for shim_mode in shim_modes:
@@ -719,7 +723,7 @@ 6 | Process fmap/TFL (flip angle maps)GAMMA = 2.675e8; # [rad / (s T)]
requested_fa = 90 # saturation flip angle -- hard-coded in sequence
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
for subject in subjects:
os.chdir(os.path.join(path_data, subject, "fmap"))
for shim_mode in shim_modes:
@@ -755,7 +759,7 @@ 6 | Process fmap/TFL (flip angle maps)Extract B1+ value along the spinal cord between levels C3 and T2 (included)
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
for subject in subjects:
os.chdir(os.path.join(path_data, subject, "fmap"))
for shim_mode in shim_modes:
@@ -797,6 +801,15 @@ 6 | Process fmap/TFL (flip angle maps)# Number of subjects determines the number of rows in the subplot
n_rows = len(subjects)
+# Create a figure with multiple subplots
+fig, axes = plt.subplots(n_rows, 1, figsize=(10, 6 * n_rows))
+font_size = 18
+line_width = 3
+
+# Check if axes is an array or a single object
+if n_rows == 1:
+ axes = [axes]
+
# Data storage for statistics
data_stats = []
@@ -805,7 +818,9 @@ 6 | Process fmap/TFL (flip angle maps)# Iterate over each subject and create a subplot
for i, subject in enumerate(subjects):
-
+
+ ax = axes[i]
+
os.chdir(os.path.join(path_data, subject, "fmap"))
b1_data_plotly[subject]={}
@@ -834,6 +849,7 @@ 6 | Process fmap/TFL (flip angle maps)# Plotting each file's data separately
for resampled_data in method_data:
b1_data_plotly[subject][shim_mode]=resampled_data
+ ax.plot(x_grid, resampled_data, label=f"{shim_mode}", linewidth=line_width)
# Compute stats on the non-resampled data (to avoid interpolation errors)
mean_data = np.mean(wa_data)
@@ -841,6 +857,34 @@ 6 | Process fmap/TFL (flip angle maps)data_stats.append([subject, shim_mode, mean_data, sd_data])
else:
b1_data_plotly[subject][shim_mode]=None
+
+ # Set x-ticks and labels for the bottom subplot
+ if i == n_rows - 1: # Check if it's the last subplot
+ # Create a secondary axis for vertebral level labels
+ secax = ax.secondary_xaxis('bottom')
+ secax.set_xticks(label_positions)
+ secax.set_xticklabels(vertebral_levels, fontsize=font_size-4)
+ secax.tick_params(axis='x', which='major', length=0) # Hide tick marks
+
+ ax.set_xticks(custom_xticks)
+ ax.set_xticklabels([''] * len(custom_xticks))
+ ax.tick_params(axis='x', which='major', length=0) # Hide tick marks for the primary axis
+
+ ax.set_title(f'{subject}', fontsize=font_size)
+ ax.set_ylabel('B1+ efficiency [nT/V]', fontsize=font_size)
+ ax.tick_params(axis='y', which='major', labelsize=font_size-4)
+
+ # Add legend only to the first subplot
+ if i == 0:
+ ax.legend(fontsize=font_size)
+
+ ax.grid(True)
+
+# Adjust the layout so labels and titles do not overlap
+plt.tight_layout()
+plt.savefig(os.path.join(path_results, 'fig_b1plus.png'), dpi=300, format='png')
+
+plt.show()
@@ -910,40 +954,6 @@ 6 | Process fmap/TFL (flip angle maps)
-
- Anova
-=======================================
- F Value Num DF Den DF Pr > F
----------------------------------------
-Shim_Mode 14.0743 6.0000 24.0000 0.0000
-=======================================
-
-Paired t-tests:
- Pair P-Value Adjusted P-Value
-0 (CP, patient) 0.007728 0.040570
-1 (CP, volume) 0.009006 0.037825
-2 (CP, phase) 0.079896 0.104863
-3 (CP, CoV) 0.318010 0.371012
-4 (CP, target) 0.010284 0.030853
-5 (CP, SAReff) 0.563249 0.622539
-6 (patient, volume) 0.821572 0.862651
-7 (patient, phase) 0.005550 0.116560
-8 (patient, CoV) 0.036644 0.059195
-9 (patient, target) 0.006302 0.066176
-10 (patient, SAReff) 0.010083 0.035289
-11 (volume, phase) 0.006565 0.045958
-12 (volume, CoV) 0.032112 0.056197
-13 (volume, target) 0.027717 0.052915
-14 (volume, SAReff) 0.012891 0.030078
-15 (phase, CoV) 0.989088 0.989088
-16 (phase, target) 0.011515 0.030226
-17 (phase, SAReff) 0.070778 0.099089
-18 (CoV, target) 0.236842 0.292570
-19 (CoV, SAReff) 0.061149 0.091724
-20 (target, SAReff) 0.018986 0.039871
-
-
-
@@ -957,7 +967,7 @@ 7 | Paper figures# Create RF shimming mask from the segmentation (re-create the live RF shimming procedure)
file_mask = f"{subject}_acq-anatCP_TB1TFL_mask-shimming.nii.gz"
-if notebook != 'neurolibre-figures':
+if 'figures' not in notebook:
!sct_maths -i {subject}_acq-anatCP_TB1TFL_seg_labeled.nii.gz -thr 3 -uthr 9 -o {file_mask}
!sct_maths -i {file_mask} -bin 1 -o {file_mask}
@@ -1068,13 +1078,11 @@ 7 | Paper figures# cbar_ax = fig.add_axes([0.95, 0.5, 0.04, 0.4])
# cbar = plt.colorbar(im, cax=cbar_ax)
cbar_ax.set_title('nT/V', size=12)
+plt.savefig(os.path.join(path_results, 'fig_b1plus_map.png'), dpi=300, format='png')
plt.show()
-
-
-
Figure 2. B1+ efficiency for one participant (sub-05) across all seven RF shimming conditions. The top left panel shows the tfl_b1map magnitude image with an overlay of the mask that was used to perform RF shimming. Text inserts show the mean (in nT/V) and CoV (in %) of B1+ efficiency along the spinal cord between C3 and T2.
-
-
-
-
-
-
-
-
Figure 3. B1+ efficiency (A) and CSF/Cord signal ratio from the GRE scan (B) across subjects and across different RF shimming conditions. Data were measured in the spinal cord from C3 to T2 vertebral levels. To match the x-ticks across subjects, the C2-C3 and the T2-T3 intervertebral discs of each subject were aligned with that of the PAM50 template [De Leener et al., 2018], and the curves were linearly scaled.
diff --git a/reports/index.log b/reports/index.log
new file mode 100644
index 0000000..c44e471
--- /dev/null
+++ b/reports/index.log
@@ -0,0 +1,103 @@
+Traceback (most recent call last):
+ File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/jupyter_cache/executors/utils.py", line 51, in single_nb_execution
+ executenb(
+ File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/nbclient/client.py", line 1204, in execute
+ return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute()
+ File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/nbclient/util.py", line 84, in wrapped
+ return just_run(coro(*args, **kwargs))
+ File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/nbclient/util.py", line 62, in just_run
+ return loop.run_until_complete(coro)
+ File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
+ return future.result()
+ File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/nbclient/client.py", line 663, in async_execute
+ await self.async_execute_cell(
+ File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/nbclient/client.py", line 965, in async_execute_cell
+ await self._check_raise_for_error(cell, cell_index, exec_reply)
+ File "/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/nbclient/client.py", line 862, in _check_raise_for_error
+ raise CellExecutionError.from_cell_and_msg(cell, exec_reply_content)
+nbclient.exceptions.CellExecutionError: An error occurred while executing the following cell:
+------------------
+# Download data and define path variables
+
+# Google Colab-Only
+if notebook=='colab':
+ !datalad install https://github.com/OpenNeuroDatasets/ds004906.git
+ os.chdir("ds004906")
+ !datalad get . # uncomment for production
+ # !datalad get sub-01/ # debugging
+ # Get derivatives containing manual labels
+ !datalad get derivatives
+ path_data = os.getcwd()
+
+if notebook!='colab':
+
+ if notebook=='repo2docker-figures' or notebook=='repo2docker-clean':
+ !repo2data -r ../binder/data_requirement.json
+
+ # Copy data from NeuroLibre servers to image to gain write permissions
+ clean_dir = os.path.join(os.getenv("HOME"), "clean")
+ if os.path.exists(clean_dir) and os.path.isdir(clean_dir):
+ shutil.rmtree(clean_dir)
+ os.mkdir(clean_dir)
+ os.mkdir(os.path.join(clean_dir, "data"))
+
+ # Source path
+ src = os.path.join(os.getenv("HOME"),"data/rf-shimming-7t")
+
+ # Destination path
+ dest = os.path.join(os.getenv("HOME"), "clean/data/rf-shimming-7t")
+
+ # Copy the content of source to destination
+ destination = shutil.copytree(src, dest)
+ os.chdir(os.path.join(os.getenv("HOME"),"clean/data/rf-shimming-7t/ds004906"))
+
+ # Assumes data/rf-shimming-7t is found at $HOME
+ path_data = os.path.join(os.getenv("HOME"),"clean/data/rf-shimming-7t/ds004906")
+
+ if notebook=='neurolibre-clean' or notebook=='repo2docker-clean':
+ flist = open('cleanup.txt', 'r')
+ for f in flist:
+ fname = f.rstrip('\n')
+ fname = Path(os.getcwd()) / Path(fname)
+
+ # or, if you get rid of os.chdir(path) above,
+ # fname = os.path.join(path, f.rstrip())
+ if os.path.isfile(fname): # this makes the code more robust
+ print('Removing file: ' + str(fname))
+ os.remove(fname)
+ elif os.path.isdir(fname):
+ print('Removing directory: ' + str(fname))
+ rmtree(fname)
+
+ # also, don't forget to close the text file:
+ flist.close()
+
+------------------
+
+[0;31m---------------------------------------------------------------------------[0m
+[0;31mFileNotFoundError[0m Traceback (most recent call last)
+Cell [0;32mIn[5], line 32[0m
+[1;32m 29[0m dest [38;5;241m=[39m os[38;5;241m.[39mpath[38;5;241m.[39mjoin(os[38;5;241m.[39mgetenv([38;5;124m"[39m[38;5;124mHOME[39m[38;5;124m"[39m), [38;5;124m"[39m[38;5;124mclean/data/rf-shimming-7t[39m[38;5;124m"[39m)
+[1;32m 31[0m [38;5;66;03m# Copy the content of source to destination [39;00m
+[0;32m---> 32[0m destination [38;5;241m=[39m [43mshutil[49m[38;5;241;43m.[39;49m[43mcopytree[49m[43m([49m[43msrc[49m[43m,[49m[43m [49m[43mdest[49m[43m)[49m
+[1;32m 33[0m os[38;5;241m.[39mchdir(os[38;5;241m.[39mpath[38;5;241m.[39mjoin(os[38;5;241m.[39mgetenv([38;5;124m"[39m[38;5;124mHOME[39m[38;5;124m"[39m),[38;5;124m"[39m[38;5;124mclean/data/rf-shimming-7t/ds004906[39m[38;5;124m"[39m))
+[1;32m 35[0m [38;5;66;03m# Assumes data/rf-shimming-7t is found at $HOME[39;00m
+
+File [0;32m/opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/shutil.py:555[0m, in [0;36mcopytree[0;34m(src, dst, symlinks, ignore, copy_function, ignore_dangling_symlinks, dirs_exist_ok)[0m
+[1;32m 518[0m [38;5;250m[39m[38;5;124;03m"""Recursively copy a directory tree and return the destination directory.[39;00m
+[1;32m 519[0m
+[1;32m 520[0m [38;5;124;03mdirs_exist_ok dictates whether to raise an exception in case dst or any[39;00m
+[0;32m (...)[0m
+[1;32m 552[0m
+[1;32m 553[0m [38;5;124;03m"""[39;00m
+[1;32m 554[0m sys[38;5;241m.[39maudit([38;5;124m"[39m[38;5;124mshutil.copytree[39m[38;5;124m"[39m, src, dst)
+[0;32m--> 555[0m [38;5;28;01mwith[39;00m [43mos[49m[38;5;241;43m.[39;49m[43mscandir[49m[43m([49m[43msrc[49m[43m)[49m [38;5;28;01mas[39;00m itr:
+[1;32m 556[0m entries [38;5;241m=[39m [38;5;28mlist[39m(itr)
+[1;32m 557[0m [38;5;28;01mreturn[39;00m _copytree(entries[38;5;241m=[39mentries, src[38;5;241m=[39msrc, dst[38;5;241m=[39mdst, symlinks[38;5;241m=[39msymlinks,
+[1;32m 558[0m ignore[38;5;241m=[39mignore, copy_function[38;5;241m=[39mcopy_function,
+[1;32m 559[0m ignore_dangling_symlinks[38;5;241m=[39mignore_dangling_symlinks,
+[1;32m 560[0m dirs_exist_ok[38;5;241m=[39mdirs_exist_ok)
+
+[0;31mFileNotFoundError[0m: [Errno 2] No such file or directory: '/home/runner/data/rf-shimming-7t'
+FileNotFoundError: [Errno 2] No such file or directory: '/home/runner/data/rf-shimming-7t'
+