def __init__(self, name, formula, cell_volume=None, density=None, charge=0): # Fill in density or cell_volume. M = pt.formula(formula, natural_density=density) if cell_volume is not None: M.density = 1e24 * M.molecular_mass / cell_volume if cell_volume > 0 else 0 #print name, M.molecular_mass, cell_volume, M.density else: cell_volume = 1e24 * M.molecular_mass / M.density Hnatural = isotope_substitution(M, pt.T, pt.H) H = isotope_substitution(M, pt.T, pt.H[1]) D = isotope_substitution(M, pt.T, pt.D) self.name = name self.formula = M self.cell_volume = cell_volume self.sld = pt.neutron_sld(Hnatural, wavelength=5)[0] self.Hsld = pt.neutron_sld(H, wavelength=5)[0] self.Dsld = pt.neutron_sld(D, wavelength=5)[0] self.mass, self.Hmass, self.Dmass = Hnatural.mass, H.mass, D.mass self.D2Omatch = D2Omatch(self.sld, self.Dsld) self.charge = charge self.Hnatural = Hnatural
def __init__(self, name, formula, cell_volume=None, natural_density=None, charge=0): M = pt.formula(formula, natural_density=natural_density) # Fill in density or cell_volume if cell_volume is not None: M.density = 1e24 * M.molecular_mass / cell_volume if cell_volume > 0 else 0 else: cell_volume = 1e24 * M.molecular_mass / M.density self.cell_volume = cell_volume self.name = name self.formula = M self.natural = isotope_substitution(M, pt.T, pt.H) self.H = isotope_substitution(M, pt.T, pt.H[1]) self.D = isotope_substitution(M, pt.T, pt.D) self.sld = pt.neutron_sld(self.natural, wavelength=5)[0] self.H_sld = pt.neutron_sld(self.H, wavelength=5)[0] self.D_sld = pt.neutron_sld(self.D, wavelength=5)[0] self.D2Omatch = D2Omatch(self.H_sld, self.D_sld) self.charge = charge
def test(): # Regression test: make sure neutron sld is an isotope property # Note: it is important that this test be run separately D2O = periodictable.formula('D2O',density=20./18) D2O_coh,D2O_abs,D2O_inc = periodictable.neutron_sld(D2O) D2O_coh2,D2O_abs2,D2O_inc2 = periodictable.neutron_sld(D2O) H2O = periodictable.formula('H2O',density=1) H2O_coh,H2O_abs,H2O_inc = periodictable.neutron_sld(H2O) assert D2O_coh == D2O_coh2 assert D2O_coh != H2O_coh
def test(): # Regression test: make sure neutron sld is an isotope property # Note: it is important that this test be run separately D2O = periodictable.formula('D2O', density=20. / 18) D2O_coh, D2O_abs, D2O_inc = periodictable.neutron_sld(D2O) D2O_coh2, D2O_abs2, D2O_inc2 = periodictable.neutron_sld(D2O) H2O = periodictable.formula('H2O', density=1) H2O_coh, H2O_abs, H2O_inc = periodictable.neutron_sld(H2O) assert D2O_coh == D2O_coh2 assert D2O_coh != H2O_coh
def calculate(self): try: formula = pt.formula(self.ui.chemical_formula.text(), ) except (pyparsing.ParseException, TypeError, ValueError): return density = self.ui.mass_density.value() molecular_volume = self.ui.molecular_volume.value() neutron_wavelength = self.ui.neutron_wavelength.value() xray_energy = self.ui.xray_energy.value() if self.ui.use_volume.isChecked(): density = formula.molecular_mass / formula.volume( a=molecular_volume, b=1, c=1) self.ui.mass_density.setValue(density) elif self.ui.use_density.isChecked(): volume = formula.mass / density / \ pt.constants.avogadro_number * 1e24 self.ui.molecular_volume.setValue(volume) real, imag, mu = pt.neutron_sld(formula, density=density, wavelength=neutron_wavelength) self.ui.neutron_SLD.setText('%.6g' % real + ' + ' + '%.6g' % imag + 'j') real, imag = pt.xray_sld(formula, density=density, energy=xray_energy) self.ui.xray_SLD.setText('%.6g' % real + ' + ' + '%.6g' % imag + 'j')
def __init__(self, name, formula, cell_volume=None, density=None, charge=0): # Fill in density or cell_volume M = pt.formula(formula, natural_density=density) if cell_volume != None: M.density = 1e24*M.molecular_mass/cell_volume if cell_volume>0 else 0 #print name, M.molecular_mass, cell_volume, M.density else: cell_volume = 1e24*M.molecular_mass/M.density Hnatural = isotope_substitution(M, pt.T, pt.H) H = isotope_substitution(M, pt.T, pt.H[1]) D = isotope_substitution(M, pt.T, pt.D) self.name = name self.formula = M self.cell_volume = cell_volume self.sld = pt.neutron_sld(Hnatural, wavelength=5)[0] self.Hsld = pt.neutron_sld(H, wavelength=5)[0] self.Dsld = pt.neutron_sld(D, wavelength=5)[0] self.mass, self.Hmass, self.Dmass = Hnatural.mass, H.mass, D.mass self.D2Omatch = D2Omatch(self.Hsld, self.Dsld) self.charge = charge
def neutron_scattering_lengths(self, condition, vf_d_solvent=1, neutron_wavelength=1.8): vh, vt = self.conditions[condition] hf = exchange_protons_formula(self.hf, self.head_exchangable, vf_d_solvent) tf = exchange_protons_formula(self.tf, self.tail_exchangable, vf_d_solvent) h_density = calculate_density(hf, vh) t_density = calculate_density(tf, vt) h_sld = pt.neutron_sld(hf, density=h_density, wavelength=neutron_wavelength) t_sld = pt.neutron_sld(tf, density=t_density, wavelength=neutron_wavelength) h_scatlen = complex(*h_sld[0:2]) * vh / 1e6 t_scatlen = complex(*t_sld[0:2]) * vt / 1e6 return h_scatlen, t_scatlen
def calculate(self): try: formula = pt.formula(self.ui.chemical_formula.text()) except (pyparsing.ParseException, TypeError, ValueError, KeyError): # a problem was experience during parsing of the formula. return if not len(formula.atoms): return density = self.ui.mass_density.value() molecular_volume = self.ui.molecular_volume.value() neutron_wavelength = self.ui.neutron_wavelength.value() xray_energy = self.ui.xray_energy.value() if self.ui.use_volume.isChecked(): density = formula.molecular_mass / formula.volume( a=molecular_volume, b=1, c=1) self.ui.mass_density.setValue(density) elif self.ui.use_density.isChecked(): try: volume = (formula.mass / density / pt.constants.avogadro_number * 1e24) except ZeroDivisionError: volume = np.nan self.ui.molecular_volume.setValue(volume) try: real, imag, mu = pt.neutron_sld(formula, density=density, wavelength=neutron_wavelength) self.ui.neutron_SLD.setText("%.6g" % real + " + " + "%.6g" % imag + "j") except Exception: self.ui.neutron_SLD.setText("NaN") try: real, imag = pt.xray_sld(formula, density=density, energy=xray_energy) self.ui.xray_SLD.setText("%.6g" % real + " + " + "%.6g" % imag + "j") except Exception: self.ui.xray_SLD.setText("NaN")
def calculate(self): try: formula = pt.formula(self.ui.chemical_formula.text(),) except (pyparsing.ParseException, TypeError, ValueError): return density = self.ui.mass_density.value() molecular_volume = self.ui.molecular_volume.value() neutron_wavelength = self.ui.neutron_wavelength.value() xray_energy = self.ui.xray_energy.value() if self.ui.use_volume.isChecked(): density = formula.molecular_mass / formula.volume( a=molecular_volume, b=1, c=1) self.ui.mass_density.setValue(density) elif self.ui.use_density.isChecked(): volume = formula.mass / density / \ pt.constants.avogadro_number * 1e24 self.ui.molecular_volume.setValue(volume) real, imag, mu = pt.neutron_sld(formula, density=density, wavelength=neutron_wavelength) self.ui.neutron_SLD.setText( '%.6g' % real + ' + ' + '%.6g' % imag + 'j') real, imag = pt.xray_sld(formula, density=density, energy=xray_energy) self.ui.xray_SLD.setText('%.6g' % real + ' + ' + '%.6g' % imag + 'j')
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
if type is None: if filename.endswith('.fna'): type = 'dna' elif filename.endswith('.ffn'): type = 'dna' elif filename.endswith('.faa'): type = 'aa' elif filename.endswith('.frn'): type = 'rna' else: type = 'aa' return type # Water density at 20C; neutron wavelength doesn't matter (use 5 A). H2O_SLD = pt.neutron_sld(pt.formula("[email protected]"), wavelength=5)[0] D2O_SLD = pt.neutron_sld(pt.formula("[email protected]"), wavelength=5)[0] def D2Omatch(Hsld, Dsld): """ Find the D2O% concentration of solvent such that neutron SLD of the material matches the neutron SLD of the solvent. *Hsld*, *Dsld* are the SLDs for the hydrogenated and deuterated forms of the material respectively, where *D* includes all the labile protons swapped for deuterons. Water SLD is calculated at 20 C. Note that the resulting percentage is only meaningful between 0% to 100%. Beyond 100% you will need an additional constrast agent in the 100% D2O solvent to increase the SLD enough to match.
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
def _guess_type_from_filename(filename, type): if type is None: if filename.endswith('.fna'): type = 'dna' elif filename.endswith('.ffn'): type = 'dna' elif filename.endswith('.faa'): type = 'aa' elif filename.endswith('.frn'): type = 'rna' else: type = 'aa' return type # Water density at 20C; neutron wavelength doesn't matter (use 5 A). H2O_SLD = pt.neutron_sld(pt.formula("[email protected]"), wavelength=5)[0] D2O_SLD = pt.neutron_sld(pt.formula("[email protected]"), wavelength=5)[0] def D2Omatch(Hsld, Dsld): """ Find the D2O% concentration of solvent such that neutron SLD of the material matches the neutron SLD of the solvent. *Hsld*, *Dsld* are the SLDs for the hydrogenated and deuterated forms of the material respectively, where *D* includes all the labile protons swapped for deuterons. Water SLD is calculated at 20 C. Note that the resulting percentage is only meaningful between 0% to 100%. Beyond 100% you will need an additional constrast agent in the 100% D2O solvent to increase the SLD enough to match. """ # SLD(%Dsample + (1-%)Hsample) = SLD(%D2O + (1-%)H2O)