def _compute_dvh(roi_numbers, rtstruct, rtdose): y_range = None plots = [] max_x = 0 rtdose = dicomparser.DicomParser(rtdose) dp = dicomparser.DicomParser(rtstruct) for roi_number in roi_numbers: roi_number = int(roi_number) for roi in dp.ds.ROIContourSequence: if roi.ReferencedROINumber == roi_number and 'ContourSequence' in roi: for c in roi.ContourSequence: if 'ContourImageSequence' not in c: c.ContourImageSequence = [] for roi_number in roi_numbers: roi_number = int(roi_number) s = dp.GetStructures()[roi_number] pkdlog(' {}: {}', roi_number, s['name']) s['planes'] = dp.GetStructureCoordinates(roi_number) s['thickness'] = dp.CalculatePlaneThickness(s['planes']) calcdvh = dvhcalc.calculate_dvh(s, rtdose, None, True, None) counts = np.append(calcdvh.histogram, 0.0) counts = counts[::-1].cumsum()[::-1] if counts.any() and counts.max() > 0: counts = 100 * counts / counts.max() max_x = max(max_x, counts.size) min_y = np.min(counts) max_y = np.max(counts) if y_range: if min_y < y_range[0]: y_range[0] = min_y if max_y > y_range[1]: y_range[1] = max_y else: y_range = [min_y, max_y] rgb = s['color'] plots.append({ 'points': counts.tolist(), 'color': '#{:02x}{:02x}{:02x}'.format(int(rgb[0]), int(rgb[1]), int(rgb[2])), 'label': s['name'], }) return { 'title': '', 'aspectRatio': 1, 'x_range': [0, max_x / 100.0, max_x], 'y_label': 'Volume [%]', 'x_label': 'Dose [gy]', 'y_range': y_range, 'plots': sorted(plots, key=lambda v: v['label'].lower()), }
def _run_dvh(data, cfg_dir): dvh_report = data['models']['dvhReport'] assert dvh_report['roiNumbers'], 'No selection' y_range = None plots = [] max_x = 0 for roi_number in data['models']['dvhReport']['roiNumbers']: roi_number = int(roi_number) dp = dicomparser.DicomParser( _parent_file(cfg_dir, template.RTSTRUCT_EXPORT_FILENAME)) for roi in dp.ds.ROIContourSequence: if roi.ReferencedROINumber == roi_number: for c in roi.ContourSequence: if 'ContourImageSequence' not in c: c.ContourImageSequence = [] s = dp.GetStructures()[roi_number] s['planes'] = dp.GetStructureCoordinates(roi_number) s['thickness'] = dp.CalculatePlaneThickness(s['planes']) rtdose = dicomparser.DicomParser( _parent_file(cfg_dir, template._DOSE_DICOM_FILE)) calcdvh = dvhcalc.calculate_dvh(s, rtdose, None, True, None) counts = np.append(calcdvh.histogram, 0.0) if dvh_report['dvhType'] == 'cumulative': counts = counts[::-1].cumsum()[::-1] else: counts = np.append(abs(np.diff(counts) * -1), [0]) if dvh_report['dvhVolume'] == 'relative': if dvh_report['dvhType'] == 'differential': counts = counts[::-1].cumsum()[::-1] if counts.any() and counts.max() > 0: counts = 100 * counts / counts.max() if dvh_report['dvhType'] == 'differential': counts = np.append(abs(np.diff(counts) * -1), [0]) else: counts /= 10 max_x = max(max_x, counts.size) min_y = np.min(counts) max_y = np.max(counts) if y_range: if min_y < y_range[0]: y_range[0] = min_y if max_y > y_range[1]: y_range[1] = max_y else: y_range = [min_y, max_y] rgb = s['color'] plots.append({ 'points': counts.tolist(), 'color': '#{:02x}{:02x}{:02x}'.format(int(rgb[0]), int(rgb[1]), int(rgb[2])), 'label': s['name'], }) res = { 'title': '', 'x_range': [0, max_x / 100.0, max_x], 'y_label': 'Volume [{}]'.format('%' if dvh_report['dvhVolume'] == 'relative' else 'm³'), 'x_label': 'Dose [gy]', 'y_range': y_range, 'plots': sorted(plots, key=lambda v: v['label'].lower()), } template_common.write_sequential_result(res)
def _run_dvh(data, cfg_dir): dvh_report = data['models']['dvhReport'] if not len(dvh_report['roiNumbers']): simulation_db.write_result({ 'error': 'No selection', }) y_range = None plots = [] max_x = 0 for roi_number in data['models']['dvhReport']['roiNumbers']: roi_number = int(roi_number) dp = dicomparser.DicomParser(_parent_file(cfg_dir, template.RTSTRUCT_EXPORT_FILENAME)) for roi in dp.ds.ROIContourSequence: if roi.ReferencedROINumber == roi_number: for c in roi.ContourSequence: if 'ContourImageSequence' not in c: c.ContourImageSequence = [] s = dp.GetStructures()[roi_number] s['planes'] = dp.GetStructureCoordinates(roi_number) s['thickness'] = dp.CalculatePlaneThickness(s['planes']) rtdose = dicomparser.DicomParser(_parent_file(cfg_dir, template._DOSE_DICOM_FILE)) calcdvh = dvhcalc.calculate_dvh(s, rtdose, None, True, None) counts = np.append(calcdvh.histogram, 0.0) if dvh_report['dvhType'] == 'cumulative': counts = counts[::-1].cumsum()[::-1] else: counts = np.append(abs(np.diff(counts) * -1), [0]) if dvh_report['dvhVolume'] == 'relative': if dvh_report['dvhType'] == 'differential': counts = counts[::-1].cumsum()[::-1] if len(counts) and counts.max() > 0: counts = 100 * counts / counts.max() if dvh_report['dvhType'] == 'differential': counts = np.append(abs(np.diff(counts) * -1), [0]) else: counts /= 10 max_x = max(max_x, counts.size) min_y = np.min(counts) max_y = np.max(counts) if y_range: if min_y < y_range[0]: y_range[0] = min_y if max_y > y_range[1]: y_range[1] = max_y else: y_range = [min_y, max_y] plots.append({ 'points': counts.tolist(), 'color': '#{}'.format(struct.pack('BBB', *s['color']).encode('hex')), 'label': s['name'], }) res = { 'title': '', 'x_range': [0, max_x / 100.0, max_x], 'y_label': 'Volume [{}]'.format('%' if dvh_report['dvhVolume'] == 'relative' else 'm³'), 'x_label': 'Dose [gy]', 'y_range': y_range, 'plots': sorted(plots, key=lambda v: v['label'].lower()), } simulation_db.write_result(res)