def create_bb_points_function(bb_diameter): max_distance = bb_diameter * 0.5 min_distance = 0 num_steps = 11 min_dist_between_points = (max_distance - min_distance) / num_steps distances = np.arange(min_distance, max_distance + min_dist_between_points, min_dist_between_points) x = [] y = [] dist = [] for _, distance in enumerate(distances): ( new_x, new_y, ) = pymedphys._utilities.createshells.calculate_coordinates_shell_2d( # pylint: disable = protected-access distance, min_dist_between_points) x.append(new_x) y.append(new_y) dist.append(distance * np.ones_like(new_x)) x = np.concatenate(x) y = np.concatenate(y) dist = np.concatenate(dist) def points_to_check(bb_centre): x_shifted = x + bb_centre[0] y_shifted = y + bb_centre[1] return x_shifted, y_shifted return points_to_check, dist
def apply_negative(column): result = np.ones_like(column).astype(np.float64) * np.nan negative_values = column.values > 2**15 result[negative_values] = column[negative_values] - 2**16 result[np.invert(negative_values)] = column[np.invert(negative_values)] if np.any(np.isnan(result)): raise Exception("Not all column values were converted") return result
def gamma_filter_brute_force(axes_reference, dose_reference, axes_evaluation, dose_evaluation, distance_mm_threshold, dose_threshold, lower_dose_cutoff=0, **_): xx_ref, yy_ref, zz_ref = np.meshgrid(*axes_reference, indexing="ij") gamma_array = np.ones_like(dose_evaluation).astype(np.float) * np.nan mesh_index = np.meshgrid( *[np.arange(len(coord_eval)) for coord_eval in axes_evaluation]) eval_index = np.reshape(np.array(mesh_index), (3, -1)) run_index = np.arange(np.shape(eval_index)[1]) np.random.shuffle(run_index) sys.stdout.write(" ") for counter, point_index in enumerate(run_index): i, j, k = eval_index[:, point_index] eval_x = axes_evaluation[0][i] eval_y = axes_evaluation[1][j] eval_z = axes_evaluation[2][k] if dose_evaluation[i, j, k] < lower_dose_cutoff: continue distance = np.sqrt((xx_ref - eval_x)**2 + (yy_ref - eval_y)**2 + (zz_ref - eval_z)**2) dose_diff = dose_evaluation[i, j, k] - dose_reference gamma = np.min( np.sqrt((dose_diff / dose_threshold)**2 + (distance / distance_mm_threshold)**2)) gamma_array[i, j, k] = gamma if counter // 30 == counter / 30: percent_pass = str( np.round(calculate_pass_rate(gamma_array), decimals=1)) sys.stdout.write( "\rPercent Pass: {0}% | Percent Complete: {1:.2f}%".format( percent_pass, counter / np.shape(eval_index)[1] * 100)) sys.stdout.flush() return calculate_pass_rate(gamma_array)
def apply_transform(xx, yy, transform): xx = np.array(xx, copy=False) yy = np.array(yy, copy=False) xx_flat = np.ravel(xx) transformed = transform @ np.vstack( [xx_flat, np.ravel(yy), np.ones_like(xx_flat)]) xx_transformed = transformed[0] yy_transformed = transformed[1] xx_transformed.shape = xx.shape yy_transformed.shape = yy.shape return xx_transformed, yy_transformed
def _calc_blocked_t(travel_diff, grid_resolution): blocked_t = np.ones_like(travel_diff) * np.nan fully_blocked = travel_diff <= -grid_resolution / 2 fully_open = travel_diff >= grid_resolution / 2 blocked_t[fully_blocked] = 1 blocked_t[fully_open] = 0 transient = ~fully_blocked & ~fully_open blocked_t[transient] = (-travel_diff[transient] + grid_resolution / 2) / grid_resolution assert np.all(~np.isnan(blocked_t)) return blocked_t
def format_coords_for_dicom(all_merged): dicom_format_coords_by_z = {} for z, merged in all_merged.items(): coords = get_coords_from_polygon_or_multipolygon(merged) new_contour_data = [] for coord in coords: stacked_coords = np.hstack( list(zip(coord[0], coord[1], z * np.ones_like(coord[1])))) stacked_coords = np.round(stacked_coords, 1) stacked_coords = stacked_coords.tolist() new_contour_data.append(stacked_coords) dicom_format_coords_by_z[z] = new_contour_data return dicom_format_coords_by_z
def calculate_coordinates_shell_3d(distance, distance_step_size): """Create points along the surface of a sphere (a shell) where no gap between points is larger than the defined distance_step_size""" number_of_rows = np.ceil(np.pi * distance / distance_step_size).astype(int) + 1 elevation = np.linspace(0, np.pi, number_of_rows) row_radii = distance * np.sin(elevation) row_circumference = 2 * np.pi * row_radii amount_in_row = np.ceil(row_circumference / distance_step_size).astype(int) + 1 x_coords = [] y_coords = [] z_coords = [] for i, phi in enumerate(elevation): azimuth = np.linspace(0, 2 * np.pi, amount_in_row[i] + 1)[:-1:] x_coords.append(distance * np.sin(phi) * np.cos(azimuth)) y_coords.append(distance * np.sin(phi) * np.sin(azimuth)) z_coords.append(distance * np.cos(phi) * np.ones_like(azimuth)) return (np.hstack(x_coords), np.hstack(y_coords), np.hstack(z_coords))
def calculate_min_dose_difference(options, distance, to_be_checked, distance_step_size): """Determine the minimum dose difference. Calculated for a given distance from each reference point. """ min_relative_dose_difference = np.nan * np.ones_like( options.flat_dose_reference[to_be_checked]) num_dimensions = np.shape(options.flat_mesh_axes_reference)[0] coordinates_at_distance_shell = pymedphys._utilities.createshells.calculate_coordinates_shell( # pylint: disable = protected-access distance, num_dimensions, distance_step_size) num_points_in_shell = np.shape(coordinates_at_distance_shell)[1] estimated_ram_needed = (np.uint64(num_points_in_shell) * np.uint64(np.count_nonzero(to_be_checked)) * np.uint64(32) * np.uint64(num_dimensions) * np.uint64(2)) num_slices = np.floor( estimated_ram_needed / options.ram_available).astype(int) + 1 if not options.quiet: sys.stdout.write( " | Points tested per reference point: {} | RAM split count: {}". format(num_points_in_shell, num_slices)) sys.stdout.flush() all_checks = np.where(np.ravel(to_be_checked))[0] index = np.arange(len(all_checks)) sliced = np.array_split(index, num_slices) sorted_sliced = [np.sort(current_slice) for current_slice in sliced] for current_slice in sorted_sliced: to_be_checked_sliced = np.full_like(to_be_checked, False, dtype=bool) to_be_checked_sliced[ # pylint: disable=unsupported-assignment-operation all_checks[current_slice]] = True assert np.all(to_be_checked[to_be_checked_sliced]) axes_reference_to_be_checked = options.flat_mesh_axes_reference[:, to_be_checked_sliced] evaluation_dose = interpolate_evaluation_dose_at_distance( options.evaluation_interpolation, axes_reference_to_be_checked, coordinates_at_distance_shell, ) if options.local_gamma: with np.errstate(divide="ignore"): relative_dose_difference = ( evaluation_dose - options.flat_dose_reference[to_be_checked_sliced][None, :] ) / ( options.flat_dose_reference[to_be_checked_sliced][None, :]) else: relative_dose_difference = ( evaluation_dose - options.flat_dose_reference[to_be_checked_sliced][None, :] ) / options.global_normalisation min_relative_dose_difference[current_slice] = np.min( np.abs(relative_dose_difference), axis=0) return min_relative_dose_difference