Example #1
0
def get_dicom_data(root_path: str) -> Dict[str, List[str]]:
    """
        Provide all participant required files (RP,RS an RD DICOM FILES)
    :param root_path: participant folder
    :return: Pandas DataFrame containing path to files
    """
    files = [
        os.path.join(root, name) for root, dirs, files in os.walk(root_path)
        for name in files if name.endswith(('.dcm', '.DCM'))
    ]

    filtered_files = []
    for f in files:
        obj = PyDicomParser(filename=f)
        rt_type = obj.GetSOPClassUID()
        # fix halcyon SOP class UI
        if rt_type is None:
            rt_type = obj.ds.Modality.lower()

        if rt_type in ['rtdose', 'rtplan', 'rtss']:
            filtered_files.append([rt_type, f])

    # filter rtdose
    rd_files = [d[1] for d in filtered_files if d[0] == 'rtdose']
    rp_files = [d[1] for d in filtered_files if d[0] == 'rtplan']
    rs_files = [d[1] for d in filtered_files if d[0] == 'rtss']

    dcm_files = {'rtdose': rd_files, 'rtplan': rp_files, 'rtss': rs_files}

    return dcm_files
Example #2
0
def py_planning_item():
    plan_dict = PyDicomParser(filename=rp).GetPlan()
    rs_dvh = os.path.join(DATA_DIR, 'RS_dvh.dcm')
    structures_tmp1 = PyDicomParser(filename=rs_dvh).GetStructures()
    criteria1 = pd.read_excel(file_path, sheet_name='calc_dvh')
    rt_case_tmp = RTCase("H&N", 123, structures_tmp1, criteria1)
    dose_values = PyDicomParser(filename=rd).get_dose_matrix()
    grid = PyDicomParser(filename=rd).get_grid_3d()
    dose = Dose3D(dose_values, grid, pq.Gy)
    dvh_calc = DVHCalculator(rt_case_tmp, calculation_options)

    return PyPlanningItem(plan_dict, rt_case_tmp, dose, dvh_calc)
Example #3
0
def test_dvh_comparisson(setup_calculation_options):
    # Given plan DVH
    folder = os.path.join(DATA_DIR, 'lungSBRT')

    # parse DICOM folder
    # plan_folder = r'C:\Users\Victor\Dropbox\Plan_Competition_Project\tests\tests_data\pinnacle\plan1'
    plan_folder = r'C:\Users\Victor\Dropbox\Plan_Competition_Project\tests\tests_data\pinnacle\plan2'
    dcm_files, flag = get_participant_folder_data(plan_folder)

    rs_dvh = os.path.join(folder, 'RS.dcm')

    plan_dict = PyDicomParser(filename=dcm_files['rtplan']).GetPlan()
    # structures = PyDicomParser(filename=dcm_files['rtss']).GetStructures()
    structures = PyDicomParser(filename=rs_dvh).GetStructures()
    rd_dcm = PyDicomParser(filename=dcm_files['rtdose'])
    dose = rd_dcm.get_dose_3d()

    # criteria file
    file_path = os.path.join(folder, 'Scoring_criteria.xlsx')
    criteria = pd.read_excel(file_path, sheet_name='BiLateralLungSBRTCase')

    # setup RT case
    rt_case_tmp = RTCase("SBRT", 123, structures, criteria)
    dvh_calc = DVHCalculator(rt_case_tmp, setup_calculation_options)

    # when calculate DVH using pyplanScoring
    planning_obj = PyPlanningItem(plan_dict, rt_case_tmp, dose, dvh_calc)
    planning_obj.calculate_dvh()

    # for k, v in planning_obj.dvh_data.items():
    #     plot_dvh(v, v['name'])
    #     plt.show()

    # # Calculating the score
    plan_eval = PlanEvaluation()
    plan_eval.criteria = criteria
    df = plan_eval.eval_plan(planning_obj)

    raw_score = df['Raw score'].sum()
    pass
