Ejemplo n.º 1
0
def test_get_dlf_points():  # 9. get_dlf_points
    # Check one example
    filt = filters.key_81_CosSin_2009()
    out, new_inp = transform.get_dlf_points(filt, np.arange(1, 6), -1)
    # Expected values
    oout = np.array([
        6.70925256e-05, 8.19469958e-05, 1.00090287e-04, 1.22250552e-04,
        1.49317162e-04, 1.82376393e-04, 2.22755030e-04, 2.72073608e-04,
        3.32311455e-04, 4.05886127e-04, 4.95750435e-04, 6.05510949e-04,
        7.39572743e-04, 9.03316189e-04, 1.10331288e-03, 1.34758940e-03,
        1.64594941e-03, 2.01036715e-03, 2.45546798e-03, 2.99911536e-03,
        3.66312778e-03, 4.47415437e-03, 5.46474449e-03, 6.67465399e-03,
        8.15244080e-03, 9.95741367e-03, 1.21620125e-02, 1.48547156e-02,
        1.81435907e-02, 2.21606317e-02, 2.70670566e-02, 3.30597776e-02,
        4.03793036e-02, 4.93193928e-02, 6.02388424e-02, 7.35758882e-02,
        8.98657928e-02, 1.09762327e-01, 1.34064009e-01, 1.63746151e-01,
        2.00000000e-01, 2.44280552e-01, 2.98364940e-01, 3.64423760e-01,
        4.45108186e-01, 5.43656366e-01, 6.64023385e-01, 8.11039993e-01,
        9.90606485e-01, 1.20992949e+00, 1.47781122e+00, 1.80500270e+00,
        2.20463528e+00, 2.69274761e+00, 3.28892935e+00, 4.01710738e+00,
        4.90650604e+00, 5.99282001e+00, 7.31964689e+00, 8.94023690e+00,
        1.09196300e+01, 1.33372662e+01, 1.62901737e+01, 1.98968631e+01,
        2.43020835e+01, 2.96826318e+01, 3.62544484e+01, 4.42812832e+01,
        5.40852815e+01, 6.60599120e+01, 8.06857587e+01, 9.85498082e+01,
        1.20369008e+02, 1.47019038e+02, 1.79569458e+02, 2.19326632e+02,
        2.67886153e+02, 3.27196886e+02, 3.99639179e+02, 4.88120396e+02,
        5.96191597e+02, 7.28190061e+02, 8.89413350e+02, 1.08633192e+03,
        1.32684880e+03, 1.62061679e+03, 1.97942581e+03, 2.41767615e+03,
        2.95295631e+03, 3.60674899e+03
    ])
    onew_inp = np.array([
        5., 4.09365377, 3.35160023, 2.74405818, 2.24664482, 1.83939721,
        1.50597106, 1.23298482, 1.00948259, 0.82649444
    ])
    # Comparison
    # WARNING - for some reasons, on GHA, out has at times 91 elemens.
    # NO IDEA WHY!
    assert_allclose(out[0, :90], oout)
    assert_allclose(new_inp, onew_inp)

    # Ensure output dimension
    hfilt = filters.anderson_801_1982()
    out, _ = transform.get_dlf_points(hfilt, np.array([1, 1.1]), -1)
    assert_allclose(out.size, 804)

    # Check a hypothetical short filter, with small pts_per_dec, and ensure
    # at least four points are returned
    filt = filters.DigitalFilter('shortest')
    filt.base = np.array([1., 1.1])
    out, new_inp = transform.get_dlf_points(filt, np.array([1.]), 1)
    assert_allclose(out.size, 4)

    # Check standard example
    ffilt = filters.key_81_CosSin_2009()
    inp = np.arange(1, 6)
    out, new_inp = transform.get_dlf_points(ffilt, inp, 0)
    assert_allclose(inp, new_inp)
    assert_allclose(out, ffilt.base / inp[:, None])
