def read_bin_file(file_name): """ read sinogram from binary file Return sinogram np.array produced by reading an Accuray sinogram BIN file with the provided file name. Parameters ---------- file_name : str long file name of csv file Returns ------- sinogram : np.array Notes ----- BIN files are sinograms stored in binary format used in Tomotherapy calibration plans. """ leaf_open_times = np.fromfile(file_name, dtype=float, count=-1, sep="") num_leaves = 64 num_projections = int(len(leaf_open_times) / num_leaves) sinogram = np.reshape(leaf_open_times, (num_projections, num_leaves)) return sinogram
def reduce_expanded_mask(expanded_mask, img_size, expansion): return np.mean( np.mean( np.reshape(expanded_mask, (img_size, expansion, img_size, expansion)), axis=1, ), axis=2, )
def get_interpolated_dose(coords_grid, dose_interpolation): coords_grid_ij_indexing = np.array([ np.ravel(coords_grid[:, :, 1]), np.ravel(coords_grid[:, :, 0]), np.ravel(coords_grid[:, :, 2]), ]).T interpolated_dose = dose_interpolation(coords_grid_ij_indexing) coords_dim = np.shape(coords_grid) interpolated_dose = np.reshape(interpolated_dose, (coords_dim[0], coords_dim[1])) return interpolated_dose
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 create_point_combination(coords): mesh_index = np.meshgrid(*coords) point_combination = np.reshape(np.array(mesh_index), (3, -1)) return point_combination
def gamma_shell( axes_reference, dose_reference, axes_evaluation, dose_evaluation, dose_percent_threshold, distance_mm_threshold, lower_percent_dose_cutoff=20, interp_fraction=10, max_gamma=None, local_gamma=False, global_normalisation=None, skip_once_passed=False, random_subset=None, ram_available=DEFAULT_RAM, quiet=False, ): """Compare two dose grids with the gamma index. It computes 1, 2, or 3 dimensional gamma with arbitrary gird sizes while interpolating on the fly. This function makes use of some of the ideas presented within <http://dx.doi.org/10.1118/1.2721657>. Parameters ---------- axes_reference : tuple The reference coordinates. dose_reference : np.array The reference dose grid. Each point in the reference grid becomes the centre of a Gamma ellipsoid. For each point of the reference, nearby evaluation points are searched at increasing distances. axes_evaluation : tuple The evaluation coordinates. dose_evaluation : np.array The evaluation dose grid. Evaluation here is defined as the grid which is interpolated and searched over at increasing distances away from each reference point. dose_percent_threshold : float The percent dose threshold distance_mm_threshold : float The gamma distance threshold. Units must match of the coordinates given. lower_percent_dose_cutoff : float, optional The percent lower dose cutoff below which gamma will not be calculated. This is only applied to the reference grid. interp_fraction : float, optional The fraction which gamma distance threshold is divided into for interpolation. Defaults to 10 as recommended within <http://dx.doi.org/10.1118/1.2721657>. If a 3 mm distance threshold is chosen this default value would mean that the evaluation grid is interpolated at a step size of 0.3 mm. max_gamma : float, optional The maximum gamma searched for. This can be used to speed up calculation, once a search distance is reached that would give gamma values larger than this parameter, the search stops. Defaults to :obj:`np.inf` local_gamma Designates local gamma should be used instead of global. Defaults to False. global_normalisation : float, optional The dose normalisation value that the percent inputs calculate from. Defaults to the maximum value of :obj:`dose_reference`. random_subset : int, optional Used to only calculate a random subset of the reference grid. The number chosen is how many random points to calculate. ram_available : int, optional The number of bytes of RAM available for use by this function. Defaults to 0.8 times your total RAM as determined by psutil. quiet : bool, optional Used to quiet informational printing during function usage. Defaults to False. Returns ------- gamma The array of gamma values the same shape as that given by the reference coordinates and dose. """ if max_gamma is None: max_gamma = np.inf options = GammaInternalFixedOptions.from_user_inputs( axes_reference, dose_reference, axes_evaluation, dose_evaluation, dose_percent_threshold, distance_mm_threshold, lower_percent_dose_cutoff, interp_fraction, max_gamma, local_gamma, global_normalisation, skip_once_passed, random_subset, ram_available, quiet, ) if not options.quiet: if options.local_gamma: print("Calcing using local normalisation point for gamma") else: print("Calcing using global normalisation point for gamma") print("Global normalisation set to {}".format( options.global_normalisation)) print("Global dose threshold set to {} ({}% of normalisation)".format( options.global_dose_threshold, options.dose_percent_threshold)) print("Distance threshold set to {}".format( options.distance_mm_threshold)) print("Lower dose cutoff set to {} ({}% of normalisation)".format( options.lower_dose_cutoff, lower_percent_dose_cutoff)) print("") current_gamma = gamma_loop(options) gamma = {} for i, dose_threshold in enumerate(options.dose_percent_threshold): for j, distance_threshold in enumerate(options.distance_mm_threshold): key = (dose_threshold, distance_threshold) gamma_temp = current_gamma[:, i, j] gamma_temp = np.reshape(gamma_temp, np.shape(dose_reference)) gamma_temp[np.isinf(gamma_temp)] = np.nan with np.errstate(invalid="ignore"): gamma_greater_than_ref = gamma_temp > max_gamma gamma_temp[gamma_greater_than_ref] = max_gamma gamma[key] = gamma_temp if not options.quiet: print("\nComplete!") if len(gamma.keys()) == 1: gamma = next(iter(gamma.values())) return gamma