示例#1
0
def EnergySpecular(Energy, TwoThetaQz, sample, instrument):
    ''' Simulate the specular signal from sample when probed with instrument. Energy should be in eV.

    # BEGIN Parameters
    Energy data.x
    TwoThetaQz 3.0
    # END Parameters
    '''
    # preamble to get it working with my class interface
    restype = instrument.getRestype()
    #TODO: Fix so that resolution can be included.
    if restype != 0 and restype != instrument_string_choices['restype'][0]:
        raise ValueError('Only no resolution is allowed for energy scans.')

    wl = AA_to_eV / Energy

    # TTH values given as x
    if instrument.getCoords() == instrument_string_choices['coords'][1] \
            or instrument.getCoords() == 1:
        theta = TwoThetaQz / 2.0
    # Q vector given....
    elif instrument.getCoords() == instrument_string_choices['coords'][0] \
            or instrument.getCoords() == 0:
        theta = arcsin(TwoThetaQz * wl / 4 / pi) * 180.0 / pi

    else:
        raise ValueError('The value for coordinates, coords, is WRONG!'
                         'should be q(0) or tth(1).')
    Q = 4 * pi / wl * sin((2 * theta + instrument.getTthoff()) * pi / 360.0)

    type = instrument.getProbe()

    parameters = sample.resolveLayerParameters()
    if type == instrument_string_choices['probe'][0] or type == 0:
        sld = refl.cast_to_array(parameters['sld_x'], Energy) * 1e-6
    else:
        sld = array(parameters['sld_n'], dtype=complex64).real * 1e-6

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

    wl = instrument.getWavelength()
    l2pi = wl**2 / 2 / 3.141592
    # 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)
        R = Paratt.Refl_nvary2(theta, wl, 1.0 - l2pi * sld, d, sigma)
    else:
        raise ValueError('The choice of probe is WRONG')
    #TODO: Fix corrections
    #FootprintCorrections
    #foocor = footprintcorr(Q, instrument)
    #Resolution corrections
    #R = resolutioncorr(R, TwoThetaQz, foocor, instrument, weight)

    return R * instrument.getI0() + instrument.getIbkg()
示例#2
0
def SLD_calculations(z, item, sample, inst):
    ''' Calculates the scatteringlength density as at the positions z
    if item is None or "all" the function returns a dictonary of values.
    Otherwise it returns the item as identified by its string.
    
    # BEGIN Parameters
    z data.x
    item 'Re'
    # END Parameters
    '''
    parameters = sample.resolveLayerParameters()
    dens = array(parameters['dens'], dtype=complex64)
    #f = array(parameters['f'], dtype = complex64)
    e = AA_to_eV / inst.getWavelength()
    f = refl.cast_to_array(parameters['f'], e)
    b = array(parameters['b'], dtype=complex64) * 1e-5
    abs_xs = array(parameters['xs_ai'], dtype=complex64) * (1e-4)**2
    wl = inst.getWavelength()
    type = inst.getProbe()
    magnetic = False
    mag_sld = 0
    sld_unit = 'r_{e}/\AA^{3}'
    if type == instrument_string_choices['probe'][0] or type == 0:
        sld = dens * f
    elif type == instrument_string_choices['probe'][1] or type == 1 or\
        type == instrument_string_choices['probe'][4] or type == 4:
        sld = dens * (wl**2 / 2 / pi * b -
                      1.0J * abs_xs * wl / 4 / pi) / 1e-5 / (wl**2 / 2 / pi)
        sld_unit = 'fm/\AA^{3}'
    else:
        magnetic = True
        sld = dens * (wl**2 / 2 / pi * b -
                      1.0J * abs_xs * wl / 4 / pi) / 1e-5 / (wl**2 / 2 / pi)
        magn = array(parameters['magn'], dtype=float64)
        #Transform to radians
        magn_ang = array(parameters['magn_ang'], dtype=float64) * pi / 180.0
        mag_sld = 2.645 * magn * dens
        mag_sld_x = mag_sld * cos(magn_ang)
        mag_sld_y = mag_sld * sin(magn_ang)
        sld_unit = 'fm/\AA^{3}'

    d = array(parameters['d'], dtype=float64)
    d = d[1:-1]
    # Include one extra element - the zero pos (substrate/film interface)
    int_pos = cumsum(r_[0, d])
    sigma = array(parameters['sigma'], dtype=float64)[:-1] + 1e-7
    if z == None:
        z = arange(-sigma[0] * 5, int_pos.max() + sigma[-1] * 5, 0.5)
    if not magnetic:
        rho = sum((sld[:-1] - sld[1:])*(0.5 -\
            0.5*erf((z[:,newaxis]-int_pos)/sqrt(2.)/sigma)), 1) + sld[-1]
        dic = {'Re': real(rho), 'Im': imag(rho), 'z': z, 'SLD unit': sld_unit}
    else:
        sld_p = sld + mag_sld
        sld_m = sld - mag_sld
        rho_p = sum((sld_p[:-1] - sld_p[1:])*(0.5 -\
            0.5*erf((z[:,newaxis]-int_pos)/sqrt(2.)/sigma)), 1) + sld_p[-1]
        rho_m = sum((sld_m[:-1] - sld_m[1:])*(0.5 -\
            0.5*erf((z[:,newaxis]-int_pos)/sqrt(2.)/sigma)), 1)  + sld_m[-1]
        rho_mag_x = sum((mag_sld_x[:-1] - mag_sld_x[1:]) * (0.5 - 0.5 * erf(
            (z[:, newaxis] - int_pos) / sqrt(2.) / sigma)), 1) + mag_sld_x[-1]
        rho_mag_y = sum((mag_sld_y[:-1] - mag_sld_y[1:]) * (0.5 - 0.5 * erf(
            (z[:, newaxis] - int_pos) / sqrt(2.) / sigma)), 1) + mag_sld_y[-1]
        #dic = {'Re sld +': real(rho_p), 'Im sld +': imag(rho_p),\
        #        'Re sld -': real(rho_m), 'Im sld -': imag(rho_m), 'z':z,
        #        'SLD unit': sld_unit}
        rho_nucl = (rho_p + rho_m) / 2.
        dic = {'Re non-mag': real(rho_nucl), 'Im non-mag': imag(rho_nucl),\
                'mag': real(rho_p - rho_m)/2, 'z':z, 'mag_x': rho_mag_x, 'mag_y': rho_mag_y,
                'SLD unit': sld_unit}
    if item == None or item == 'all':
        return dic
    else:
        try:
            return dic[item]
        except:
            raise ValueError('The chosen item, %s, does not exist' % item)