Ejemplo n.º 2
0
 def lambd(self):
     """
         Spatial frequency in Hankel domain
         np.sqrt(kx*2 + ky**2) = lamda
     """
     # TODO: only works isotropic sigma
     if getattr(self, "_lambd", None) is None:
         self._lambd = np.empty([self.offset.size, self.n_filter],
                                order="F",
                                dtype=complex)
         self.lambd[:, :], _ = get_dlf_points(self.fhtfilt, self.offset,
                                              self.hankel_pts_per_dec)
     return self._lambd
Ejemplo n.º 3
0
def test_dlf():  # 10. dlf
    # DLF is integral of hankel_dlf and fourier_dlf, and therefore tested a lot
    # through those. Here we just ensure status quo. And if a problem arises in
    # hankel_dlf or fourier_dlf, it would make it obvious if the problem arises
    # from dlf or not.

    # Check DLF for Fourier
    t = DATA['t'][()]
    for i in [0, 1, 2]:
        dat = DATA['fourier_dlf' + str(i)][()]
        tres = DATA['tEM' + str(i)][()]
        finp = dat['fEM']
        ftarg = dat['ftarg']
        if i > 0:
            finp /= 2j * np.pi * dat['f']
        if i > 1:
            finp *= -1

        if ftarg['pts_per_dec'] == 0:
            finp = finp.reshape(t.size, -1)

        tEM = transform.dlf(finp,
                            2 * np.pi * dat['f'],
                            t,
                            ftarg['dlf'],
                            ftarg['pts_per_dec'],
                            kind=ftarg['kind'])
        assert_allclose(tEM * 2 / np.pi, tres, rtol=1e-3)

    # Check DLF for Hankel
    for ab in [12, 22, 13, 33]:
        model = utils.check_model([], 10, 2, 2, 5, 1, 10, True, 0)
        depth, res, aniso, epermH, epermV, mpermH, mpermV, _ = model
        frequency = utils.check_frequency(1, res, aniso, epermH, epermV,
                                          mpermH, mpermV, 0)
        _, etaH, etaV, zetaH, zetaV = frequency
        src = [0, 0, 0]
        src, nsrc = utils.check_dipole(src, 'src', 0)
        ab, msrc, mrec = utils.check_ab(ab, 0)
        ht, htarg = utils.check_hankel('dlf', {}, 0)
        xdirect = False  # Important, as we want to comp. wavenumber-frequency!
        rec = [np.arange(1, 11) * 500, np.zeros(10), 300]
        rec, nrec = utils.check_dipole(rec, 'rec', 0)
        off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0)
        lsrc, zsrc = utils.get_layer_nr(src, depth)
        lrec, zrec = utils.get_layer_nr(rec, depth)
        dlf = htarg['dlf']
        pts_per_dec = htarg['pts_per_dec']

        # # # 0. No Spline # # #

        # dlf calculation
        lambd = dlf.base / off[:, None]
        PJ = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV,
                               zetaH, zetaV, lambd, ab, xdirect, msrc, mrec)

        # Angle factor, one example with None instead of 1's.
        if ab != 13:
            ang_fact = kernel.angle_factor(angle, ab, msrc, mrec)
        else:
            ang_fact = None

        # dlf calculation
        fEM0 = transform.dlf(PJ, lambd, off, dlf, 0, ang_fact=ang_fact, ab=ab)

        # Analytical frequency-domain solution
        freq1 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH,
                                 zetaV, ab, msrc, mrec)
        # Compare
        assert_allclose(np.squeeze(fEM0), np.squeeze(freq1))

        # # # 1. Spline; One angle # # #

        # dlf calculation
        lambd, _ = transform.get_dlf_points(dlf, off, pts_per_dec)
        PJ1 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV,
                                zetaH, zetaV, lambd, ab, xdirect, msrc, mrec)

        # dlf calculation
        fEM1 = transform.dlf(PJ1,
                             lambd,
                             off,
                             dlf,
                             pts_per_dec,
                             ang_fact=ang_fact,
                             ab=ab)

        # Compare
        assert_allclose(np.squeeze(fEM1), np.squeeze(freq1), rtol=1e-4)

        # # # 2.a Lagged; One angle # # #
        rec = [np.arange(1, 11) * 500, np.arange(-5, 5) * 0, 300]
        rec, nrec = utils.check_dipole(rec, 'rec', 0)
        off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0)

        # dlf calculation
        lambd, _ = transform.get_dlf_points(dlf, off, -1)
        PJ2 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV,
                                zetaH, zetaV, lambd, ab, xdirect, msrc, mrec)
        ang_fact = kernel.angle_factor(angle, ab, msrc, mrec)

        # dlf calculation
        fEM2 = transform.dlf(PJ2,
                             lambd,
                             off,
                             dlf,
                             -1,
                             ang_fact=ang_fact,
                             ab=ab)

        # Analytical frequency-domain solution
        freq2 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH,
                                 zetaV, ab, msrc, mrec)
        # Compare
        assert_allclose(np.squeeze(fEM2), np.squeeze(freq2), rtol=1e-4)

        # # # 2.b Lagged; Multi angle # # #
        rec = [np.arange(1, 11) * 500, np.arange(-5, 5) * 200, 300]
        rec, nrec = utils.check_dipole(rec, 'rec', 0)
        off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0)

        # dlf calculation
        lambd, _ = transform.get_dlf_points(dlf, off, -1)
        PJ2 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV,
                                zetaH, zetaV, lambd, ab, xdirect, msrc, mrec)
        ang_fact = kernel.angle_factor(angle, ab, msrc, mrec)

        # dlf calculation
        fEM2 = transform.dlf(PJ2,
                             lambd,
                             off,
                             dlf,
                             -1,
                             ang_fact=ang_fact,
                             ab=ab)

        # Analytical frequency-domain solution
        freq2 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH,
                                 zetaV, ab, msrc, mrec)
        # Compare
        assert_allclose(np.squeeze(fEM2), np.squeeze(freq2), rtol=1e-4)

        # # # 3. Spline; Multi angle # # #

        lambd, _ = transform.get_dlf_points(dlf, off, 30)
        # dlf calculation
        PJ3 = kernel.wavenumber(zsrc, zrec, lsrc, lrec, depth, etaH, etaV,
                                zetaH, zetaV, lambd, ab, xdirect, msrc, mrec)

        # dlf calculation
        fEM3 = transform.dlf(PJ3,
                             lambd,
                             off,
                             dlf,
                             30,
                             ang_fact=ang_fact,
                             ab=ab)

        # Compare
        assert_allclose(np.squeeze(fEM3), np.squeeze(freq2), rtol=1e-3)
