Пример #1
0
    def test_refl_air_nonmag(self):
        # test ambient layer non-air
        Q = np.linspace(0.001, 0.5, 1000, dtype=np.float64)
        SLDs = np.array([6.36e+00, (4.66e+00 - 1.60e-02j), 0e+00],
                        dtype=np.complex128) * 1e-6
        n = 1.0 - SLDs

        Vp = ((2.0 * np.pi / 4.5)**2 * (1 - n**2)).astype(np.complex128)
        Vm = Vp
        d = np.array([0, 100, 0], dtype=np.float64)
        M_ang = np.array([
            0.0,
            0.0,
            0.0,
        ], dtype=np.float64)
        sigma = np.array([10., 3., 0.], dtype=np.float64)

        G0 = paratt.ReflQ(Q, 4.5, n, d, sigma, return_int=True)
        G1 = neutron_refl.Refl(Q, Vp, Vm, d, M_ang, sigma, return_int=True)
        G2 = neutron_numba.Refl(Q, Vp, Vm, d, M_ang, sigma, return_int=True)
        np.testing.assert_array_almost_equal(G0, G1[0])
        np.testing.assert_array_almost_equal(G1, G2)
        if CUDA:
            G2 = neutron_cuda.Refl(Q, Vp, Vm, d, M_ang, sigma, return_int=True)
            np.testing.assert_array_almost_equal(G1, G2)
Пример #2
0
    def test_refl_nonmag_no_roughness(self):
        # test ambient layer non-air
        Q = np.linspace(0.001, 0.5, 1000, dtype=np.float64)
        SLDs = np.array([6.36e+00, (4.66e+00 - 1.60e-02j), 2.07e+00],
                        dtype=np.complex128) * 1e-6
        n = 1.0 - SLDs
        n_prime = 1.0 - (SLDs - SLDs[-1]
                         )  # use corrected SLD for matrix method

        Vp = ((2.0 * np.pi / 4.5)**2 * (1 - n_prime**2)).astype(np.complex128)
        Vm = Vp

        d = np.array([0, 100, 0], dtype=np.float64)
        M_ang = np.array([
            0.0,
            0.0,
            0.0,
        ], dtype=np.float64)
        sigma = None

        G0 = paratt.ReflQ(Q, 4.5, n, d, d * 0., return_int=True)
        G1 = neutron_refl.Refl(Q, Vp, Vm, d, M_ang, sigma, return_int=True)
        G2 = neutron_numba.Refl(Q, Vp, Vm, d, M_ang, sigma, return_int=True)
        np.testing.assert_array_almost_equal(G0, G1[0], decimal=4)
        np.testing.assert_array_almost_equal(G1, G2)
        if CUDA:
            G2 = neutron_cuda.Refl(Q, Vp, Vm, d, M_ang, sigma, return_int=True)
            np.testing.assert_array_almost_equal(G1, G2)
Пример #3
0
 def test_reflq_amp_roughness(self):
     Q = np.linspace(0., 0.5, 1000, dtype=np.float64)
     lamda = 4.5
     n = np.array([
         1 - 7.57e-6 + 1.73e-7j, 1 - 2.24e-5 + 2.89e-6j, 1 - 7.57e-6 +
         1.73e-7j, 1 - 2.24e-5 + 2.89e-6j, 1 - 7.57e-6 + 1.73e-7j,
         1 - 2.24e-5 + 2.89e-6j, 1 - 7.57e-6 + 1.73e-7j, 1
     ],
                  dtype=np.complex128)
     d = np.array([2, 80, 20, 80, 20, 80, 20, 2], dtype=np.float64)
     sigma = np.array([10, 10, 10, 10, 10, 10, 10, 10], dtype=np.float64)
     G1 = paratt.ReflQ(Q, lamda, n, d, sigma, return_int=False)
     G2 = paratt_numba.ReflQ(Q, lamda, n, d, sigma, return_int=False)
     np.testing.assert_array_almost_equal(G1, G2)
     if CUDA:
         G2 = paratt_cuda.ReflQ(Q, lamda, n, d, sigma, return_int=False)
         np.testing.assert_array_almost_equal(G1, G2)
