def test_contrast_matching(): from periodictable import fasta # Test constrast match holds for varying volume fractions (no labile) SiO2 = formula("[email protected]") match, sld_real = nsf.D2O_match(SiO2) sld_0p0 = nsf.D2O_sld(SiO2, volume_fraction=0.0, D2O_fraction=match) sld_0p7 = nsf.D2O_sld(SiO2, volume_fraction=0.7, D2O_fraction=match) sld_1p0 = nsf.D2O_sld(SiO2, volume_fraction=1.0, D2O_fraction=match) assert np.isclose(sld_0p0[0], sld_real, 1e-14) assert np.isclose(sld_0p7[0], sld_real, 1e-14) assert np.isclose(sld_1p0[0], sld_real, 1e-14) assert not np.isclose(sld_1p0[0], sld_1p0[1], 1e-14) mol = fasta.LIPIDS["cholesteral"].labile_formula match, sld_real = nsf.D2O_match(mol) sld_0p7 = nsf.D2O_sld(mol, volume_fraction=0.7, D2O_fraction=match) assert np.isclose(sld_0p7[0], sld_real, 1e-14) # Test that labile hydrogens are being subsituted in contrast match # Note that D2O mixture is formed from pure D2O and pure water with # natural H:D ratios. mol = formula("C3H4H[1][email protected]") # alanine sld_0p7 = nsf.D2O_sld(mol, volume_fraction=1., D2O_fraction=0.7) sld_0p7_direct = nsf.neutron_sld("[email protected]") #print(sld_0p7) #print(sld_0p7_direct) assert np.isclose(sld_0p7[0], sld_0p7_direct[0], 1e-14) assert np.isclose(sld_0p7[1], sld_0p7_direct[1], 1e-14)
def molecule_table(): # Table of scattering length densities for various molecules print("SLDS for some molecules") for molecule,density in [('SiO2',2.2),('B4C',2.52)]: atoms = formula(molecule).atoms rho,mu,inc = neutron_sld(atoms,density,wavelength=4.75) print("%s(%g g/cm**3) rho=%.4g mu=%.4g inc=%.4g" %(molecule,density,rho,mu,inc))
def molecule_table(): # Table of scattering length densities for various molecules print("SLDS for some molecules") for molecule, density in [('SiO2', 2.2), ('B4C', 2.52)]: atoms = formula(molecule).atoms rho, mu, inc = neutron_sld(atoms, density, wavelength=4.75) print("%s(%g g/cm**3) rho=%.4g mu=%.4g inc=%.4g" % (molecule, density, rho, mu, inc))
def test_composite(): from periodictable.nsf import neutron_composite_sld calc = neutron_composite_sld([formula(s) for s in ('HSO4', 'H2O', 'CCl4')], wavelength=4.75) sld = calc(np.array([3, 1, 2]), density=1.2) sld2 = neutron_sld('3HSO4+1H2O+2CCl4', density=1.2, wavelength=4.75) #print(sld) #print(sld2) assert all(abs(v - w) < 1e-14 for v, w in zip(sld, sld2))
def test_composite(): from periodictable.nsf import neutron_composite_sld calc = neutron_composite_sld([formula(s) for s in ('HSO4','H2O','CCl4')], wavelength=4.75) sld = calc(numpy.array([3,1,2]),density=1.2) sld2 = neutron_sld('3HSO4+1H2O+2CCl4',density=1.2,wavelength=4.75) #print(sld) #print(sld2) assert all(abs(v-w)<1e-14 for v,w in zip(sld,sld2))
def _summarize(M): from periodictable.nsf import neutron_sld, neutron_xs sld = neutron_sld(M,wavelength=4.75) xs = neutron_xs(M,wavelength=4.75) print("%s sld %s"%(M,sld)) print("%s xs %s 1/e %s"%(M,xs,1/sum(xs))) #return for el in list(M.atoms.keys()): print("%s density %s"%(el,el.density)) print("%s sld %s"%(el,el.neutron.sld(wavelength=4.75))) print("%s xs"%el + " %.15g %.15g %.15g"%el.neutron.xs(wavelength=4.75)) print("%s 1/e %s"%(el,1./sum(el.neutron.xs(wavelength=4.75))))
def _summarize(M): from periodictable.nsf import neutron_sld, neutron_xs sld = neutron_sld(M, wavelength=4.75) xs = neutron_xs(M, wavelength=4.75) print M, "sld", sld print M, "xs", xs, "1/e", 1 / sum(xs) #return for el in M.atoms.keys(): print el, "density", el.density print el, "sld", el.neutron.sld(wavelength=4.75) print el, "xs", "%.15g %.15g %.15g" % el.neutron.xs(wavelength=4.75) print el, "1/e", 1. / sum(el.neutron.xs(wavelength=4.75))
def _summarize(M): from periodictable.nsf import neutron_sld, neutron_xs sld = neutron_sld(M,wavelength=4.75) xs = neutron_xs(M,wavelength=4.75) print M,"sld",sld print M,"xs",xs,"1/e",1/sum(xs) #return for el in M.atoms.keys(): print el,"density",el.density print el,"sld",el.neutron.sld(wavelength=4.75) print el,"xs","%.15g %.15g %.15g"%el.neutron.xs(wavelength=4.75) print el,"1/e",1./sum(el.neutron.xs(wavelength=4.75))
def capacity(self): """ Calculate capacity [micro Ah] The charge packing refers, for instance, to the maximum x in Li_x:Si. To test: Li_15 Si_4 -> 3579 mAh :param electrode: electrode composition [string] :param radius: electrode radius [cm] :param thickness: electrode thickness [nm] :param packing: charge packing :param valence_change: change in oxidation state of the carrier """ N_a = 6.022 * 10**23 # Charge unit in Coulombs q = 1.602 * 10**(-19) electrode_material = pt.formula(self.cleaned_data['material_formula']) density = self.cleaned_data['electrode_density'] if density is None: density = electrode_material.density # g/cm^3 if density is None: return None atomic_weight = electrode_material.mass # g/mol volume = 3.1416 * self.cleaned_data[ 'electrode_radius']**2 * self.cleaned_data[ 'electrode_thickness'] / 10**7 # Amp*hour = Coulombs/sec * 3600 sec = 3600 Coulombs capacity_per_gram = self.cleaned_data[ 'ion_packing'] * q * self.cleaned_data[ 'valence_change'] / 3600 / atomic_weight * N_a * 1000 capacity = volume * density * capacity_per_gram # Scattering length density # sld, imaginary sld, incoherent sld, im_sld, incoh = nsf.neutron_sld( compound=self.cleaned_data['material_formula'], wavelength=6.0, density=density) # Return value in muAh return dict(capacity='%6.3g' % capacity, sld='%6.3f' % sld, im_sld='%6.6f' % im_sld, incoherent='%6.3f' % incoh, density=density, c_over_3='%6.3g' % (capacity / 3.0), c_over_5='%6.3g' % (capacity / 5.0))
def _summarize(M): from periodictable.nsf import neutron_sld, neutron_xs sld = neutron_sld(M, wavelength=4.75) xs = neutron_xs(M, wavelength=4.75) print("%s sld %s" % (M, sld)) print("%s xs %s 1/e %s" % (M, xs, 1 / sum(xs))) #return for el in list(M.atoms.keys()): print("%s density %s" % (el, el.density)) print("%s sld %s" % (el, el.neutron.sld(wavelength=4.75))) print("%s xs" % el + " %.15g %.15g %.15g" % el.neutron.xs(wavelength=4.75)) print("%s 1/e %s" % (el, 1. / sum(el.neutron.xs(wavelength=4.75))))
def calculate_sld(self, compound, neutron_wavelength, xray_wavelength): wavelength_n = neutron_wavelength wavelength_x = xray_wavelength density = compound.density n_real, n_imag, n_incoh = self._r( neutron_sld(compound, density=density, wavelength=wavelength_n)) x_real, x_imag = self._r( xray_sld(compound, density=density, wavelength=wavelength_x)) self.ui.lE_SLD_neutron_real.setText(f"{n_real}") self.ui.lE_SLD_neutron_imag.setText(f"{n_imag}") self.ui.lE_SLD_neutron_incoh.setText(f"{n_incoh}") self.ui.lE_SLD_xray_real.setText(f"{x_real}") self.ui.lE_SLD_xray_imag.setText(f"{x_imag}")
def time_composite(): from periodictable.nsf import neutron_composite_sld import time calc = neutron_composite_sld([formula(s) for s in 'HSO4','H2O','CCl4'], wavelength=4.75) q = numpy.array([3,1,2]) N = 1000 bits = [formula(s) for s in 'HSO4','H2O','CCl4'] tic = time.time() for i in range(N): sld = calc(q,density=1.2) toc = time.time()-tic print "composite %.1f us"%(toc/N*1e6) tic = time.time() for i in range(N): sld = neutron_sld(q[0]*bits[0]+q[1]*bits[1]+q[2]*bits[2], density=1.2,wavelength=4.75) toc = time.time()-tic print "direct %.1f us"%(toc/N*1e6)
def time_composite(): from periodictable.nsf import neutron_composite_sld import time calc = neutron_composite_sld([formula(s) for s in ('HSO4','H2O','CCl4')], wavelength=4.75) q = numpy.array([3,1,2]) N = 1000 bits = [formula(s) for s in ('HSO4','H2O','CCl4')] tic = time.time() for i in range(N): sld = calc(q,density=1.2) toc = time.time()-tic print("composite %.1f us"%(toc/N*1e6)) tic = time.time() for i in range(N): sld = neutron_sld(q[0]*bits[0]+q[1]*bits[1]+q[2]*bits[2], density=1.2,wavelength=4.75) toc = time.time()-tic print("direct %.1f us"%(toc/N*1e6))
def test(): H, He, D, O = elements.H, elements.He, elements.D, elements.O assert H.neutron.absorption == 0.3326 assert H.neutron.total == 82.02 assert H.neutron.incoherent == 80.26 assert H.neutron.coherent == 1.7568 assert elements.Ru[101].neutron.bp == None assert H[1].nuclear_spin == '1/2' assert H[2].nuclear_spin == '1' assert not H[6].neutron.has_sld() assert He[3].neutron.b_c_i == -1.48 assert He[3].neutron.bm_i == -5.925 Nb = elements.Nb assert Nb.neutron.absorption == Nb[93].neutron.absorption # Check that b_c values match abundance-weighted values # Note: Currently they do not for match within 5% for Ar,V,Sm or Gd for el in elements: if not hasattr(el, 'neutron'): continue b_c = 0 complete = True for iso in el: if iso.neutron != None: if iso.neutron.b_c == None: complete = False else: b_c += iso.neutron.b_c * iso.neutron.abundance / 100. if complete and b_c != 0 and abs((b_c - el.neutron.b_c) / b_c) > 0.05: err = abs((b_c - el.neutron.b_c) / b_c) ## Printing suppressed for the release version #print("%2s %.3f % 7.3f % 7.3f"%(el.symbol,err,b_c,el.neutron.b_c)) # Check neutron_sld and neutron_xs against NIST calculator # Note that we are using different tables, so a general comparison with # NIST numbers is not possible, but ^30Si and ^18O are the same in both. M = formula('Si[30]O[18]2', density=2.2) sld, xs, depth = neutron_scattering(M, wavelength=4.75) sld2 = neutron_sld(M, wavelength=4.75) assert all(abs(v - w) < 1e-10 for v, w in zip(sld, sld2)) #_summarize(M) #_summarize(formula('O2',density=1.14)) # Alan's numbers: assert abs(sld[0] - 3.27) < 0.01 assert abs(sld[1] - 0) < 0.01 #assert abs(xs[2] - 0.00292) < 0.00001 # TODO fix test assert abs(xs[1] - 0.00569) < 0.00001 #assert abs(depth - 4.329) < 0.001 # TODO fix test # Cu/Mo K-alpha = 1.89e-5 + 2.45e-7i / 1.87e-5 + 5.16e-8i Ni, Si = elements.Ni, elements.Si # Make sure molecular calculation corresponds to direct calculation sld = neutron_sld('Si', density=Si.density, wavelength=4.75) sld2 = Si.neutron.sld(wavelength=4.75) assert all(abs(v - w) < 1e-10 for v, w in zip(sld, sld2)) sld, _, _ = Si.neutron.scattering(wavelength=4.75) sld2 = Si.neutron.sld(wavelength=4.75) assert all(abs(v - w) < 1e-10 for v, w in zip(sld, sld2)) sld, xs, depth = neutron_scattering('Si', density=Si.density, wavelength=4.75) sld2, xs2, depth2 = Si.neutron.scattering(wavelength=4.75) assert all(abs(v - w) < 1e-10 for v, w in zip(sld, sld2)) assert all(abs(v - w) < 1e-10 for v, w in zip(xs, xs2)) assert abs(depth - depth2) < 1e-14 # incoherent cross sections for Ni[62] used to be negative sld, xs, depth = neutron_scattering('Ni[62]', density=Ni[62].density, wavelength=4.75) assert sld[2] == 0 and xs[2] == 0 sld, xs, depth = Ni[62].neutron.scattering(wavelength=4.75) assert sld[2] == 0 and xs[2] == 0 assert Ni[62].neutron.sld()[2] == 0 # Test call from periodictable sld, xs, depth = periodictable.neutron_scattering('H2O', density=1, wavelength=4.75) sld2, xs2, depth2 = neutron_scattering('H2O', density=1, wavelength=4.75) assert all(abs(v - w) < 1e-10 for v, w in zip(sld, sld2)) assert all(abs(v - w) < 1e-10 for v, w in zip(xs, xs2)) assert depth == depth2 sld = periodictable.neutron_sld('H2O', density=1, wavelength=4.75) assert all(abs(v - w) < 1e-10 for v, w in zip(sld, sld2)) # Check empty formula sld, xs, depth = neutron_scattering('', density=0, wavelength=4.75) assert all(v == 0 for v in sld) assert all(v == 0 for v in xs) assert np.isinf(depth) # Check density == 0 works sld, xs, depth = neutron_scattering('Si', density=0, wavelength=4.75) assert all(v == 0 for v in sld) assert all(v == 0 for v in xs) assert np.isinf(depth) # Test natural density D2O_density = (2 * D.mass + O.mass) / (2 * H.mass + O.mass) sld, xs, depth = neutron_scattering('D2O', natural_density=1, wavelength=4.75) sld2, xs2, depth2 = neutron_scattering('D2O', density=D2O_density, wavelength=4.75) assert all(abs(v - w) < 1e-14 for v, w in zip(sld, sld2)) assert all(abs(v - w) < 1e-14 for v, w in zip(xs, xs2)) assert abs(depth - depth2) < 1e-14 # Test that sld depends on density not on the size of the unit cell D2O_density = (2 * D.mass + O.mass) / (2 * H.mass + O.mass) sld, xs, depth = neutron_scattering('D2O', natural_density=1, wavelength=4.75) sld2, xs2, depth2 = neutron_scattering('2D2O', natural_density=1, wavelength=4.75) assert all(abs(v - w) < 1e-14 for v, w in zip(sld, sld2)) assert all(abs(v - w) < 1e-14 for v, w in zip(xs, xs2)) assert abs(depth - depth2) < 1e-14 # Test energy <=> velocity <=> wavelength assert abs( nsf.neutron_wavelength_from_velocity(2200) - 1.7981972618436388) < 1e-14 assert abs(nsf.neutron_wavelength(25) - 1.8) < 0.1 assert abs(nsf.neutron_energy(nsf.neutron_wavelength(25)) - 25) < 1e-14 # Confirm scattering functions accept energy and wavelength sld, xs, depth = neutron_scattering('H2O', density=1, wavelength=4.75) sld2, xs2, depth2 = neutron_scattering('H2O', density=1, energy=nsf.neutron_energy(4.75)) assert all(abs(v - w) < 1e-14 for v, w in zip(sld, sld2)) assert all(abs(v - w) < 1e-14 for v, w in zip(xs, xs2)) assert abs(depth - depth2) < 1e-14
def read(self, path): """ Load data file :param path: file path :return: MagSLD :raise RuntimeError: when the file can't be opened """ pos_x = np.zeros(0) pos_y = np.zeros(0) pos_z = np.zeros(0) sld_n = np.zeros(0) sld_mx = np.zeros(0) sld_my = np.zeros(0) sld_mz = np.zeros(0) vol_pix = np.zeros(0) pix_symbol = np.zeros(0) x_line = [] y_line = [] z_line = [] x_lines = [] y_lines = [] z_lines = [] try: input_f = open(path, 'rb') buff = decode(input_f.read()) lines = buff.split('\n') input_f.close() num = 0 for line in lines: try: # check if line starts with "ATOM" if line[0:6].strip().count('ATM') > 0 or \ line[0:6].strip() == 'ATOM': # define fields of interest atom_name = line[12:16].strip() try: float(line[12]) atom_name = atom_name[1].upper() except Exception: if len(atom_name) == 4: atom_name = atom_name[0].upper() elif line[12] != ' ': atom_name = atom_name[0].upper() + \ atom_name[1].lower() else: atom_name = atom_name[0].upper() _pos_x = float(line[30:38].strip()) _pos_y = float(line[38:46].strip()) _pos_z = float(line[46:54].strip()) pos_x = np.append(pos_x, _pos_x) pos_y = np.append(pos_y, _pos_y) pos_z = np.append(pos_z, _pos_z) try: val = nsf.neutron_sld(atom_name)[0] # sld in Ang^-2 unit val *= 1.0e-6 sld_n = np.append(sld_n, val) atom = formula(atom_name) # cm to A units vol = 1.0e+24 * atom.mass / atom.density / NA vol_pix = np.append(vol_pix, vol) except Exception: logger.error("Error: set the sld of %s to zero" % atom_name) sld_n = np.append(sld_n, 0.0) sld_mx = np.append(sld_mx, 0) sld_my = np.append(sld_my, 0) sld_mz = np.append(sld_mz, 0) pix_symbol = np.append(pix_symbol, atom_name) elif line[0:6].strip().count('CONECT') > 0: toks = line.split() num = int(toks[1]) - 1 val_list = [] for val in toks[2:]: try: int_val = int(val) except Exception: break if int_val == 0: break val_list.append(int_val) #need val_list ordered for val in val_list: index = val - 1 if (pos_x[index], pos_x[num]) in x_line and \ (pos_y[index], pos_y[num]) in y_line and \ (pos_z[index], pos_z[num]) in z_line: continue x_line.append((pos_x[num], pos_x[index])) y_line.append((pos_y[num], pos_y[index])) z_line.append((pos_z[num], pos_z[index])) if len(x_line) > 0: x_lines.append(x_line) y_lines.append(y_line) z_lines.append(z_line) except Exception as exc: logger.error(exc) output = MagSLD(pos_x, pos_y, pos_z, sld_n, sld_mx, sld_my, sld_mz) output.set_conect_lines(x_line, y_line, z_line) output.filename = os.path.basename(path) output.set_pix_type('atom') output.set_pixel_symbols(pix_symbol) output.set_nodes() output.set_pixel_volumes(vol_pix) output.sld_unit = '1/A^(2)' return output except Exception: raise RuntimeError("%s is not a sld file" % path)
def read(self, path): """ Load data file :param path: file path :return: MagSLD :raise RuntimeError: when the file can't be opened """ pos_x = np.zeros(0) pos_y = np.zeros(0) pos_z = np.zeros(0) sld_n = np.zeros(0) sld_mx = np.zeros(0) sld_my = np.zeros(0) sld_mz = np.zeros(0) vol_pix = np.zeros(0) pix_symbol = np.zeros(0) x_line = [] y_line = [] z_line = [] x_lines = [] y_lines = [] z_lines = [] try: input_f = open(path, 'rb') buff = input_f.read() lines = buff.split('\n') input_f.close() num = 0 for line in lines: try: # check if line starts with "ATOM" if line[0:6].strip().count('ATM') > 0 or \ line[0:6].strip() == 'ATOM': # define fields of interest atom_name = line[12:16].strip() try: float(line[12]) atom_name = atom_name[1].upper() except: if len(atom_name) == 4: atom_name = atom_name[0].upper() elif line[12] != ' ': atom_name = atom_name[0].upper() + \ atom_name[1].lower() else: atom_name = atom_name[0].upper() _pos_x = float(line[30:38].strip()) _pos_y = float(line[38:46].strip()) _pos_z = float(line[46:54].strip()) pos_x = np.append(pos_x, _pos_x) pos_y = np.append(pos_y, _pos_y) pos_z = np.append(pos_z, _pos_z) try: val = nsf.neutron_sld(atom_name)[0] # sld in Ang^-2 unit val *= 1.0e-6 sld_n = np.append(sld_n, val) atom = formula(atom_name) # cm to A units vol = 1.0e+24 * atom.mass / atom.density / NA vol_pix = np.append(vol_pix, vol) except: print("Error: set the sld of %s to zero"% atom_name) sld_n = np.append(sld_n, 0.0) sld_mx = np.append(sld_mx, 0) sld_my = np.append(sld_my, 0) sld_mz = np.append(sld_mz, 0) pix_symbol = np.append(pix_symbol, atom_name) elif line[0:6].strip().count('CONECT') > 0: toks = line.split() num = int(toks[1]) - 1 val_list = [] for val in toks[2:]: try: int_val = int(val) except: break if int_val == 0: break val_list.append(int_val) #need val_list ordered for val in val_list: index = val - 1 if (pos_x[index], pos_x[num]) in x_line and \ (pos_y[index], pos_y[num]) in y_line and \ (pos_z[index], pos_z[num]) in z_line: continue x_line.append((pos_x[num], pos_x[index])) y_line.append((pos_y[num], pos_y[index])) z_line.append((pos_z[num], pos_z[index])) if len(x_line) > 0: x_lines.append(x_line) y_lines.append(y_line) z_lines.append(z_line) except: logger.error(sys.exc_value) output = MagSLD(pos_x, pos_y, pos_z, sld_n, sld_mx, sld_my, sld_mz) output.set_conect_lines(x_line, y_line, z_line) output.filename = os.path.basename(path) output.set_pix_type('atom') output.set_pixel_symbols(pix_symbol) output.set_nodes() output.set_pixel_volumes(vol_pix) output.sld_unit = '1/A^(2)' return output except: raise RuntimeError, "%s is not a sld file" % path
def test(): H,He,D,O = elements.H,elements.He,elements.D,elements.O assert H.neutron.absorption == 0.3326 assert H.neutron.total == 82.02 assert H.neutron.incoherent == 80.26 assert H.neutron.coherent == 1.7568 assert elements.Ru[101].neutron.bp == None assert H[1].nuclear_spin == '1/2' assert H[2].nuclear_spin == '1' assert not H[6].neutron.has_sld() assert He[3].neutron.b_c_i == -1.48 assert He[3].neutron.bm_i == -5.925 Nb = elements.Nb assert Nb.neutron.absorption == Nb[93].neutron.absorption # Check that b_c values match abundance-weighted values # Note: Currently they do not for match within 5% for Ar,V,Sm or Gd for el in elements: if not hasattr(el,'neutron'): continue b_c = 0 complete = True for iso in el: if iso.neutron != None: if iso.neutron.b_c == None: complete = False else: b_c += iso.neutron.b_c*iso.neutron.abundance/100. if complete and b_c != 0 and abs((b_c-el.neutron.b_c)/b_c) > 0.05: err = abs((b_c-el.neutron.b_c)/b_c) ## Printing suppressed for the release version #print("%2s %.3f % 7.3f % 7.3f"%(el.symbol,err,b_c,el.neutron.b_c)) # Check neutron_sld and neutron_xs against NIST calculator # Note that we are using different tables, so a general comparison with # NIST numbers is not possible, but ^30Si and ^18O are the same in both. M = formula('Si[30]O[18]2',density=2.2) sld,xs,depth = neutron_scattering(M,wavelength=4.75) sld2 = neutron_sld(M,wavelength=4.75) assert all(abs(v-w)<1e-10 for v,w in zip(sld,sld2)) #_summarize(M) #_summarize(formula('O2',density=1.14)) # Alan's numbers: assert abs(sld[0] - 3.27) < 0.01 assert abs(sld[1] - 0) < 0.01 #assert abs(xs[2] - 0.00292) < 0.00001 # TODO fix test assert abs(xs[1] - 0.00569) < 0.00001 #assert abs(depth - 4.329) < 0.001 # TODO fix test # Cu/Mo K-alpha = 1.89e-5 + 2.45e-7i / 1.87e-5 + 5.16e-8i Ni,Si = elements.Ni, elements.Si # Make sure molecular calculation corresponds to direct calculation sld = neutron_sld('Si',density=Si.density,wavelength=4.75) sld2 = Si.neutron.sld(wavelength=4.75) assert all(abs(v-w)<1e-10 for v,w in zip(sld,sld2)) sld,_,_ = Si.neutron.scattering(wavelength=4.75) sld2 = Si.neutron.sld(wavelength=4.75) assert all(abs(v-w)<1e-10 for v,w in zip(sld,sld2)) sld,xs,depth = neutron_scattering('Si',density=Si.density,wavelength=4.75) sld2,xs2,depth2 = Si.neutron.scattering(wavelength=4.75) assert all(abs(v-w)<1e-10 for v,w in zip(sld,sld2)) assert all(abs(v-w)<1e-10 for v,w in zip(xs,xs2)) assert abs(depth-depth2) < 1e-14 # incoherent cross sections for Ni[62] used to be negative sld,xs,depth = neutron_scattering('Ni[62]',density=Ni[62].density, wavelength=4.75) assert sld[2] == 0 and xs[2] == 0 sld,xs,depth = Ni[62].neutron.scattering(wavelength=4.75) assert sld[2] == 0 and xs[2] == 0 assert Ni[62].neutron.sld()[2] == 0 # Test call from periodictable sld,xs,depth = periodictable.neutron_scattering('H2O',density=1,wavelength=4.75) sld2,xs2,depth2 = neutron_scattering('H2O',density=1,wavelength=4.75) assert all(abs(v-w)<1e-10 for v,w in zip(sld,sld2)) assert all(abs(v-w)<1e-10 for v,w in zip(xs,xs2)) assert depth==depth2 sld = periodictable.neutron_sld('H2O',density=1,wavelength=4.75) assert all(abs(v-w)<1e-10 for v,w in zip(sld,sld2)) # Check empty formula sld,xs,depth = neutron_scattering('',density=0,wavelength=4.75) assert all(v == 0 for v in sld) assert all(v == 0 for v in xs) assert numpy.isinf(depth) # Check density == 0 works sld,xs,depth = neutron_scattering('Si',density=0,wavelength=4.75) assert all(v == 0 for v in sld) assert all(v == 0 for v in xs) assert numpy.isinf(depth) # Test natural density D2O_density = (2*D.mass + O.mass)/(2*H.mass + O.mass) sld,xs,depth = neutron_scattering('D2O',natural_density=1,wavelength=4.75) sld2,xs2,depth2 = neutron_scattering('D2O',density=D2O_density,wavelength=4.75) assert all(abs(v-w)<1e-14 for v,w in zip(sld,sld2)) assert all(abs(v-w)<1e-14 for v,w in zip(xs,xs2)) assert abs(depth-depth2)<1e-14 # Test that sld depends on density not on the size of the unit cell D2O_density = (2*D.mass + O.mass)/(2*H.mass + O.mass) sld,xs,depth = neutron_scattering('D2O',natural_density=1,wavelength=4.75) sld2,xs2,depth2 = neutron_scattering('2D2O',natural_density=1,wavelength=4.75) assert all(abs(v-w)<1e-14 for v,w in zip(sld,sld2)) assert all(abs(v-w)<1e-14 for v,w in zip(xs,xs2)) assert abs(depth-depth2)<1e-14 # Test energy <=> velocity <=> wavelength assert abs(nsf.neutron_wavelength_from_velocity(2200) - 1.7981972618436388) < 1e-14 assert abs(nsf.neutron_wavelength(25) - 1.8) < 0.1 assert abs(nsf.neutron_energy(nsf.neutron_wavelength(25)) - 25) < 1e-14 # Confirm scattering functions accept energy and wavelength sld,xs,depth = neutron_scattering('H2O',density=1,wavelength=4.75) sld2,xs2,depth2 = neutron_scattering('H2O',density=1,energy=nsf.neutron_energy(4.75)) assert all(abs(v-w)<1e-14 for v,w in zip(sld,sld2)) assert all(abs(v-w)<1e-14 for v,w in zip(xs,xs2)) assert abs(depth-depth2)<1e-14