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()
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)
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()
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()