Example #1
0
 def __init__(self,
              atoms,
              keV,
              DW,
              comment=None,
              occupancy=1.0,
              fit_cell_to_atoms=False):
     self.atoms = atoms.copy()
     from collections import OrderedDict
     self.atom_types = list(
         OrderedDict((element, None)
                     for element in self.atoms.get_chemical_symbols()))
     self.keV = keV
     self.DW = DW
     self._check_key_dictionary(self.DW, 'DW')
     self.comment = comment
     if np.isscalar(occupancy):
         self.occupancy = dict(
             zip(self.atom_types, [occupancy] * len(self.atom_types)))
     else:
         self.occupancy = occupancy
     self._check_key_dictionary(self.occupancy, 'occupancy')
     self.numbers = symbols2numbers(self.atom_types)
     if fit_cell_to_atoms:
         self.atoms.translate(-self.atoms.positions.min(axis=0))
         self.atoms.set_cell(self.atoms.positions.max(axis=0))
Example #2
0
    def _parse_array_from_atoms(self, name, element, check_same_value):
        """
        Return the array "name" for the given element.

        Parameters
        ----------
        name : str
            The name of the arrays. Can be any key of `atoms.arrays`
        element : str, int
            The element to be considered.
        check_same_value : bool
            Check if all values are the same in the array. Necessary for
            'occupancies' and 'debye_waller_factors' arrays.

        Returns
        -------
        array containing the values corresponding defined by "name" for the
        given element. If check_same_value, return a single element.

        """
        if isinstance(element, str):
            element = symbols2numbers(element)[0]
        sliced_array = self.atoms.arrays[name][self.atoms.numbers == element]

        if check_same_value:
            # to write the occupancies and the Debye Waller factor of xtl file
            # all the value must be equal
            if np.unique(sliced_array).size > 1:
                raise ValueError(
                    "All the '{}' values for element '{}' must be "
                    "equal.".format(name, chemical_symbols[element]))
            sliced_array = sliced_array[0]

        return sliced_array
Example #3
0
def AlloyAtomsRandom(symbols, atoms):
    numbers_new = symbols2numbers(symbols)
    numbers_old = atoms.get_atomic_numbers()
    natoms = len(numbers_old)

    if len(numbers_old) != len(numbers_new):
        raise ValueError("The number of atoms in symbols (%i) " %(len(numbers_new),) +
                         "must be equal to that in atoms (%i)!" % (len(atoms),))

    numbers = []
    indexes = []
    for n in np.unique(numbers_new + numbers_old.tolist()):
        d = (numbers_new == n).sum() - (numbers_old == n).sum()
        if d > 0: # Add
            while d > 0:
                i = np.random.random_integers(0, len(numbers))
                numbers.insert(i, n)
                d -= 1
        elif d < 0: # Remove
            ind = np.arange(natoms)[numbers_old == n].tolist()
            while d < 0:
                i = np.random.random_integers(0, len(ind) - 1)
                indexes.append(ind.pop(i))
                d += 1

    numbers_old[indexes] = numbers
    atoms.set_atomic_numbers(numbers_old)
    return atoms
Example #4
0
    def _get_debye_waller_factors(self, DW):
        if np.isscalar(DW):
            if len(self.atom_types) > 1:
                raise ValueError('This cell contains more then one type of '
                                 'atoms and the Debye-Waller factor needs to '
                                 'be provided for each atom using a '
                                 'dictionary.')
            DW = np.ones_like(self.atoms.numbers) * DW
        elif isinstance(DW, dict):
            verify_dictionary(self.atoms, DW, 'DW')
            # Get the arrays of DW from mapping the DW defined by symbol
            DW = {symbols2numbers(k)[0]: v for k, v in DW.items()}
            DW = np.vectorize(DW.get)(self.atoms.numbers)
        else:
            for name in ['DW', 'debye_waller_factors']:
                if name in self.atoms.arrays:
                    DW = self.atoms.get_array(name)

        if DW is None:
            raise ValueError('Missing Debye-Waller factors. It can be '
                             'provided as a dictionary with symbols as key or '
                             'can be set for each atom by using the '
                             '`set_array("debye_waller_factors", values)` of '
                             'the `Atoms` object.')

        return DW
