def LoadPatientDataThread(ptdata): """Load the patient data.""" patient = {} if not 'images' in ptdata: #Look for DICOM data in the ptdata dictionary for rtdatatype in ptdata.keys(): if isinstance(ptdata[rtdatatype], pydicom.dataset.FileDataset): patient.update(dp(ptdata[rtdatatype]).GetDemographics()) break if 'rtss' in ptdata: d = dp(ptdata['rtss']) s = d.GetStructures() for k in s.keys(): s[k]['planes'] = d.GetStructureCoordinates(k) s[k]['thickness'] = d.CalculatePlaneThickness(s[k]['planes']) patient['structures'] = s if 'images' in ptdata: if not 'id' in patient: patient.update(dp(ptdata['images'][0]).GetDemographics()) patient['images'] = [] for image in ptdata['images']: patient['images'].append(dp(image)) return patient
def LoadPatientDataThread(self, parent, ptdata, progressFunc, updateFunc): """Thread to load the patient data.""" # Call the progress function to update the gui wx.CallAfter(progressFunc, 0, 0, 'Processing patient data...') patient = {} if not 'images' in ptdata: #Look for DICOM data in the ptdata dictionary for rtdatatype in ptdata.keys(): if isinstance(ptdata[rtdatatype], pydicom.dataset.FileDataset): patient.update(dp(ptdata[rtdatatype]).GetDemographics()) break if 'rtss' in ptdata: wx.CallAfter(progressFunc, 20, 100, 'Processing RT Structure Set...') d = dp(ptdata['rtss']) s = d.GetStructures() for k in s.keys(): s[k]['planes'] = d.GetStructureCoordinates(k) s[k]['thickness'] = d.CalculatePlaneThickness(s[k]['planes']) patient['structures'] = s if 'rtplan' in ptdata: wx.CallAfter(progressFunc, 40, 100, 'Processing RT Plan...') patient['plan'] = dp(ptdata['rtplan']).GetPlan() if 'rtdose' in ptdata: wx.CallAfter(progressFunc, 60, 100, 'Processing RT Dose...') patient['dvhs'] = dp(ptdata['rtdose']).GetDVHs() patient['dose'] = dp(ptdata['rtdose']) if 'images' in ptdata: wx.CallAfter(progressFunc, 80, 100, 'Processing Images...') if not 'id' in patient: patient.update(dp(ptdata['images'][0]).GetDemographics()) patient['images'] = [] for image in ptdata['images']: patient['images'].append(dp(image)) if 'rxdose' in ptdata: if not 'plan' in patient: patient['plan'] = {} patient['plan']['rxdose'] = ptdata['rxdose'] # if the min/max/mean dose was not present, calculate it and save it for each structure wx.CallAfter(progressFunc, 90, 100, 'Processing DVH data...') if ('dvhs' in patient) and ('structures' in patient): # If the DVHs are not present, calculate them i = 0 for key, structure in patient['structures'].items(): # Only calculate DVHs if they are not present for the structure # or recalc all DVHs if the preference is set if ((not (key in patient['dvhs'].keys())) or (self.dvhRecalc == 'Always Recalculate DVH')): # Only calculate DVHs for structures, not applicators # and only if the dose grid is present if ((structure['name'].startswith('Applicator')) or (not "PixelData" in patient['dose'].ds)): continue wx.CallAfter( progressFunc, 10 * i / len(patient['structures']) + 90, 100, 'Calculating DVH for ' + structure['name'] + '...') # Limit DVH bins to 500 Gy due to high doses in brachy dvh = dvhcalc.get_dvh(ptdata['rtss'], patient['dose'].ds, key, 50000) if len(dvh.counts): patient['dvhs'][key] = dvh i += 1 for key, dvh in patient['dvhs'].items(): dvh.rx_dose = patient['plan']['rxdose'] / 100 wx.CallAfter(progressFunc, 100, 100, 'Done') wx.CallAfter(updateFunc, patient)
def LoadPatientDataThread(self, parent, ptdata, progressFunc, updateFunc): """Thread to load the patient data.""" # Call the progress function to update the gui wx.CallAfter(progressFunc, 0, 0, 'Processing patient data...') patient = {} if not 'images' in ptdata: #Look for DICOM data in the ptdata dictionary for rtdatatype in ptdata.keys(): if isinstance(ptdata[rtdatatype], pydicom.dataset.FileDataset): patient.update(dp(ptdata[rtdatatype]).GetDemographics()) break if 'rtss' in ptdata: wx.CallAfter(progressFunc, 20, 100, 'Processing RT Structure Set...') d = dp(ptdata['rtss']) s = d.GetStructures() for k in s.keys(): s[k]['planes'] = d.GetStructureCoordinates(k) s[k]['thickness'] = d.CalculatePlaneThickness(s[k]['planes']) patient['structures'] = s if 'rtplan' in ptdata: wx.CallAfter(progressFunc, 40, 100, 'Processing RT Plan...') patient['plan'] = dp(ptdata['rtplan']).GetPlan() if 'rtdose' in ptdata: wx.CallAfter(progressFunc, 60, 100, 'Processing RT Dose...') patient['dvhs'] = dp(ptdata['rtdose']).GetDVHs() patient['dose'] = dp(ptdata['rtdose']) if 'images' in ptdata: wx.CallAfter(progressFunc, 80, 100, 'Processing Images...') if not 'id' in patient: patient.update(dp(ptdata['images'][0]).GetDemographics()) patient['images'] = [] for image in ptdata['images']: patient['images'].append(dp(image)) if 'rxdose' in ptdata: if not 'plan' in patient: patient['plan'] = {} patient['plan']['rxdose'] = ptdata['rxdose'] # if the min/max/mean dose was not present, calculate it and save it for each structure wx.CallAfter(progressFunc, 90, 100, 'Processing DVH data...') if ('dvhs' in patient) and ('structures' in patient): # If the DVHs are not present, calculate them i = 0 for key, structure in patient['structures'].items(): # Only calculate DVHs if they are not present for the structure # or recalc all DVHs if the preference is set if ((not (key in patient['dvhs'].keys())) or (self.dvhRecalc == 'Always Recalculate DVH')): # Only calculate DVHs for structures, not applicators # and only if the dose grid is present if ((structure['name'].startswith('Applicator')) or (not "PixelData" in patient['dose'].ds)): continue wx.CallAfter(progressFunc, 10*i/len(patient['structures'])+90, 100, 'Calculating DVH for ' + structure['name'] + '...') # Limit DVH bins to 500 Gy due to high doses in brachy dvh = dvhcalc.get_dvh(ptdata['rtss'], patient['dose'].ds, key, 50000) if len(dvh.counts): patient['dvhs'][key] = dvh i += 1 for key, dvh in patient['dvhs'].items(): dvh.rx_dose = patient['plan']['rxdose'] / 100 wx.CallAfter(progressFunc, 100, 100, 'Done') wx.CallAfter(updateFunc, patient)
def LoadPatientDataThread(self, parent, ptdata, progressFunc, updateFunc): """Thread to load the patient data.""" # Call the progress function to update the gui wx.CallAfter(progressFunc, 0, 0, 'Processing patient data...') patient = {} if not 'images' in ptdata: #Look for DICOM data in the ptdata dictionary for rtdatatype in ptdata.keys(): if isinstance(ptdata[rtdatatype], pydicom.dataset.FileDataset): patient.update(dp(ptdata[rtdatatype]).GetDemographics()) break if 'rtss' in ptdata: wx.CallAfter(progressFunc, 20, 100, 'Processing RT Structure Set...') d = dp(ptdata['rtss']) s = d.GetStructures() for k in s.keys(): s[k]['planes'] = d.GetStructureCoordinates(k) s[k]['thickness'] = d.CalculatePlaneThickness(s[k]['planes']) patient['structures'] = s if 'rtplan' in ptdata: wx.CallAfter(progressFunc, 40, 100, 'Processing RT Plan...') patient['plan'] = dp(ptdata['rtplan']).GetPlan() if 'rtdose' in ptdata: wx.CallAfter(progressFunc, 60, 100, 'Processing RT Dose...') patient['dvhs'] = dp(ptdata['rtdose']).GetDVHs() patient['dose'] = dp(ptdata['rtdose']) if 'images' in ptdata: wx.CallAfter(progressFunc, 80, 100, 'Processing Images...') if not 'id' in patient: patient.update(dp(ptdata['images'][0]).GetDemographics()) patient['images'] = [] for image in ptdata['images']: patient['images'].append(dp(image)) if 'rxdose' in ptdata: if not 'plan' in patient: patient['plan'] = {} patient['plan']['rxdose'] = ptdata['rxdose'] # if the min/max/mean dose was not present, calculate it and save it for each structure wx.CallAfter(progressFunc, 90, 100, 'Processing DVH data...') if ('dvhs' in patient) and ('structures' in patient): # If the DVHs are not present, calculate them i = 0 # Grabbing patient ID dvh_patientID = ptdata['rtdose'].PatientID csv_filename = str(dvh_patientID) + '.csv' dvh_csv_list = [] # maximum dose of all ROIs max_roi_dose = 0 # csv Header csv_header = [] for key, structure in patient['structures'].items(): # Initialize a list for dvh exporting to csv dvh_roi_list = [] # Only calculate DVHs if they are not present for the structure # or recalc all DVHs if the preference is set if ((not (key in patient['dvhs'].keys())) or (self.dvhRecalc == 'Always Recalculate DVH')): # Only calculate DVHs for structures, not applicators # and only if the dose grid is present if ((structure['name'].startswith('Applicator')) or (not "PixelData" in patient['dose'].ds)): continue wx.CallAfter( progressFunc, 10 * i / len(patient['structures']) + 90, 100, 'Calculating DVH for ' + structure['name'] + '...') # Limit DVH bins to 500 Gy due to high doses in brachy dvh = dvhcalc.get_dvh(ptdata['rtss'], patient['dose'].ds, key, 50000) # Retrieve roi name dvh_roiName = dvh.name # Retrieve roi dvh volume dvh_roiVolume = dvh.volume # Append info dvh_roi_list.append(dvh_patientID) dvh_roi_list.append(dvh_roiName) dvh_roi_list.append(dvh_roiVolume) # dvh_roiDose = dvh.relative_volume.counts for i in range(0, len(dvh_roiDose), 10): dvh_roi_list.append(dvh_roiDose[i]) if i > max_roi_dose: max_roi_dose = i dvh_csv_list.append(dvh_roi_list) if len(dvh.counts): patient['dvhs'][key] = dvh i += 1 csv_header.append('Hash ID') csv_header.append('ROI') csv_header.append('Volume (mL)') for i in range(0, max_roi_dose + 1, 10): csv_header.append(str(i) + 'cGy') pddf_csv = pd.DataFrame(dvh_csv_list, columns=csv_header).round(2) pddf_csv.fillna(0.0, inplace=True) pddf_csv.set_index('Hash ID', inplace=True) if not os.path.exists(self.path + '/CSV'): os.makedirs(self.path + '/CSV') pddf_csv.to_csv(self.path + '/CSV/' + 'DVH_' + csv_filename) for key, dvh in patient['dvhs'].items(): dvh.rx_dose = patient['plan']['rxdose'] / 100 wx.CallAfter(progressFunc, 100, 100, 'Done') wx.CallAfter(updateFunc, patient)