Standardize analysis across subjects

Ok so
in my script I created labels at the top of C1 vertebrae (value:1) and at C3-C4 disc (value:4), centered in the cord

> sct_label_utils -i 3dT1.nii.gz -create-viewer 1,4 -msg "Create label at the posterior tip of the top of C1 vertebra and at C3-C4 disc" -o labels_disc1-4.nii.gz
Before I extracted metrics specifying vertebral levels C1-C3 because outside of these levels the registration is inaccurrate and/or MRI signal is corrupted

> sct_extract_metric -i dti_${metric}.nii.gz -l 4,5 -vert 1:3 -perslice 0 -o ./DWI_${metric}.csv -append 1
However, since vertebral levels c1-c3 does not always correspond to slices where segmentation is ok, do you mean I should use sct_extract metrics together with the labels_disc1-4.nii.gz file?
thanks
Rosella

no.

i meant to use sct_extract_metrics with the label/template/PAM50_levels.nii.gz vertebral level file, which is created by sct_warp_template.

as i said here, sct_extract_metrics will ignore voxels that have value=0 in the input mask (flag -f).

this, regardless the vertebral level.

ok. So my approach based on selected slices is not correct isn’t it?
And the correct usage of sct_extract_metric would then be:

> sct_extract_metric -i dti_{metric}.nii.gz -f label/template/PAM50_levels.nii.gz -l 51,52 -o ./DKI_${metric}.csv -append 1

thanks,
Rosella

no, that will not work.

As i explained in a previous post, copied here for convenience:

so, if you use -f, metrics will only be computed in your provided mask, therefore the -l flag is useless. If you want to compute metrics in specific sub-tracts, then you need to modify your atlas as explained in the link provided in the quote above.

EDITED 2020-07-09 13:08:58: the link above is only an example of how you could modify the atlas, it is not what you should do in your case. In your situation, what you want to do is simply multiply each label entry (label/atlas/PAM50_atlas_${label}.nii.gz) with your mask.

The point is that my segmentation mask - for which I am supposed to multiply my gm and wm labels-is not reliable for some slices in certain subjects (as you can see from the qc results’ screenshots). So my aim was selecting a set of slices, corresponding to the same vertebral levels for all subjects, where segmentation is correct and where therefore computing metrics.
Best
Rosella

yes, i understand this. The approach i suggested above does precisely address this scenario. Let me explain differently:

  • sct_extract_metric takes as input: -i: a metric, and -f: a mask or a folder that contains a series of masks.
  • for each voxel “i”, the function will multiply the metric by the mask value. This gives you “M(i)”.
  • Then, it does a weighted average of M(i) across all voxels in the slice. Depending on your aggregation method across the S-I axis (slicewise, levelwise, etc.), M(i) will be averaged across multiple slices (or not).

So, what it means is that, if a voxel in a mask has the value “0”, then “M(i)” will be 0 and will not contribute to the aggregated metric.

This explanation is based of the “weighted average” method. Other methods (maximum likelihood, maximum a posteriori) are a bit more complicated to explain, but the spirit is the same: a voxel of value 0 in your mask will not contribute to the extracted metric.

ok, but happens in slices where the segmentation is like this:
that is not all voxels are set to 0 but the segmentation is not right?
image
Moreover, the ROIs into which I want to compute metrics are just gm and wm.
So , could such a code be ok for my purpose:

# Multiply segmentation dilated mask by specific atlas ROI
  sct_maths -i kurtosis_crop_moco_dwi_mean_seg_dil.nii.gz -mul label/template/PAM50_gm.nii.gz  -o segm_gm.nii.gz
  sct_maths -i kurtosis_crop_moco_dwi_mean_seg_dil.nii.gz -mul label/template/PAM50_wm.nii.gz  -o segm_wm.nii.gz
  sct_extract_metric -i ${metric}.nii.gz -f segm_gm.nii.gz -vert 1:3 -o ./DKI_${metric}_gm.csv -append 1
  sct_extract_metric -i ${metric}.nii.gz -f segm_wm.nii.gz -vert 1:3 -o ./DKI_${metric}_wm.csv -append 1

best,
Rosella

you need to manually remove the spurious voxel=1 in your segmentation mask.

yes, your code is fine, but you should use kurtosis_crop_moco_dwi_mean_seg.nii.gz instead of kurtosis_crop_moco_dwi_mean_seg_dil.nii.gz for the multiplication (otherwise you will introduce voxels that should not be there at the first place)

ok thank you.
One last question: in other words, where segmentation is not fine I need to manually correct it? If I just simply wanted to stop my metrics average computation before those problematic slices?
And , my approach through selecting slices is inappropriate as it may not correspond to the same vertebral levels for all subjects?
thanks,
Rosella

One last question: in other words, where segmentation is not fine I need to manually correct it?

Indeed. Here is a recommended workflow to manually correct and save the manual correction in a specific folder, to ensure your pipeline can be reproduced by anybody, at any time.

If I just simply wanted to stop my metrics average computation before those problematic slices?

I’m not sure I understand the question, but the answer is probably that the provided label or mask is what defines the voxels where metrics statistics will be computed.

And , my approach through selecting slices is inappropriate as it may not correspond to the same vertebral levels for all subjects?

Indeed, this is not the approach I would recommend.

If when using sct_extract_metric I specify - vert 1:3, metrics extraction will be limited to slices corresponding to those vertebral levels, regardless segmentation, right? I do not want to extract metrics from last slices, as segmentation stops or continues below certain vertebral levels according to the subject.
Thanks
Rosella

that’s right.

Thank you for your support. Do you think, basing on the qc segmentation results posted before, computing metrics between levels c1:c3 is ok?
Thanks
Rosella

my pleasure. It is difficult for me to say, because i don’t know, from these axial EPI data, what vertebral levels those slices cover.

that is exactely what I wanted to know, that is how to associate slices and vertebral levels .
best,
Rosella

in this discussion thread, we’ve discussed ways for you to label vertebral levels and use this information to extract metrics at specific levels. Let me know if something is unclear about the process.

OK , I already have created a file labels1_4.nii.gz by manually selecting labels at posterior tip of c1 and between c3 and c4. Do I have to overlay this file on my DKI image and segmentation mask in order to associate segmentation, slices and vertebral levels?
thanks,
Rosella

Lines 18-23 of your analysis script kurtosis_def.sh (3.2 KB) bring the template (incl. vertebral levels) in the space of the DWI data. This is a pretty fundamental question, which is covered in the SCT course as well as in the example batch_processing.sh script. I would advise you spend some time on the course material and script, to better understand how the analysis pipeline works. This will answer many of your concerns.

Best,
Julien

1 Like

just one more question, on a pretty different matter. After manual correction of segmentation, is there a way to display it as in qc results, in order to highlight the changes introduced?
thanks,
Rosella

just one more question, on a pretty different matter. After manual correction of segmentation, is there a way to display it as in qc results, in order to highlight the changes introduced?

Yes, you can run sct_qc with the input you want (i.e. manual and automatic segmentation).

1 Like