Example #5
0
def RandomSphereAtoms(symbols, covalent=None, radius=None, vacuum=0.0):
    numbers = symbols2numbers(symbols)
    if covalent is None:
        covalent = 0.8 * np.mean(covalent_radii[numbers])
    if radius is None:
        radius = covalent * float(len(numbers))**(1.0/3.0)
    cell = 3.0 * radius * np.ones(3, float) + vacuum
    positions = radius * np.ones((len(numbers), 3))
    for i in range(len(numbers)):
        pos = radius * RandSphere(1) + 0.5 * cell
        while np.any(np.sum((positions - pos)**2, axis=1) < covalent**2):
            pos = radius * RandSphere(1) + 0.5 * cell
        positions[i] = pos.copy()
    #positions = radius * RandSphere(len(numbers)) + 0.5 * cell
    return Atoms(numbers, positions=positions, cell=cell)
Example #6
0
    def __init__(self,
                 atoms,
                 keV,
                 debye_waller_factors=None,
                 comment=None,
                 occupancies=None,
                 fit_cell_to_atoms=False):
        verify_cell_for_export(atoms.get_cell())

        self.atoms = atoms.copy()
        self.atom_types = sorted(set(atoms.symbols))
        self.keV = keV
        self.comment = comment
        self.occupancies = self._get_occupancies(occupancies)
        self.RMS = self._get_RMS(debye_waller_factors)

        self.numbers = symbols2numbers(self.atom_types)
        if fit_cell_to_atoms:
            self.atoms.translate(-self.atoms.positions.min(axis=0))
            self.atoms.set_cell(self.atoms.positions.max(axis=0))
Example #7
0
 def __init__(self, atoms, keV, DW, comment=None, occupancy=1.0,
              fit_cell_to_atoms=False):
     self.atoms = atoms.copy()
     self.atom_types = []
     for atom in self.atoms:
         if atom.symbol not in self.atom_types:
             self.atom_types.append(atom.symbol)
     self.keV = keV
     self.DW = DW
     self._check_key_dictionary(self.DW, 'DW')
     self.comment = comment
     if np.isscalar(occupancy):
         self.occupancy = dict(zip(self.atom_types,
                                   [occupancy] * len(self.atom_types)))
     else:
         self.occupancy = occupancy
     self._check_key_dictionary(self.occupancy, 'occupancy')
     self.numbers = symbols2numbers(self.atom_types)
     if fit_cell_to_atoms:
         self.atoms.translate(-self.atoms.positions.min(axis=0))
         self.atoms.set_cell(self.atoms.positions.max(axis=0))
Example #8
0
    def parse_selection(self, selection, **kwargs):
        if selection is None or selection == '':
            expressions = []
        elif isinstance(selection, int):
            expressions = [('id', '=', selection)]
        elif isinstance(selection, list):
            expressions = selection
        else:
            expressions = [w.strip() for w in selection.split(',')]
        keys = []
        comparisons = []
        for expression in expressions:
            if isinstance(expression, (list, tuple)):
                comparisons.append(expression)
                continue
            if expression.count('<') == 2:
                value, expression = expression.split('<', 1)
                if expression[0] == '=':
                    op = '>='
                    expression = expression[1:]
                else:
                    op = '>'
                key = expression.split('<', 1)[0]
                comparisons.append((key, op, value))
            for op in ['!=', '<=', '>=', '<', '>', '=']:
                if op in expression:
                    break
            else:
                if expression in atomic_numbers:
                    comparisons.append((expression, '>', 0))
                else:
                    keys.append(expression)
                continue
            key, value = expression.split(op)
            comparisons.append((key, op, value))

        cmps = []
        for key, value in kwargs.items():
            comparisons.append((key, '=', value))
            
        for key, op, value in comparisons:
            if key == 'age':
                key = 'ctime'
                op = invop[op]
                value = now() - time_string_to_float(value)
            elif key == 'formula':
                assert op == '='
                numbers = symbols2numbers(value)
                count = collections.defaultdict(int)
                for Z in numbers:
                    count[Z] += 1
                cmps.extend((Z, '=', count[Z]) for Z in count)
                key = 'natoms'
                value = len(numbers)
            elif key in atomic_numbers:
                key = atomic_numbers[key]
                value = int(value)
            elif isinstance(value, basestring):
                value = convert_str_to_float_or_str(value)
            if key in numeric_keys and not isinstance(value, (int, float)):
                msg = 'Wrong type for "{0}{1}{2}" - must be a number'
                raise ValueError(msg.format(key, op, value))
            cmps.append((key, op, value))
            
        return keys, cmps