Ejemplo n.º 4
0
def test_hankel(htype):  # 1. DLF / 2. QWE / 3. QUAD
    # Compare wavenumber-domain calculation / DLF with analytical
    # frequency-domain fullspace solution
    calc = getattr(transform, 'hankel_' + htype)
    model = utils.check_model([], 10, 2, 2, 5, 1, 10, True, 0)
    depth, res, aniso, epermH, epermV, mpermH, mpermV, _ = model
    frequency = utils.check_frequency(1, res, aniso, epermH, epermV, mpermH,
                                      mpermV, 0)
    _, etaH, etaV, zetaH, zetaV = frequency
    src = [0, 0, 0]
    src, nsrc = utils.check_dipole(src, 'src', 0)
    for ab_inp in [11, 12, 13, 33]:
        ab, msrc, mrec = utils.check_ab(ab_inp, 0)
        _, htarg = utils.check_hankel(htype, {}, 0)
        xdirect = False  # Important, as we want to compare wavenr-frequency!
        rec = [np.arange(1, 11) * 500, np.zeros(10), 300]
        rec, nrec = utils.check_dipole(rec, 'rec', 0)
        off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0)
        ang_fact = kernel.angle_factor(angle, ab, msrc, mrec)
        lsrc, zsrc = utils.get_layer_nr(src, depth)
        lrec, zrec = utils.get_layer_nr(rec, depth)

        # # # 0. No Spline # # #
        if htype != 'quad':  # quad is always using spline
            # Wavenumber solution plus transform

            # Adjust htarg for dlf
            if htype == 'dlf':
                lambd, int_pts = transform.get_dlf_points(
                    htarg['dlf'], off, htarg['pts_per_dec'])
                htarg['lambd'] = lambd
                htarg['int_pts'] = int_pts

            wvnr0, _, conv = calc(zsrc, zrec, lsrc, lrec, off, ang_fact, depth,
                                  ab, etaH, etaV, zetaH, zetaV, xdirect, htarg,
                                  msrc, mrec)
            # Analytical frequency-domain solution
            freq0 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH,
                                     zetaV, ab, msrc, mrec)
            # Compare
            assert_allclose(conv, True)
            assert_allclose(np.squeeze(wvnr0), np.squeeze(freq0))

        # # # 1. Spline; One angle # # #
        _, htarg = utils.check_hankel(htype, {'pts_per_dec': 80}, 0)
        if htype == 'quad':  # Lower atol to ensure convergence
            _, htarg = utils.check_hankel('quad', {'rtol': 1e-8}, 0)
        elif htype == 'dlf':  # Adjust htarg for dlf
            lambd, int_pts = transform.get_dlf_points(htarg['dlf'], off,
                                                      htarg['pts_per_dec'])
            htarg['lambd'] = lambd
            htarg['int_pts'] = int_pts

        # Wavenumber solution plus transform
        wvnr1, _, conv = calc(zsrc, zrec, lsrc, lrec, off, ang_fact, depth, ab,
                              etaH, etaV, zetaH, zetaV, xdirect, htarg, msrc,
                              mrec)
        # Analytical frequency-domain solution
        freq1 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH,
                                 zetaV, ab, msrc, mrec)
        # Compare
        if htype == 'qwe' and ab in [13, 33]:
            assert_allclose(conv, False)
        else:
            assert_allclose(conv, True)
        assert_allclose(np.squeeze(wvnr1), np.squeeze(freq1), rtol=1e-4)

        # # # 2. Spline; Multi angle # # #
        rec = [np.arange(1, 11) * 500, np.arange(-5, 5) * 200, 300]
        rec, nrec = utils.check_dipole(rec, 'rec', 0)
        off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0)
        ang_fact = kernel.angle_factor(angle, ab, msrc, mrec)
        if htype == 'qwe':  # Put a very low diff_quad, to test it.; lower err
            _, htarg = utils.check_hankel(
                'qwe', {
                    'rtol': 1e-8,
                    'maxint': 200,
                    'pts_per_dec': 80,
                    'diff_quad': .1,
                    'a': 1e-6,
                    'b': .1,
                    'limit': 1000
                }, 0)
        elif htype == 'dlf':  # Adjust htarg for dlf
            lambd, int_pts = transform.get_dlf_points(htarg['dlf'], off,
                                                      htarg['pts_per_dec'])
            htarg['lambd'] = lambd
            htarg['int_pts'] = int_pts

        # Analytical frequency-domain solution
        wvnr2, _, conv = calc(zsrc, zrec, lsrc, lrec, off, ang_fact, depth, ab,
                              etaH, etaV, zetaH, zetaV, xdirect, htarg, msrc,
                              mrec)
        # Analytical frequency-domain solution
        freq2 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH,
                                 zetaV, ab, msrc, mrec)
        # Compare
        assert_allclose(conv, True)
        assert_allclose(np.squeeze(wvnr2), np.squeeze(freq2), rtol=1e-4)

        # # # 3. Spline; pts_per_dec # # #
        if htype == 'dlf':
            _, htarg = utils.check_hankel('dlf', {
                'dlf': 'key_201_2012',
                'pts_per_dec': 20
            }, 0)
            lambd, int_pts = transform.get_dlf_points(htarg['dlf'], off,
                                                      htarg['pts_per_dec'])
            htarg['lambd'] = lambd
            htarg['int_pts'] = int_pts
        elif htype == 'qwe':
            _, htarg = utils.check_hankel('qwe', {
                'maxint': 80,
                'pts_per_dec': 100
            }, 0)
        if htype != 'quad':  # quad is always pts_per_dec
            # Analytical frequency-domain solution
            wvnr3, _, conv = calc(zsrc, zrec, lsrc, lrec, off, ang_fact, depth,
                                  ab, etaH, etaV, zetaH, zetaV, xdirect, htarg,
                                  msrc, mrec)
            # Analytical frequency-domain solution
            freq3 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH,
                                     zetaV, ab, msrc, mrec)
            # Compare
            assert_allclose(conv, True)
            assert_allclose(np.squeeze(wvnr3), np.squeeze(freq3), rtol=1e-4)

        # # # 4. Spline; Only one offset # # #
        rec = [5000, 0, 300]
        rec, nrec = utils.check_dipole(rec, 'rec', 0)
        off, angle = utils.get_off_ang(src, rec, nsrc, nrec, 0)
        ang_fact = kernel.angle_factor(angle, ab, msrc, mrec)
        if htype == 'qwe':
            _, htarg = utils.check_hankel('qwe', {
                'maxint': 200,
                'pts_per_dec': 80
            }, 0)
        elif htype == 'quad':
            _, htarg = utils.check_hankel('quad', {}, 0)
        elif htype == 'dlf':
            lambd, int_pts = transform.get_dlf_points(htarg['dlf'], off,
                                                      htarg['pts_per_dec'])
            htarg['lambd'] = lambd
            htarg['int_pts'] = int_pts
        # Analytical frequency-domain solution
        wvnr4, _, conv = calc(zsrc, zrec, lsrc, lrec, off, ang_fact, depth, ab,
                              etaH, etaV, zetaH, zetaV, xdirect, htarg, msrc,
                              mrec)
        # Analytical frequency-domain solution
        freq4 = kernel.fullspace(off, angle, zsrc, zrec, etaH, etaV, zetaH,
                                 zetaV, ab, msrc, mrec)
        # Compare
        assert_allclose(conv, True)
        assert_allclose(np.squeeze(wvnr4), np.squeeze(freq4), rtol=1e-4)
