Skip to content

Commit

Permalink
Use manual CSF mask and improve CSF/SC figure (#69)
Browse files Browse the repository at this point in the history
* Using manual T2starw SC segmentation if it exists

Fixes #56

* Get CSF masks from the derivatives

Fixes #67

* Fixed cropping and metric extraction for CSF

* Display CSF/SC instead of SC/CSF

Clearer to show the better on top

* Updated smoothing kernel to 40
  • Loading branch information
jcohenadad authored Jan 20, 2024
1 parent 39495d0 commit bf4cf2f
Showing 1 changed file with 43 additions and 29 deletions.
72 changes: 43 additions & 29 deletions data_processing.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,44 @@
"\n",
"for subject in subjects:\n",
" os.chdir(os.path.join(path_data, subject, \"anat\"))\n",
" # Use another syntax for sub-04. See: https://github.com/shimming-toolbox/rf-shimming-7t/issues/31\n",
" if subject == 'sub-04':\n",
" !sct_deepseg_sc -i {subject}_acq-CoV_T2starw.nii.gz -c t2 -qc {path_qc}\n",
" fname_manual_seg = os.path.join(path_labels, subject, \"anat\", f\"{subject}_acq-CoV_T2starw_label-SC_seg.nii.gz\")\n",
" if os.path.exists(fname_manual_seg):\n",
" # Manual segmentation already exists. Copy it to local folder\n",
" print(f\"{subject}: Manual segmentation found\\n\")\n",
" shutil.copyfile(fname_manual_seg, f\"{subject}_acq-CoV_T2starw_seg.nii.gz\")\n",
" # Generate QC report to make sure the manual segmentation is correct\n",
" !sct_qc -i {subject}_acq-CoV_T2starw.nii.gz -s {subject}_acq-CoV_T2starw_seg.nii.gz -p sct_deepseg_sc -qc {path_qc} -qc-subject {subject}\n",
" else:\n",
" # Manual segmentation does not exist. Run automatic segmentation.\n",
" print(f\"{subject}: Manual segmentation not found\")\n",
" !sct_deepseg_sc -i {subject}_acq-CoV_T2starw.nii.gz -c t2s -qc {path_qc}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eb9a9267",
"metadata": {},
"outputs": [],
"source": [
"# Copy CSF masks from the derivatives folder\n",
"\n",
"# For more details about how these masks were created, see: https://github.com/shimming-toolbox/rf-shimming-7t/issues/67\n",
"\n",
"for subject in subjects:\n",
" os.chdir(os.path.join(path_data, subject, \"anat\"))\n",
" fname_manual_seg = os.path.join(path_labels, subject, \"anat\", f\"{subject}_acq-CoV_T2starw_label-CSF_seg.nii.gz\")\n",
" if os.path.exists(fname_manual_seg):\n",
" # Manual segmentation already exists. Copy it to local folder\n",
" print(f\"{subject}: Manual segmentation found\\n\")\n",
" shutil.copyfile(fname_manual_seg, f\"{subject}_acq-CoV_T2starw_label-CSF_seg.nii.gz\")\n",
" # Generate QC report to make sure the manual segmentation is correct\n",
" !sct_qc -i {subject}_acq-CoV_T2starw.nii.gz -s {subject}_acq-CoV_T2starw_label-CSF_seg.nii.gz -p sct_deepseg_sc -qc {path_qc} -qc-subject {subject}\n",
" else:\n",
" # Manual segmentation does not exist. Panic!\n",
" print(f\"{subject}: Manual segmentation not found 😱\")"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -224,7 +255,8 @@
"for subject in subjects:\n",
" os.chdir(os.path.join(path_data, subject, \"anat\"))\n",
" !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\n",
" !sct_crop_image -i {subject}_acq-CoV_T2starw_seg.nii.gz -m {subject}_acq-CoV_T2starw_seg.nii.gz -dilate 20x20x0 -o {subject}_acq-CoV_T2starw_crop_seg.nii.gz"
" !sct_crop_image -i {subject}_acq-CoV_T2starw_seg.nii.gz -m {subject}_acq-CoV_T2starw_seg.nii.gz -dilate 20x20x0 -o {subject}_acq-CoV_T2starw_crop_seg.nii.gz\n",
" !sct_crop_image -i {subject}_acq-CoV_T2starw_label-CSF_seg.nii.gz -m {subject}_acq-CoV_T2starw_seg.nii.gz -dilate 20x20x0 -o {subject}_acq-CoV_T2starw_crop_label-CSF_seg.nii.gz"
]
},
{
Expand Down Expand Up @@ -254,7 +286,6 @@
"source": [
"# Register *_T2starw to CoV_T2starw\n",
"\n",
"# Commenting for now, due to https://github.com/shimming-toolbox/rf-shimming-7t/issues/35\n",
"for subject in subjects:\n",
" os.chdir(os.path.join(path_data, subject, \"anat\"))\n",
" for shim_mode in shim_modes:\n",
Expand All @@ -263,23 +294,6 @@
" !sct_register_multimodal -i {subject}_acq-{shim_mode}_T2starw.nii.gz -d {subject}_acq-CoV_T2starw_crop.nii.gz -dseg {subject}_acq-CoV_T2starw_crop_seg.nii.gz -param step=1,type=im,algo=dl -qc {path_qc}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eb9a9267",
"metadata": {},
"outputs": [],
"source": [
"# Create CSF mask by dilating the spinal cord segmentation\n",
"\n",
"for subject in subjects:\n",
" os.chdir(os.path.join(path_data, subject, \"anat\"))\n",
" !sct_maths -i {subject}_acq-CoV_T2starw_crop_seg.nii.gz -dilate 3 -shape disk -dim 2 -o {subject}_acq-CoV_T2starw_crop_seg_dilate.nii.gz\n",
" !sct_maths -i {subject}_acq-CoV_T2starw_crop_seg_dilate.nii.gz -sub {subject}_acq-CoV_T2starw_crop_seg.nii.gz -o {subject}_acq-CoV_T2starw_crop_CSFseg.nii.gz\n",
" # Generate QC report to assess CSF mask\n",
" !sct_qc -i {subject}_acq-CoV_T2starw_crop.nii.gz -s {subject}_acq-CoV_T2starw_crop_CSFseg.nii.gz -p sct_deepseg_sc -qc {path_qc} -qc-subject {subject}"
]
},
{
"cell_type": "markdown",
"id": "aac9d889",
Expand All @@ -303,7 +317,7 @@
"\n",
"for subject in subjects:\n",
" os.chdir(os.path.join(path_data, subject, \"anat\"))\n",
" for shim_method in ['CoV', 'CP']: # TODO: shim_modes:\n",
" for shim_method in shim_modes:\n",
" # Shim methods are registered to the CoV T2starw scan, so we need to use the added suffix to identify them\n",
" if shim_method == 'CoV':\n",
" file_suffix = 'crop'\n",
Expand All @@ -312,7 +326,7 @@
" fname_result_sc = os.path.join(path_results, f\"{subject}_acq-{shim_method}_T2starw_label-SC.csv\")\n",
" !sct_extract_metric -i {subject}_acq-{shim_method}_T2starw_{file_suffix}.nii.gz -f {subject}_acq-CoV_T2starw_crop_seg.nii.gz -method wa -vert 3:9 -vertfile {subject}_acq-CoV_T2starw_crop_seg_labeled.nii.gz -perslice 1 -o {fname_result_sc}\n",
" fname_result_csf = os.path.join(path_results, f\"{subject}_acq-{shim_method}_T2starw_label-CSF.csv\")\n",
" !sct_extract_metric -i {subject}_acq-{shim_method}_T2starw_{file_suffix}.nii.gz -f {subject}_acq-CoV_T2starw_crop_CSFseg.nii.gz -method wa -vert 3:9 -vertfile {subject}_acq-CoV_T2starw_crop_seg_labeled.nii.gz -perslice 1 -o {fname_result_csf}"
" !sct_extract_metric -i {subject}_acq-{shim_method}_T2starw_{file_suffix}.nii.gz -f {subject}_acq-CoV_T2starw_crop_label-CSF_seg.nii.gz -method wa -vert 3:9 -vertfile {subject}_acq-CoV_T2starw_crop_seg_labeled.nii.gz -perslice 1 -o {fname_result_csf}"
]
},
{
Expand All @@ -322,12 +336,12 @@
"metadata": {},
"outputs": [],
"source": [
"# Make figure of SC/CSF signal ratio from T2starw scan\n",
"# Make figure of CSF/SC signal ratio from T2starw scan\n",
"\n",
"# Go back to root data folder\n",
"os.chdir(path_data)\n",
"\n",
"def smooth_data(data, window_size=20):\n",
"def smooth_data(data, window_size=40):\n",
" \"\"\" Apply a simple moving average to smooth the data. \"\"\"\n",
" return uniform_filter1d(data, size=window_size, mode='nearest')\n",
"\n",
Expand Down Expand Up @@ -360,7 +374,7 @@
"for i, subject in enumerate(subjects):\n",
" ax = axes[i]\n",
"\n",
" for shim_method in ['CoV', 'CP']: # TODO: shim_modes:\n",
" for shim_method in shim_modes:\n",
" # Initialize list to collect data for this shim method\n",
" method_data = []\n",
"\n",
Expand All @@ -375,7 +389,7 @@
" data_csf = df['WA()']\n",
" \n",
" # Compute ratio\n",
" data_sc_csf_ratio = data_sc / data_csf\n",
" data_sc_csf_ratio = data_csf / data_sc\n",
"\n",
" # Normalize the x-axis to a 0-1 scale for each subject\n",
" x_subject = np.linspace(0, 1, len(data_sc_csf_ratio))\n",
Expand All @@ -400,7 +414,7 @@
" ax.set_xticklabels([''] * len(original_vector))\n",
"\n",
" ax.set_title(f'{subject}', fontsize=font_size)\n",
" ax.set_ylabel('Cord/CSF T2starw signal ratio', fontsize=font_size)\n",
" ax.set_ylabel('CSF/Cord T2starw signal ratio', fontsize=font_size)\n",
" ax.tick_params(axis='y', which='major', labelsize=font_size-4)\n",
"\n",
" # Add legend only to the first subplot\n",
Expand Down

0 comments on commit bf4cf2f

Please sign in to comment.