Exemplo n.º 1
0
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
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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)