Statistiques
| Révision :

root / ase / io / exciting.py @ 17

Historique | Voir | Annoter | Télécharger (3,9 ko)

1
"""
2
This is the Implementation of the exciting I/O Functions
3
The functions are called with read write usunf the format "exi"
4

5
The module depends on lxml  http://codespeak.net/lxml/
6
"""
7
from math import pi, cos, sin, sqrt, acos
8

    
9
from ase.atoms import Atoms
10
from ase.parallel import paropen
11
from ase.units import Bohr
12

    
13
def read_exciting(fileobj, index=-1):
14
    """Reads structure from exiting xml file.
15
    
16
    Parameters
17
    ----------
18
    fileobj: file object
19
        Filehandle from which data should be read.
20
        
21
    Other parameters
22
    ----------------
23
    index: integer -1
24
        Not used in this implementation.
25
    """
26
    from lxml import etree as ET
27
    #parse file into element tree
28
    doc = ET.parse(fileobj)
29
    root = doc.getroot()
30
    speciesnodes = root.find('structure').getiterator('species') 
31
 
32
    symbols = []
33
    positions = []
34
    basevects = []
35
    atoms = None
36
    #collect data from tree
37
    for speciesnode in speciesnodes:
38
        symbol = speciesnode.get('speciesfile').split('.')[0]
39
        natoms = speciesnode.getiterator('atom')
40
        for atom in natoms:
41
            x, y, z = atom.get('coord').split()
42
            positions.append([float(x), float(y), float(z)])
43
            symbols.append(symbol)
44
    basevectsn = doc.xpath('//basevect/text()') 
45
 
46
    for basevect in basevectsn:
47
        x, y, z = basevect.split()
48
        basevects.append([float(x) * Bohr, float(y) * Bohr, float(z) * Bohr])
49
    atoms = Atoms(symbols=symbols, cell=basevects)
50
    atoms.set_scaled_positions(positions)
51
    if 'molecule' in root.find('structure').attrib.keys():
52
        if root.find('structure').attrib['molecule']:
53
            atoms.set_pbc(False)
54
    else:
55
        atoms.set_pbc(True)
56
        
57
    return atoms
58

    
59
def write_exciting(fileobj, images):
60
    """writes exciting input structure in XML
61
    
62
    Parameters
63
    ----------
64
    fileobj : File object
65
        Filehandle to which data should be written
66
    images : Atom Object or List of Atoms objects
67
        This function will write the first Atoms object to file 
68
    
69
    Returns
70
    -------
71
    """
72
    from lxml import etree as ET
73
    if isinstance(fileobj, str):
74
        fileobj = paropen(fileobj, 'w')
75
    root = atoms2etree(images)
76
    fileobj.write(ET.tostring(root, method='xml', 
77
                              pretty_print=True,
78
                              xml_declaration=True,
79
                              encoding='UTF-8'))
80

    
81
def atoms2etree(images):
82
    """This function creates the xml DOM corresponding
83
     to the structure for use in write and calculator
84
    
85
    Parameters
86
    ----------
87
    
88
    images : Atom Object or List of Atoms objects
89
        This function will create a 
90
    
91
    Returns
92
    -------
93
    root : etree object
94
        Element tree of exciting input file containing the structure
95
    """
96
    from lxml import etree as ET
97
    if not isinstance(images, (list, tuple)):
98
        images = [images]
99

    
100
    root = ET.Element('input')
101
    title = ET.SubElement(root, 'title')
102
    title.text = ''
103
    structure = ET.SubElement(root, 'structure')
104
    crystal= ET.SubElement(structure, 'crystal')
105
    atoms = images[0]
106
    for vec in atoms.cell:
107
        basevect = ET.SubElement(crystal, 'basevect')
108
        basevect.text = '%.14f %.14f %.14f' % tuple(vec / Bohr)
109
                             
110
    species = {}
111
    symbols = []
112
    for a, symbol in enumerate(atoms.get_chemical_symbols()):
113
        if symbol in species:
114
            species[symbol].append(a)
115
        else:
116
            species[symbol] = [a]
117
            symbols.append(symbol)
118
    scaled = atoms.get_scaled_positions()
119
    for symbol in symbols:
120
        speciesnode = ET.SubElement(structure, 'species',
121
                                    speciesfile='%s.xml' % symbol,
122
                                    chemicalSymbol=symbol)
123
        for a in species[symbol]:
124
           atom = ET.SubElement(speciesnode, 'atom',
125
                                coord='%.14f %.14f %.14f' % tuple(scaled[a]))
126
    return root