Example #9
0
def parse_selection(selection, **kwargs):
    if selection is None or selection == '':
        expressions = []
    elif isinstance(selection, int):
        expressions = [('id', '=', selection)]
    elif isinstance(selection, list):
        expressions = selection
    else:
        expressions = [w.strip() for w in selection.split(',')]
    keys = []
    comparisons = []
    for expression in expressions:
        if isinstance(expression, (list, tuple)):
            comparisons.append(expression)
            continue
        if expression.count('<') == 2:
            value, expression = expression.split('<', 1)
            if expression[0] == '=':
                op = '>='
                expression = expression[1:]
            else:
                op = '>'
            key = expression.split('<', 1)[0]
            comparisons.append((key, op, value))
        for op in ['!=', '<=', '>=', '<', '>', '=']:
            if op in expression:
                break
        else:
            if expression in atomic_numbers:
                comparisons.append((expression, '>', 0))
            else:
                try:
                    symbols = string2symbols(expression)
                except ValueError:
                    keys.append(expression)
                else:
                    count = collections.Counter(symbols)
                    comparisons.extend(
                        (symbol, '>', n - 1) for symbol, n in count.items())
            continue
        key, value = expression.split(op)
        comparisons.append((key, op, value))

    cmps = []
    for key, value in kwargs.items():
        comparisons.append((key, '=', value))

    for key, op, value in comparisons:
        if key == 'age':
            key = 'ctime'
            op = invop[op]
            value = now() - time_string_to_float(value)
        elif key == 'formula':
            if op != '=':
                raise ValueError('Use fomula=...')
            numbers = symbols2numbers(value)
            count = collections.defaultdict(int)
            for Z in numbers:
                count[Z] += 1
            cmps.extend((Z, '=', count[Z]) for Z in count)
            key = 'natoms'
            value = len(numbers)
        elif key in atomic_numbers:
            key = atomic_numbers[key]
            value = int(value)
        elif isinstance(value, basestring):
            value = convert_str_to_int_float_or_str(value)
        if key in numeric_keys and not isinstance(value, (int, float)):
            msg = 'Wrong type for "{}{}{}" - must be a number'
            raise ValueError(msg.format(key, op, value))
        cmps.append((key, op, value))

    return keys, cmps
