root / ase / io / cfg.py @ 15
Historique | Voir | Annoter | Télécharger (6,56 ko)
1 | 1 | tkerber | import numpy as np |
---|---|---|---|
2 | 1 | tkerber | |
3 | 1 | tkerber | import ase |
4 | 1 | tkerber | |
5 | 1 | tkerber | from ase.parallel import paropen |
6 | 1 | tkerber | |
7 | 1 | tkerber | |
8 | 1 | tkerber | cfg_default_fields = np.array( [ 'positions', 'momenta', 'numbers', 'magmoms' ] ) |
9 | 1 | tkerber | |
10 | 1 | tkerber | def write_cfg(f, a): |
11 | 1 | tkerber | """Write atomic configuration to a CFG-file (native AtomEye format).
|
12 | 1 | tkerber | See: http://mt.seas.upenn.edu/Archive/Graphics/A/
|
13 | 1 | tkerber | """
|
14 | 1 | tkerber | if isinstance(f, str): |
15 | 1 | tkerber | f = paropen(f, 'w')
|
16 | 1 | tkerber | |
17 | 1 | tkerber | f.write('Number of particles = %i\n' % len(a)) |
18 | 1 | tkerber | f.write('A = 1.0 Angstrom\n')
|
19 | 1 | tkerber | cell = a.get_cell() |
20 | 1 | tkerber | for i in range(3): |
21 | 1 | tkerber | for j in range(3): |
22 | 1 | tkerber | f.write('H0(%1.1i,%1.1i) = %f A\n' % ( i + 1, j + 1, cell[i, j] )) |
23 | 1 | tkerber | |
24 | 1 | tkerber | entry_count = 3
|
25 | 1 | tkerber | for x in a.arrays.keys(): |
26 | 1 | tkerber | if not x in cfg_default_fields: |
27 | 1 | tkerber | if len(a.get_array(x).shape) == 1: |
28 | 1 | tkerber | entry_count += 1
|
29 | 1 | tkerber | else:
|
30 | 1 | tkerber | entry_count += a.get_array(x).shape[1]
|
31 | 1 | tkerber | |
32 | 1 | tkerber | vels = a.get_velocities() |
33 | 1 | tkerber | if type(vels) == np.ndarray: |
34 | 1 | tkerber | entry_count += 3
|
35 | 1 | tkerber | else:
|
36 | 1 | tkerber | f.write('.NO_VELOCITY.\n')
|
37 | 1 | tkerber | |
38 | 1 | tkerber | f.write('entry_count = %i\n' % entry_count)
|
39 | 1 | tkerber | |
40 | 1 | tkerber | i = 0
|
41 | 1 | tkerber | for name, aux in a.arrays.iteritems(): |
42 | 1 | tkerber | if not name in cfg_default_fields: |
43 | 1 | tkerber | if len(aux.shape) == 1: |
44 | 1 | tkerber | f.write('auxiliary[%i] = %s [a.u.]\n' % ( i, name ))
|
45 | 1 | tkerber | i += 1
|
46 | 1 | tkerber | else:
|
47 | 1 | tkerber | for j in range(aux.shape[1]): |
48 | 1 | tkerber | f.write('auxiliary[%i] = %s_%1.1i [a.u.]\n' % ( i, name, j ))
|
49 | 1 | tkerber | i += 1
|
50 | 1 | tkerber | |
51 | 1 | tkerber | # Distinct elements
|
52 | 1 | tkerber | spos = a.get_scaled_positions() |
53 | 1 | tkerber | for i in a: |
54 | 1 | tkerber | el = i.get_symbol() |
55 | 1 | tkerber | |
56 | 1 | tkerber | f.write('%f\n' % ase.data.atomic_masses[ase.data.chemical_symbols.index(el)])
|
57 | 1 | tkerber | f.write('%s\n' % el)
|
58 | 1 | tkerber | |
59 | 1 | tkerber | x, y, z = spos[i.index, :] |
60 | 1 | tkerber | s = '%e %e %e ' % ( x, y, z )
|
61 | 1 | tkerber | |
62 | 1 | tkerber | if type(vels) == np.ndarray: |
63 | 1 | tkerber | vx, vy, vz = vels[i.index, :] |
64 | 1 | tkerber | s = s + ' %e %e %e ' % ( vx, vy, vz )
|
65 | 1 | tkerber | |
66 | 1 | tkerber | for name, aux in a.arrays.iteritems(): |
67 | 1 | tkerber | if not name in cfg_default_fields: |
68 | 1 | tkerber | if len(aux.shape) == 1: |
69 | 1 | tkerber | s += ' %e' % aux[i.index]
|
70 | 1 | tkerber | else:
|
71 | 1 | tkerber | s += ( aux.shape[1]*' %e' ) % tuple(aux[i.index].tolist()) |
72 | 1 | tkerber | |
73 | 1 | tkerber | f.write('%s\n' % s)
|
74 | 1 | tkerber | |
75 | 1 | tkerber | |
76 | 1 | tkerber | default_color = { |
77 | 1 | tkerber | 'H': [ 0.800, 0.800, 0.800 ], |
78 | 1 | tkerber | 'C': [ 0.350, 0.350, 0.350 ], |
79 | 1 | tkerber | 'O': [ 0.800, 0.200, 0.200 ] |
80 | 1 | tkerber | } |
81 | 1 | tkerber | |
82 | 1 | tkerber | default_radius = { |
83 | 1 | tkerber | 'H': 0.435, |
84 | 1 | tkerber | 'C': 0.655, |
85 | 1 | tkerber | 'O': 0.730 |
86 | 1 | tkerber | } |
87 | 1 | tkerber | |
88 | 1 | tkerber | |
89 | 1 | tkerber | |
90 | 1 | tkerber | def write_clr(f, atoms): |
91 | 1 | tkerber | """Write extra color and radius code to a CLR-file (for use with AtomEye).
|
92 | 1 | tkerber | Hit F12 in AtomEye to use.
|
93 | 1 | tkerber | See: http://mt.seas.upenn.edu/Archive/Graphics/A/
|
94 | 1 | tkerber | """
|
95 | 1 | tkerber | color = None
|
96 | 1 | tkerber | radius = None
|
97 | 1 | tkerber | if atoms.has('color'): |
98 | 1 | tkerber | color = atoms.get_array('color')
|
99 | 1 | tkerber | if atoms.has('radius'): |
100 | 1 | tkerber | radius = atoms.get_array('radius')
|
101 | 1 | tkerber | |
102 | 1 | tkerber | if color is None: |
103 | 1 | tkerber | color = np.zeros([len(atoms),3], dtype=float) |
104 | 1 | tkerber | for a in atoms: |
105 | 1 | tkerber | color[a.index, :] = default_color[a.get_symbol()] |
106 | 1 | tkerber | |
107 | 1 | tkerber | if radius is None: |
108 | 1 | tkerber | radius = np.zeros(len(atoms), dtype=float) |
109 | 1 | tkerber | for a in atoms: |
110 | 1 | tkerber | radius[a.index] = default_radius[a.get_symbol()] |
111 | 1 | tkerber | |
112 | 1 | tkerber | radius.shape = (-1, 1) |
113 | 1 | tkerber | |
114 | 1 | tkerber | if isinstance(f, str): |
115 | 1 | tkerber | f = paropen(f, 'w')
|
116 | 1 | tkerber | for c1, c2, c3, r in np.append(color, radius, axis=1): |
117 | 1 | tkerber | f.write('%f %f %f %f\n' % ( c1, c2, c3, r ))
|
118 | 1 | tkerber | |
119 | 1 | tkerber | |
120 | 1 | tkerber | ###
|
121 | 1 | tkerber | |
122 | 1 | tkerber | def read_key_val(f): |
123 | 1 | tkerber | if isinstance(f, str): |
124 | 1 | tkerber | l = f |
125 | 1 | tkerber | else:
|
126 | 1 | tkerber | l = f.readline() |
127 | 1 | tkerber | s = l.split('=')
|
128 | 1 | tkerber | if len(s) != 2: |
129 | 1 | tkerber | raise RuntimeError("Line '%s' is not of the form 'key = value'." % l[:-1]) |
130 | 1 | tkerber | return ( s[0].strip(), s[1].strip() ) |
131 | 1 | tkerber | |
132 | 1 | tkerber | |
133 | 1 | tkerber | def read_str_key(f, key, key2=None): |
134 | 1 | tkerber | in_key, val = read_key_val(f) |
135 | 1 | tkerber | if key2 is None: |
136 | 1 | tkerber | if key.upper() != in_key.upper():
|
137 | 1 | tkerber | raise RuntimeError("Key '%s' expected, '%s' found." % ( key, in_key )) |
138 | 1 | tkerber | else:
|
139 | 1 | tkerber | if key.upper() != in_key.upper() and key2.upper() != in_key.upper(): |
140 | 1 | tkerber | raise RuntimeError("Key '%s' or '%s' expected, '%s' found." % ( key, key2, in_key )) |
141 | 1 | tkerber | return val
|
142 | 1 | tkerber | |
143 | 1 | tkerber | |
144 | 1 | tkerber | def read_int_key(f, key): |
145 | 1 | tkerber | vals = read_str_key(f, key).split() |
146 | 1 | tkerber | # Ignore units
|
147 | 1 | tkerber | return int(vals[0]) |
148 | 1 | tkerber | |
149 | 1 | tkerber | |
150 | 1 | tkerber | def read_float_key(f, key): |
151 | 1 | tkerber | vals = read_str_key(f, key).split() |
152 | 1 | tkerber | # Ignore units
|
153 | 1 | tkerber | return float(vals[0]) |
154 | 1 | tkerber | |
155 | 1 | tkerber | |
156 | 1 | tkerber | ###
|
157 | 1 | tkerber | |
158 | 1 | tkerber | def read_cfg(f): |
159 | 1 | tkerber | """Read atomic configuration from a CFG-file (native AtomEye format).
|
160 | 1 | tkerber | See: http://mt.seas.upenn.edu/Archive/Graphics/A/
|
161 | 1 | tkerber | """
|
162 | 1 | tkerber | if isinstance(f, str): |
163 | 1 | tkerber | f = open(f)
|
164 | 1 | tkerber | |
165 | 1 | tkerber | nat = read_int_key(f, 'Number of particles')
|
166 | 1 | tkerber | unit = read_float_key(f, 'A')
|
167 | 1 | tkerber | |
168 | 1 | tkerber | cell = np.zeros( [ 3, 3 ] ) |
169 | 1 | tkerber | for i in range(3): |
170 | 1 | tkerber | for j in range(3): |
171 | 1 | tkerber | cell[i, j] = read_float_key(f, 'H0(%1.1i,%1.1i)' % (i + 1, j + 1)) |
172 | 1 | tkerber | |
173 | 1 | tkerber | l = f.readline() |
174 | 1 | tkerber | vels = None
|
175 | 1 | tkerber | if l.strip() == '.NO_VELOCITY.': |
176 | 1 | tkerber | l = f.readline() |
177 | 1 | tkerber | else:
|
178 | 1 | tkerber | vels = np.zeros( [ nat, 3 ] )
|
179 | 1 | tkerber | |
180 | 1 | tkerber | naux = read_int_key(l, 'entry_count') - 3 |
181 | 1 | tkerber | if vels is not None: |
182 | 1 | tkerber | naux -= 3
|
183 | 1 | tkerber | aux = np.zeros( [ nat, naux ] ) |
184 | 1 | tkerber | |
185 | 1 | tkerber | auxstrs = [ ] |
186 | 1 | tkerber | for i in range(naux): |
187 | 1 | tkerber | s = read_str_key(f, 'auxiliary[%1.1i]' % i, 'auxiliary[%2.2i]' % i) |
188 | 1 | tkerber | auxstrs += [ s[:s.find('[')].strip() ]
|
189 | 1 | tkerber | |
190 | 1 | tkerber | spos = np.zeros( [ nat, 3 ] )
|
191 | 1 | tkerber | masses = np.zeros( nat ) |
192 | 1 | tkerber | syms = [ '' for i in range(nat) ] |
193 | 1 | tkerber | |
194 | 1 | tkerber | i = 0
|
195 | 1 | tkerber | s = f.readline().split() |
196 | 1 | tkerber | while l:
|
197 | 1 | tkerber | mass = float(s[0]) |
198 | 1 | tkerber | sym = f.readline().strip() |
199 | 1 | tkerber | |
200 | 1 | tkerber | l = f.readline() |
201 | 1 | tkerber | s = l.split() |
202 | 1 | tkerber | |
203 | 1 | tkerber | while l and len(s) > 1: |
204 | 1 | tkerber | masses[i] = mass |
205 | 1 | tkerber | syms[i] = sym |
206 | 1 | tkerber | props = [ float(x) for x in s ] |
207 | 1 | tkerber | |
208 | 1 | tkerber | spos[i, :] = props[0:3] |
209 | 1 | tkerber | off = 3
|
210 | 1 | tkerber | if vels is not None: |
211 | 1 | tkerber | off = 6
|
212 | 1 | tkerber | vels[i, :] = props[3:6] |
213 | 1 | tkerber | |
214 | 1 | tkerber | aux[i, :] = props[off:] |
215 | 1 | tkerber | |
216 | 1 | tkerber | i += 1
|
217 | 1 | tkerber | |
218 | 1 | tkerber | l = f.readline() |
219 | 1 | tkerber | if l:
|
220 | 1 | tkerber | s = l.split() |
221 | 1 | tkerber | |
222 | 1 | tkerber | if vels is None: |
223 | 1 | tkerber | a = ase.Atoms( |
224 | 1 | tkerber | symbols = syms, |
225 | 1 | tkerber | masses = masses, |
226 | 1 | tkerber | scaled_positions = spos, |
227 | 1 | tkerber | cell = cell, |
228 | 1 | tkerber | pbc = True
|
229 | 1 | tkerber | ) |
230 | 1 | tkerber | else:
|
231 | 1 | tkerber | a = ase.Atoms( |
232 | 1 | tkerber | symbols = syms, |
233 | 1 | tkerber | masses = masses, |
234 | 1 | tkerber | scaled_positions = spos, |
235 | 1 | tkerber | momenta = masses.reshape(-1,1)*vels, |
236 | 1 | tkerber | cell = cell, |
237 | 1 | tkerber | pbc = True
|
238 | 1 | tkerber | ) |
239 | 1 | tkerber | |
240 | 1 | tkerber | i = 0
|
241 | 1 | tkerber | while i < naux:
|
242 | 1 | tkerber | auxstr = auxstrs[i] |
243 | 1 | tkerber | |
244 | 1 | tkerber | if auxstr[-2:] == '_x': |
245 | 1 | tkerber | a.set_array(auxstr[:-2], aux[:, i:i+3]) |
246 | 1 | tkerber | |
247 | 1 | tkerber | i += 3
|
248 | 1 | tkerber | else:
|
249 | 1 | tkerber | a.set_array(auxstr, aux[:, i]) |
250 | 1 | tkerber | |
251 | 1 | tkerber | i += 1
|
252 | 1 | tkerber | |
253 | 1 | tkerber | return a |