/usr/share/pyshared/ase/io/etsf.py is in python-ase 3.6.0.2515-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | import numpy as np
from ase.atoms import Atoms
from ase.units import Bohr
from ase.io.pupynere import NetCDFFile
class ETSFReader:
def __init__(self, filename):
self.nc = NetCDFFile(filename, 'r')
def read_atoms(self):
var = self.nc.variables
cell = var['primitive_vectors']
assert cell.units == 'atomic units'
species = var['atom_species'][:]
spos = var['reduced_atom_positions'][:]
numbers = var['atomic_numbers'][:]
return Atoms(numbers=numbers[species - 1],
scaled_positions=spos,
cell=cell[:] * Bohr,
pbc=True)
class ETSFWriter:
def __init__(self, filename):
from Scientific.IO.NetCDF import NetCDFFile
self.nc = NetCDFFile(filename, 'w')
self.nc.file_format = 'ETSF Nanoquanta'
self.nc.file_format_version = np.array([3.3], dtype=np.float32)
self.nc.Conventions = 'http://www.etsf.eu/fileformats/'
self.nc.history = 'File generated by ASE'
def write_atoms(self, atoms):
specie_a = np.empty(len(atoms), np.int32)
nspecies = 0
species = {}
numbers = []
for a, Z in enumerate(atoms.get_atomic_numbers()):
if Z not in species:
species[Z] = nspecies
nspecies += 1
numbers.append(Z)
specie_a[a] = species[Z]
dimensions = [
('character_string_length', 80),
('number_of_atoms', len(atoms)),
('number_of_atom_species', nspecies),
('number_of_cartesian_directions', 3),
('number_of_reduced_dimensions', 3),
('number_of_vectors', 3)]
for name, size in dimensions:
self.nc.createDimension(name, size)
var = self.add_variable
var('primitive_vectors',
('number_of_vectors', 'number_of_cartesian_directions'),
atoms.cell / Bohr, units='atomic units')
var('atom_species', ('number_of_atoms',), specie_a + 1)
var('reduced_atom_positions',
('number_of_atoms', 'number_of_reduced_dimensions'),
atoms.get_scaled_positions())
var('atomic_numbers', ('number_of_atom_species',),
np.array(numbers, dtype=float))
def close(self):
self.nc.close()
def add_variable(self, name, dims, data=None, **kwargs):
if data is None:
char = 'd'
else:
if isinstance(data, np.ndarray):
char = data.dtype.char
elif isinstance(data, float):
char = 'd'
elif isinstance(data, int):
char = 'i'
else:
char = 'c'
var = self.nc.createVariable(name, char, dims)
for attr, value in kwargs.items():
setattr(var, attr, value)
if data is not None:
if len(dims) == 0:
var.assignValue(data)
else:
if char == 'c':
if len(dims) == 1:
var[:len(data)] = data
else:
for i, x in enumerate(data):
var[i, :len(x)] = x
else:
var[:] = data
return var
|