def test_make_views(): context = make_context() probe_oriented_points = context["probe_oriented_points"] scatterer_oriented_points = context["scatterer_oriented_points"] exam_obj = context["exam_obj"] views = bim.make_views(exam_obj, probe_oriented_points, scatterer_oriented_points) assert list(views.keys()) == list(context["views"].keys())
def uniform_tfm(dataset_name, save): # %% conf = arim.io.load_conf(dataset_name) # conf['grid']['pixel_size'] = 2e-3 # debug aplt.conf["savefig"] = save 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, ) views = common.filter_views(views, conf) # %% 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) # %% Save if save: with open(result_dir / "tfm_experimental_large.pickle", "wb") as f: # Pickle the 'data' dictionary using the highest protocol available. pickle.dump(tfms, f, pickle.HIGHEST_PROTOCOL) return tfms
def model_sensitivity(dataset_name, save): # %% 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) model_options = dict( frequency=common.get_centre_freq(conf, probe), probe_element_width=probe.dimensions.x[0], ) grid_p = common.defect_oriented_point(conf) probe_p = probe.to_oriented_points() views = 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) scat_obj = arim.scat.scat_factory( **conf["scatterer"]["specs"], material=examination_object.block_material) scat_angle = np.deg2rad(conf["scatterer"]["angle_deg"]) with arim.helpers.timeit("Scattering matrices", logger=logger): # scat_mat = scat_obj.as_single_freq_matrices(model_options['frequency'], 360) # use precomputation scat_mat = scat_obj.as_angles_funcs( model_options["frequency"]) # no precomputation with arim.helpers.timeit("Computation of ray weights for all paths", logger=logger): ray_weights = bim.ray_weights_for_views(views, **model_options) theoretical_intensities_dict = dict() scanline_weights = np.ones(numscanlines) for viewname, view in views.items(): model_coefficients = arim.model.model_amplitudes_factory( tx.astype(int), rx.astype(int), view, ray_weights, scat_mat, scat_angle=scat_angle, ) # shape: numpoints, numscanlines theoretical_intensities_dict[ viewname] = model_coefficients.sensitivity_uniform_tfm( scanline_weights) # ax, _ = aplt.plot_oxz(np.abs(theoretical_intensities_dict[viewname]), grid, scale='linear', title=viewname) # %% data = [] for viewname, th_amp in theoretical_intensities_dict.items(): data.append((viewname, np.abs(th_amp[0]))) intensities = pd.DataFrame(data, columns=("view", "Model_Sensitivity")).set_index("view") if save: intensities.to_csv(result_dir / "intensities_sensitivity_unscaled.csv") # %% return intensities
def compute_sensitivity(dataset_name, save): conf = arim.io.load_conf(dataset_name) result_dir = conf["result_dir"] probe = arim.io.probe_from_conf(conf) examination_object = arim.io.block_in_immersion_from_conf(conf) tx, rx = arim.ut.fmc(probe.numelements) numscanlines = len(tx) model_options = dict( frequency=probe.frequency, probe_element_width=probe.dimensions.x[0] ) tic = time.time() grid = arim.io.grid_from_conf(conf) grid_p = grid.to_oriented_points() logger.info(f"grid numpoints: {grid.numpoints}") probe_p = probe.to_oriented_points() views = bim.make_views( examination_object, probe_p, grid_p, max_number_of_reflection=1, tfm_unique_only=True, ) aplt.plot_interfaces( [probe_p, examination_object.frontwall, examination_object.backwall, grid_p], show_orientations=False, show_last=True, # markers=[".", "-", "-"], filename=str(result_dir / "interfaces"), savefig=save, ) arim.ray.ray_tracing(views.values(), convert_to_fortran_order=True) scat_obj = arim.scat.scat_factory( **conf["scatterer"]["specs"], material=examination_object.block_material ) scat_angle = np.deg2rad(conf["scatterer"]["angle_deg"]) with arim.helpers.timeit("Scattering matrices", logger=logger): scat_mat = scat_obj.as_single_freq_matrices( model_options["frequency"], 180 ) # use precomputation with arim.helpers.timeit("Computation of ray weights for all paths", logger=logger): ray_weights = bim.ray_weights_for_views(views, **model_options) sensitivity_images_dict = dict() scanline_weights = np.ones(numscanlines) for viewname, view in views.items(): model_coefficients = arim.model.model_amplitudes_factory( tx.astype(int), rx.astype(int), view, ray_weights, scat_mat, scat_angle=scat_angle, ) sensitivity_images_dict[viewname] = model_coefficients.sensitivity_uniform_tfm( scanline_weights ) toc = time.time() elapsed = toc - tic logger.info( f"Total time for sensitivity images: {elapsed:.2f} s ({grid.numpoints} points)" ) # %% out = {"images": sensitivity_images_dict, "grid": grid} with open(result_dir / "sensitivity_images.pickle", "wb") as f: pickle.dump(out, f, pickle.HIGHEST_PROTOCOL) return sensitivity_images_dict
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
[ probe.to_oriented_points(), examination_object.frontwall, examination_object.backwall, scatterer, grid_p, ], show_last=False, markers=[".", "-", "-", "d", ".k"], ) #%% Ray tracing for scatterer views = bim.make_views( examination_object, probe.to_oriented_points(), scatterer, max_number_of_reflection, tfm_unique_only, ) # views = {viewname: view for viewname, view in views.items() if viewname in {"L-T", "T-L"}} # debug print("Views: " + ", ".join(views.keys())) arim.ray.ray_tracing(views.values(), convert_to_fortran_order=True) #%% Ray tracing for wall echoes frontwall_path = bim.frontwall_path( examination_object.couplant_material, examination_object.block_material, *probe.to_oriented_points(), *examination_object.frontwall, )
def wall_views(conf, use_line_grids=False, wall_keys=WALL_KEYS): """ Create views for imaging walls Returns ------- grids : list of Grid views : list of Views keys: frontwall, backwall_LL, backwall_LT, backwall_LLLL """ wall_keys = set(wall_keys) unknown_wall_keys = wall_keys - WALL_KEYS if unknown_wall_keys: raise ValueError(f"Unknown wall keys: {unknown_wall_keys}") probe = common.load_probe(conf) probe_p = probe.to_oriented_points() examination_object = arim.io.examination_object_from_conf(conf) if use_line_grids: dz = 0.0 else: dz = 1.5e-3 z_backwall = conf["backwall"]["z"] grid_kwargs = dict( xmin=probe.locations.x.min(), xmax=probe.locations.x.max(), ymin=0.0, ymax=0.0, pixel_size=0.15e-3, ) grid_front = arim.geometry.Grid(**grid_kwargs, zmin=-dz, zmax=dz) grid_back = arim.geometry.Grid(**grid_kwargs, zmin=z_backwall - dz, zmax=z_backwall + dz) assert not use_line_grids or grid_front.shape[2] == 1 assert not use_line_grids or grid_back.shape[2] == 1 front_views = bim.make_views( examination_object, probe_p, grid_front.to_oriented_points(), max_number_of_reflection=0, tfm_unique_only=True, ) back_views = bim.make_views( examination_object, probe_p, grid_back.to_oriented_points(), max_number_of_reflection=2, tfm_unique_only=True, ) views = { "frontwall": front_views["L-L"], "backwall_LL": back_views["L-L"], "backwall_LT": back_views["L-T"], "backwall_LLLL": back_views["LLL-L"], } grids = { "frontwall": grid_front, "backwall_LL": grid_back, "backwall_LT": grid_back, "backwall_LLLL": grid_back, } grids = {k: v for k, v in grids.items() if k in wall_keys} views = {k: v for k, v in views.items() if k in wall_keys} return grids, views
def test_fulltime_model(use_multifreq, show_plots): # Setup couplant = arim.Material(longitudinal_vel=1480.0, density=1000.0, state_of_matter="liquid") block = arim.Material( longitudinal_vel=6320.0, transverse_vel=3130.0, density=2700.0, state_of_matter="solid", longitudinal_att=arim.material_attenuation_factory("constant", 2.0), transverse_att=arim.material_attenuation_factory("constant", 20.0), ) probe = arim.Probe.make_matrix_probe(20, 1e-3, 1, np.nan, 5e6) probe_element_width = 0.8e-3 probe.set_reference_element("first") probe.reset_position() probe.translate([0.0, 0.0, -5e-3]) probe.rotate(arim.geometry.rotation_matrix_y(np.deg2rad(10))) probe_p = probe.to_oriented_points() frontwall = arim.geometry.points_1d_wall_z(numpoints=1000, xmin=0.0e-3, xmax=40.0e-3, z=0.0, name="Frontwall") backwall = arim.geometry.points_1d_wall_z(numpoints=1000, xmin=0.0e-3, xmax=40.0e-3, z=30.0e-3, name="Backwall") scatterer_p = arim.geometry.default_oriented_points( arim.Points([[35e-3, 0.0, 20e-3]])) all_points = [probe_p, frontwall, backwall, scatterer_p] # if show_plots: # import arim.plot as aplt # aplt.plot_interfaces( # all_points, markers=["o", "o", "o", "d"], show_orientations=True # ) # aplt.plt.show() exam_obj = arim.BlockInImmersion(block, couplant, frontwall, backwall, scatterer_p) scat_obj = arim.scat.scat_factory(material=block, kind="sdh", radius=0.5e-3) scat_funcs = scat_obj.as_angles_funcs(probe.frequency) scat_angle = 0.0 tx_list, rx_list = arim.ut.fmc(probe.numelements) # Toneburst dt = 0.25 / probe.frequency # to adjust so that the whole toneburst is sampled toneburst_time, toneburst, toneburst_t0_idx = arim.model.make_toneburst2( 5, probe.frequency, dt, num_before=1) toneburst_f = np.fft.rfft(toneburst) toneburst_freq = np.fft.rfftfreq(len(toneburst_time), dt) # Allocate a long enough time vector for the timetraces views = bim.make_views( exam_obj, probe_p, scatterer_p, max_number_of_reflection=0, tfm_unique_only=False, ) arim.ray.ray_tracing(views.values()) max_delay = max( (view.tx_path.rays.times.max() + view.rx_path.rays.times.max() for view in views.values())) timetraces_time = arim.Time( 0.0, dt, math.ceil(max_delay / dt) + len(toneburst_time)) timetraces = None # Run model if use_multifreq: model_freq_array = toneburst_freq else: model_freq_array = probe.frequency transfer_function_iterator = bim.scat_unshifted_transfer_functions( views, tx_list, rx_list, model_freq_array, scat_obj, probe_element_width=probe_element_width, use_directivity=True, use_beamspread=True, use_transrefl=True, use_attenuation=True, scat_angle=scat_angle, numangles_for_scat_precomp=120, ) for unshifted_transfer_func, delays in transfer_function_iterator: timetraces = arim.model.transfer_func_to_timetraces( unshifted_transfer_func, delays, timetraces_time, toneburst_time, toneburst_freq, toneburst_f, toneburst_t0_idx, timetraces=timetraces, ) frame = arim.Frame(timetraces, timetraces_time, tx_list, rx_list, probe, exam_obj) if show_plots: import matplotlib.pyplot as plt import arim.plot as aplt aplt.plot_bscan_pulse_echo(frame) plt.title( f"test_fulltime_model - Bscan - use_multifreq={use_multifreq}") tx = 0 rx = probe.numelements - 1 plt.figure() plt.plot(np.real(frame.get_timetrace(tx, rx)), label=f"tx={tx}, rx={rx}") plt.plot(np.real(frame.get_timetrace(rx, tx)), label=f"tx={rx}, rx={tx}") plt.title(f"test_fulltime_model - use_multifreq={use_multifreq}") plt.legend() plt.show()
def test_model(scat_specs, show_plots): couplant = arim.Material( longitudinal_vel=1480.0, density=1000.0, state_of_matter="liquid", longitudinal_att=arim.material_attenuation_factory("constant", 1.0), ) block = arim.Material( longitudinal_vel=6320.0, transverse_vel=3130.0, density=2700.0, state_of_matter="solid", longitudinal_att=arim.material_attenuation_factory("constant", 2.0), transverse_att=arim.material_attenuation_factory("constant", 3.0), ) probe = arim.Probe.make_matrix_probe(5, 1e-3, 1, np.nan, 5e6) probe_element_width = 0.8e-3 probe.set_reference_element("first") probe.reset_position() probe.translate([0.0, 0.0, -5e-3]) probe.rotate(arim.geometry.rotation_matrix_y(np.deg2rad(10))) probe_p = probe.to_oriented_points() frontwall = arim.geometry.points_1d_wall_z(numpoints=1000, xmin=-5.0e-3, xmax=20.0e-3, z=0.0, name="Frontwall") backwall = arim.geometry.points_1d_wall_z(numpoints=1000, xmin=-5.0e-3, xmax=20.0e-3, z=30.0e-3, name="Backwall") scatterer_p = arim.geometry.default_oriented_points( arim.Points([[19e-3, 0.0, 20e-3]])) all_points = [probe_p, frontwall, backwall, scatterer_p] # import arim.plot as aplt # aplt.plot_interfaces(all_points, markers=['o', 'o', 'o', 'd'], # show_orientations=True) # aplt.plt.show() exam_obj = arim.BlockInImmersion(block, couplant, frontwall, backwall, scatterer_p) scat_obj = arim.scat.scat_factory(material=block, **scat_specs) scat_funcs = scat_obj.as_angles_funcs(probe.frequency) # compute only a subset of the FMC: first row and first column tx = np.zeros(probe.numelements * 2, np.int_) tx[:probe.numelements] = np.arange(probe.numelements) rx = np.zeros(probe.numelements * 2, np.int_) rx[probe.numelements:] = np.arange(probe.numelements) # Compute model views = bim.make_views(exam_obj, probe_p, scatterer_p, max_number_of_reflection=2) arim.ray.ray_tracing(views.values()) ray_weights = bim.ray_weights_for_views(views, probe.frequency, probe_element_width) lti_coefficients = collections.OrderedDict() for viewname, view in views.items(): amp_obj = arim.model.model_amplitudes_factory(tx, rx, view, ray_weights, scat_funcs) lti_coefficients[viewname] = amp_obj[0] # Test reciprocity for i, viewname in enumerate(views): viewname_r = arim.ut.reciprocal_viewname(viewname) lhs = lti_coefficients[viewname][:probe. numelements] # (tx=k, rx=0) for all k rhs = lti_coefficients[viewname_r][ probe.numelements:] # (tx=0, rx=k) for all k max_err = np.max(np.abs(lhs - rhs)) err_msg = "view {} (#{}) - max_err={}".format(viewname, i, max_err) tol = dict(rtol=1e-7, atol=1e-8) try: np.testing.assert_allclose(lhs, rhs, err_msg=err_msg, **tol) except AssertionError as e: if show_plots: import matplotlib.pyplot as plt fig, axes = plt.subplots(nrows=2, sharex=True) ax = axes[0] ax.plot(lhs.real, label="tx=k, rx=0") ax.plot(rhs.real, label="tx=0, rx=k") ax.set_title(scat_obj.__class__.__name__ + "\n {} and {}".format(viewname, viewname_r)) ax.set_ylabel("real") ax.legend() ax = axes[1] ax.plot(lhs.imag, label="tx=k, rx=0") ax.plot(rhs.imag, label="tx=0, rx=k") ax.legend() ax.set_xlabel("element index k") ax.set_ylabel("imag") plt.show() raise e
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_timetraces_full(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) examination_object = arim.io.block_in_immersion_from_conf(conf) probe_p = frame.probe.to_oriented_points() scatterers = common.defect_oriented_point(conf) views = bim.make_views( examination_object, probe_p, scatterers, max_number_of_reflection=1, tfm_unique_only=False, ) arim.ray.ray_tracing(views.values()) frontwall_path = bim.frontwall_path( examination_object.couplant_material, examination_object.block_material, *frame.probe.to_oriented_points(), *examination_object.frontwall, ) backwall_paths = bim.backwall_paths( examination_object.couplant_material, examination_object.block_material, frame.probe.to_oriented_points(), examination_object.frontwall, examination_object.backwall, max_number_of_reflection=1, ) wall_paths = [frontwall_path] + list(backwall_paths.values()) arim.ray.ray_tracing_for_paths(wall_paths) def make_linestyles(): linestyles = itertools.product( ["-", "--", "-.", ":"], plt.rcParams["axes.prop_cycle"].by_key()["color"]) return itertools.cycle(linestyles) #%% Ascan def plot_ascan(tx, rx): scanline = np.abs(frame.get_scanline(tx, rx)) plt.figure(figsize=FIGSIZE) plt.plot(frame.time.samples, scanline, "k") plt.xlabel("Time (µs)") plt.title(f"tx={tx}, rx={rx}") linestyle_cycler = make_linestyles() for path, (ls, color) in zip(wall_paths, linestyle_cycler): plt.axvline( path.rays.times[tx, rx], label=path.name, ymin=0, color=color, ls=ls, lw=2.5, ) for view, (ls, color) in zip(views.values(), linestyle_cycler): plt.axvline( view.tx_path.rays.times[tx, 0] + view.rx_path.rays.times[rx, 0], label=view.name, ymin=0, color=color, ls=ls, ) plt.gca().xaxis.set_major_formatter(aplt.micro_formatter) plt.gca().xaxis.set_minor_formatter(aplt.micro_formatter) plt.ylim([scanline.min(), scanline.max()]) plt.legend() if save: plt.savefig(result_dir / f"ascan_full_{tx}_{rx}") plot_ascan(0, 0) plot_ascan(0, frame.probe.numelements - 1) #%% Bscan def plot_bscan(scanlines_idx, filename, **kwargs): fig, ax = plt.subplots(figsize=FIGSIZE) aplt.plot_bscan(frame, scanlines_idx, ax=ax, savefig=False, cmap="Greys", **kwargs) linestyle_cycler = make_linestyles() tx_arr = frame.tx[scanlines_idx] rx_arr = frame.rx[scanlines_idx] y = np.arange(len(tx_arr)) for path, (ls, color) in zip(wall_paths, linestyle_cycler): plt.plot( path.rays.times[tx_arr, rx_arr], y, label=path.name, color=color, ls=ls, lw=3.0, ) for view, (ls, color) in zip(views.values(), linestyle_cycler): plt.plot( view.tx_path.rays.times[tx_arr, 0] + view.rx_path.rays.times[rx_arr, 0], y, label=view.name, color=color, ls=ls, ) plt.legend() if save: plt.savefig(result_dir / filename) plot_bscan(frame.tx == frame.rx, "bscan_full_1") plot_bscan(frame.tx == 0, "bscan_full_2") plot_bscan(frame.tx == frame.probe.numelements - 1, "bscan_full_3") #%% 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
def locate_defect(dataset_name, save): # %% conf = arim.io.load_conf(dataset_name) # conf['grid']['pixel_size'] = 2e-3 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=0, ) # views = {'L-L':views['L-L']} # if conf['views_to_use'] != 'all': # views = OrderedDict([(viewname, view) for viewname, view in views.items() # if viewname in conf['views_to_use']]) # %% 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) # %% Matplotlib event handler out_file = result_dir / "conf.d/15_defect_loc.yaml" def save_defect_loc_on_click(event): if event.button != 1: return # use .item() to get a Python type instead of Numpy type data = dict(scatterer=dict( location=dict(x=event.xdata.item(), y=0.0, z=event.ydata.item()))) out_content = "# generated by locate_defect.py\n" + yaml.dump( data, default_flow_style=False) if save: with out_file.open("w", encoding="utf8") as stream: stream.write(out_content) print(f"----- Output: {out_file}") print(out_content) print("-----") # %% Plot all TFM cids = [] for i, (viewname, view) in enumerate(views.items()): tfm = tfms[viewname] ref_db = None clim = [-80.0, 0.0] ax, _ = aplt.plot_tfm( tfm, clim=clim, scale="db", ref_db=ref_db, title=f"TFM {viewname} - Left-click on defect to write conf", filename=str(result_dir / f"tfm_{i:02}_{viewname}"), figsize=(10, 5), ) cid = ax.figure.canvas.mpl_connect("button_press_event", save_defect_loc_on_click) cids.append(cid) return cids
[probe_p, frame.examination_object.frontwall, frame.examination_object.backwall], show_orientations=False, show_last=True, markers=[".", "-", "-"], filename=str(result_dir / "interfaces"), savefig=save, ) # %% Ray tracing grid = arim.io.grid_from_conf(conf) grid_p = grid.to_oriented_points() views = bim.make_views( frame.examination_object, probe_p, grid_p, tfm_unique_only=True, max_number_of_reflection=1, ) arim.ray.ray_tracing(views.values(), convert_to_fortran_order=True) # %% Compute TFM tfms = dict() for viewname, view in views.items(): with arim.helpers.timeit("TFM {}".format(view.name)): tfms[viewname] = arim.im.tfm.tfm_for_view( frame, grid, view, fillvalue=0.0, interpolation="nearest" )