예제 #1
0
파일: test_tfm.py 프로젝트: nbud/arim
def test_multiview_tfm(use_real_grid):
    # make probe
    probe = arim.Probe.make_matrix_probe(5, 0.5e-3, 1, np.nan, 1e6)
    probe.set_reference_element("first")
    probe.reset_position()
    probe.translate([0.0, 0.0, -1e-3])

    # make frame
    tx_arr, rx_arr = arim.ut.fmc(probe.numelements)
    time = arim.Time(0.5e-6, 1 / 20e6, 100)
    # use random data but ensure reciprocity
    scanlines = np.zeros((len(tx_arr), len(time)))
    for i, (tx, rx) in enumerate(zip(tx_arr, rx_arr)):
        np.random.seed((tx * rx)**2)  # symmetric in tx and rx
        scanlines[i] = np.random.rand(len(time))
    block = arim.Material(6300, 3100)
    frame = arim.Frame(scanlines, time, tx_arr, rx_arr, probe,
                       arim.ExaminationObject(block))

    # prepare view LL-T in contact
    if use_real_grid:
        grid = arim.Grid(0.0, 0.0, 0.0, 0.0, 5e-3, 5e-3, np.nan)
        grid_interface = arim.Interface(*grid.to_oriented_points())
    else:
        grid = arim.Points(np.array([0.0, 0.0, 5e-3]), name="Grid")
        grid_interface = arim.Interface(
            *arim.geometry.default_oriented_points(grid.to_1d_points()))

    backwall = arim.geometry.points_1d_wall_z(-1e-3, 1e-3, 10e-3, 200)
    backwall_interface = arim.Interface(*backwall)
    probe_interface = arim.Interface(*probe.to_oriented_points())

    path_LL = arim.Path(
        [probe_interface, backwall_interface, grid_interface],
        [block, block],
        ["L", "L"],
    )
    path_T = arim.Path([probe_interface, grid_interface], [block], ["T"])
    view = arim.View(path_LL, path_T, "LL-T")
    arim.ray.ray_tracing([view], convert_to_fortran_order=True)

    # make TFM
    tfm = im.tfm.tfm_for_view(frame, grid, view, fillvalue=np.nan)

    # Check this value is unchanged over time!
    expected_val = 12.745499105785953
    assert tfm.res.shape == grid.shape
    if use_real_grid:
        np.testing.assert_array_almost_equal(tfm.res, [[[expected_val]]])
    else:
        np.testing.assert_allclose(tfm.res, expected_val)

    # Reverse view
    view_rev = arim.View(path_LL, path_T, "T-LL")
    tfm_rev = im.tfm.tfm_for_view(frame, grid, view_rev, fillvalue=np.nan)
    assert tfm.res.shape == grid.shape
    if use_real_grid:
        np.testing.assert_array_almost_equal(tfm_rev.res, [[[expected_val]]])
    else:
        np.testing.assert_allclose(tfm_rev.res, expected_val)
예제 #2
0
파일: test_tfm.py 프로젝트: nbud/arim
def test_contact_tfm(use_hmc):
    # make probe
    probe = arim.Probe.make_matrix_probe(5, 0.5e-3, 1, np.nan, 1e6)
    probe.set_reference_element("first")
    probe.reset_position()
    probe.translate([0.0, 0.0, -1e-3])

    # make frame
    if use_hmc:
        tx_arr, rx_arr = arim.ut.hmc(probe.numelements)
    else:
        tx_arr, rx_arr = arim.ut.fmc(probe.numelements)

    time = arim.Time(0.5e-6, 1 / 20e6, 100)

    # use random data but ensure reciprocity
    scanlines = np.zeros((len(tx_arr), len(time)))
    for i, (tx, rx) in enumerate(zip(tx_arr, rx_arr)):
        np.random.seed((tx * rx)**2)  # symmetric in tx and rx
        scanlines[i] = np.random.rand(len(time))

    # check reciprocity
    if not use_hmc:
        for i, (tx, rx) in enumerate(zip(tx_arr, rx_arr)):
            scanline_1 = scanlines[i]
            scanline_2 = scanlines[np.logical_and(tx_arr == rx,
                                                  rx_arr == tx)][0]
            np.testing.assert_allclose(scanline_1,
                                       scanline_2,
                                       err_msg="fmc data not symmetric")

    block = arim.Material(6300, 3100)
    frame = arim.Frame(scanlines, time, tx_arr, rx_arr, probe,
                       arim.ExaminationObject(block))

    # prepare view LL-T in contact
    grid = arim.Points(np.array([0.0, 0.0, 5e-3]), name="Grid")

    tfm = im.tfm.contact_tfm(frame,
                             grid,
                             block.longitudinal_vel,
                             fillvalue=np.nan)

    # Check this value is unchanged over time!
    expected_val = 12.49925772283528
    assert tfm.res.shape == grid.shape
    np.testing.assert_allclose(tfm.res, expected_val)
예제 #3
0
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()
예제 #4
0
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