Example #10
0
File: core.py Project: askhl/ase
    def select(self, selection=None, fancy=True, filter=None, explain=False,
               verbosity=1, limit=None, **kwargs):
        """Select rows.
        
        Return iterator with results as dictionaries.  Selection is done
        using key-value pairs, keywords and the special keys:
            
            formula, age, user, calculator, natoms, energy, magmom
            and/or charge.
        
        selection: int, str or list
            Can be:
            
            * an integer id
            * a string like 'key=value', where '=' can also be one of
              '<=', '<', '>', '>=' or '!='.
            * a string like 'keyword'
            * comma separated strings like 'key1<value1,key2=value2,keyword'
            * list of strings or tuples: [('charge', '=', 1)].
        fancy: bool
            return fancy dictionary with keys as attributes (this is the
            default).
        filter: function
            A function that takes as input a dictionary and returns True
            or False.
        explain: bool
            Explain query plan.
        verbosity: int
            Possible values: 0, 1 or 2.
        limit: int or None
            Limit selection.
        """
        
        if selection is None or selection == '':
            expressions = []
        elif isinstance(selection, int):
            expressions = [('id', '=', selection)]
        elif isinstance(selection, list):
            expressions = selection
        else:
            expressions = selection.split(',')
        keywords = []
        comparisons = []
        for expression in expressions:
            if isinstance(expression, (list, tuple)):
                comparisons.append(expression)
                continue
            if expression.count('<') == 2:
                value, expression = expression.split('<', 1)
                if expression[0] == '=':
                    op = '>='
                    expression = expression[1:]
                else:
                    op = '>'
                key = expression.split('<', 1)[0]
                comparisons.append((key, op, value))
            for op in ['!=', '<=', '>=', '<', '>', '=']:
                if op in expression:
                    break
            else:
                keywords.append(expression)
                continue
            key, value = expression.split(op)
            comparisons.append((key, op, value))

        cmps = []
        for key, value in kwargs.items():
            comparisons.append((key, '=', value))
            
        for key, op, value in comparisons:
            if key == 'age':
                key = 'ctime'
                op = invop[op]
                value = now() - time_string_to_float(value)
            elif key == 'formula':
                assert op == '='
                numbers = symbols2numbers(value)
                count = collections.defaultdict(int)
                for Z in numbers:
                    count[Z] += 1
                cmps.extend((Z, '=', count[Z]) for Z in count)
                key = 'natoms'
                value = len(numbers)
            elif key in atomic_numbers:
                key = atomic_numbers[key]
                value = int(value)
            elif isinstance(value, str):
                try:
                    value = float(value)
                except ValueError:
                    assert op == '=' or op == '!='
            if key in numeric_keys and not isinstance(value, (int, float)):
                msg = 'Wrong type for "{0}{1}{2}" - must be a number'
                raise ValueError(msg.format(key, op, value))
            cmps.append((key, op, value))

        for dct in self._select(keywords, cmps, explain=explain,
                                verbosity=verbosity, limit=limit):
            if filter is None or filter(dct):
                if fancy:
                    dct = FancyDict(dct)
                    if 'key_value_pairs' in dct:
                        dct.update(dct['key_value_pairs'])
                yield dct
Example #11
0
    def parse_selection(self, selection, **kwargs):
        if selection is None or selection == "":
            expressions = []
        elif isinstance(selection, int):
            expressions = [("id", "=", selection)]
        elif isinstance(selection, list):
            expressions = selection
        else:
            expressions = selection.split(",")
        keys = []
        comparisons = []
        for expression in expressions:
            if isinstance(expression, (list, tuple)):
                comparisons.append(expression)
                continue
            if expression.count("<") == 2:
                value, expression = expression.split("<", 1)
                if expression[0] == "=":
                    op = ">="
                    expression = expression[1:]
                else:
                    op = ">"
                key = expression.split("<", 1)[0]
                comparisons.append((key, op, value))
            for op in ["!=", "<=", ">=", "<", ">", "="]:
                if op in expression:
                    break
            else:
                if expression in atomic_numbers:
                    comparisons.append((expression, ">", 0))
                else:
                    keys.append(expression)
                continue
            key, value = expression.split(op)
            comparisons.append((key, op, value))

        cmps = []
        for key, value in kwargs.items():
            comparisons.append((key, "=", value))

        for key, op, value in comparisons:
            if key == "age":
                key = "ctime"
                op = invop[op]
                value = now() - time_string_to_float(value)
            elif key == "formula":
                assert op == "="
                numbers = symbols2numbers(value)
                count = collections.defaultdict(int)
                for Z in numbers:
                    count[Z] += 1
                cmps.extend((Z, "=", count[Z]) for Z in count)
                key = "natoms"
                value = len(numbers)
            elif key in atomic_numbers:
                key = atomic_numbers[key]
                value = int(value)
            elif isinstance(value, (str, unicode)):
                try:
                    value = float(value)
                except ValueError:
                    assert op == "=" or op == "!="
            if key in numeric_keys and not isinstance(value, (int, float)):
                msg = 'Wrong type for "{0}{1}{2}" - must be a number'
                raise ValueError(msg.format(key, op, value))
            cmps.append((key, op, value))

        return keys, cmps