Example #4
0
    def setup_planing_item(self):

        if self.dcm_files is not None and self.case is not None:
            if self.dvh_calculator is not None:
                # TODO refactor this into abstractions
                plan_dcm = PyDicomParser(filename=self.dcm_files['rtplan'])
                dose_dcm = PyDicomParser(filename=self.dcm_files['rtdose'])
                plan_dict = plan_dcm.GetPlan()
                dose_3d = dose_dcm.get_dose_3d()
                self._planning_item = PyPlanningItem(plan_dict, self.case,
                                                     dose_3d,
                                                     self.dvh_calculator)
Example #5
0
    def setup_planing_item(self):
        if self.dcm_files is not None and self.case is not None:
            if self.dvh_calculator is not None:
                # TODO refactor this into abstractions
                plan_dict = {}
                if self.dcm_files['rtdose']:
                    dcm_objs = [
                        PyDicomParser(filename=f)
                        for f in self.dcm_files['rtdose']
                    ]
                    if len(dcm_objs) == 1:
                        dose_3d = dcm_objs[0].get_dose_3d()
                    else:
                        # add 3D doses
                        doses_3d = [obj.get_dose_3d() for obj in dcm_objs]
                        # Sum DVHs
                        acc = DoseAccumulation(doses_3d)
                        dose_3d = acc.get_plan_sum()

                    self._planning_item = PyPlanningItem(
                        plan_dict, self.case, dose_3d, self.dvh_calculator)
Example #6
0
def test_gk_dvh():
    # Given
    slicer_dvh_file = r'C:\Users\Victor\Dropbox\Plan_Competition_Project\tests\tests_data\gk_plan\SLICER_RT_DVH.csv'
    plan_folder = r'C:\Users\Victor\Dropbox\Plan_Competition_Project\tests\tests_data\gk_plan'

    slicer_dvh = read_slicer_dvh(slicer_dvh_file)

    # strip columns names
    slicer_dvh.columns = [
        'Skull Value', 'CerebelarDir', 'FrontalEsq ', 'Tumor', 'Tumor 2',
        'Tumor 3', 'Tumor 4', 'Tumor 5'
    ]

    dcm_files, flag = get_participant_folder_data(plan_folder)
    plan_dict = PyDicomParser(filename=dcm_files['rtplan']).GetPlan()
    structures = PyDicomParser(filename=dcm_files['rtss']).GetStructures()
    rd_dcm = PyDicomParser(filename=dcm_files['rtdose'])
    dose = rd_dcm.get_dose_3d()
    structures_py = [
        PyStructure(s, end_cap=s['thickness'] / 2)
        for k, s in structures.items()
    ]

    grid = (0.1, 0.1, 0.1)
    dvh_pyplan = {}
    for s in structures_py[:-1]:
        dvh_calci = DVHCalculation(s, dose, calc_grid=grid)
        dvh_l = dvh_calci.calculate(verbose=True)
        dvh_pyplan[dvh_l['name']] = dvh_l
        # plot_dvh(dvh_l, dvh_l['name'])

    for target_name, dvh_calc in dvh_pyplan.items():
        dose_t5 = slicer_dvh.index
        t5 = slicer_dvh.loc[:, target_name].values
        x_calc = np.arange(len(dvh_calc['data'])) * float(dvh_calc['scaling'])
        py_t5 = dvh_calc['data']

        plt.plot(dose_t5, t5, label='Slicer-RT')
        plt.plot(x_calc, py_t5, label='PyPlanScoring')
        plt.title(target_name)
        plt.legend()
        plt.show()
