def calculateSld(self, event): """ Calculate the neutron scattering density length of a molecule """ self.clear_outputs() try: #Check validity user inputs flag, msg = self.check_inputs() if self.base is not None and msg.lstrip().rstrip() != "": msg = "SLD Calculator: %s" % str(msg) wx.PostEvent(self.base, StatusEvent(status=msg)) if not flag: return #get ready to compute self.sld_formula = formula(self.compound, density=self.density) (sld_real, sld_im, _), (_, absorp, incoh), \ length = neutron_scattering(compound=self.compound, density=self.density, wavelength=self.neutron_wavelength) if self.xray_source == "[A]": energy = xray_energy(self.xray_source_input) xray_real, xray_im = xray_sld_from_atoms( self.sld_formula.atoms, density=self.density, energy=energy) elif self.xray_source == "[keV]": xray_real, xray_im = xray_sld_from_atoms( self.sld_formula.atoms, density=self.density, energy=self.xray_source_input) elif self.xray_source == "Element": xray_real, xray_im = self.calculate_sld_helper( element=self.xray_source_input, density=self.density, molecule_formula=self.sld_formula) # set neutron sld values val = format_number(sld_real * _SCALE) self.neutron_sld_real_ctl.SetValue(val) val = format_number(math.fabs(sld_im) * _SCALE) self.neutron_sld_im_ctl.SetValue(val) # Compute the Cu SLD self.xray_sld_real_ctl.SetValue(format_number(xray_real * _SCALE)) val = format_number(math.fabs(xray_im) * _SCALE) self.xray_sld_im_ctl.SetValue(val) # set incoherence and absorption self.neutron_inc_ctl.SetValue(format_number(incoh)) self.neutron_abs_ctl.SetValue(format_number(absorp)) # Neutron length self.neutron_length_ctl.SetValue(format_number(length)) # display wavelength #self.wavelength_ctl.SetValue(str(self.wavelength)) #self.wavelength_ctl.SetValue(str(self.wavelength)) except: if self.base is not None: msg = "SLD Calculator: %s" % (sys.exc_value) wx.PostEvent(self.base, StatusEvent(status=msg)) if event is not None: event.Skip()
def calculateSld(self, event): """ Calculate the neutron scattering density length of a molecule """ self.clear_outputs() try: #Check validity user inputs flag, msg = self.check_inputs() if self.base is not None and msg.lstrip().rstrip() != "": msg = "SLD Calculator: %s" % str(msg) wx.PostEvent(self.base, StatusEvent(status=msg)) if not flag: return #get ready to compute self.sld_formula = formula(self.compound, density=self.density) (sld_real, sld_im, _), (_, absorp, incoh), \ length = neutron_scattering(compound=self.compound, density=self.density, wavelength=self.neutron_wavelength) if self.xray_source == "[A]": energy = xray_energy(self.xray_source_input) xray_real, xray_im = xray_sld_from_atoms(self.sld_formula.atoms, density=self.density, energy=energy) elif self.xray_source == "[keV]": xray_real, xray_im = xray_sld_from_atoms(self.sld_formula.atoms, density=self.density, energy=self.xray_source_input) elif self.xray_source == "Element": xray_real, xray_im = self.calculate_sld_helper(element=self.xray_source_input, density=self.density, molecule_formula=self.sld_formula) # set neutron sld values val = format_number(sld_real * _SCALE) self.neutron_sld_real_ctl.SetValue(val) val = format_number(math.fabs(sld_im) * _SCALE) self.neutron_sld_im_ctl.SetValue(val) # Compute the Cu SLD self.xray_sld_real_ctl.SetValue(format_number(xray_real * _SCALE)) val = format_number(math.fabs(xray_im) * _SCALE) self.xray_sld_im_ctl.SetValue(val) # set incoherence and absorption self.neutron_inc_ctl.SetValue(format_number(incoh)) self.neutron_abs_ctl.SetValue(format_number(absorp)) # Neutron length self.neutron_length_ctl.SetValue(format_number(length)) # display wavelength #self.wavelength_ctl.SetValue(str(self.wavelength)) #self.wavelength_ctl.SetValue(str(self.wavelength)) except: if self.base is not None: msg = "SLD Calculator: %s" % (sys.exc_value) wx.PostEvent(self.base, StatusEvent(status=msg)) if event is not None: event.Skip()
def calculate_xray_sld(element, density, molecule_formula): """ Get an element and compute the corresponding SLD for a given formula :param element: elements a string of existing atom """ element_formula = formula(str(element)) if len(element_formula.atoms) != 1: return element = element_formula.atoms.keys()[0] energy = xray_energy(element.K_alpha) atom = molecule_formula.atoms return xray_sld_from_atoms(atom, density=density, energy=energy)
def calculate_xray_sld(element, density, molecule_formula): """ Get an element and compute the corresponding SLD for a given formula :param element: elements a string of existing atom """ element_formula = formula(str(element)) if len(element_formula.atoms) != 1: return element = next(iter(element_formula.atoms)) # only one element... energy = xray_energy(element.K_alpha) atom = molecule_formula.atoms return xray_sld_from_atoms(atom, density=density, energy=energy)
def calculate_sld_helper(self, element, density, molecule_formula): """ Get an element and compute the corresponding SLD for a given formula :param element: elements a string of existing atom """ element_formula = formula(str(element)) if len(element_formula.atoms) != 1: return element = element_formula.atoms.keys()[0] energy = xray_energy(element.K_alpha) atom = molecule_formula.atoms return xray_sld_from_atoms(atom, density=density, energy=energy)
def calculate_xray_sld(self, element): """ Get an element and compute the corresponding SLD for a given formula :param element: elements a string of existing atom """ myformula = formula(str(element)) if len(myformula.atoms) != 1: return element = myformula.atoms.keys()[0] energy = xray_energy(element.K_alpha) self.sld_formula = formula(str(self.compound), density=self.density) atom = self.sld_formula.atoms return xray_sld_from_atoms(atom, density=self.density, energy=energy)
def calculate_xray_sld(self, element): """ Get an element and compute the corresponding SLD for a given formula :param element: elements a string of existing atom """ # TODO: use periodictable.elements object # energy = xray_energy(periodictable.elements[element].K_alpha) # TODO: code is very similar to sld helper myformula = formula(str(element)) if len(myformula.atoms) != 1: return element = list(myformula.atoms.keys())[0] energy = xray_energy(element.K_alpha) self.sld_formula = formula(str(self.compound), density=self.density) atom = self.sld_formula.atoms return xray_sld_from_atoms(atom, density=self.density, energy=energy)
tstart_cpu = time.clock() # start the CPU timer E = 12 # Energy in keV M = 'Be' # Material R = 50 # CRL radius of curvature N = 40 # number of refractive lens M = getattr(pt, '%s'%M) # I dont know how, but 'eval' - not good idea!) name = getattr(pt.elements, '%s'%M).name # name of element density = M.density # density mass = M.mass # mass of element lyamda = ptx.xray_energy(E) n = ptx.index_of_refraction(M, energy=E) # index of refraction delta = 1-n.real # Delta beta = -n.imag # Beta u = 4*np.pi*beta/(lyamda*1e-10) # Linear attenuation coefficient Lpi = 1e-10*lyamda/(2*delta) F = (R*1e-6)/(2*N*delta) # CRL focus distance (thin lens) e1 = (2*np.log(2)/np.pi)**.5 # V.Kohn coefficient Aeff = e1*(F*lyamda*1e-10*delta/beta)**.5 # CRL effective aperture (V.Kohn) Aeff_1m = e1*(1*lyamda*1e-10*delta/beta)**.5 # CRL effective aperture @ 1m focus distance print ('Material %s (%s)'%(M, name)) print ('Density %s g/cm^3'%density)
def cgi_call(): form = cgi.FieldStorage() #print >>sys.stderr, form #print >>sys.stderr, "sample",form.getfirst('sample') #print >>sys.stderr, "mass",form.getfirst('mass') # Parse inputs errors = {}; calculate = form.getfirst('calculate','all') if calculate not in ('scattering','activation','all'): errors['calculate'] = "calculate should be one of 'scattering', 'activation' or 'all'" try: chem = formula(form.getfirst('sample')) except: errors['sample'] = error() try: fluence = float(form.getfirst('flux',100000)) except: errors['flux'] = error() try: fast_ratio = float(form.getfirst('fast','0')) except: errors['fast'] = error() try: Cd_ratio = float(form.getfirst('Cd','0')) except: errors['Cd'] = error() try: exposure = parse_hours(form.getfirst('exposure','1')) except: errors['exposure'] = error() try: mass_str = form.getfirst('mass','1') if mass_str.endswith('kg'): mass = 1000*float(mass_str[:-2]) elif mass_str.endswith('mg'): mass = 0.001*float(mass_str[:-2]) elif mass_str.endswith('ug'): mass = 1e-6*float(mass_str[:-2]) elif mass_str.endswith('g'): mass = float(mass_str[:-1]) else: mass = float(mass_str) except: errors['mass'] = error() try: density_type,density_value = parse_density(form.getfirst('density','0')) except: errors['density'] = error() try: #print >>sys.stderr,form.getlist('rest[]') rest_times = [parse_rest(v) for v in form.getlist('rest[]')] if not rest_times: rest_times = [0,1,24,360] except: errors['rest'] = error() try: decay_level = float(form.getfirst('decay','0.001')) except: errors['decay'] = error() try: thickness = float(form.getfirst('thickness', '1')) except: errors['thickness'] = error() try: wavelength_str = form.getfirst('wavelength','1').strip() if wavelength_str.endswith('meV'): wavelength = nsf.neutron_wavelength(float(wavelength_str[:-3])) elif wavelength_str.endswith('m/s'): wavelength = nsf.neutron_wavelength_from_velocity(float(wavelength_str[:-3])) elif wavelength_str.endswith('Ang'): wavelength = float(wavelength_str[:-3]) else: wavelength = float(wavelength_str) #print >>sys.stderr,wavelength_str except: errors['wavelength'] = error() try: xray_source = form.getfirst('xray','Cu Ka').strip() if xray_source.endswith('Ka'): xray_wavelength = elements.symbol(xray_source[:-2].strip()).K_alpha elif xray_source.endswith('keV'): xray_wavelength = xsf.xray_wavelength(float(xray_source[:-3])) elif xray_source.endswith('Ang'): xray_wavelength = float(xray_source[:-3]) elif xray_source[0].isalpha(): xray_wavelength = elements.symbol(xray_source).K_alpha else: xray_wavelength = float(xray_source) #print >>sys.stderr,"xray",xray_source,xray_wavelength except: errors['xray'] = error() try: abundance_source = form.getfirst('abundance','IAEA') if abundance_source == "NIST": abundance = activation.NIST2001_isotopic_abundance elif abundance_source == "IAEA": abundance = activation.IAEA1987_isotopic_abundance else: raise ValueError("abundance should be NIST or IAEA") except: errors['abundance'] = error() if errors: return {'success':False, 'error':'invalid request', 'detail':errors} # Fill in defaults #print >>sys.stderr,density_type,density_value,chem.density if density_type == 'default' or density_value == 0: # default to a density of 1 if chem.density is None: chem.density = 1 elif density_type == 'volume': chem.density = chem.molecular_mass/density_value elif density_type == 'natural': # if density is given, assume it is for natural abundance chem.natural_density = density_value elif density_type == 'isotope': chem.density = density_value else: raise ValueError("unknown density type %r"%density_type) result = {'success': True} result['sample'] = { 'formula': str(chem), 'mass': mass, 'density': chem.density, 'thickness': thickness, 'natural_density': chem.natural_density, } # Run calculations if calculate in ('activation', 'all'): try: env = activation.ActivationEnvironment(fluence=fluence,fast_ratio=fast_ratio, Cd_ratio=Cd_ratio) sample = activation.Sample(chem, mass=mass) sample.calculate_activation(env,exposure=exposure,rest_times=rest_times,abundance=abundance) decay_time = sample.decay_time(decay_level) total = [0]*len(sample.rest_times) rows = [] for el,activity_el in activation.sorted_activity(sample.activity.items()): total = [t+a for t,a in zip(total,activity_el)] rows.append({'isotope':el.isotope,'reaction':el.reaction,'product':el.daughter, 'halflife':el.Thalf_str,'comments':el.comments,'levels':activity_el}) result['activation'] = { 'flux': fluence, 'fast': fast_ratio, 'Cd': Cd_ratio, 'exposure': exposure, 'rest': rest_times, 'activity': rows, 'total': total, 'decay_level': decay_level, 'decay_time': decay_time, } #print >>sys.stderr,result except: result['activation'] = {"error": error()} #nsf_sears.replace_neutron_data() if calculate in ('scattering', 'all'): try: sld,xs,penetration = neutron_scattering(chem, wavelength=wavelength) result['scattering'] = { 'neutron': { 'wavelength': wavelength, 'energy': nsf.neutron_energy(wavelength), 'velocity': nsf.VELOCITY_FACTOR/wavelength, }, 'xs': {'coh': xs[0], 'abs': xs[1], 'incoh': xs[2]}, 'sld': {'real': sld[0], 'imag': sld[1], 'incoh': sld[2]}, 'penetration': penetration, 'transmission': 100*exp(-thickness/penetration), } except: missing = [str(el) for el in chem.atoms if not el.neutron.has_sld()] if any(missing): msg = "missing neutron cross sections for "+", ".join(missing) else: msg = error() result['scattering'] = {'error': msg } try: xsld = xray_sld(chem, wavelength=xray_wavelength) result['xray_scattering'] = { 'xray': { 'wavelength': xray_wavelength, 'energy': xsf.xray_energy(xray_wavelength), }, 'sld': {'real': xsld[0], 'imag': xsld[1]}, } except: result['xray_scattering'] = {'error': error()} return result
def test_xsf(): # Check some K_alpha and K_beta1 values assert Cu.K_alpha == 1.5418 assert Cu.K_beta1 == 1.3922 # Check scalar scattering factor lookup f1,f2 = Ni.xray.scattering_factors(energy=xray_energy(Cu.K_alpha)) assert abs(f1-25.0229)<0.0001 assert abs(f2-0.5249)<0.0001 # Check array scattering factor lookup f1,f2 = Ni.xray.scattering_factors(wavelength=Cu.K_alpha) m1,m2 = Ni.xray.scattering_factors(wavelength=Mo.K_alpha) B1,B2 = Ni.xray.scattering_factors(wavelength=[Cu.K_alpha,Mo.K_alpha]) assert (B1==[f1,m1]).all() and (B2==[f2,m2]).all() # Check that we can lookup sld by wavelength and energy Fe_rho,Fe_mu = Fe.xray.sld(wavelength=Cu.K_alpha) assert abs(Fe_rho-59.45) < 0.01 Si_rho,Si_mu = Si.xray.sld(energy=8.050) assert abs(Si_rho-20.0701) < 0.0001 assert abs(Si_mu-0.4572) < 0.0001 # Check that wavelength is the default Fe_rho_default,Fe_mu_default = Fe.xray.sld(wavelength=Cu.K_alpha) assert Fe_rho == Fe_rho_default and Fe_mu == Fe_mu_default # Check array form of sld lookup f1,f2 = Si.xray.sld(wavelength=Cu.K_alpha) m1,m2 = Si.xray.sld(wavelength=Mo.K_alpha) B1,B2 = Si.xray.sld(wavelength=[Cu.K_alpha,Mo.K_alpha]) assert (B1==[f1,m1]).all() and (B2==[f2,m2]).all() # Check energy conversion is consistent f1,f2 = Si.xray.sld(energy=xray_energy(Cu.K_alpha)) m1,m2 = Si.xray.sld(energy=xray_energy(Mo.K_alpha)) assert (B1==[f1,m1]).all() and (B2==[f2,m2]).all() B1,B2 = Si.xray.sld(energy=xray_energy([Cu.K_alpha,Mo.K_alpha])) assert (B1==[f1,m1]).all() and (B2==[f2,m2]).all() #print Cu.xray.sftable #plot_xsf(Cu) #emission_table() #sld_table(table,Cu.K_alpha) """ # Table of scattering length densities for various molecules for molecule,density in [('SiO2',2.2),('B4C',2.52)]: atoms = formula(molecule).atoms rho,mu = xray_sld(atoms,density,wavelength=Cu.K_alpha) print "sld for %s(%g g/cm**3) rho=%.4g mu=%.4g"\ %(molecule,density,rho,mu) """ # Cross check against mo rho,mu = xray_sld({Si:1},density=Si.density,wavelength=1.54) rhoSi,muSi = Si.xray.sld(wavelength=1.54) assert abs(rho - rhoSi) < 1e-14 assert abs(mu - muSi) < 1e-14 # Check that xray_sld works as expected atoms = formula('SiO2').atoms rho,mu = xray_sld(atoms,density=2.2,energy=xray_energy(Cu.K_alpha)) assert abs(rho-18.87)<0.1 atoms = formula('B4C').atoms rho,mu = xray_sld(atoms,density=2.52,energy=xray_energy(Cu.K_alpha)) assert abs(rho-20.17)<0.1 F = formula('', density=0) rho,mu = xray_sld('', density=0, wavelength=Cu.K_alpha) assert rho==mu==0 # Check natural density calculations D2O_density = (2*D.mass + O.mass)/(2*H.mass + O.mass) rho,mu = xray_sld('D2O',natural_density=1,wavelength=1.54) rho2,mu2 = xray_sld('D2O',density=D2O_density,wavelength=1.54) assert abs(rho-rho2)<1e-14 and abs(mu-mu2)<1e-14 # Check f0 calculation for scalar, vector, array and empty Q1,Q2 = 4*pi/Cu.K_alpha, 4*pi/Mo.K_alpha f0 = Ni.xray.f0(Q=Q1) assert abs(f0-10.11303) < 0.00001 assert isnan(Ni.xray.f0(Q=7*4*pi)) f0 = Ni.xray.f0(Q=Q1) m0 = Ni.xray.f0(Q=Q2) B0 = Ni.xray.f0(Q=[Q1,Q2]) assert (B0==[f0,m0]).all() f0 = Ni.xray.f0(Q=[]) assert len(f0) == 0 f0 = Ni.xray.f0(Q=[[1,2],[3,4]]) assert abs(f0[0,0] - Ni.xray.f0(1)) < 1e-14 assert abs(f0[0,1] - Ni.xray.f0(2)) < 1e-14 assert abs(f0[1,0] - Ni.xray.f0(3)) < 1e-14 assert abs(f0[1,1] - Ni.xray.f0(4)) < 1e-14 # Check f0 calculation for ion Ni_2p_f0 = Ni.ion[2].xray.f0(Q=Q1) assert abs(Ni_2p_f0-10.09535) < 0.00001 Ni58_2p_f0 = Ni[58].ion[2].xray.f0(Q=Q1) assert Ni_2p_f0 == Ni58_2p_f0 # The following test is implementation specific, and is not guaranteed # to succeed if the extension interface changes. assert '_xray' not in Ni[58].__dict__
def test_xsf(): # Check some K_alpha and K_beta1 values assert Cu.K_alpha == 1.5418 assert Cu.K_beta1 == 1.3922 # Check scalar scattering factor lookup f1, f2 = Ni.xray.scattering_factors(energy=xray_energy(Cu.K_alpha)) assert abs(f1 - 25.0229) < 0.0001 assert abs(f2 - 0.5249) < 0.0001 # Check array scattering factor lookup f1, f2 = Ni.xray.scattering_factors(wavelength=Cu.K_alpha) m1, m2 = Ni.xray.scattering_factors(wavelength=Mo.K_alpha) B1, B2 = Ni.xray.scattering_factors(wavelength=[Cu.K_alpha, Mo.K_alpha]) assert (B1 == [f1, m1]).all() and (B2 == [f2, m2]).all() # Check that we can lookup sld by wavelength and energy Fe_rho, Fe_mu = Fe.xray.sld(wavelength=Cu.K_alpha) assert abs(Fe_rho - 59.45) < 0.01 Si_rho, Si_mu = Si.xray.sld(energy=8.050) assert abs(Si_rho - 20.0701) < 0.0001 assert abs(Si_mu - 0.4572) < 0.0001 # Check that wavelength is the default Fe_rho_default, Fe_mu_default = Fe.xray.sld(wavelength=Cu.K_alpha) assert Fe_rho == Fe_rho_default and Fe_mu == Fe_mu_default # Check array form of sld lookup f1, f2 = Si.xray.sld(wavelength=Cu.K_alpha) m1, m2 = Si.xray.sld(wavelength=Mo.K_alpha) B1, B2 = Si.xray.sld(wavelength=[Cu.K_alpha, Mo.K_alpha]) assert (B1 == [f1, m1]).all() and (B2 == [f2, m2]).all() # Check energy conversion is consistent f1, f2 = Si.xray.sld(energy=xray_energy(Cu.K_alpha)) m1, m2 = Si.xray.sld(energy=xray_energy(Mo.K_alpha)) assert (B1 == [f1, m1]).all() and (B2 == [f2, m2]).all() B1, B2 = Si.xray.sld(energy=xray_energy([Cu.K_alpha, Mo.K_alpha])) assert (B1 == [f1, m1]).all() and (B2 == [f2, m2]).all() #print Cu.xray.sftable #plot_xsf(Cu) #emission_table() #sld_table(table,Cu.K_alpha) """ # Table of scattering length densities for various molecules for molecule,density in [('SiO2',2.2),('B4C',2.52)]: atoms = formula(molecule).atoms rho,mu = xray_sld(atoms,density,wavelength=Cu.K_alpha) print "sld for %s(%g g/cm**3) rho=%.4g mu=%.4g"\ %(molecule,density,rho,mu) """ # Cross check against mo rho, mu = xray_sld({Si: 1}, density=Si.density, wavelength=1.54) rhoSi, muSi = Si.xray.sld(wavelength=1.54) assert abs(rho - rhoSi) < 1e-14 assert abs(mu - muSi) < 1e-14 # Check that xray_sld works as expected atoms = formula('SiO2').atoms rho, mu = xray_sld(atoms, density=2.2, energy=xray_energy(Cu.K_alpha)) assert abs(rho - 18.87) < 0.1 atoms = formula('B4C').atoms rho, mu = xray_sld(atoms, density=2.52, energy=xray_energy(Cu.K_alpha)) assert abs(rho - 20.17) < 0.1 F = formula('', density=0) rho, mu = xray_sld('', density=0, wavelength=Cu.K_alpha) assert rho == mu == 0 # Check natural density calculations D2O_density = (2 * D.mass + O.mass) / (2 * H.mass + O.mass) rho, mu = xray_sld('D2O', natural_density=1, wavelength=1.54) rho2, mu2 = xray_sld('D2O', density=D2O_density, wavelength=1.54) assert abs(rho - rho2) < 1e-14 and abs(mu - mu2) < 1e-14 # Check f0 calculation for scalar, vector, array and empty Q1, Q2 = 4 * pi / Cu.K_alpha, 4 * pi / Mo.K_alpha f0 = Ni.xray.f0(Q=Q1) assert abs(f0 - 10.11303) < 0.00001 assert isnan(Ni.xray.f0(Q=7 * 4 * pi)) f0 = Ni.xray.f0(Q=Q1) m0 = Ni.xray.f0(Q=Q2) B0 = Ni.xray.f0(Q=[Q1, Q2]) assert (B0 == [f0, m0]).all() f0 = Ni.xray.f0(Q=[]) assert len(f0) == 0 f0 = Ni.xray.f0(Q=[[1, 2], [3, 4]]) assert f0[0, 0] == Ni.xray.f0(1) assert f0[0, 1] == Ni.xray.f0(2) assert f0[1, 0] == Ni.xray.f0(3) assert f0[1, 1] == Ni.xray.f0(4) # Check f0 calculation for ion Ni_2p_f0 = Ni.ion[2].xray.f0(Q=Q1) assert abs(Ni_2p_f0 - 10.09535) < 0.00001 Ni58_2p_f0 = Ni[58].ion[2].xray.f0(Q=Q1) assert Ni_2p_f0 == Ni58_2p_f0 # The following test is implementation specific, and is not guaranteed # to succeed if the extension interface changes. assert '_xray' not in Ni[58].__dict__