Example #1
0
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)
Example #2
0
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))
Example #3
0
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))
Example #4
0
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))
Example #5
0
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))
Example #6
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))))
Example #7
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 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))
Example #8
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 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))
Example #9
0
    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))
Example #10
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))))
Example #11
0
    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)
Example #13
0
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))
Example #14
0
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
Example #15
0
    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)
Example #16
0
    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
Example #17
0
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