|
import os |
|
import pydicom |
|
|
|
from libraries.Process.CTimage import * |
|
from libraries.Process.MRimage import * |
|
from libraries.Process.RTdose import * |
|
from libraries.Process.RTstruct import * |
|
from libraries.Process.RTplan import * |
|
|
|
class PatientList: |
|
|
|
def __init__(self): |
|
self.list = [] |
|
|
|
|
|
|
|
def find_CT_image(self, display_id): |
|
count = -1 |
|
for patient_id in range(len(self.list)): |
|
for ct_id in range(len(self.list[patient_id].CTimages)): |
|
if(self.list[patient_id].CTimages[ct_id].isLoaded == 1): count += 1 |
|
if(count == display_id): break |
|
if(count == display_id): break |
|
|
|
return patient_id, ct_id |
|
|
|
|
|
|
|
def find_dose_image(self, display_id): |
|
count = -1 |
|
for patient_id in range(len(self.list)): |
|
for dose_id in range(len(self.list[patient_id].RTdoses)): |
|
if(self.list[patient_id].RTdoses[dose_id].isLoaded == 1): count += 1 |
|
if(count == display_id): break |
|
if(count == display_id): break |
|
|
|
return patient_id, dose_id |
|
|
|
|
|
|
|
def find_contour(self, ROIName): |
|
for patient_id in range(len(self.list)): |
|
for struct_id in range(len(self.list[patient_id].RTstructs)): |
|
if(self.list[patient_id].RTstructs[struct_id].isLoaded == 1): |
|
for contour_id in range(len(self.list[patient_id].RTstructs[struct_id].Contours)): |
|
if(self.list[patient_id].RTstructs[struct_id].Contours[contour_id].ROIName == ROIName): |
|
return patient_id, struct_id, contour_id |
|
|
|
|
|
|
|
def list_dicom_files(self, folder_path, recursive): |
|
file_list = os.listdir(folder_path) |
|
|
|
for file_name in file_list: |
|
file_path = os.path.join(folder_path, file_name) |
|
|
|
|
|
if os.path.isdir(file_path): |
|
if recursive == True: |
|
subfolder_list = self.list_dicom_files(file_path, True) |
|
|
|
|
|
|
|
elif os.path.isfile(file_path): |
|
|
|
try: |
|
dcm = pydicom.dcmread(file_path) |
|
except: |
|
print("Invalid Dicom file: " + file_path) |
|
continue |
|
|
|
patient_id = next((x for x, val in enumerate(self.list) if val.PatientInfo.PatientID == dcm.PatientID), -1) |
|
|
|
|
|
if patient_id == -1: |
|
Patient = PatientData() |
|
Patient.PatientInfo.PatientID = dcm.PatientID |
|
Patient.PatientInfo.PatientName = str(dcm.PatientName) |
|
Patient.PatientInfo.PatientBirthDate = dcm.PatientBirthDate |
|
Patient.PatientInfo.PatientSex = dcm.PatientSex |
|
self.list.append(Patient) |
|
patient_id = len(self.list) - 1 |
|
|
|
|
|
if dcm.SOPClassUID == "1.2.840.10008.5.1.4.1.1.2": |
|
ct_id = next((x for x, val in enumerate(self.list[patient_id].CTimages) if val.SeriesInstanceUID == dcm.SeriesInstanceUID), -1) |
|
if ct_id == -1: |
|
CT = CTimage() |
|
CT.SeriesInstanceUID = dcm.SeriesInstanceUID |
|
CT.SOPClassUID == "1.2.840.10008.5.1.4.1.1.2" |
|
CT.PatientInfo = self.list[patient_id].PatientInfo |
|
CT.StudyInfo = StudyInfo() |
|
CT.StudyInfo.StudyInstanceUID = dcm.StudyInstanceUID |
|
CT.StudyInfo.StudyID = dcm.StudyID |
|
CT.StudyInfo.StudyDate = dcm.StudyDate |
|
CT.StudyInfo.StudyTime = dcm.StudyTime |
|
if(hasattr(dcm, 'SeriesDescription') and dcm.SeriesDescription != ""): CT.ImgName = dcm.SeriesDescription |
|
else: CT.ImgName = dcm.SeriesInstanceUID |
|
self.list[patient_id].CTimages.append(CT) |
|
ct_id = len(self.list[patient_id].CTimages) - 1 |
|
|
|
self.list[patient_id].CTimages[ct_id].DcmFiles.append(file_path) |
|
|
|
|
|
elif dcm.SOPClassUID == "1.2.840.10008.5.1.4.1.1.4": |
|
mr_id = next((x for x, val in enumerate(self.list[patient_id].MRimages) if val.SeriesInstanceUID == dcm.SeriesInstanceUID), -1) |
|
if mr_id == -1: |
|
MR = MRimage() |
|
MR.SeriesInstanceUID = dcm.SeriesInstanceUID |
|
MR.SOPClassUID == "1.2.840.10008.5.1.4.1.1.4" |
|
MR.PatientInfo = self.list[patient_id].PatientInfo |
|
MR.StudyInfo = StudyInfo() |
|
MR.StudyInfo.StudyInstanceUID = dcm.StudyInstanceUID |
|
MR.StudyInfo.StudyID = dcm.StudyID |
|
MR.StudyInfo.StudyDate = dcm.StudyDate |
|
MR.StudyInfo.StudyTime = dcm.StudyTime |
|
if(hasattr(dcm, 'SeriesDescription') and dcm.SeriesDescription != ""): MR.ImgName = dcm.SeriesDescription |
|
else: MR.ImgName = dcm.SeriesInstanceUID |
|
self.list[patient_id].MRimages.append(MR) |
|
mr_id = len(self.list[patient_id].MRimages) - 1 |
|
|
|
self.list[patient_id].MRimages[mr_id].DcmFiles.append(file_path) |
|
|
|
|
|
elif dcm.SOPClassUID == "1.2.840.10008.5.1.4.1.1.481.2": |
|
dose_id = next((x for x, val in enumerate(self.list[patient_id].RTdoses) if val.SOPInstanceUID == dcm.SOPInstanceUID), -1) |
|
if dose_id == -1: |
|
dose = RTdose() |
|
dose.SOPInstanceUID = dcm.SOPInstanceUID |
|
dose.SeriesInstanceUID = dcm.SeriesInstanceUID |
|
dose.PatientInfo = self.list[patient_id].PatientInfo |
|
dose.StudyInfo = StudyInfo() |
|
dose.StudyInfo.StudyInstanceUID = dcm.StudyInstanceUID |
|
dose.StudyInfo.StudyID = dcm.StudyID |
|
dose.StudyInfo.StudyDate = dcm.StudyDate |
|
dose.StudyInfo.StudyTime = dcm.StudyTime |
|
if dcm.DoseSummationType == "BEAM": |
|
dose.beam_number = str(dcm.ReferencedRTPlanSequence[0].ReferencedFractionGroupSequence[0].ReferencedBeamSequence[0].ReferencedBeamNumber) |
|
elif dcm.DoseSummationType == "PRIOR_TARGET": |
|
dose.beam_number = "PRIOR_TARGET" |
|
elif "PRIOR_TARGET_OAR" in dcm.DoseSummationType : |
|
dose.beam_number = "PRIOR_TARGET_OAR" |
|
else: |
|
dose.beam_number = "PLAN" |
|
if(hasattr(dcm, 'SeriesDescription') and dcm.SeriesDescription != ""): dose.ImgName = dcm.SeriesDescription |
|
else: dose.ImgName = dcm.SeriesInstanceUID |
|
dose.DcmFile = file_path |
|
self.list[patient_id].RTdoses.append(dose) |
|
|
|
|
|
elif dcm.SOPClassUID == "1.2.840.10008.5.1.4.1.1.481.3": |
|
|
|
|
|
struct = RTstruct() |
|
struct.SeriesInstanceUID = dcm.SeriesInstanceUID |
|
struct.PatientInfo = self.list[patient_id].PatientInfo |
|
struct.StudyInfo = StudyInfo() |
|
struct.StudyInfo.StudyInstanceUID = dcm.StudyInstanceUID |
|
struct.StudyInfo.StudyID = dcm.StudyID |
|
struct.StudyInfo.StudyDate = dcm.StudyDate |
|
struct.StudyInfo.StudyTime = dcm.StudyTime |
|
struct.DcmFile = file_path |
|
|
|
|
|
stop = 0 |
|
for s in range(len(dcm.ROIContourSequence)): |
|
if hasattr(dcm.ROIContourSequence[s], 'ContourSequence') and stop == 0: |
|
stop = 1 |
|
if dcm.ROIContourSequence[s].ContourSequence[0].ContourImageSequence[0].ReferencedSOPClassUID=="1.2.840.10008.5.1.4.1.1.2": |
|
self.list[patient_id].RTstructs_CT.append(struct) |
|
elif dcm.ROIContourSequence[s].ContourSequence[0].ContourImageSequence[0].ReferencedSOPClassUID=="1.2.840.10008.5.1.4.1.1.4": |
|
self.list[patient_id].RTstructs_MR.append(struct) |
|
else: |
|
continue |
|
|
|
|
|
|
|
elif dcm.SOPClassUID == "1.2.840.10008.5.1.4.1.1.481.5" or dcm.SOPClassUID == "1.2.840.10008.5.1.4.1.1.481.8": |
|
plan_id = next((x for x, val in enumerate(self.list[patient_id].RTplans) if val.SeriesInstanceUID == dcm.SeriesInstanceUID), -1) |
|
if plan_id == -1: |
|
plan = RTplan() |
|
plan.SeriesInstanceUID = dcm.SeriesInstanceUID |
|
plan.PatientInfo = self.list[patient_id].PatientInfo |
|
plan.StudyInfo = StudyInfo() |
|
plan.StudyInfo.StudyInstanceUID = dcm.StudyInstanceUID |
|
plan.StudyInfo.StudyID = dcm.StudyID |
|
plan.StudyInfo.StudyDate = dcm.StudyDate |
|
plan.StudyInfo.StudyTime = dcm.StudyTime |
|
if(hasattr(dcm, 'SeriesDescription') and dcm.SeriesDescription != ""): plan.PlanName = dcm.SeriesDescription |
|
else: plan.PlanName = dcm.SeriesInstanceUID |
|
plan.DcmFile = file_path |
|
self.list[patient_id].RTplans.append(plan) |
|
|
|
else: |
|
print("Unknown SOPClassUID " + dcm.SOPClassUID + " for file " + file_path) |
|
|
|
|
|
else: |
|
print("Unknown file type " + file_path) |
|
|
|
|
|
def print_patient_list(self): |
|
print("") |
|
for patient in self.list: |
|
patient.print_patient_info() |
|
|
|
print("") |
|
|
|
|
|
|
|
class PatientData: |
|
|
|
def __init__(self): |
|
self.PatientInfo = PatientInfo() |
|
self.CTimages = [] |
|
self.MRimages = [] |
|
self.RTdoses = [] |
|
self.RTplans = [] |
|
self.RTstructs_CT = [] |
|
self.RTstructs_MR = [] |
|
|
|
def print_patient_info(self, prefix=""): |
|
print("") |
|
print(prefix + "PatientName: " + self.PatientInfo.PatientName) |
|
print(prefix+ "PatientID: " + self.PatientInfo.PatientID) |
|
|
|
for ct in self.CTimages: |
|
print("") |
|
ct.print_CT_info(prefix + " ") |
|
print("") |
|
|
|
for mr in self.MRimages: |
|
print("") |
|
mr.print_MR_info(prefix + " ") |
|
|
|
print("") |
|
for dose in self.RTdoses: |
|
print("") |
|
dose.print_dose_info(prefix + " ") |
|
|
|
print("") |
|
for struct in self.RTstructs_CT: |
|
print("") |
|
struct.print_struct_info(prefix + " ") |
|
|
|
print("") |
|
for struct in self.RTstructs_MR: |
|
print("") |
|
struct.print_struct_info(prefix + " ") |
|
|
|
|
|
def import_patient_data(self,newvoxelsize=None): |
|
|
|
for i,ct in enumerate(self.CTimages): |
|
if(ct.isLoaded == 1): continue |
|
ct.import_Dicom_CT() |
|
|
|
for i,mr in enumerate(self.MRimages): |
|
if(mr.isLoaded == 1): continue |
|
mr.import_Dicom_MR() |
|
|
|
for i, struct in enumerate(self.RTstructs_CT): |
|
struct.import_Dicom_struct(self.CTimages[i]) |
|
|
|
for i, struct in enumerate(self.RTstructs_MR): |
|
struct.import_Dicom_struct(self.MRimages[i]) |
|
|
|
for i,plan in enumerate(self.RTplans): |
|
if(plan.isLoaded == 1): continue |
|
plan.import_Dicom_plan() |
|
|
|
if newvoxelsize is not None: |
|
|
|
for i,ct in enumerate(self.CTimages): |
|
ct.resample_CT(newvoxelsize) |
|
|
|
for i,mr in enumerate(self.MRimages): |
|
mr.resample_MR(newvoxelsize) |
|
|
|
for i, struct in enumerate(self.RTstructs_CT): |
|
struct.resample_struct(newvoxelsize) |
|
|
|
for i, dose in enumerate(self.RTdoses): |
|
if(dose.isLoaded == 1): continue |
|
dose.import_Dicom_dose(self.CTimages[0]) |
|
|
|
|
|
|
|
|
|
class PatientInfo: |
|
|
|
def __init__(self): |
|
self.PatientID = '' |
|
self.PatientName = '' |
|
self.PatientBirthDate = '' |
|
self.PatientSex = '' |
|
|
|
|
|
|
|
|
|
class StudyInfo: |
|
|
|
def __init__(self): |
|
self.StudyInstanceUID = '' |
|
self.StudyID = '' |
|
self.StudyDate = '' |
|
self.StudyTime = '' |
|
|