Python program to calculate voxel count

538 views Asked by At

I want to write a script to calculate voxel count using python. I have one main folder named "PET-CT" and inside this main folder there are 100 "mrn" sub-folder named as 12345, 43523, 73092,....... Inside each sub-folder there are other 3 "followup" sub-folder named 11, 12, 13 and inside these folder there are 2 image file named "Roi_xyz.nii.gz" and "pet_xyz.nii.gz".

I have written a code for calculating the voxel_count from any single folder. I was wondering if anyone has an easy implementation using python to make it automatic. Please help me to write an automatic python script to calculate voxel_count which results two file (like 'uptake_ratio_12345_12.csv' and 'copy_pet_12345_12.nii.gz') for each of above respective folder. It has to go through these multiple folder and sub-folders and save two results. If it doesn't found any of the given file it has to processed to next folder.

Here is the code for single folder:

import nibabel as nib
import numpy as np
import pandas as pd

mrn='12345'
followup='12'
rootdir= "C:/Users/ak/Downloads/PET-CT"

fdir=os.path.join(rootdir,mrn,followup)

roi = nib.load(os.path.join(fdir,'ROI_xyz.nii.gz'))
pet = nib.load(os.path.join(fdir,'pet_xyz.nii.gz'))

copy_pet = nib.Nifti1Image(pet.get_fdata(),pet.affine)
nib.save(copy_pet,'copy_pet_12345_12.nii.gz')

roi_indices, roi_counts = np.unique(roi.get_fdata(), return_counts=True)

avg_count = roi_counts[1:].mean()

uptake_ratio = (roi_counts/avg_count)

df = pd.DataFrame({'ROI': roi_indices[1:], 'Counts': roi_counts[1:], 'UptakeRatio': uptake_ratio[1:]}) 

# saving the dataframe 
df.to_csv('uptake_ratio_12345_12.csv')  ```
1

There are 1 answers

0
ced-mos On

Given your folder structures this code go through all the subfolders ./[rootdir]/[mrn]/[followup]/ and processes all the data if both files are available.

import os
import nibabel as nib
import numpy as np
import pandas as pd

rootdir = "./PET-CT/"

# Search all mrn folders on level ./[rootdir]/..
for mrn in os.listdir(rootdir):
    # Search all followup folders on level ./[rootdir]/[mrn]/..
    for followup in os.listdir(os.path.join(rootdir,mrn)):
        try:
            # YOUR CODE
            fdir=os.path.join(rootdir,mrn,followup)
            roi = nib.load(os.path.join(fdir,'ROI_xyz.nii.gz'))
            pet = nib.load(os.path.join(fdir,'pet_xyz.nii.gz'))

            copy_pet = nib.Nifti1Image(pet.get_fdata(),pet.affine)
            nib.save(copy_pet,'copy_pet_{}_{}.nii.gz'.format(mrn,followup))

            roi_indices, roi_counts = np.unique(roi.get_fdata(), return_counts=True)

            avg_count = roi_counts[1:].mean()

            uptake_ratio = (roi_counts/avg_count)

            df = pd.DataFrame({'ROI': roi_indices[1:], 'Counts': roi_counts[1:], 'UptakeRatio': uptake_ratio[1:]}) 

            # saving the dataframe 
            df.to_csv('uptake_ratio_{}_{}.csv'.format(mrn,followup))
        except:
          print("An exception occurred when processing folder {}".format(fdir))

From you description it was not clear for me where to store the new output. If you want to store the files where you started your python application everything is fine. Otherwise you have to change the paths. Below I added the changes when your output files need to be stored in the same folder as the input files are.

nib.save(copy_pet,os.path.join(fdir, 'copy_pet_{}_{}.nii.gz'.format(mrn,followup)))
...
df.to_csv(os.path.join(fdir,'uptake_ratio_{}_{}.csv'.format(mrn,followup)))