Example #7
0
if __name__ == '__main__':
    # Given
    # planIQ dvh
    dvh_ref_path = '/home/victor/Dropbox/Plan_Competition_Project/tests/tests_data/ptv_based_SRS/PTV Based - PlanIQ DVH - Eclipse VMAT - Body included - Ahmad March 24.txt'
    plan_iq_dvh = read_planiq_dvh(dvh_ref_path)

    # compare against SLICER DV
    plan_folder = r'/home/victor/Dropbox/Plan_Competition_Project/tests/tests_data/ptv_based_SRS'

    # dcm_files, flag = get_participant_folder_data(plan_folder)
    rtss = r'/home/victor/Dropbox/Plan_Competition_Project/tests/tests_data/ptv_based_SRS/RS.1.2.246.352.205.5644208623194161296.369175407993399980.dcm'
    rt_dose = '/home/victor/Dropbox/Plan_Competition_Project/tests/tests_data/ptv_based_SRS/RD.1.2.246.352.71.7.584747638204.1898898.20180324182516.dcm'
    ini_file = '/home/victor/Dropbox/Plan_Competition_Project/gui/cases/BrainMetSRSCase/PyPlanScoring.ini'
    setup_calculation_options = get_calculation_options(ini_file)

    structures = PyDicomParser(filename=rtss).GetStructures()
    rd_dcm = PyDicomParser(filename=rt_dose)
    dose = rd_dcm.get_dose_3d()
    plan_dict = {}

    # criteria file
    file_path = '/home/victor/Dropbox/Plan_Competition_Project/tests/tests_data/ptv_based_SRS/Scoring_criteria.xlsx'
    criteria = pd.read_excel(file_path, sheet_name='BrainSRS')

    # setup RT case
    rt_case_tmp = RTCase("SRS", 123, structures, criteria)
    dvh_calc = DVHCalculator(rt_case_tmp, setup_calculation_options)

    # when calculate DVH using pyplanScoring
    planning_obj = PyPlanningItem(plan_dict, rt_case_tmp, dose, dvh_calc)
    planning_obj.calculate_dvh()
Example #8
0
def test_lung_case_dvh(setup_calculation_options):
    # Given plan DVH
    folder = os.path.join(DATA_DIR, 'lungSBRT')

    # DVH reference
    dvh_ref_path = os.path.join(folder,
                                'PlanIQ DVH - Ahmad Plan - March 12.txt')
    plan_dvh = read_planiq_dvh(dvh_ref_path)

    # parse DICOM folder

    rp = os.path.join(folder, 'RP.dcm')
    rs_dvh = os.path.join(folder, 'RS.dcm')
    rd = os.path.join(folder, 'RD.dcm')

    plan_dict = PyDicomParser(filename=rp).GetPlan()
    structures = PyDicomParser(filename=rs_dvh).GetStructures()
    dose_values = PyDicomParser(filename=rd).get_dose_matrix()
    grid = PyDicomParser(filename=rd).get_grid_3d()
    dose = Dose3D(dose_values, grid, pq.Gy)

    # criteria file
    file_path = os.path.join(folder, 'Scoring_criteria.xlsx')
    criteria = pd.read_excel(file_path, sheet_name='BiLateralLungSBRTCase')

    # setup RT case
    rt_case_tmp = RTCase("SBRT", 123, structures, criteria)
    dvh_calc = DVHCalculator(rt_case_tmp, setup_calculation_options)

    # when calculate DVH using pyplanScoring
    planning_obj = PyPlanningItem(plan_dict, rt_case_tmp, dose, dvh_calc)
    planning_obj.calculate_dvh()

    # compare against PLANIQ
    for roi_number, dvh in planning_obj.dvh_data.items():
        name = dvh['name']
        plot_dvh_comp(dvh, plan_dvh, name, folder)

    # plt.show()

    # compare clinical DVH data
    #
    dvhs = PyDicomParser(filename=rd).GetDVHs()
    # compare against Eclipse DVH
    dvh_calculated = planning_obj.dvh_data
    res = {}
    res_eclipse = {}
    for roi_number in dvhs.keys():
        if roi_number in dvh_calculated:
            dvh_calc = dvh_calculated[roi_number]
            planiq_dvh = plan_dvh[structures[roi_number]['name']]

            x_calc = np.arange(len(dvh_calc['data'])) * float(
                dvh_calc['scaling'])
            x_planiq = plan_dvh.index
            cmp = CurveCompare(x_planiq, planiq_dvh, x_calc, dvh_calc['data'])
            # cmp.plot_results("PlanIQ", "PyPlanScoring", structures[roi_number]['name'])
            # plt.show()
            res[structures[roi_number]['name']] = cmp.stats_paper

            # Eclipse
            eclipse_dvh = dvhs[roi_number]
            x_eclipse = np.arange(len(eclipse_dvh['data'])) * float(
                eclipse_dvh['scaling'])

            cmp1 = CurveCompare(x_eclipse, eclipse_dvh['data'], x_calc,
                                dvh_calc['data'])
            # cmp.plot_results("PlanIQ", "PyPlanScoring", structures[roi_number]['name'])
            res_eclipse[structures[roi_number]['name']] = cmp1.stats_paper

    res_plan_iq = pd.DataFrame.from_dict(res)
    res_plan_iq.to_csv(os.path.join(folder, "PyPlanScoringXPlanIQ.csv"))

    res_eclipsedf = pd.DataFrame.from_dict(res_eclipse)
    res_eclipsedf.to_csv(os.path.join(folder, "PyPlanScoringXEclipse.csv"))

    piq = [
        res_plan_iq.min().min(),
        res_plan_iq.max().max(),
        res_plan_iq.mean().mean()
    ]
    ecl = [
        res_eclipsedf.min().min(),
        res_eclipsedf.max().max(),
        res_eclipsedf.mean().mean()
    ]

    # # # then Get dvh data and compare with plan_data
    # for roi_number, dvh in planning_obj.dvh_data.items():
    #     name = dvh['name']
    #     plot_dvh_comp(dvh, plan_dvh, name, folder)
    #
    # plt.show()
    #
    # # compare it abainst eclipse data
    # # compare with TPS DVH
    dvhs = PyDicomParser(filename=rd).GetDVHs()
    # compare against Eclipse DVH
    dvh_calculated = planning_obj.dvh_data
    for roi_number in dvhs.keys():
        if roi_number in dvh_calculated:
            plot_dvh_comp1(dvh_calculated[roi_number], dvhs[roi_number],
                           structures[roi_number]['name'], folder)

    # plt.show()
    # # lung SBRT case
    #
    # # Calculating the score
    plan_eval = PlanEvaluation()
    plan_eval.criteria = criteria
    df = plan_eval.eval_plan(planning_obj)

    assert df['Raw score'].sum() == 88.612
