tfms[viewname] = arim.im.tfm.tfm_for_view(frame, grid, view, fillvalue=0.0, interpolation="nearest") # %% Plot TFM reference_rect = conf["reference_rect"] if reference_rect is None: reference_area = None else: reference_area = grid.points_in_rectbox(**reference_rect) # dynamic dB scale: scale = aplt.common_dynamic_db_scale([tfm.res for tfm in tfms.values()], reference_area, db_range=40.0) for i, (viewname, tfm) in enumerate(tfms.items()): assert tfm.grid is grid ref_db, clim = next(scale) if reference_rect is None: patches = None else: patches = [ mpl.patches.Rectangle( (reference_rect["xmin"], reference_rect["zmin"]), reference_rect["xmax"] - reference_rect["xmin"], reference_rect["zmax"] - reference_rect["zmin"],
def model_full(dataset_name, use_multifreq, full_tfm=True): # %% conf = arim.io.load_conf(dataset_name) result_dir = conf["result_dir"] logger.info(f"dataset_name: {dataset_name}") probe = common.load_probe(conf) examination_object = arim.io.block_in_immersion_from_conf(conf) tx, rx = arim.ut.fmc(probe.numelements) numscanlines = len(tx) scatterers = common.defect_oriented_point(conf) grid = common.grid_near_defect(conf) grid_p = grid.to_oriented_points() probe_p = probe.to_oriented_points() views = bim.make_views( examination_object, probe_p, scatterers, max_number_of_reflection=1, tfm_unique_only=True, ) views_imaging = bim.make_views( examination_object, probe_p, grid_p, max_number_of_reflection=1, tfm_unique_only=True, ) arim.ray.ray_tracing(views.values(), convert_to_fortran_order=True) arim.ray.ray_tracing(views_imaging.values(), convert_to_fortran_order=True) if full_tfm: grid_large = common.make_grid_tfm(conf) grid_large_p = grid_large.to_oriented_points() views_imaging_large = bim.make_views( examination_object, probe_p, grid_large_p, max_number_of_reflection=1, tfm_unique_only=True, ) arim.ray.ray_tracing(views_imaging_large.values(), convert_to_fortran_order=True) if use_multifreq: multifreq_key = "multif" multifreq_key_title = "MultiFreq" else: multifreq_key = "singlef" multifreq_key_title = "SingleFreq" # %% Toneburst and time vector max_delay = max( (view.tx_path.rays.times.max() + view.rx_path.rays.times.max() for view in views.values())) numcycles = conf["model"]["toneburst"]["numcycles"] centre_freq = common.get_centre_freq(conf, probe) dt = 0.25 / centre_freq # to adjust so that the whole toneburst is sampled _tmax = max_delay + 4 * numcycles / centre_freq numsamples = scipy.fftpack.next_fast_len(math.ceil(_tmax / dt)) time = arim.Time(0.0, dt, numsamples) freq_array = np.fft.rfftfreq(len(time), dt) numfreq = len(freq_array) toneburst = arim.model.make_toneburst(numcycles, centre_freq, dt, numsamples, wrap=True) toneburst *= 1.0 / np.abs(hilbert(toneburst)[0]) toneburst_f = np.fft.rfft(toneburst) # plot toneburst plt.figure(figsize=(10, 5)) plt.subplot(1, 2, 1) plt.plot(1e6 * time.samples, toneburst) plt.title("toneburst (time domain)") plt.xlabel("time (µs)") plt.subplot(1, 2, 2) plt.plot(1e-6 * np.fft.rfftfreq(len(toneburst), dt), abs(toneburst_f)) plt.title("toneburst (frequency domain)") plt.xlabel("frequency (MHz)") # %% Compute transfer function numangles_for_scat_precomp = 180 # 0 to disable model_options = dict( probe_element_width=probe.dimensions.x[0], numangles_for_scat_precomp=numangles_for_scat_precomp, ) scat_obj = arim.scat.scat_factory( material=examination_object.block_material, **conf["scatterer"]["specs"]) scat_angle = np.deg2rad(conf["scatterer"]["angle_deg"]) transfer_function_f = np.zeros((numscanlines, numfreq), np.complex_) tfms = OrderedDict() if full_tfm: tfms_large = OrderedDict() else: tfms_large = None if use_multifreq: # Multi frequency model transfer_function_iterator = bim.multifreq_scat_transfer_functions( views, tx, rx, freq_array=freq_array, scat_obj=scat_obj, scat_angle=scat_angle, **model_options, ) else: # Single frequency model transfer_function_iterator = bim.singlefreq_scat_transfer_functions( views, tx, rx, freq_array=freq_array, scat_obj=scat_obj, scat_angle=scat_angle, **model_options, frequency=common.get_centre_freq(conf, probe), ) with arim.helpers.timeit("Main loop"): for viewname, partial_transfer_func in transfer_function_iterator: transfer_function_f += partial_transfer_func # imaging: partial_response = arim.signal.rfft_to_hilbert( partial_transfer_func * toneburst_f, numsamples) partial_frame = arim.Frame(partial_response, time, tx, rx, probe, examination_object) tfms[viewname] = arim.im.tfm.tfm_for_view( partial_frame, grid, views_imaging[viewname], interpolation=common.TFM_FINE_INTERP, fillvalue=0.0, ) if full_tfm: tfms_large[viewname] = arim.im.tfm.tfm_for_view( partial_frame, grid_large, views_imaging_large[viewname], fillvalue=0.0, ) # %% Save raw TFM results if save: with open(result_dir / f"tfm_{multifreq_key}.pickle", "wb") as f: pickle.dump(tfms, f, pickle.HIGHEST_PROTOCOL) if full_tfm: with open(result_dir / f"tfm_{multifreq_key}_large.pickle", "wb") as f: pickle.dump(tfms_large, f, pickle.HIGHEST_PROTOCOL) # %% Measure TFM intensities tmp = [] scatterer_idx = grid.closest_point(*scatterers.points[0]) for viewname, tfm in tfms.items(): max_tfm_idx = np.argmax(np.abs(tfm.res)) tmp.append(( viewname, np.abs(tfm.res.flat[scatterer_idx]), np.abs(tfm.res.flat[max_tfm_idx]), grid.x.flat[max_tfm_idx], grid.y.flat[max_tfm_idx], grid.z.flat[max_tfm_idx], )) intensities_df = pd.DataFrame( tmp, columns=[ "view", f"Model_{multifreq_key_title}_Centre", f"Model_{multifreq_key_title}_Max", "x_max_intensity", "y_max_intensity", "z_max_intensity", ], ).set_index("view") if save: intensities_df.to_csv( str(result_dir / f"intensities_{multifreq_key}_unscaled.csv")) # %% Plot TFM (defect only) scale_tfm = aplt.common_dynamic_db_scale( [tfm.res for tfm in tfms.values()]) # scale_tfm = itertools.repeat((None, None)) ncols = 6 fig, axes = plt.subplots( ncols=ncols, nrows=math.ceil(len(tfms) / ncols), figsize=(16, 9), sharex=True, sharey=True, ) for (viewname, tfm), ax in zip(tfms.items(), axes.ravel()): ref_db, clim = next(scale_tfm) aplt.plot_tfm( tfm, ax=ax, scale="db", ref_db=ref_db, clim=clim, interpolation="none", savefig=False, ) ax.set_title(viewname) if ax in axes[-1, :]: ax.set_xlabel("x (mm)") else: ax.set_xlabel("") if ax in axes[:, 0]: ax.set_ylabel("z (mm)") else: ax.set_ylabel("") amp = intensities_df.loc[viewname] ax.plot(amp["x_max_intensity"], amp["z_max_intensity"], "1m") ax.plot(scatterers.points.x, scatterers.points.z, "dm") fig.savefig(str(result_dir / f"tfm_model_{multifreq_key}")) # %% return tfms, tfms_large, intensities_df
def locate_artefact(dataset_name, save): # %% conf = arim.io.load_conf(dataset_name) # conf['grid']['pixel_size'] = 2e-3 # debug conf["grid"]["pixel_size"] = 0.5e-3 # hardcode to make faster aplt.conf["savefig"] = False result_dir = conf["result_dir"] logger.info(f"dataset_name: {dataset_name}") # Load frame frame = common.load_frame(conf, apply_filter=True, expand=True) # Make grid z_backwall = conf["backwall"]["z"] assert not np.isnan(z_backwall) grid = common.make_grid_tfm(conf) grid_p = grid.to_oriented_points() probe_p = frame.probe.to_oriented_points() # Make views views = bim.make_views( frame.examination_object, probe_p, grid_p, tfm_unique_only=True, max_number_of_reflection=1, ) # %% Plot Bscan bscan_ax, _ = aplt.plot_bscan_pulse_echo(frame, clim=[-60, -20], interpolation="bilinear") bscan_ax.figure.canvas.set_window_title("Bscan") # %% Perform ray tracing arim.ray.ray_tracing(views.values(), convert_to_fortran_order=True) # %% Run TFM tfms = OrderedDict() for i, view in enumerate(views.values()): with arim.helpers.timeit("TFM {}".format(view.name), logger=logger): tfms[view.name] = arim.im.tfm.tfm_for_view(frame, grid, view, fillvalue=0.0) # %% Plot all TFM try: reference_rect = common.reference_rect(conf) reference_area = grid.points_in_rectbox(**reference_rect) except common.NoDefect: reference_rect = None reference_area = None if USE_DYNAMIC_SCALE: scale = aplt.common_dynamic_db_scale( [tfm.res for tfm in tfms.values()], reference_area) else: scale = itertools.repeat((None, None)) tfm_axes = {} ncols = 3 nrows = 7 fig, axes = plt.subplots(ncols=ncols, nrows=nrows, figsize=(9, 12), sharex=False, sharey=False) xmin = grid.xmin xmax = grid.xmax zmin = conf["frontwall"]["z"] zmax = conf["backwall"]["z"] for i, ((viewname, tfm), ax) in enumerate(zip(tfms.items(), axes.ravel())): ref_db, clim = next(scale) clim = [-40, 0.0] ax, im = aplt.plot_tfm( tfm, ax=ax, scale="db", ref_db=ref_db, clim=clim, interpolation="none", savefig=False, draw_cbar=False, ) ax.set_title(viewname, y=0.9, size="small") ax.set_adjustable("box") ax.axis([xmin, xmax, zmax, zmin]) tfm_axes[viewname] = ax if ax in axes[-1, :]: ax.set_xlabel("x (mm)") ax.set_xticks( [xmin, xmax, np.round((xmin + xmax) / 2, decimals=3)]) else: ax.set_xlabel("") ax.set_xticks([]) if ax in axes[:, 0]: ax.set_ylabel("z (mm)") ax.set_yticks( [zmax, zmin, np.round((zmin + zmax) / 2, decimals=3)]) else: ax.set_ylabel("") ax.set_yticks([]) cbar = fig.colorbar(im, ax=axes.ravel().tolist(), location="top", fraction=0.05, aspect=40, pad=0.03) cbar.ax.set_ylabel("dB") ax.figure.canvas.set_window_title(f"TFMs") return bscan_ax, tfm_axes, tfms, views
def plot_tfms( dataset_name, tfms, save, suffix, is_paper=False, noshow=False, db_range=40.0 ): """ Plot TFMs and save them in result directory """ conf = arim.io.load_conf(dataset_name) result_dir = conf["result_dir"] if is_paper: style_context = mpl.style.context("to_pdf.mplstyle") figsize = (5, 2.5) use_cbar = False title = None interpolation = "none" else: style_context = contextlib.suppress() # nullcontext figsize = (10, 5) use_cbar = True interpolation = None # get an element tfm = next(iter(tfms.values())) grid = tfm.grid try: reference_rect = common.reference_rect(conf) reference_area = grid.points_in_rectbox(**reference_rect) except common.NoDefect: reference_rect = None reference_area = None if USE_DYNAMIC_SCALE: scale = aplt.common_dynamic_db_scale( [tfm.res for tfm in tfms.values()], reference_area, db_range=db_range ) else: scale = itertools.repeat((None, [-db_range, 0.0])) with style_context: for i, (viewname, tfm) in enumerate(tfms.items()): assert tfm.grid is grid ref_db, clim = next(scale) if PLOT_DEFECT_BOX and reference_rect is not None: patches = [common.rect_to_patch(reference_rect)] else: patches = None if not (is_paper): title = f"TFM {viewname}" ax, _ = aplt.plot_tfm( tfm, clim=clim, scale="db", ref_db=ref_db, title=title, savefig=False, figsize=figsize, patches=patches, draw_cbar=use_cbar, interpolation=interpolation, ) ax.set_adjustable("box") ax.axis([grid.xmin, grid.xmax, grid.zmax, 0]) if save: ax.figure.savefig(str(result_dir / f"tfm_{i:02}_{viewname}{suffix}")) if noshow: plt.close(ax.figure) if noshow: plt.close("all") else: plt.show()
def measure_tfm_intensity(dataset_name, save, noshow=False): conf = arim.io.load_conf(dataset_name) result_dir = conf["result_dir"] logger.info(f"dataset_name: {dataset_name}") frame = common.load_frame(conf, apply_filter=True, expand=True) grid = common.grid_near_defect(conf) grid_p = grid.to_oriented_points() probe_p = frame.probe.to_oriented_points() views = bim.make_views( frame.examination_object, probe_p, grid_p, max_number_of_reflection=1, tfm_unique_only=True, ) views = common.filter_views(views, conf) # %% arim.ray.ray_tracing(views.values(), convert_to_fortran_order=True) # %% Run TFM tfms = dict() for viewname, view in views.items(): tfms[viewname] = arim.im.tfm.tfm_for_view( frame, grid, view, interpolation=common.TFM_FINE_INTERP, fillvalue=np.nan) # %% Save raw TFM results if save: with open(result_dir / "tfm_experimental.pickle", "wb") as f: # Pickle the 'data' dictionary using the highest protocol available. pickle.dump(tfms, f, pickle.HIGHEST_PROTOCOL) # %% Plot scale_tfm = aplt.common_dynamic_db_scale( [tfm.res for tfm in tfms.values()]) # scale_tfm = itertools.repeat((None, None)) ncols = 6 fig, axes = plt.subplots( ncols=ncols, nrows=math.ceil(len(tfms) / ncols), figsize=(16, 9), sharex=True, sharey=True, ) for (viewname, tfm), ax in zip(tfms.items(), axes.ravel()): ref_db, clim = next(scale_tfm) aplt.plot_tfm( tfm, ax=ax, scale="db", ref_db=ref_db, clim=clim, interpolation="none", savefig=False, ) ax.set_title(viewname) if ax in axes[-1, :]: ax.set_xlabel("x (mm)") else: ax.set_xlabel("") if ax in axes[:, 0]: ax.set_ylabel("z (mm)") else: ax.set_ylabel("") if save: fig.savefig(str(result_dir / "tfm_near_defect")) if noshow: plt.close("all") else: plt.show() # %% Measure amplitudes and save and save as csv data = [] for viewname, tfm in tfms.items(): data.append((viewname, np.max(np.abs(tfm.res)))) intensities = pd.DataFrame(data, columns=("view", "Experimental")).set_index("view") if save: intensities.to_csv(result_dir / "intensities_experimental.csv") return tfms, intensities