def calculate_projection(self, voi, gantry, couch, calculate_from=0, stepsize=1.0): """ TODO: documentation :param Voi voi: tumortarget, type is Voi :param float gantry: angle in degrees :param float couch: angle in degrees :param int calculate_from: 0 is mass center 1 is the most distant point in the tumor from the beamaxis :param float stepsize: relative to pixelsize, 1 is a step of 1 pixel :return: """ # min_structure = 5 TODO why not used ? basis = get_basis_from_angles(gantry, couch) # Convert angles from degrees to radians gantry /= 180.0 / np.pi couch /= 180.0 / np.pi # calculate surface normal step_vec = -stepsize * self.cube.pixel_size * np.array(basis[0]) step_length = stepsize * self.cube.pixel_size center = voi.calculate_center() # ~ (b,c) = self.calculate_plane_vectors(gantry,couch) b = basis[1] c = basis[2] min_window, max_window = voi.get_min_max() size = np.array(max_window) - np.array(min_window) window_size = np.array([((sin(couch) * size[1])**2 + (cos(couch) * size[2])**2)**0.5, ((sin(gantry) * size[0])**2 + (cos(gantry) * size[1])**2 + (sin(couch) * size[2])**2)**0.5]) * 2 dimension = window_size / self.cube.pixel_size dimension = np.int16(dimension) start = center - self.cube.pixel_size * 0.5 * np.array( dimension[0] * b + dimension[1] * c) if calculate_from is 1: start = self.calculate_back_start_voi(voi, start, step_vec) if calculate_from is 2: start = self.calculate_front_start_voi(voi, start, step_vec) data = pytriplib.calculate_wepl( self.cube.cube, np.array(start), np.array(basis) * step_length, dimension, np.array([ self.cube.pixel_size, self.cube.pixel_size, self.cube.slice_distance ])) data *= step_length return data, start, [b, c]
def analyse_cube(self): keys = self.projectiles.keys() p1 = self.projectiles[keys[0]] p2 = self.projectiles[keys[1]] cube1 = p1["target_dos"] cube2 = p2["target_dos"] if not self.cube_in_other_cube(cube1, cube2): temp = p1 p1 = p2 p2 = temp cube1 = p1["target_dos"] cube2 = p2["target_dos"] self.execute_order = [keys[0], keys[1]] self.split_proj_key = keys[1] else: self.execute_order = [keys[1], keys[0]] self.split_proj_key = keys[0] target_cube = copy.deepcopy(cube1) shadow_cubes = [] for i, field in enumerate(p1["fields"]): d = DosCube(cube1) basis = get_basis_from_angles(field.get_gantry(), field.get_couch()) basis = basis[0] basis = np.array([ basis[0] / cube1.pixel_size, basis[1] / cube1.pixel_size, basis[2] / cube1.slice_distance ]) basis /= np.max(np.abs(basis)) d.cube = pytriplib.create_field_shadow( cube1.cube, cube2.cube, np.array(basis, dtype=np.double)) target_cube -= d shadow_cubes.append(d) target_cube.cube[target_cube.cube < 0] = 0 cube2.cube = cube2.cube + target_cube.cube # ~ cube2.cube = pytriplib.extend_cube(cube2.cube) cube1.cube = cube1.cube - target_cube.cube if len(p1["fields"]) == 2: a = self.execute_order.pop(1) b = self.projectile_dose_level[a] self.execute_order.append(a + str(1)) self.execute_order.append(a + str(2)) self.projectile_dose_level[a + str(1)] = b self.projectile_dose_level[a + str(2)] = b
def calculate_projection(self, voi, gantry, couch, calculate_from=0, stepsize=1.0): """ TODO: documentation :param Voi voi: tumortarget, type is Voi :param float gantry: angle in degrees :param float couch: angle in degrees :param int calculate_from: 0 is mass center 1 is the most distant point in the tumor from the beamaxis :param float stepsize: relative to pixelsize, 1 is a step of 1 pixel :return: """ # min_structure = 5 TODO why not used ? basis = get_basis_from_angles(gantry, couch) # Convert angles from degrees to radians gantry /= 180.0 / np.pi couch /= 180.0 / np.pi # calculate surface normal step_vec = -stepsize * self.cube.pixel_size * np.array(basis[0]) step_length = stepsize * self.cube.pixel_size center = voi.calculate_center() # ~ (b,c) = self.calculate_plane_vectors(gantry,couch) b = basis[1] c = basis[2] min_window, max_window = voi.get_min_max() size = np.array(max_window) - np.array(min_window) window_size = np.array([((sin(couch) * size[1])**2 + (cos(couch) * size[2])**2)**0.5, ( (sin(gantry) * size[0])**2 + (cos(gantry) * size[1])**2 + (sin(couch) * size[2])**2)**0.5]) * 2 dimension = window_size / self.cube.pixel_size dimension = np.int16(dimension) start = center - self.cube.pixel_size * 0.5 * np.array(dimension[0] * b + dimension[1] * c) if calculate_from == 1: start = self.calculate_back_start_voi(voi, start, step_vec) elif calculate_from == 2: start = self.calculate_front_start_voi(voi, start, step_vec) data = pytriplib.calculate_wepl( self.cube.cube, np.array(start), np.array(basis) * step_length, dimension, np.array([self.cube.pixel_size, self.cube.pixel_size, self.cube.slice_distance])) data *= step_length return data, start, [b, c]
def get_cube_basis(self): return get_basis_from_angles(self.gantry_angle, self.couch_angle)
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]