Ejemplo n.º 5
0
    def magnetic_field(self, xyz, field="secondary"):
        """
        Magnetic field due to a magnetic dipole in a layered halfspace at a specific height z

        Parameters
        ----------
        xyz : numpy.ndarray
            receiver locations of shape (n_locations, 3).
            The z component cannot be below the surface (z=0.0).
        field : ("secondary", "total")
            Flag for the type of field to return.
        """

        if np.any(xyz[:, 2] < 0.0):
            raise ValueError("Cannot compute fields below the surface")
        h = self.location[2]
        dxyz = xyz - self.location
        offsets = np.linalg.norm(dxyz[:, :-1], axis=-1)

        # Comput transform operations
        # -1 gives lagged convolution in dlf
        ht, htarg = check_hankel('dlf', {
            'dlf': 'key_101_2009',
            'pts_per_dec': 0
        }, 1)
        fhtfilt = htarg['dlf']
        pts_per_dec = htarg['pts_per_dec']

        f = self.frequency
        n_frequency = len(f)

        lambd, int_points = get_dlf_points(fhtfilt, offsets, pts_per_dec)

        thick = self.thickness
        n_layer = len(thick) + 1

        thick, sigma, epsilon, mu = self._get_valid_properties()
        sigh = sigma_hat(
            self.frequency[:, None],
            sigma,
            epsilon,
            quasistatic=self.quasistatic
        ).T  # this gets sigh with proper shape (n_layer x n_freq) and fortran ordering.
        mu = np.tile(mu, (n_frequency, 1)).T  # shape(n_layer x n_freq)

        rTE = rTE_forward(f, lambd.reshape(-1), sigh, mu, thick)
        rTE = rTE.reshape((n_frequency, *lambd.shape))

        # secondary is height of receiver plus height of source
        rTE *= np.exp(-lambd * (xyz[:, -1] + h)[:, None])
        # works for variable xyz because each point has it's own lambdas

        src_x, src_y, src_z = self.orientation
        C0x = C0y = C0z = 0.0
        C1x = C1y = C1z = 0.0
        if src_x != 0.0:
            C0x += src_x * (dxyz[:, 0]**2 / offsets**2)[:, None] * lambd**2
            C1x += src_x * (1 / offsets -
                            2 * dxyz[:, 0]**2 / offsets**3)[:, None] * lambd
            C0y += src_x * (dxyz[:, 0] * dxyz[:, 1] /
                            offsets**2)[:, None] * lambd**2
            C1y -= src_x * (2 * dxyz[:, 0] * dxyz[:, 1] /
                            offsets**3)[:, None] * lambd
            # C0z += 0.0
            C1z -= (src_x * dxyz[:, 0] / offsets)[:, None] * lambd**2

        if src_y != 0.0:
            C0x += src_y * (dxyz[:, 0] * dxyz[:, 1] /
                            offsets**2)[:, None] * lambd**2
            C1x -= src_y * (2 * dxyz[:, 0] * dxyz[:, 1] /
                            offsets**3)[:, None] * lambd
            C0y += src_y * (dxyz[:, 1]**2 / offsets**2)[:, None] * lambd**2
            C1y += src_y * (1 / offsets -
                            2 * dxyz[:, 1]**2 / offsets**3)[:, None] * lambd
            # C0z += 0.0
            C1z -= (src_y * dxyz[:, 1] / offsets)[:, None] * lambd**2

        if src_z != 0.0:
            # C0x += 0.0
            C1x += (src_z * dxyz[:, 0] / offsets)[:, None] * lambd**2
            # C0y += 0.0
            C1y += (src_z * dxyz[:, 1] / offsets)[:, None] * lambd**2
            C0z += src_z * lambd**2
            # C1z += 0.0

        # Do the hankel transform on each component
        em_x = ((C0x * rTE) @ fhtfilt.j0 + (C1x * rTE) @ fhtfilt.j1) / offsets
        em_y = ((C0y * rTE) @ fhtfilt.j0 + (C1y * rTE) @ fhtfilt.j1) / offsets
        em_z = ((C0z * rTE) @ fhtfilt.j0 + (C1z * rTE) @ fhtfilt.j1) / offsets

        if field == "total":
            # add in the primary field
            r = np.linalg.norm(dxyz, axis=-1)
            mdotr = src_x * dxyz[:, 0] + src_y * dxyz[:, 1] + src_z * dxyz[:,
                                                                           2]

            em_x += 3 * dxyz[:, 0] * mdotr / r**5 - src_x / r**3
            em_y += 3 * dxyz[:, 1] * mdotr / r**5 - src_y / r**3
            em_z += 3 * dxyz[:, 2] * mdotr / r**5 - src_z / r**3

        return self.moment / (4 * np.pi) * np.stack(
            (em_x, em_y, em_z), axis=-1)
