root / ase / io / cfg.py @ 14
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 |