Example #12
0
    def initialise_lammps(self, atoms):

        # Initialising commands
        if self.parameters.boundary:
            # if the boundary command is in the supplied commands use that
            # otherwise use atoms pbc
            pbc = atoms.get_pbc()
            for cmd in self.parameters.lmpcmds:
                if 'boundary' in cmd:
                    break
            else:
                self.lmp.command('boundary ' +
                                 ' '.join([self.lammpsbc(bc) for bc in pbc]))

        # Initialize cell
        self.set_cell(atoms, change=not self.parameters.create_box)

        if self.parameters.atom_types is None:
            raise NameError("atom_types are mandatory.")

        if isinstance(self.parameters.atom_types, dict):
            # atom_types is a dictionary with symbols (or numbers) as keys
            self.parameters.atom_types_equal_atomic_numbers = False
            symbol_atom_types = self.parameters.atom_types.copy()
            self.parameters.atom_types = {}
            for sym in symbol_atom_types:
                try:
                    num = int(sym)
                except:
                    num = symbols2numbers(sym)[0]
                self.parameters.atom_types[num] = symbol_atom_types[sym]
        else:  # not a dict, must be the string TYPE_EQUALS_Z
            if self.parameters.atom_types == "TYPE_EQUALS_Z":
                self.parameters.atom_types_equal_atomic_numbers = True
                self.parameters.atom_types = {}
                for Z in atoms.get_atomic_numbers():
                    self.parameters.atom_types[Z] = Z
            else:
                raise ValueError(
                    'atom_types parameter "%s" is string, but not TYPE_EQUALS_Z'
                    % self.parameters.atom_types)

        # Collect chemical symbols
        symbols = np.asarray(atoms.get_chemical_symbols())
        numbers = np.asarray(atoms.get_atomic_numbers())

        # Initialize box
        if self.parameters.create_box:
            # count number of known types
            n_types = len(self.parameters.atom_types)
            create_box_command = 'create_box {} cell'.format(n_types)

            # count numbers of bonds and angles defined by potential
            n_dihedral_types = 0
            n_improper_types = 0
            n_angle_types = 0
            n_bond_types = 0
            for cmd in self.parameters.lmpcmds:
                m = re.match('\s*angle_coeff\s+(\d+)', cmd)
                if m is not None:
                    n_angle_types = max(int(m.group(1)), n_angle_types)
                m = re.match('\s*bond_coeff\s+(\d+)', cmd)
                if m is not None:
                    n_bond_types = max(int(m.group(1)), n_bond_types)
                m = re.match('\s*dihedral_coeff\s+(\d+)', cmd)
                if m is not None:
                    n_dihedral_types = max(int(m.group(1)), n_dihedral_types)
                m = re.match('\s*improper_coeff\s+(\d+)', cmd)
                if m is not None:
                    n_improper_types = max(int(m.group(1)), n_improper_types)

            if self.parameters.read_molecular_info:
                if 'bonds' in atoms.arrays:
                    self.parse_bonds(atoms)
                    create_box_command += ' bond/types {} extra/bond/per/atom {}'.format(
                        n_bond_types, atoms.max_n_bonds)
                if 'angles' in atoms.arrays:
                    self.parse_angles(atoms)
                    create_box_command += ' angle/types {} extra/angle/per/atom {}'.format(
                        n_angle_types, atoms.max_n_angles)
                if 'dihedrals' in atoms.arrays:
                    self.parse_dihedrals(atoms)
                    create_box_command += ' dihedral/types {} extra/dihedral/per/atom {}'.format(
                        n_dihedral_types, atoms.max_n_dihedrals)
                if 'impropers' in atoms.arrays:
                    self.parse_impropers(atoms)
                    create_box_command += ' improper/types {} extra/improper/per/atom {}'.format(
                        n_improper_types, atoms.max_n_impropers)

            self.lmp.command(create_box_command)

        # Initialize the atoms with their types
        # positions do not matter here
        if self.parameters.create_atoms:
            self.lmp.command('echo none')  # don't echo the atom positions
            self.rebuild(atoms)
            self.lmp.command('echo log')  # turn back on

        # execute the user commands
        for cmd in self.parameters.lmpcmds:
            self.lmp.command(cmd)

        # Set masses after user commands, to override EAM provided masses, e.g.
        masses = atoms.get_masses()
        for Z in self.parameters.atom_types:
            in_cur_sys = False
            for i in range(len(atoms)):
                if numbers[i] == Z:
                    # convert from amu (ASE) to lammps mass unit)
                    self.lmp.command(
                        'mass %d %.30f' %
                        (self.parameters.atom_types[Z],
                         masses[i] / unit_convert("mass", self.units)))
                    in_cur_sys = True
                    break
            if not in_cur_sys:
                self.lmp.command('mass %d %.30f' %
                                 (self.parameters.atom_types[Z], 1.0))

        # Define force & energy variables for extraction
        self.lmp.command('variable pxx equal pxx')
        self.lmp.command('variable pyy equal pyy')
        self.lmp.command('variable pzz equal pzz')
        self.lmp.command('variable pxy equal pxy')
        self.lmp.command('variable pxz equal pxz')
        self.lmp.command('variable pyz equal pyz')

        # I am not sure why we need this next line but LAMMPS will
        # raise an error if it is not there. Perhaps it is needed to
        # ensure the cell stresses are calculated
        self.lmp.command('thermo_style custom pe pxx emol ecoul')

        self.lmp.command('variable fx atom fx')
        self.lmp.command('variable fy atom fy')
        self.lmp.command('variable fz atom fz')

        # do we need this if we extract from a global ?
        self.lmp.command('variable pe equal pe')

        self.lmp.command("neigh_modify delay 0 every 1 check yes")

        if self.parameters.read_molecular_info:
            # read in bonds if there are bonds from the ase-atoms object if the molecular flag is set
            if 'bonds' in atoms.arrays:
                self.set_bonds(atoms)
            # read in angles if there are angles from the ase-atoms object if the molecular flag is set
            if 'angles' in atoms.arrays:
                self.set_angles(atoms)
            # read in dihedrals if there are dihedrals from the ase-atoms object if the molecular flag is set
            if 'dihedrals' in atoms.arrays:
                self.set_dihedrals(atoms)
            # read in impropers if there are impropers from the ase-atoms object if the molecular flag is set
            if 'impropers' in atoms.arrays:
                self.set_impropers(atoms)

        if self.parameters.read_molecular_info and 'mmcharge' in atoms.arrays:
            self.set_charges(atoms)

        self.initialized = True
