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
|
import numpy as np
from ase import io
from dynasor.trajectory.abstract_trajectory_reader import AbstractTrajectoryReader
from dynasor.trajectory.trajectory_frame import ReaderFrame
from itertools import count
class ASETrajectoryReader(AbstractTrajectoryReader):
"""Read ASE trajectory file
...
Parameters
----------
filename
Name of input file.
length_unit
Unit of length for the input trajectory (``'Angstrom'``, ``'nm'``, ``'pm'``, ``'fm'``).
time_unit
Unit of time for the input trajectory (``'fs'``, ``'ps'``, ``'ns'``).
"""
def __init__(
self,
filename: str,
length_unit: str = 'Angstrom',
time_unit: str = 'fs',
):
self._frame_index = count(0)
self._atoms = io.iread(filename, index=':')
# setup units
if length_unit not in self.lengthunits_to_nm_table:
raise ValueError(f'Specified length unit {length_unit} is not an available option.')
else:
self.x_factor = self.lengthunits_to_nm_table[length_unit]
if time_unit not in self.timeunits_to_fs_table:
raise ValueError(f'Specified time unit {time_unit} is not an available option.')
else:
self.t_factor = self.timeunits_to_fs_table[time_unit]
self.v_factor = self.x_factor / self.t_factor
def __iter__(self):
return self
def close(self):
pass
def __next__(self):
ind = next(self._frame_index)
a = next(self._atoms)
if 'momenta' in a.arrays:
vel = self.v_factor * a.get_velocities()
else:
vel = None
return ReaderFrame(
frame_index=ind,
n_atoms=len(a),
cell=self.x_factor * a.cell.array.copy('F'),
positions=self.x_factor * a.get_positions(),
velocities=vel,
atom_types=np.array(list(a.symbols)),
)
|