Ejemplo n.º 6
0
    def forward(self, m, output_type='response'):
        """
            Return Bz or dBzdt
        """

        self.model = m

        n_frequency = self.survey.n_frequency
        flag = self.survey.field_type
        n_layer = self.survey.n_layer
        depth = self.survey.depth
        I = self.survey.I
        n_filter = self.n_filter

        # Get lambd and offset, will depend on pts_per_dec
        if self.survey.src_type == "VMD":
            r = self.survey.offset
        else:
            # a is the radius of the loop
            r = self.survey.a * np.ones(n_frequency)

        # Use function from empymod
        # size of lambd is (n_frequency x n_filter)
        lambd = np.empty([self.survey.frequency.size, n_filter], order='F')
        lambd[:, :], _ = get_dlf_points(self.fhtfilt, r,
                                        self.hankel_pts_per_dec)

        # TODO: potentially store
        f = np.empty([self.survey.frequency.size, n_filter], order='F')
        f[:, :] = np.tile(self.survey.frequency.reshape([-1, 1]),
                          (1, n_filter))
        # h is an inversion parameter
        if self.hMap is not None:
            h = self.h
        else:
            h = self.survey.h

        z = h + self.survey.dz

        chi = self.chi

        if np.isscalar(self.chi):
            chi = np.ones_like(self.sigma) * self.chi

        # TODO: potentially store
        sig = self.sigma_cole()

        if output_type == 'response':
            # for simulation
            if self.survey.src_type == 'VMD':
                hz = self.hz_kernel_vertical_magnetic_dipole(
                    lambd,
                    f,
                    n_layer,
                    sig,
                    chi,
                    depth,
                    h,
                    z,
                    flag,
                    I,
                    output_type=output_type)

                # kernels for each bessel function
                # (j0, j1, j2)
                PJ = (hz, None, None)  # PJ0

            elif self.survey.src_type == 'CircularLoop':
                hz = self.hz_kernel_circular_loop(lambd,
                                                  f,
                                                  n_layer,
                                                  sig,
                                                  chi,
                                                  depth,
                                                  h,
                                                  z,
                                                  I,
                                                  r,
                                                  flag,
                                                  output_type=output_type)

                # kernels for each bessel function
                # (j0, j1, j2)
                PJ = (None, hz, None)  # PJ1

            # TODO: This has not implemented yet!
            elif self.survey.src_type == "piecewise_line":
                # Need to compute y
                hz = self.hz_kernel_horizontal_electric_dipole(
                    lambd,
                    f,
                    n_layer,
                    sig,
                    chi,
                    depth,
                    h,
                    z,
                    I,
                    r,
                    flag,
                    output_type=output_type)
                # kernels for each bessel function
                # (j0, j1, j2)
                PJ = (None, hz, None)  # PJ1

            else:
                raise Exception("Src options are only VMD or CircularLoop!!")

        elif output_type == 'sensitivity_sigma':

            # for simulation
            if self.survey.src_type == 'VMD':
                hz = self.hz_kernel_vertical_magnetic_dipole(
                    lambd,
                    f,
                    n_layer,
                    sig,
                    chi,
                    depth,
                    h,
                    z,
                    flag,
                    I,
                    output_type=output_type)

                PJ = (hz, None, None)  # PJ0

            elif self.survey.src_type == 'CircularLoop':

                hz = self.hz_kernel_circular_loop(lambd,
                                                  f,
                                                  n_layer,
                                                  sig,
                                                  chi,
                                                  depth,
                                                  h,
                                                  z,
                                                  I,
                                                  r,
                                                  flag,
                                                  output_type=output_type)

                PJ = (None, hz, None)  # PJ1

            else:
                raise Exception("Src options are only VMD or CircularLoop!!")

            r = np.tile(r, (n_layer, 1))

        elif output_type == 'sensitivity_height':

            # for simulation
            if self.survey.src_type == 'VMD':
                hz = self.hz_kernel_vertical_magnetic_dipole(
                    lambd,
                    f,
                    n_layer,
                    sig,
                    chi,
                    depth,
                    h,
                    z,
                    flag,
                    I,
                    output_type=output_type)

                PJ = (hz, None, None)  # PJ0

            elif self.survey.src_type == 'CircularLoop':

                hz = self.hz_kernel_circular_loop(lambd,
                                                  f,
                                                  n_layer,
                                                  sig,
                                                  chi,
                                                  depth,
                                                  h,
                                                  z,
                                                  I,
                                                  r,
                                                  flag,
                                                  output_type=output_type)

                PJ = (None, hz, None)  # PJ1

            else:
                raise Exception("Src options are only VMD or CircularLoop!!")

        # Carry out Hankel DLF
        # ab=66 => 33 (vertical magnetic src and rec)
        # For response
        # HzFHT size = (n_frequency,)
        # For sensitivity
        # HzFHT size = (n_layer, n_frequency)

        HzFHT = dlf(PJ,
                    lambd,
                    r,
                    self.fhtfilt,
                    self.hankel_pts_per_dec,
                    ang_fact=None,
                    ab=33)

        if output_type == "sensitivity_sigma":
            return HzFHT.T

        return HzFHT