示例#3
0
def Specular(TwoThetaQz, sample, instrument):
    """ 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)
        #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)
    #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)
        # 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)
        elif pol == instrument_string_choices['pol'][3] or pol == 3:
            Rp = Paratt.ReflQ(Q, instrument.getWavelength(), 1.0 - sld - msld,
                              d, sigma)
            Rm = Paratt.ReflQ(Q, instrument.getWavelength(), 1.0 - sld + msld,
                              d, sigma)
            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)
            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)
    # 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)
        # 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)
        # 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)
            Ru = Paratt.Refl_nvary2(
                instrument.getIncangle() * ones(Q.shape),
                (4 * pi * sin(instrument.getIncangle() * pi / 180) / Q),
                1.0 - sld - msld, d, sigma)
            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')
    #FootprintCorrections

    foocor = footprintcorr(Q, instrument)
    #Resolution corrections
    R = resolutioncorr(R, TwoThetaQz, foocor, instrument, weight)

    return R * instrument.getI0() + instrument.getIbkg()
示例#4
0
def Specular(TwoThetaQz, sample, instrument):
    """ 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()
        sld = refl.cast_to_array(parameters['sld_x'], e) * 1e-6
    else:
        sld = array(parameters['sld_n'], dtype=complex128) * 1e-6

    d = array(parameters['d'], dtype=float64)
    sld_m = array(parameters['sld_m'], dtype=float64) * 1e-6
    #Transform to radians
    magn_ang = array(parameters['magn_ang'], dtype=float64) * pi / 180.0

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

    wl = instrument.getWavelength()
    l2pi = wl**2 / 2 / 3.141592
    # Ordinary Paratt X-rays
    if type == instrument_string_choices['probe'][0] or type == 0:
        R = Paratt.ReflQ(Q, instrument.getWavelength(), 1.0 - l2pi * sld, d,
                         sigma)
    #Ordinary Paratt Neutrons
    elif type == instrument_string_choices['probe'][1] or type == 1:
        R = Paratt.ReflQ(Q, instrument.getWavelength(), 1.0 - l2pi * sld, d,
                         sigma)
    #Ordinary Paratt but with magnetization
    elif type == instrument_string_choices['probe'][2] or type == 2:
        # Polarization uu or ++
        if pol == instrument_string_choices['pol'][0] or pol == 0:
            R = Paratt.ReflQ(Q,instrument.getWavelength(),\
                1.0 - l2pi*(sld + sld_m), d, sigma)
        # Polarization dd or --
        elif pol == instrument_string_choices['pol'][1] or pol == 1:
            R = Paratt.ReflQ(Q,instrument.getWavelength(),\
                 1.0 - l2pi*(sld - sld_m), d, sigma)
        elif pol == instrument_string_choices['pol'][3] or pol == 3:
            Rp = Paratt.ReflQ(Q, instrument.getWavelength(),
                              1.0 - l2pi * (sld - sld_m), d, sigma)
            Rm = Paratt.ReflQ(Q, instrument.getWavelength(),
                              1.0 - l2pi * (sld + sld_m), d, sigma)
            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 - l2pi * (sld + sld_m)
            nm = 1.0 - l2pi * (sld - sld_m)
            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)
            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)'
            )
    else:
        raise ValueError('The choice of probe is WRONG')
    #FootprintCorrections

    foocor = footprintcorr(Q, instrument)
    #Resolution corrections
    R = resolutioncorr(R, TwoThetaQz, foocor, instrument, weight)

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