Spinal cord DKI processing

Yes, I have noticed and can’t understand why if I run the single command it works and if I use the entire script it gives problems as it varies .
By the way, mk values between the left and right tract vary a lot and the std is high. Can it be due to the quality of the DKI maps?
thanks,
Rosella

By the way, mk values between the left and right tract vary a lot and the std is high. Can it be due to the quality of the DKI maps?

yup!

So, do you suggest to improve the image quality by changing the acquisition sequence in order to get reliable DKI maps? My final aim is to evaluate DKI metrics change in left and right cortico-spinal tract of ischemic patients.
thank you,
Rosella

Yes, data quality needs to be improved in order to drastically increase the reliability of the extracted metrics. Sorry for not bringing better news, but acquiring diffusion data in the spinal cord is already quite challenging, so in pediatric population and using less noisier models (DKI vs. DTI) this is to be expected.

If as a first step I try to threshold my DKI maps in order to exclude too noisy voxels, which is the way I can compute the aforementioned STD maps?

rosella@vivi:~$ ./3dt1.sh


Spinal Cord Toolbox (4.1.0)

Folder ./qc_singleSubj has been created.

Create temporary folder (/tmp/sct-20191129160754.744033-label_vertebrae-tq_p7fs9)…
/home/rosella/sct_4.1.0/bin/isct_propseg -t t1 -o ./ -verbose -init-mask /home/rosella/1/3D_T1W_TSE_401_rv/ROI.nii -i /home/rosella/1/3D_T1W_TSE_401_rv/3dT1.nii -centerline-binary # in /home/rosella

Check consistency of segmentation…

Create temporary folder (/tmp/sct-20191129160824.171060-propseg-0c91zz64)…
tmp.segmentation.nii.gz
tmp.centerline.nii.gz

Get data dimensions…
tmp.segmentation_RPI_c.nii.gz
rm -rf /tmp/sct-20191129160824.171060-propseg-0c91zz64
Copy header input → output(s) to make sure qform is the same.
WARNING: File /home/rosella/3dT1_seg.nii already exists. Will overwrite it.
WARNING: File /home/rosella/3dT1_centerline.nii already exists. Will overwrite it.
Successfully generated the QC results in /home/rosella/qc_singleSubj/_json/qc_2019_11_29_160855.592548.json
Use the following command to see the results in a browser:
xdg-open “/home/rosella/qc_singleSubj/index.html”

Done! To view results, type:
fsleyes /home/rosella/1/3D_T1W_TSE_401_rv/3dT1.nii -cm greyscale /home/rosella/3dT1_seg.nii -cm red -a 100.0 &


Spinal Cord Toolbox (4.1.0)

/home/rosella/sct_4.1.0/python/envs/venv_sct/lib/python3.6/site-packages/scipy/ndimage/measurements.py:1359: RuntimeWarning: invalid value encountered in double_scalars
** for dir in range(input.ndim)]**
Traceback (most recent call last):
** File “/home/rosella/sct_4.1.0/scripts/sct_label_utils.py”, line 828, in **
** main()**
** File “/home/rosella/sct_4.1.0/scripts/sct_label_utils.py”, line 818, in main**
** processor.process(process_type)**
** File “/home/rosella/sct_4.1.0/scripts/sct_label_utils.py”, line 112, in process**
** self.output_image = self.create_label_along_segmentation()**
** File “/home/rosella/sct_4.1.0/scripts/sct_label_utils.py”, line 217, in create_label_along_segmentation**
** x, y = int(np.round(x)), int(np.round(y))**
ValueError: cannot convert float NaN to integer

This is the error it gives me when trying to coregister the 3dT1 image to PAM50 template
Here is the script to do so 3dt1.sh (533 Bytes)
and the link to the mask used to initialize the centerline (ROI_centerline) and to the 3dT1 image
https://drive.google.com/drive/u/0/folders/1x5qsuhjFkTi7N3LfSJOwB4cIwm-7UPoe
Thanks so much,
Rosella

hi, i just requested you access to the gdrive (i am using gmail).
also: could you please update your script to remove the hardcoded absolute path, so it saves me some time-- thanks

@Rosella_Tro, the issue is related to the fact that the propseg algorithm is trained on adult cord size, therefore the segmentation fails (hence the rest of the processing fails). Fortunately, we recently added a flag -rescale to propseg, enabling to adapt the algorithm for pediatric population. However, this functionality currently does not work if it is combined with another input mask (here, -init-mask).

I’ve opened a ticket here, which I hope to solve within a few days.

Thank you for your feedback,
Julien

Ok thank you! I will try and find a solution.
In the meantime, as it is essential for the doctors I work with to keep acquisition time as shirt as possibile I need to try and work on the DKI images I have. So, if as a first step I try to threshold my DKI maps in order to exclude too noisy voxels, which is the way I can compute the aforementioned STD maps?

which is the way I can compute the aforementioned STD maps?

I’ve already sent you a couple of links and paper above, you will find a few software that do it. This is not something SCT covers (at least for now). I’ve opened a ticket here.

Ok thank you !
Best regards,
Rosella

I will let you know how the outcome will be with better quality DKI maps.
Rosella

Is there a way to threshold images in SCT between a range of values?
thanks
rosella

Is there a way to threshold images in SCT between a range of values?

sct_maths -thr <float>          Use following number to threshold image (zero below number).

p.s. it would be great if you could please create a new forum entry for specific question, so that the title of the category reflects the question (the current title of this thread is “Spinal cord DKI processing”). This will help other people when they need to look for specific answers. Also, this thread is becoming difficult to read. Thank you!

1 Like

You can avoid this with a mask method. Note first that in python NaN is defined as the number which is not equal to itself:

>float('nan') == float('nan')      
False

It might be worth avoiding use of np.NaN altogether. NaN literally means “not a number”, and it cannot be converted to an integer. In general, Python prefers raising an exception to returning NaN, so things like sqrt(-1) and log(0.0) will generally raise instead of returning NaN. However, you may get this value back from some other library. From v0.24, you actually can. Pandas introduces Nullable Integer Data Types which allows integers to coexist with NaNs. Also, even at the lastest versions of pandas if the column is object type you would have to convert into float first, something like:

df['column_name'].astype(np.float).astype("Int32")

NB: You have to go through numpy float first and then to nullable Int32, for some reason.

2 Likes