Ejemplo n.º 7
0
    def setup_cache(self):
        """setup_cache is not parametrized, so we do it manually. """

        data = {}
        for size in self.params[0]:  # size

            data[size] = {}

            # One big, one small model
            if size == 'Small':  # Small; Total size: 5*1*1*1 = 5
                x = np.array([500., 1000.])
            else:       # Big; Total size: 5*100*100*201 = 10'050'000
                x = np.arange(1, 101)*200.

            # Define model parameters
            freq = np.array([1])
            src = [0, 0, 250]
            rec = [x, np.zeros(x.shape), 300]
            depth = np.array([-np.infty, 0, 300, 2000, 2100])
            res = np.array([2e14, .3, 1, 50, 1])
            ab = 11
            xdirect = False
            verb = 0

            if not VERSION2:
                use_ne_eval = False

            # Checks (since DLF exists the `utils`-checks haven't changed, so
            # we just use them here.
            model = utils.check_model(depth, res, None, None, None, None, None,
                                      xdirect, verb)
            depth, res, aniso, epermH, epermV, mpermH, mpermV, _ = model
            frequency = utils.check_frequency(freq, res, aniso, epermH, epermV,
                                              mpermH, mpermV, verb)
            freq, etaH, etaV, zetaH, zetaV = frequency
            ab, msrc, mrec = utils.check_ab(ab, verb)
            src, nsrc = utils.check_dipole(src, 'src', verb)
            rec, nrec = utils.check_dipole(rec, 'rec', verb)
            off, angle = utils.get_off_ang(src, rec, nsrc, nrec, verb)
            lsrc, zsrc = utils.get_layer_nr(src, depth)
            lrec, zrec = utils.get_layer_nr(rec, depth)

            for htype in self.params[1]:  # htype

                # pts_per_dec depending on htype
                if htype == 'Standard':
                    pts_per_dec = 0
                elif htype == 'Lagged':
                    pts_per_dec = -1
                else:
                    pts_per_dec = 10

                # Compute kernels for dlf
                if VERSION2:
                    # HT arguments
                    _, fhtarg = utils.check_hankel(
                            'dlf',
                            {'dlf': 'key_201_2009',
                             'pts_per_dec': pts_per_dec},
                            0)

                    inp = (fhtarg['dlf'], off, fhtarg['pts_per_dec'])
                    lambd, _ = transform.get_dlf_points(*inp)
                else:
                    # HT arguments
                    _, fhtarg = utils.check_hankel(
                            'fht', ['key_201_2009', pts_per_dec], 0)

                    inp = (fhtarg[0], off, fhtarg[1])
                    lambd, _ = transform.get_spline_values(*inp)

                if VERSION2:
                    inp = (zsrc, zrec, lsrc, lrec, depth, etaH, etaV, zetaH,
                           zetaV, lambd, ab, xdirect, msrc, mrec)
                else:
                    inp = (zsrc, zrec, lsrc, lrec, depth, etaH,
                           etaV, zetaH, zetaV, lambd, ab, xdirect,
                           msrc, mrec, use_ne_eval)
                PJ = kernel.wavenumber(*inp)

                factAng = kernel.angle_factor(angle, ab, msrc, mrec)

                # Signature changed at commit a15af07 (20/05/2018; before
                # v1.6.2)
                try:
                    dlf = {'signal': PJ, 'points': lambd, 'out_pts': off,
                           'ab': ab}
                    if VERSION2:
                        dlf['ang_fact'] = factAng
                        dlf['filt'] = fhtarg['dlf']
                        dlf['pts_per_dec'] = fhtarg['pts_per_dec']
                    else:
                        dlf['factAng'] = factAng
                        dlf['filt'] = fhtarg[0]
                        dlf['pts_per_dec'] = fhtarg[1]
                    transform.dlf(**dlf)
                except VariableCatch:
                    dlf = {'signal': PJ, 'points': lambd, 'out_pts': off,
                           'targ': fhtarg, 'factAng': factAng}

                data[size][htype] = dlf

        return data