root / ase / io / exciting.py @ 13
Historique | Voir | Annoter | Télécharger (3,9 ko)
1 | 1 | tkerber | """
|
---|---|---|---|
2 | 1 | tkerber | This is the Implementation of the exciting I/O Functions
|
3 | 1 | tkerber | The functions are called with read write usunf the format "exi"
|
4 | 1 | tkerber |
|
5 | 1 | tkerber | The module depends on lxml http://codespeak.net/lxml/
|
6 | 1 | tkerber | """
|
7 | 1 | tkerber | from math import pi, cos, sin, sqrt, acos |
8 | 1 | tkerber | |
9 | 1 | tkerber | from ase.atoms import Atoms |
10 | 1 | tkerber | from ase.parallel import paropen |
11 | 1 | tkerber | from ase.units import Bohr |
12 | 1 | tkerber | |
13 | 1 | tkerber | def read_exciting(fileobj, index=-1): |
14 | 1 | tkerber | """Reads structure from exiting xml file.
|
15 | 1 | tkerber |
|
16 | 1 | tkerber | Parameters
|
17 | 1 | tkerber | ----------
|
18 | 1 | tkerber | fileobj: file object
|
19 | 1 | tkerber | Filehandle from which data should be read.
|
20 | 1 | tkerber |
|
21 | 1 | tkerber | Other parameters
|
22 | 1 | tkerber | ----------------
|
23 | 1 | tkerber | index: integer -1
|
24 | 1 | tkerber | Not used in this implementation.
|
25 | 1 | tkerber | """
|
26 | 1 | tkerber | from lxml import etree as ET |
27 | 1 | tkerber | #parse file into element tree
|
28 | 1 | tkerber | doc = ET.parse(fileobj) |
29 | 1 | tkerber | root = doc.getroot() |
30 | 1 | tkerber | speciesnodes = root.find('structure').getiterator('species') |
31 | 1 | tkerber | |
32 | 1 | tkerber | symbols = [] |
33 | 1 | tkerber | positions = [] |
34 | 1 | tkerber | basevects = [] |
35 | 1 | tkerber | atoms = None
|
36 | 1 | tkerber | #collect data from tree
|
37 | 1 | tkerber | for speciesnode in speciesnodes: |
38 | 1 | tkerber | symbol = speciesnode.get('speciesfile').split('.')[0] |
39 | 1 | tkerber | natoms = speciesnode.getiterator('atom')
|
40 | 1 | tkerber | for atom in natoms: |
41 | 1 | tkerber | x, y, z = atom.get('coord').split()
|
42 | 1 | tkerber | positions.append([float(x), float(y), float(z)]) |
43 | 1 | tkerber | symbols.append(symbol) |
44 | 1 | tkerber | basevectsn = doc.xpath('//basevect/text()')
|
45 | 1 | tkerber | |
46 | 1 | tkerber | for basevect in basevectsn: |
47 | 1 | tkerber | x, y, z = basevect.split() |
48 | 1 | tkerber | basevects.append([float(x) * Bohr, float(y) * Bohr, float(z) * Bohr]) |
49 | 1 | tkerber | atoms = Atoms(symbols=symbols, cell=basevects) |
50 | 1 | tkerber | atoms.set_scaled_positions(positions) |
51 | 1 | tkerber | if 'molecule' in root.find('structure').attrib.keys(): |
52 | 1 | tkerber | if root.find('structure').attrib['molecule']: |
53 | 1 | tkerber | atoms.set_pbc(False)
|
54 | 1 | tkerber | else:
|
55 | 1 | tkerber | atoms.set_pbc(True)
|
56 | 1 | tkerber | |
57 | 1 | tkerber | return atoms
|
58 | 1 | tkerber | |
59 | 1 | tkerber | def write_exciting(fileobj, images): |
60 | 1 | tkerber | """writes exciting input structure in XML
|
61 | 1 | tkerber |
|
62 | 1 | tkerber | Parameters
|
63 | 1 | tkerber | ----------
|
64 | 1 | tkerber | fileobj : File object
|
65 | 1 | tkerber | Filehandle to which data should be written
|
66 | 1 | tkerber | images : Atom Object or List of Atoms objects
|
67 | 1 | tkerber | This function will write the first Atoms object to file
|
68 | 1 | tkerber |
|
69 | 1 | tkerber | Returns
|
70 | 1 | tkerber | -------
|
71 | 1 | tkerber | """
|
72 | 1 | tkerber | from lxml import etree as ET |
73 | 1 | tkerber | if isinstance(fileobj, str): |
74 | 1 | tkerber | fileobj = paropen(fileobj, 'w')
|
75 | 1 | tkerber | root = atoms2etree(images) |
76 | 1 | tkerber | fileobj.write(ET.tostring(root, method='xml',
|
77 | 1 | tkerber | pretty_print=True,
|
78 | 1 | tkerber | xml_declaration=True,
|
79 | 1 | tkerber | encoding='UTF-8'))
|
80 | 1 | tkerber | |
81 | 1 | tkerber | def atoms2etree(images): |
82 | 1 | tkerber | """This function creates the xml DOM corresponding
|
83 | 1 | tkerber | to the structure for use in write and calculator
|
84 | 1 | tkerber |
|
85 | 1 | tkerber | Parameters
|
86 | 1 | tkerber | ----------
|
87 | 1 | tkerber |
|
88 | 1 | tkerber | images : Atom Object or List of Atoms objects
|
89 | 1 | tkerber | This function will create a
|
90 | 1 | tkerber |
|
91 | 1 | tkerber | Returns
|
92 | 1 | tkerber | -------
|
93 | 1 | tkerber | root : etree object
|
94 | 1 | tkerber | Element tree of exciting input file containing the structure
|
95 | 1 | tkerber | """
|
96 | 1 | tkerber | from lxml import etree as ET |
97 | 1 | tkerber | if not isinstance(images, (list, tuple)): |
98 | 1 | tkerber | images = [images] |
99 | 1 | tkerber | |
100 | 1 | tkerber | root = ET.Element('input')
|
101 | 1 | tkerber | title = ET.SubElement(root, 'title')
|
102 | 1 | tkerber | title.text = ''
|
103 | 1 | tkerber | structure = ET.SubElement(root, 'structure')
|
104 | 1 | tkerber | crystal= ET.SubElement(structure, 'crystal')
|
105 | 1 | tkerber | atoms = images[0]
|
106 | 1 | tkerber | for vec in atoms.cell: |
107 | 1 | tkerber | basevect = ET.SubElement(crystal, 'basevect')
|
108 | 1 | tkerber | basevect.text = '%.14f %.14f %.14f' % tuple(vec / Bohr) |
109 | 1 | tkerber | |
110 | 1 | tkerber | species = {} |
111 | 1 | tkerber | symbols = [] |
112 | 1 | tkerber | for a, symbol in enumerate(atoms.get_chemical_symbols()): |
113 | 1 | tkerber | if symbol in species: |
114 | 1 | tkerber | species[symbol].append(a) |
115 | 1 | tkerber | else:
|
116 | 1 | tkerber | species[symbol] = [a] |
117 | 1 | tkerber | symbols.append(symbol) |
118 | 1 | tkerber | scaled = atoms.get_scaled_positions() |
119 | 1 | tkerber | for symbol in symbols: |
120 | 1 | tkerber | speciesnode = ET.SubElement(structure, 'species',
|
121 | 1 | tkerber | speciesfile='%s.xml' % symbol,
|
122 | 1 | tkerber | chemicalSymbol=symbol) |
123 | 1 | tkerber | for a in species[symbol]: |
124 | 1 | tkerber | atom = ET.SubElement(speciesnode, 'atom',
|
125 | 1 | tkerber | coord='%.14f %.14f %.14f' % tuple(scaled[a])) |
126 | 1 | tkerber | return root |