IvanEz / learn-morph-infer

7 stars 0 forks source link

Patient Specific Simulation #9

Open shiblyg opened 10 months ago

shiblyg commented 10 months ago

Hi Ivan, I trained the model using simulated data. Now during inference I gave only (binary segmentation of T1gd and Flair), and the model can estimate the parameter. But I am having trouble for patient specific simulation. i followed the steps in figure 1 mentioned in the paper. 1) register the patient mri with the atlas ( do I need to do it for the segmented mask : binary segmentation for T1gd and Flair) 2) got the morphed atlas 3) then combined morphed T1Gd and Flair 4) infer the parameter using morphed atlas 5)simulation in the atlas space using patient registered atlas in step 1 6) reverse registration in the patient space could you please tell me am I following the correct step. I am confused in figure 2 you mentioned only the binary segmentation is used as input ? Thank you

IvanEz commented 10 months ago

Hey, so this is the code for the registration. First, the registration to the patient space:

### registration and morph can only be done if ANTs is installed and morph.sh/register.sh are in the patientdata folder
################### registration of patientspace to atlasspace ############################

registration_path = path + path_atlas

if os.path.exists(registration_path) and (not force_overwrite or mri or denoised):
    print("Registration has been completed already")
else:
    if mass_effect:
        with torch.autograd.profiler.profile() as prof:
            morph = subprocess.check_call('../register_masseffect.sh', shell=False, cwd=path, stderr=subprocess.STDOUT)
    else:
        with torch.autograd.profiler.profile() as prof:
            registration = subprocess.check_call('../register.sh', shell=False, cwd=path, stderr=subprocess.STDOUT)  # e.g. /patientdata/1/

    print(f"time spent on registration: {prof.self_cpu_time_total / (1000*1000)} s")

Now this is the register.sh:

#!/bin/sh
path_patient="t1.nii.gz"
path_atlas="../atlas_resized_229to129.nii"
path_inv_mask_f="Tumor_inverted.nii.gz" #mask that excludes tumor (in patient space)
path_tumor_mask_f="Tumor_Flair_binarized.nii.gz" # is mask from FLAIR scan
path_tumor_mask_t="Tumor_T1_binarized.nii.gz" # is mask from T1 scan

outputfile="morphed_to_atlas"

if test -f "$path_patient"; then
    echo "$path_patient exists."
else
    path_patient="t1c.nii.gz"
fi

ANTS 3 -m CC[$path_patient,$path_atlas,1,4] -i 50x20x0 -o $outputfile -t SyN[0.25] -x $path_inv_mask_f -r Gauss[3,0]

this is how you morph two binary segmetations to the atlas space:

################### morphing to atlasspace ############################

morphing_path = path + t1path_atlas

if os.path.exists(morphing_path) and not force_overwrite:
    print("Morphing complete")
else:
    if mass_effect:
        with torch.autograd.profiler.profile() as prof:
            morph = subprocess.check_call('../morph_masseffect.sh', shell=False, cwd=path, stderr=subprocess.STDOUT)
    else:
        with torch.autograd.profiler.profile() as prof:
            morph = subprocess.check_call('../morph.sh', shell=False, cwd=path, stderr=subprocess.STDOUT)

    print(f"time spent on morph: {prof.self_cpu_time_total / (1000*1000)} s")

sim_path = path + simpath_atlas

print("Simulation path: ",simpath_atlas)

if os.path.exists(sim_path) and not force_overwrite:
    print("Tumor Simulation exists already")
else:
    print("Starting new parameter inference")

where morph.sh is:

#!/bin/sh

path_patient="t1.nii.gz"
path_atlas="../atlas_resized_229to129.nii"
path_inv_mask_f="Tumor_inverted.nii.gz" #mask that excludes tumor (in patient space)
path_tumor_mask_f="Tumor_Flair_binarized.nii.gz" # is mask from FLAIR scan
path_tumor_mask_t="Tumor_T1_binarized.nii.gz" # is mask from T1 scan

outputfile="morphed_to_atlas"

if test -f "$path_patient"; then
    echo "$path_patient exists."
else 
    path_patient="t1c.nii.gz"
fi

#inverse -> patient is transformed into atlas space
WarpImageMultiTransform 3 $path_patient patient_to_atlas.nii -R $path_atlas -i morphed_to_atlasAffine.txt morphed_to_atlasInverseWarp.nii.gz
# tumor mask is transformed into atlas space
WarpImageMultiTransform 3 $path_tumor_mask_f tumor_mask_f_to_atlas.nii --use-NN -R $path_atlas -i morphed_to_atlasAffine.txt morphed_to_atlasInverseWarp.nii.gz
WarpImageMultiTransform 3 $path_tumor_mask_t tumor_mask_t_to_atlas.nii --use-NN -R $path_atlas -i morphed_to_atlasAffine.txt morphed_to_atlasInverseWarp.nii.gz

Finally, this is how you morph the simulation back to patient space:

################### morphing back to patientspace ############################

morphingback_path = path + simpath

if os.path.exists(morphingback_path):
    print("Tumor morphing to patient space has been completed already")
else:
    print("Morphing tumor back to patient space")
    morph_back = subprocess.check_call(['../morphtopatientspace_paths.sh', str(simpath_atlas), str(simpath)], shell=False, cwd=path, stderr=subprocess.STDOUT)
    print("File saved at ", morphingback_path)

currenttime = datetime.now()
currenttime = currenttime.strftime("%d%m-%H-%M-%S-")
print("End time: ", currenttime)

where morphtopatientspace_paths.sh is:

#!/bin/sh

path_patient="t1.nii.gz"
path_atlas="atlas_resized_229to129.nii"
path_tumor_sim=$1
path_tumor_sim_patientspace=$2

if test -f "$path_patient"; then
    echo "$path_patient exists."
else
    path_patient="t1c.nii.gz"
fi

echo $path_tumor_sim_patientspace
echo $path_tumor_sim

#forward -> atlas is transformed into patient space
WarpImageMultiTransform 3 $path_tumor_sim $path_tumor_sim_patientspace -R $path_patient morphed_to_atlasWarp.nii.gz morphed_to_atlasAffine.txt