Example #13
0
def test_mustem_several_elements():
    """Check writing and reading a xtl mustem file."""
    # Reproduce the sto xtl file distributed with muSTEM
    atoms = make_STO_atoms()

    filename = 'sto_mustem.xtl'
    STO_DW_dict = {'Sr': 0.62, 'O': 0.73, 'Ti': 0.43}
    STO_DW_dict_Ti_missing = {key: STO_DW_dict[key] for key in ['Sr', 'O']}

    with pytest.raises(TypeError):
        atoms.write(filename)

    with pytest.raises(ValueError):
        atoms.write(filename, keV=300)

    with pytest.raises(TypeError):
        atoms.write(filename, debye_waller_factors=STO_DW_dict)

    atoms.write(filename, keV=300, debye_waller_factors=STO_DW_dict)

    atoms2 = read(filename, format='mustem')
    atoms3 = read(filename)

    for _atoms in [atoms2, atoms3]:
        assert atoms.positions == pytest.approx(_atoms.positions)
        np.testing.assert_allclose(atoms.cell, _atoms.cell)

    with pytest.raises(ValueError):
        # Raise an error if there is a missing key.
        atoms.write(filename,
                    keV=300,
                    debye_waller_factors=STO_DW_dict_Ti_missing)

    atoms.write(filename,
                keV=300,
                debye_waller_factors=STO_DW_dict,
                occupancies={
                    'Sr': 1.0,
                    'O': 0.5,
                    'Ti': 0.9
                })

    with pytest.raises(ValueError):
        # Raise an error if there is a missing key.
        atoms.write(filename,
                    keV=300,
                    debye_waller_factors=STO_DW_dict,
                    occupancies={
                        'O': 0.5,
                        'Ti': 0.9
                    })

    with pytest.raises(ValueError):
        # Raise an error if the unit cell is not defined.
        atoms4 = Atoms(['Sr', 'Ti', 'O', 'O', 'O'],
                       positions=[[0, 0, 0], [0.5, 0.5, 0.5], [0.5, 0.5, 0],
                                  [0.5, 0, 0.5], [0, 0.5, 0.5]])
        atoms4.write(filename, keV=300, debye_waller_factors=STO_DW_dict)

    atoms5 = make_STO_atoms()
    atoms5.set_array('occupancies', np.ones(5))
    atoms5.arrays['occupancies'][atoms5.numbers == symbols2numbers('Sr')] = 0.9
    # element 0 is Sr and there is onlye one Sr in the cell: this is a valid
    # cell to export to xtl file
    atoms5.write(filename, keV=300, debye_waller_factors=STO_DW_dict)
    atoms6 = read(filename)
    condition = atoms6.numbers == symbols2numbers('Sr')
    np.testing.assert_allclose(atoms6.arrays['occupancies'][condition], 0.9)

    atoms5.arrays['occupancies'][0] = 0.8
    with pytest.raises(ValueError):
        atoms5.write(filename, keV=300, debye_waller_factors=STO_DW_dict)

    atoms7 = make_STO_atoms()
    debye_waller_factors = np.array([0.73, 0.73, 0.73, 0.62, 0.43])
    atoms7.set_array('debye_waller_factors', debye_waller_factors)
    # element 0 is Sr and there is onlye one Sr in the cell: this is a valid
    # cell to export to xtl file
    atoms7.write(filename, keV=300)
    atoms8 = read(filename)
    for element in ['Sr', 'Ti', 'O']:
        number = symbols2numbers(element)
        np.testing.assert_allclose(
            atoms7.arrays['debye_waller_factors'][atoms7.numbers == number],
            atoms8.arrays['debye_waller_factors'][atoms8.numbers == number],
            rtol=1e-2)