Example #9
0
# GETTING dvh DATA FROM DOSE
import os

import numpy as np

from pyplanscoring.constraints.metrics import PlanningItem
from pyplanscoring.core.dicom_reader import PyDicomParser
from pyplanscoring.core.types import DoseUnit, DoseValuePresentation, VolumePresentation, DoseValue
from tests.conftest import DATA_DIR, rp

# given
rd_dvh = os.path.join(DATA_DIR, 'RD_dvh.dcm')
rs_dvh = os.path.join(DATA_DIR, 'RS_dvh.dcm')
planning_item = PlanningItem(PyDicomParser(filename=rp),
                             PyDicomParser(filename=rs_dvh),
                             PyDicomParser(filename=rd_dvh))


def test_planning_item_general_info(test_case):
    ap = planning_item.approval_status
    test_case.assertEqual(ap, "UNAPPROVED")
    a_dt = planning_item.creation_date_time
    assert a_dt == '20171128'

    assert planning_item.plan
    assert planning_item.dose_data
    # test property beams
    assert len(planning_item.beams) > 0
    assert planning_item.dose_value_presentation == 1
    test_case.assertAlmostEqual(planning_item.total_prescribed_dose.value,
                                70.0)
Example #10
0
    return filtered_files


if __name__ == '__main__':

    # slicer/RT DVH
    file_path = r'/home/victor/Dropbox/Plan_Competition_Project/tests/tests_data/left_chest_wall/photon_electron/Absolute DVH Photon and electron plan sum.txt'
    eclipse_dvh = read_eclipse_dvh(file_path)

    # path to dicom files
    folder = '/home/victor/Dropbox/Plan_Competition_Project/tests/tests_data/left_chest_wall/photon_electron'
    dicom_data = get_dicom_data(folder)
    # filter rtdose
    rd_files = [d[1] for d in dicom_data if d[0] == 'rtdose']

    dcm_objs = [PyDicomParser(filename=rd_file) for rd_file in rd_files]
    doses_3d = [obj.get_dose_3d() for obj in dcm_objs]

    # Sum DVHs
    acc = DoseAccumulation(doses_3d)
    plan_sum = acc.get_plan_sum()

    # TODO compare with slicerRT plan sum DVH
    rs_file = '/home/victor/Dropbox/Plan_Competition_Project/tests/tests_data/left_chest_wall/photon_electron/RS.1.2.246.352.71.4.584747638204.283643.20180405155645.dcm'

    structures = PyDicomParser(filename=rs_file).GetStructures()
    structures_py = [
        PyStructure(s, end_cap=s['thickness']) for k, s in structures.items()
    ]

    dvh_pyplan = {}
