Statistiques
| Révision :

root / ase / io / cube.py @ 11

Historique | Voir | Annoter | Télécharger (2,81 ko)

1
"""
2
IO support for the Gaussian cube format.
3

4
See the format specifications on:
5
http://local.wasp.uwa.edu.au/~pbourke/dataformats/cube/
6
"""
7

    
8

    
9
import numpy as np
10

    
11
from ase.atoms import Atoms
12
from ase.units import Bohr
13
from ase.parallel import paropen
14

    
15

    
16
def write_cube(fileobj, atoms, data=None):
17
    if isinstance(fileobj, str):
18
        fileobj = paropen(fileobj, 'w')
19
        
20
    if isinstance(atoms, list):
21
        if len(atoms) > 1:
22
            raise ValueError('Can only write one configuration '
23
                             'to a cube file!')
24
        atoms = atoms[0]
25

    
26
    if data is None:
27
        data = np.ones((2, 2, 2))
28
    data = np.asarray(data)
29

    
30
    if data.dtype == complex:
31
        data = np.abs(data)
32

    
33
    fileobj.write('cube file from ase\n')
34
    fileobj.write('OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n')
35

    
36
    cell = atoms.get_cell()
37
    shape = np.array(data.shape)
38

    
39
    corner = np.zeros(3)
40
    for i in range(3):
41
        if shape[i] % 2 == 1:
42
            shape[i] += 1
43
            corner += cell[i] / shape[i] / Bohr
44

    
45
    fileobj.write('%5d%12.6f%12.6f%12.6f\n' % (len(atoms), corner[0],
46
                                               corner[1], corner[2]))
47

    
48
    for i in range(3):
49
        n = data.shape[i]
50
        d = cell[i] / shape[i] / Bohr
51
        fileobj.write('%5d%12.6f%12.6f%12.6f\n' % (n, d[0], d[1], d[2]))
52

    
53
    positions = atoms.get_positions() / Bohr
54
    numbers = atoms.get_atomic_numbers()
55
    for Z, (x, y, z) in zip(numbers, positions):
56
        fileobj.write('%5d%12.6f%12.6f%12.6f%12.6f\n' % (Z, 0.0, x, y, z)) 
57

    
58
    data.tofile(fileobj, sep='\n', format='%e')
59

    
60

    
61
def read_cube(fileobj, index=-1, read_data=False):
62
    if isinstance(fileobj, str):
63
        fileobj = open(fileobj)
64

    
65
    readline = fileobj.readline
66
    readline()
67
    axes = ['XYZ'.index(s[0]) for s in readline().split()[2::3]]
68
    if axes == []:
69
        axes = [0, 1, 2]
70
    line = readline().split()
71
    natoms = int(line[0])
72
    corner = [Bohr * float(x) for x in line[1:]]
73

    
74
    cell = np.empty((3, 3))
75
    shape = []
76
    for i in range(3):
77
        n, x, y, z = [float(s) for s in readline().split()]
78
        shape.append(n)
79
        if n % 2 == 1:
80
            n += 1
81
        cell[i] = n * Bohr * np.array([x, y, z])
82
        
83
    numbers = np.empty(natoms, int)
84
    positions = np.empty((natoms, 3))
85
    for i in range(natoms):
86
        line = readline().split()
87
        numbers[i] = int(line[0])
88
        positions[i] = [float(s) for s in line[2:]]
89

    
90
    positions *= Bohr
91
    atoms = Atoms(numbers=numbers, positions=positions, cell=cell)
92

    
93
    if read_data:
94
        data = np.array([float(s)
95
                         for s in fileobj.read().split()]).reshape(shape)
96
        if axes != [0, 1, 2]:
97
            data = data.transpose(axes).copy()
98
        return data, atoms
99

    
100
    return atoms
101

    
102

    
103
def read_cube_data(fileobj):
104
    return read_cube(fileobj, read_data=True)