Example #14
0
    def parse_selection(self, selection, **kwargs):
        if selection is None or selection == '':
            expressions = []
        elif isinstance(selection, int):
            expressions = [('id', '=', selection)]
        elif isinstance(selection, list):
            expressions = selection
        else:
            expressions = selection.split(',')
        keys = []
        comparisons = []
        for expression in expressions:
            if isinstance(expression, (list, tuple)):
                comparisons.append(expression)
                continue
            if expression.count('<') == 2:
                value, expression = expression.split('<', 1)
                if expression[0] == '=':
                    op = '>='
                    expression = expression[1:]
                else:
                    op = '>'
                key = expression.split('<', 1)[0]
                comparisons.append((key, op, value))
            for op in ['!=', '<=', '>=', '<', '>', '=']:
                if op in expression:
                    break
            else:
                if expression in atomic_numbers:
                    comparisons.append((expression, '>', 0))
                else:
                    keys.append(expression)
                continue
            key, value = expression.split(op)
            comparisons.append((key, op, value))

        cmps = []
        for key, value in kwargs.items():
            comparisons.append((key, '=', value))

        for key, op, value in comparisons:
            if key == 'age':
                key = 'ctime'
                op = invop[op]
                value = now() - time_string_to_float(value)
            elif key == 'formula':
                assert op == '='
                numbers = symbols2numbers(value)
                count = collections.defaultdict(int)
                for Z in numbers:
                    count[Z] += 1
                cmps.extend((Z, '=', count[Z]) for Z in count)
                key = 'natoms'
                value = len(numbers)
            elif key in atomic_numbers:
                key = atomic_numbers[key]
                value = int(value)
            elif isinstance(value, (str, unicode)):
                try:
                    value = float(value)
                except ValueError:
                    assert op == '=' or op == '!='
            if key in numeric_keys and not isinstance(value, (int, float)):
                msg = 'Wrong type for "{0}{1}{2}" - must be a number'
                raise ValueError(msg.format(key, op, value))
            cmps.append((key, op, value))

        return keys, cmps