Пример #4
0
def specular_calcs(TwoThetaQz, sample, instrument, return_int=True):
    """ Simulate the specular signal from sample when probed with instrument
    
    # BEGIN Parameters
    TwoThetaQz data.x
    # END Parameters
    """
    # preamble to get it working with my class interface
    restype = instrument.getRestype()
    Q, TwoThetaQz, weight = resolution_init(TwoThetaQz, instrument)
    if any(Q < q_limit):
        raise ValueError('The q vector has to be above %.1e' % q_limit)

    type = instrument.getProbe()
    pol = instrument.getPol()

    parameters = sample.resolveLayerParameters()
    if type == instrument_string_choices['probe'][0] or type == 0:
        #fb = array(parameters['f'], dtype = complex64)
        e = AA_to_eV / instrument.getWavelength()
        fb = refl.cast_to_array(parameters['f'], e)
    else:
        fb = array(parameters['b'], dtype=complex128) * 1e-5
        abs_xs = array(parameters['xs_ai'], dtype=complex128) * (1e-4)**2

    dens = array(parameters['dens'], dtype=complex64)
    d = array(parameters['d'], dtype=float64)
    magn = array(parameters['magn'], dtype=float64)
    #Transform to radians
    magn_ang = array(parameters['magn_ang'], dtype=float64) * pi / 180.0

    sigma = array(parameters['sigma'], dtype=float64)

    if type == instrument_string_choices['probe'][0] or type == 0:
        sld = dens * fb * instrument.getWavelength()**2 / 2 / pi
    else:
        wl = instrument.getWavelength()
        #sld = dens*(wl**2/2/pi*sqrt(fb**2 - (abs_xs/2.0/wl)**2) -
        #                       1.0J*abs_xs*wl/4/pi)
        sld = neutron_sld(abs_xs, dens, fb, wl)
    # Ordinary Paratt X-rays
    if type == instrument_string_choices['probe'][0] or type == 0:
        R = Paratt.ReflQ(Q,
                         instrument.getWavelength(),
                         1.0 - 2.82e-5 * sld,
                         d,
                         sigma,
                         return_int=return_int)
        #reload(slow_paratt)
        #R = slow_paratt.reflq_kin(Q, instrument.getWavelength(), 1.0 - 2.82e-5 * sld, d, sigma)
        #R = slow_paratt.reflq_pseudo_kin(Q, instrument.getWavelength(), 1.0 - 2.82e-5 * sld, d, sigma)
        #R = slow_paratt.reflq_sra(Q, instrument.getWavelength(), 1.0 - 2.82e-5 * sld, d, sigma)
    #Ordinary Paratt Neutrons
    elif type == instrument_string_choices['probe'][1] or type == 1:
        R = Paratt.ReflQ(Q,
                         instrument.getWavelength(),
                         1.0 - sld,
                         d,
                         sigma,
                         return_int=return_int)

    #Ordinary Paratt but with magnetization
    elif type == instrument_string_choices['probe'][2] or type == 2:
        msld = 2.645e-5 * magn * dens * instrument.getWavelength()**2 / 2 / pi
        # Polarization uu or ++
        if pol == instrument_string_choices['pol'][0] or pol == 0:
            R = Paratt.ReflQ(Q,
                             instrument.getWavelength(),
                             1.0 - sld - msld,
                             d,
                             sigma,
                             return_int=return_int)
        # Polarization dd or --
        elif pol == instrument_string_choices['pol'][1] or pol == 1:
            R = Paratt.ReflQ(Q,
                             instrument.getWavelength(),
                             1.0 - sld + msld,
                             d,
                             sigma,
                             return_int=return_int)
        elif pol == instrument_string_choices['pol'][3] or pol == 3:
            Rp = Paratt.ReflQ(Q,
                              instrument.getWavelength(),
                              1.0 - sld - msld,
                              d,
                              sigma,
                              return_int=return_int)
            Rm = Paratt.ReflQ(Q,
                              instrument.getWavelength(),
                              1.0 - sld + msld,
                              d,
                              sigma,
                              return_int=return_int)

            R = (Rp - Rm) / (Rp + Rm)

        else:
            raise ValueError('The value of the polarization is WRONG.'
                             ' It should be uu(0) or dd(1)')
    # Spin flip
    elif type == instrument_string_choices['probe'][3] or type == 3:
        # Check if we have calcluated the same sample previous:
        if Buffer.TwoThetaQz is not None:
            Q_ok = Buffer.TwoThetaQz.shape == Q.shape
            if Q_ok:
                Q_ok = any(not_equal(Buffer.TwoThetaQz, Q))
        if Buffer.parameters != parameters or not Q_ok:
            msld = 2.645e-5 * magn * dens * instrument.getWavelength(
            )**2 / 2 / pi
            np = 1.0 - sld - msld
            nm = 1.0 - sld + msld
            Vp = (2 * pi / instrument.getWavelength())**2 * (1 - np**2)
            Vm = (2 * pi / instrument.getWavelength())**2 * (1 - nm**2)
            (Ruu, Rdd, Rud, Rdu) = MatrixNeutron.Refl(Q,
                                                      Vp,
                                                      Vm,
                                                      d,
                                                      magn_ang,
                                                      sigma,
                                                      return_int=return_int)
            Buffer.Ruu = Ruu
            Buffer.Rdd = Rdd
            Buffer.Rud = Rud
            Buffer.parameters = parameters.copy()
            Buffer.TwoThetaQz = Q.copy()
        else:
            pass
        # Polarization uu or ++
        if pol == instrument_string_choices['pol'][0] or pol == 0:
            R = Buffer.Ruu
        # Polarization dd or --
        elif pol == instrument_string_choices['pol'][1] or pol == 1:
            R = Buffer.Rdd
        # Polarization ud or +-
        elif (pol == instrument_string_choices['pol'][2] or pol == 2
              or pol == instrument_string_choices['pol'][4] or pol == 4):
            R = Buffer.Rud
        # Calculating the asymmetry ass
        elif pol == instrument_string_choices['pol'][3] or pol == 3:
            R = (Buffer.Ruu - Buffer.Rdd) / (Buffer.Ruu + Buffer.Rdd +
                                             2 * Buffer.Rud)
        else:
            raise ValueError('The value of the polarization is WRONG.'
                             ' It should be uu(0), dd(1) or ud(2)')

    # tof
    elif type == instrument_string_choices['probe'][4] or type == 4:
        wl = 4 * pi * sin(instrument.getIncangle() * pi / 180) / Q
        sld = neutron_sld(abs_xs[:, newaxis], dens[:, newaxis], fb[:, newaxis],
                          wl)
        R = Paratt.Refl_nvary2(
            instrument.getIncangle() * ones(Q.shape),
            (4 * pi * sin(instrument.getIncangle() * pi / 180) / Q),
            1.0 - sld,
            d,
            sigma,
            return_int=return_int)
    # tof spin polarized
    elif type == instrument_string_choices['probe'][5] or type == 5:
        wl = 4 * pi * sin(instrument.getIncangle() * pi / 180) / Q
        sld = neutron_sld(abs_xs[:, newaxis], dens[:, newaxis], fb[:, newaxis],
                          wl)
        msld = 2.645e-5 * magn[:, newaxis] * dens[:, newaxis] * (
            4 * pi * sin(instrument.getIncangle() * pi / 180) / Q)**2 / 2 / pi

        # polarization uu or ++
        if pol == instrument_string_choices['pol'][0] or pol == 0:
            R = Paratt.Refl_nvary2(
                instrument.getIncangle() * ones(Q.shape),
                (4 * pi * sin(instrument.getIncangle() * pi / 180) / Q),
                1.0 - sld - msld,
                d,
                sigma,
                return_int=return_int)
        # polarization dd or --
        elif pol == instrument_string_choices['pol'][1] or pol == 1:
            R = Paratt.Refl_nvary2(
                instrument.getIncangle() * ones(Q.shape),
                (4 * pi * sin(instrument.getIncangle() * pi / 180) / Q),
                1.0 - sld + msld,
                d,
                sigma,
                return_int=return_int)

        # Calculating the asymmetry
        elif pol == instrument_string_choices['pol'][3] or pol == 3:
            Rd = Paratt.Refl_nvary2(
                instrument.getIncangle() * ones(Q.shape),
                (4 * pi * sin(instrument.getIncangle() * pi / 180) / Q),
                1.0 - sld + msld,
                d,
                sigma,
                return_int=return_int)
            Ru = Paratt.Refl_nvary2(
                instrument.getIncangle() * ones(Q.shape),
                (4 * pi * sin(instrument.getIncangle() * pi / 180) / Q),
                1.0 - sld - msld,
                d,
                sigma,
                return_int=return_int)
            R = (Ru - Rd) / (Ru + Rd)

        else:
            raise ValueError('The value of the polarization is WRONG.'
                             ' It should be uu(0) or dd(1) or ass')
    else:
        raise ValueError('The choice of probe is WRONG')

    if return_int:
        # FootprintCorrections
        foocor = footprintcorr(Q, instrument)
        # Resolution corrections
        R = resolutioncorr(R, TwoThetaQz, foocor, instrument, weight)

        return R * instrument.getI0() + instrument.getIbkg()
    else:
        return R