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())
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
    [
        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,
)
Beispiel #7
0
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
Beispiel #10
0
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()
Beispiel #12
0
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
Beispiel #13
0
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
Beispiel #14
0
    [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"
        )