def load_dose(self, path, _type, target_dose=0.0): """ Load and append a new DosCube from path to self.doscubes. """ dos = DosCube() dos.read(os.path.splitext(path)[0] + DosCube.data_file_extension) dos._type = _type dos.target_dose = target_dose self.dosecubes.append(dos)
def test_dicom_plan(self): c = DosCube() c.read(self.cube000) dp = c.create_dicom_plan() self.assertIsNotNone(dp) d = c.create_dicom() self.assertIsNotNone(d)
def test_write_dicom(self): c = DosCube() c.read(self.cube000) outdir = tempfile.mkdtemp() c.write_dicom(outdir) self.assertTrue(os.path.exists(os.path.join(outdir, "rtdose.dcm"))) self.assertTrue(os.path.exists(os.path.join(outdir, "rtplan.dcm"))) self.assertGreater(os.path.getsize(os.path.join(outdir, "rtdose.dcm")), 0) self.assertGreater(os.path.getsize(os.path.join(outdir, "rtplan.dcm")), 0) shutil.rmtree(outdir)
def test_read(self): c = DosCube() c.read(self.cube000) self.assertEqual(c.cube.shape[0], 300) self.assertEqual(c.cube.shape[1], 512) self.assertEqual(c.cube.shape[2], 512) # test method from C extension dose_center = pytriplib.calculate_dose_center(np.array(c.cube)) self.assertEqual(dose_center.shape[0], 3) self.assertGreater(dose_center[0], 0.0) self.assertGreater(dose_center[1], 0.0) self.assertGreater(dose_center[2], 0.0)
def calculate_rest_dose(self, proj): self.rest_dose = copy.deepcopy(self.target_dos) for k, projectile in self.projectiles.items(): if k == proj: continue name = os.path.join(self.path, self.plan_name) + "_" + projectile["name"] path = os.path.join(name + ".phys.dos") if os.path.exists(path): temp = DosCube() temp.read(path) temp = temp self.rest_dose.cube = self.rest_dose.cube - temp.cube
def test_dvh_simple(self): c = DosCube() c.read(self.cube000) v = create_sphere(c, name="sph", center=[10, 10, 10], radius=8) self.assertIsNotNone(v) logger.info("Calculating DVH simple") x, y = volume_histogram(c.cube, v) self.assertIsNotNone(x) self.assertIsNotNone(y) logger.info("Calculating DVH simple for entire cube") x, y = volume_histogram(c.cube) self.assertIsNotNone(x) self.assertIsNotNone(y)
def test_dvh(self): c = DosCube() c.read(self.cube000) v = create_sphere(c, name="sph", center=[10, 10, 10], radius=8) self.assertIsNotNone(v) logger.info("Calculating DVH") result = c.calculate_dvh(v) self.assertIsNotNone(result) dvh, min_dose, max_dose, mean, area = result self.assertGreater(area, 2.0) self.assertEqual(len(dvh.shape), 2) self.assertEqual(dvh.shape[1], 2) self.assertEqual(dvh.shape[0], 1500) self.assertEqual(min_dose, 0.0) self.assertEqual(max_dose, 0.001)
def _finish(self, plan): """ return requested results, copy them back in to plan._working_dir """ for _file_name in plan._out_files: _path = os.path.join(plan._temp_dir, _file_name) # only copy files back, if we actually have been running TRiP if self._norun: logger.info("dummy run: would now copy {:s} to {:s}".format( _path, plan._working_dir)) else: logger.info("copy {:s} to {:s}".format(_path, plan._working_dir)) shutil.copy(_path, plan._working_dir) for _file_name in plan._out_files: _path = os.path.join(plan._temp_dir, _file_name) if ".phys.dos" in _file_name: _ctx_cube = DosCube() if not self._norun: _ctx_cube.read(_path) plan.dosecubes.append(_ctx_cube) if ".bio.dos" in _file_name: _ctx_cube = CtxCube() if not self._norun: _ctx_cube.read(_path) plan.dosecubes.append(_ctx_cube) if ".dosemlet.dos" in _file_name: _let_cube = LETCube() if not self._norun: _let_cube.read(_path) plan.letcubes.append(_let_cube) if ".rst" in _file_name: logger.warning( "attaching fields to class not implemented yet {:s}". format(_path)) # TODO # need to access the RstClass here for each rst file. This will then need to be attached # to the proper field in the list of fields. if self._cleanup: logger.debug("Delete {:s}".format(plan._temp_dir)) shutil.rmtree(plan._temp_dir)
def test_write(self): c = DosCube() c.read(self.cube000) fd, outfile = tempfile.mkstemp() os.close(fd) # Windows needs it os.remove(outfile) # we need only temp filename, not the file c.write(outfile) hed_file = outfile + DosCube.header_file_extension dos_file = outfile + DosCube.data_file_extension self.assertTrue(os.path.exists(hed_file)) self.assertTrue(os.path.exists(dos_file)) logger.info("Checking if output file " + hed_file + " is not empty") self.assertGreater(os.path.getsize(hed_file), 1) logger.info("Checking if output file " + dos_file + " is not empty") self.assertGreater(os.path.getsize(dos_file), 1) os.remove(hed_file) os.remove(dos_file)
def test_write(self): c = DosCube() c.read(self.cube000) fd, outfile = tempfile.mkstemp() os.close(fd) # Windows needs it os.remove(outfile) # we need only temp filename, not the file c.write(outfile) hed_file = outfile + ".hed" dos_file = outfile + ".dos" self.assertTrue(os.path.exists(hed_file)) self.assertTrue(os.path.exists(dos_file)) logger.info("Checking if output file " + hed_file + " is not empty") self.assertGreater(os.path.getsize(hed_file), 1) logger.info("Checking if output file " + dos_file + " is not empty") self.assertGreater(os.path.getsize(dos_file), 1) os.remove(hed_file) os.remove(dos_file)
def test_dvh_simple(self): c = DosCube() c.read(self.cube000) v = create_sphere(c, name="sph", center=[10, 10, 10], radius=8) self.assertIsNotNone(v) logger.info("Calculating DVH simple") vh = VolHist(c, v) self.assertIsNotNone(vh.x) self.assertIsNotNone(vh.y) outdir = tempfile.mkdtemp() c.write_dicom(outdir) f1 = os.path.join(outdir, "foobar_1.dvh") vh.write(f1, header=True) self.assertTrue(os.path.exists(f1)) self.assertGreater(os.path.getsize(f1), 0) f2 = os.path.join(outdir, "foobar_2.dvh") vh.write(f2, header=False) self.assertTrue(os.path.exists(f2)) self.assertGreater(os.path.getsize(f2), 0) logger.info("Calculating DVH simple for entire cube") vh = VolHist(c) self.assertIsNotNone(vh.x) self.assertIsNotNone(vh.y) f3 = os.path.join(outdir, "foobar_3.dvh") vh.write(f3, header=True) self.assertTrue(os.path.exists(f3)) self.assertGreater(os.path.getsize(f3), 0) f4 = os.path.join(outdir, "foobar_4.dvh") vh.write(f4, header=False) self.assertTrue(os.path.exists(f4)) self.assertGreater(os.path.getsize(f4), 0) shutil.rmtree(outdir)
def post_process(self): phys_dose = None bio_dose = None dose_mean_let = None temp_dos = None for projectile in self.projectiles: name = os.path.join( self.path, self.plan_name) + "_" + self.projectiles[projectile]["name"] factor = float(self.projectile_dose_level[projectile]) / 1000 factor = 1 if os.path.exists(name + ".bio.dos") and self.plan.get_out_bio_dose(): path = os.path.join(name + ".bio.dos") temp = DosCube() temp.read(path) temp *= factor if self.mult_proj: self.plan.add_dose(temp, "bio_%s" % projectile) if bio_dose is None: bio_dose = temp else: bio_dose += temp if os.path.exists(name + ".phys.dos") and self.plan.get_out_phys_dose(): path = os.path.join(name + ".phys.dos") temp_dos = DosCube() temp_dos.read(path) temp_dos *= factor if self.mult_proj: self.plan.add_dose(temp_dos, "phys_%s" % projectile) if phys_dose is None: phys_dose = temp_dos else: phys_dose += temp_dos if os.path.exists(name + ".dosemlet.dos" ) and self.plan.get_out_dose_mean_let(): path = os.path.join(name + ".dosemlet.dos") temp = LETCube() temp.read(path) if not self.mult_proj: dose_mean_let = temp else: if dose_mean_let is None: dose_mean_let = temp * temp_dos else: dose_mean_let = dose_mean_let + temp * temp_dos out_path = os.path.join(self.path, self.plan_name) if bio_dose is not None: bio_dose.write(out_path + ".bio.dos") if phys_dose is not None: phys_dose.write(out_path + ".phys.dos") if dose_mean_let is not None: if self.mult_proj: dose_mean_let /= phys_dose dose_mean_let.write(out_path + ".hed")
def split_fields(self, proj): if self.split_proj_key not in self.projectiles.keys(): return name = os.path.join( self.path, self.plan_name) + "_" + self.projectiles[proj]["name"] path = os.path.join(name + ".phys.dos") temp = DosCube() temp.read(path) temp.version = "2.0" self.rest_dose = self.target_dos - temp p = self.projectiles[self.split_proj_key] p["target_dos"].cube = pytriplib.extend_cube(p["target_dos"].cube) if len(p["fields"]) == 2: temp.cube = (temp.cube < self.projectiles[proj]["target_dos"].cube) * \ self.projectiles[proj]["target_dos"].cube + \ (temp.cube > self.projectiles[proj]["target_dos"].cube) * temp.cube dose = self.target_dos - temp field1 = p["fields"][0] field2 = p["fields"][1] d1 = DosCube(temp) d2 = DosCube(temp) center = pytriplib.calculate_dose_center(p["target_dos"].cube) dose.cube[dose.cube < 0] = 0 temp.cube *= self.target_dos.cube > 0 basis = get_basis_from_angles(field1.get_gantry(), field1.get_couch())[0] basis = np.array([ basis[0] / dose.pixel_size, basis[1] / dose.pixel_size, basis[2] / dose.slice_distance ]) basis = basis / np.max(np.abs(basis)) * .5 d1.cube = pytriplib.create_field_shadow( dose.cube, temp.cube, np.array(basis, dtype=np.double)) basis = get_basis_from_angles(field2.get_gantry(), field2.get_couch())[0] basis = np.array([ basis[0] / dose.pixel_size, basis[1] / dose.pixel_size, basis[2] / dose.slice_distance ]) basis /= np.max(np.abs(basis)) d2.cube = pytriplib.create_field_shadow( dose.cube, temp.cube, np.array(basis, dtype=np.double)) a = d2.cube > d1.cube b = d2.cube < d1.cube d2.cube = p["target_dos"].cube * a d1.cube = p["target_dos"].cube * b rest = p["target_dos"].cube * ((a + b) < 1) b = pytriplib.split_by_plane(rest, center, basis) d1.cube += b d2.cube += rest - b self.plan.add_dose(d1, "H1") self.plan.add_dose(d2, "H2") self.projectiles[field1.get_projectile() + str(1)] = { "target_dos": d1, "fields": [field1], "name": field1.get_projectile() + str(1), "projectile": field1.get_projectile() } self.projectiles[field2.get_projectile() + str(2)] = { "target_dos": d2, "fields": [field2], "name": field2.get_projectile() + str(2), "projectile": field2.get_projectile() } del self.projectiles[self.split_proj_key]
def load_dose(self, path, t, target_dose=0.0): dos = DosCube() dos.read(os.path.splitext(path)[0] + ".dos") d = DoseCube(dos, t) d.set_dose(target_dose) self.add_dose(d)