Example #11
0
 def setup_case(self, rs_file_path, file_path, sheet_name):
     structures = PyDicomParser(filename=rs_file_path).GetStructures()
     self._plan_eval.read(file_path, sheet_name=sheet_name)
     # todo implement setup case by id
     self._case = RTCase(sheet_name, 1, structures,
                         self._plan_eval.criteria)
Example #12
0
def rd_dcm():
    """
        Fixture to return DICOM-RTDOSE obj
    :return:
    """
    return PyDicomParser(filename=rd)
Example #13
0

rs = os.path.join(DATA_DIR, 'RS.dcm')
rd = os.path.join(DATA_DIR, 'RD.dcm')
rp = os.path.join(DATA_DIR, 'RP.dcm')

str_names = [
    'LENS LT', 'PAROTID LT', 'BRACHIAL PLEXUS', 'OPTIC N. RT PRV',
    'OPTIC CHIASM PRV', 'OPTIC N. RT', 'ORAL CAVITY', 'BRAINSTEM',
    'SPINAL CORD', 'OPTIC CHIASM', 'LENS RT', 'LARYNX', 'SPINAL CORD PRV',
    'EYE LT', 'PTV56', 'BRAINSTEM PRV', 'PTV70', 'OPTIC N. LT PRV', 'EYE RT',
    'PTV63', 'OPTIC N. LT', 'LIPS', 'ESOPHAGUS', 'PTV70'
]

rs_dvh = os.path.join(DATA_DIR, 'RS_dvh.dcm')
structures_tmp = PyDicomParser(filename=rs_dvh).GetStructures()
to_index = {v['name']: k for k, v in structures_tmp.items()}


# fixtures
@pytest.fixture(scope="session")
def rp_dcm():
    """
        Fixture to return DICOM-RTPLAN obj
    :return:
    """
    return PyDicomParser(filename=rp)


@pytest.fixture(scope="session")
def rs_dcm():
Example #14
0
def rs_dcm():
    """
        Fixture to return DICOM-RTSTRUCT obj
    :return:
    """
    return PyDicomParser(filename=rs)
Example #15
0
def rp_dcm():
    """
        Fixture to return DICOM-RTPLAN obj
    :return:
    """
    return PyDicomParser(filename=rp)
Example #16
0
def dvh1():
    rd_dvh = os.path.join(DATA_DIR, 'RD_dvh.dcm')
    dvh_all = PyDicomParser(filename=rd_dvh).GetDVHs()
    return DVHData(dvh_all[61])
Example #17
0
def dvh_calculator():
    rs_dvh = os.path.join(DATA_DIR, 'RS_dvh.dcm')
    structures_tmp1 = PyDicomParser(filename=rs_dvh).GetStructures()
    rt_case_tmp = RTCase("H&N", 123, structures_tmp1, criteria)
    return DVHCalculator(rt_case_tmp, calculation_options)
Example #18
0
def dose_3d():
    dose_values = PyDicomParser(filename=rd).get_dose_matrix()
    grid = PyDicomParser(filename=rd).get_grid_3d()

    return Dose3D(dose_values, grid, pq.Gy)