root / ase / io / cube.py @ 11
Historique | Voir | Annoter | Télécharger (2,81 ko)
1 | 1 | tkerber | """
|
---|---|---|---|
2 | 1 | tkerber | IO support for the Gaussian cube format.
|
3 | 1 | tkerber |
|
4 | 1 | tkerber | See the format specifications on:
|
5 | 1 | tkerber | http://local.wasp.uwa.edu.au/~pbourke/dataformats/cube/
|
6 | 1 | tkerber | """
|
7 | 1 | tkerber | |
8 | 1 | tkerber | |
9 | 1 | tkerber | import numpy as np |
10 | 1 | tkerber | |
11 | 1 | tkerber | from ase.atoms import Atoms |
12 | 1 | tkerber | from ase.units import Bohr |
13 | 1 | tkerber | from ase.parallel import paropen |
14 | 1 | tkerber | |
15 | 1 | tkerber | |
16 | 1 | tkerber | def write_cube(fileobj, atoms, data=None): |
17 | 1 | tkerber | if isinstance(fileobj, str): |
18 | 1 | tkerber | fileobj = paropen(fileobj, 'w')
|
19 | 1 | tkerber | |
20 | 1 | tkerber | if isinstance(atoms, list): |
21 | 1 | tkerber | if len(atoms) > 1: |
22 | 1 | tkerber | raise ValueError('Can only write one configuration ' |
23 | 1 | tkerber | 'to a cube file!')
|
24 | 1 | tkerber | atoms = atoms[0]
|
25 | 1 | tkerber | |
26 | 1 | tkerber | if data is None: |
27 | 1 | tkerber | data = np.ones((2, 2, 2)) |
28 | 1 | tkerber | data = np.asarray(data) |
29 | 1 | tkerber | |
30 | 1 | tkerber | if data.dtype == complex: |
31 | 1 | tkerber | data = np.abs(data) |
32 | 1 | tkerber | |
33 | 1 | tkerber | fileobj.write('cube file from ase\n')
|
34 | 1 | tkerber | fileobj.write('OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n')
|
35 | 1 | tkerber | |
36 | 1 | tkerber | cell = atoms.get_cell() |
37 | 1 | tkerber | shape = np.array(data.shape) |
38 | 1 | tkerber | |
39 | 1 | tkerber | corner = np.zeros(3)
|
40 | 1 | tkerber | for i in range(3): |
41 | 1 | tkerber | if shape[i] % 2 == 1: |
42 | 1 | tkerber | shape[i] += 1
|
43 | 1 | tkerber | corner += cell[i] / shape[i] / Bohr |
44 | 1 | tkerber | |
45 | 1 | tkerber | fileobj.write('%5d%12.6f%12.6f%12.6f\n' % (len(atoms), corner[0], |
46 | 1 | tkerber | corner[1], corner[2])) |
47 | 1 | tkerber | |
48 | 1 | tkerber | for i in range(3): |
49 | 1 | tkerber | n = data.shape[i] |
50 | 1 | tkerber | d = cell[i] / shape[i] / Bohr |
51 | 1 | tkerber | fileobj.write('%5d%12.6f%12.6f%12.6f\n' % (n, d[0], d[1], d[2])) |
52 | 1 | tkerber | |
53 | 1 | tkerber | positions = atoms.get_positions() / Bohr |
54 | 1 | tkerber | numbers = atoms.get_atomic_numbers() |
55 | 1 | tkerber | for Z, (x, y, z) in zip(numbers, positions): |
56 | 1 | tkerber | fileobj.write('%5d%12.6f%12.6f%12.6f%12.6f\n' % (Z, 0.0, x, y, z)) |
57 | 1 | tkerber | |
58 | 1 | tkerber | data.tofile(fileobj, sep='\n', format='%e') |
59 | 1 | tkerber | |
60 | 1 | tkerber | |
61 | 1 | tkerber | def read_cube(fileobj, index=-1, read_data=False): |
62 | 1 | tkerber | if isinstance(fileobj, str): |
63 | 1 | tkerber | fileobj = open(fileobj)
|
64 | 1 | tkerber | |
65 | 1 | tkerber | readline = fileobj.readline |
66 | 1 | tkerber | readline() |
67 | 1 | tkerber | axes = ['XYZ'.index(s[0]) for s in readline().split()[2::3]] |
68 | 1 | tkerber | if axes == []:
|
69 | 1 | tkerber | axes = [0, 1, 2] |
70 | 1 | tkerber | line = readline().split() |
71 | 1 | tkerber | natoms = int(line[0]) |
72 | 1 | tkerber | corner = [Bohr * float(x) for x in line[1:]] |
73 | 1 | tkerber | |
74 | 1 | tkerber | cell = np.empty((3, 3)) |
75 | 1 | tkerber | shape = [] |
76 | 1 | tkerber | for i in range(3): |
77 | 1 | tkerber | n, x, y, z = [float(s) for s in readline().split()] |
78 | 1 | tkerber | shape.append(n) |
79 | 1 | tkerber | if n % 2 == 1: |
80 | 1 | tkerber | n += 1
|
81 | 1 | tkerber | cell[i] = n * Bohr * np.array([x, y, z]) |
82 | 1 | tkerber | |
83 | 1 | tkerber | numbers = np.empty(natoms, int)
|
84 | 1 | tkerber | positions = np.empty((natoms, 3))
|
85 | 1 | tkerber | for i in range(natoms): |
86 | 1 | tkerber | line = readline().split() |
87 | 1 | tkerber | numbers[i] = int(line[0]) |
88 | 1 | tkerber | positions[i] = [float(s) for s in line[2:]] |
89 | 1 | tkerber | |
90 | 1 | tkerber | positions *= Bohr |
91 | 1 | tkerber | atoms = Atoms(numbers=numbers, positions=positions, cell=cell) |
92 | 1 | tkerber | |
93 | 1 | tkerber | if read_data:
|
94 | 1 | tkerber | data = np.array([float(s)
|
95 | 1 | tkerber | for s in fileobj.read().split()]).reshape(shape) |
96 | 1 | tkerber | if axes != [0, 1, 2]: |
97 | 1 | tkerber | data = data.transpose(axes).copy() |
98 | 1 | tkerber | return data, atoms
|
99 | 1 | tkerber | |
100 | 1 | tkerber | return atoms
|
101 | 1 | tkerber | |
102 | 1 | tkerber | |
103 | 1 | tkerber | def read_cube_data(fileobj): |
104 | 1 | tkerber | return read_cube(fileobj, read_data=True) |