Example #15
0
    def select(self,
               selection=None,
               fancy=True,
               filter=None,
               explain=False,
               verbosity=1,
               limit=None,
               **kwargs):
        """Select rows.
        
        Return iterator with results as dictionaries.  Selection is done
        using key-value pairs, keywords and the special keys:
            
            formula, age, user, calculator, natoms, energy, magmom
            and/or charge.
        
        selection: int, str or list
            Can be:
            
            * an integer id
            * a string like 'key=value', where '=' can also be one of
              '<=', '<', '>', '>=' or '!='.
            * a string like 'keyword'
            * comma separated strings like 'key1<value1,key2=value2,keyword'
            * list of strings or tuples: [('charge', '=', 1)].
        fancy: bool
            return fancy dictionary with keys as attributes (this is the
            default).
        filter: function
            A function that takes as input a dictionary and returns True
            or False.
        explain: bool
            Explain query plan.
        verbosity: int
            Possible values: 0, 1 or 2.
        limit: int or None
            Limit selection.
        """

        if selection is None or selection == '':
            expressions = []
        elif isinstance(selection, int):
            expressions = [('id', '=', selection)]
        elif isinstance(selection, list):
            expressions = selection
        else:
            expressions = selection.split(',')
        keywords = []
        comparisons = []
        for expression in expressions:
            if isinstance(expression, (list, tuple)):
                comparisons.append(expression)
                continue
            if expression.count('<') == 2:
                value, expression = expression.split('<', 1)
                if expression[0] == '=':
                    op = '>='
                    expression = expression[1:]
                else:
                    op = '>'
                key = expression.split('<', 1)[0]
                comparisons.append((key, op, value))
            for op in ['!=', '<=', '>=', '<', '>', '=']:
                if op in expression:
                    break
            else:
                keywords.append(expression)
                continue
            key, value = expression.split(op)
            comparisons.append((key, op, value))

        cmps = []
        for key, value in kwargs.items():
            comparisons.append((key, '=', value))

        for key, op, value in comparisons:
            if key == 'age':
                key = 'ctime'
                op = invop[op]
                value = now() - time_string_to_float(value)
            elif key == 'formula':
                assert op == '='
                numbers = symbols2numbers(value)
                count = collections.defaultdict(int)
                for Z in numbers:
                    count[Z] += 1
                cmps.extend((Z, '=', count[Z]) for Z in count)
                key = 'natoms'
                value = len(numbers)
            elif key in atomic_numbers:
                key = atomic_numbers[key]
                value = int(value)
            elif isinstance(value, str):
                try:
                    value = float(value)
                except ValueError:
                    assert op == '=' or op == '!='
            if key in numeric_keys and not isinstance(value, (int, float)):
                msg = 'Wrong type for "{0}{1}{2}" - must be a number'
                raise ValueError(msg.format(key, op, value))
            cmps.append((key, op, value))

        for dct in self._select(keywords,
                                cmps,
                                explain=explain,
                                verbosity=verbosity,
                                limit=limit):
            if filter is None or filter(dct):
                if fancy:
                    dct = FancyDict(dct)
                    if 'key_value_pairs' in dct:
                        dct.update(dct['key_value_pairs'])
                yield dct
Example #16
0
def RandomBoxAtoms(symbols, cell=[5.0, 5.0, 5.0]):
    numbers = symbols2numbers(symbols)
    scaled_positions = np.random.uniform(0.0, 1.0, (len(numbers), 3))
    return Atoms(numbers, scaled_positions=scaled_positions, cell=cell)