Some implementation details¶
Trajectories are read frame by frame by the trajectory_reader, which is an iterable object. Each frame produced by the trajectory_reader is represented as a dictionary object containing particle positions, velocities etc.
The trajectory_iterator is then wrapped in a “window generator”, producing a sliding window of frames through the trajectory. The size of the window is decided by the requested number of time frames to consider for time correlation. The argument –nt determines the width (time length) of the window, and the argument –stride determines how many frames to move the window between two consecutive windows.
Each frame in a window will be processed to have its particle positions (and velocities) split info particle types/species, and for each particle type the corresponding fourier transform of its density (and current) will be calculated. Information about which particle belongs to which type/species comes either from the trajectory file (if available), or from a separate index file (gromacs ndx-style).
For each window, time correlations ranging from delta_t=0 (the “static” correlation) to delta_t=<window width> is calculated. The time correlations are averaged over all windows considered.
Each of the averaged time correlations are then further averaged in the reciprocal domain by mapping it into –k-bins values ranging from 0 to –k-max (for an isotropic media, only the absolute of the k-vector is of interest).
For each output format choosen, output is written.
All call to external libraries are used using ctypes. The main reason for choosing ctypes over e.g., swig/weave/f2py/... is portability. Ctypes is included with Python, and uses libffi so there is no need for a compiler. A drawback is that lots of API stuff needs to be explicitly set up in Python code. If there is a change in the API to the external libraries used, some part of the dynasor code need to be modified.