ReaDDy - A particle-based
reaction-diffusion simulator

Post-processing

Once the system is simulated, the trajectory and stored observables can be analyzed. For this purpose a trajectory object can be created by providing a path to the output file of a simulation:

trajectory = readdy.Trajectory('out.h5')

Visual representation of the trajectory

To look at the time-series of the position of particles, one can use VMD. To this end there is a function to convert the hdf5 trajectory into a VMD-readable xyz file.

trajectory.convert_to_xyz(particle_radii={'A': 1.})

In shell you can then call vmd as follows

vmd -e out.xyz.tcl

The particle_radii are all defaulted to 1. unless otherwise specified.

Information about the simulated system

The trajectory file stores some information about the system that was simulated. Given a trajectory object, one can obtain

# the thermal energy
trajectory.kbt
# the volume of the simulation box
trajectory.box_volume
# the dimensions of the simulation box
trajectory.box_size
# whether periodic boundary conditions were used
trajectory.periodic_boundary_conditions
# diffusion constants for registered particle types
trajectory.diffusion_constants
# a mapping from particle type name -> internal particle type id
trajectory.particle_types
# registered reactions
trajectory.reactions

Reading observable data

All observables including the actual trajectory have functions to read back the recorded data.

The actual trajectory can be read back as a list of lists by invoking

for frame in trajectory.read():
  for particle in frame:
    print("Particle with id {} of type {} at position {}" 
          .format(particle.id, particle.type, particle.position))

Except for the trajectory all observables can be stored at a different place in the file by providing a save argument when registering them. For such a case each method of the trajectory object that can obtain observable data has an additional argument data_set_name that needs to be set accordingly. If the default save argument was used or it was not specified, one can omit the data_set_name.

Since one can configure observables with different strides an array with simulation times is always returned, i.e., if an observable was configured with a stride of 5, it would contain [0, 5, 10, ...].

  • The radial distribution function data can be read back by
    time, bin_centers, distribution = trajectory.read_observable_rdf()
    

    where time is a list of simulation times, bin_centers are the bin centers and distribution contains the RDF in shape of a (T, N) array (T being the number of recordings and N being the number of bins).

  • The particles data can be obtained by
    time, types, ids, positions = trajectory.read_observable_particles()
    

    where time is a list of simulation times, types is a list of particle type ids that can be converted to their respective names by calling trajectory.species_name(a_particular_id), ids is a list of lists containing the unique ids of each particle, and positions is a list of lists containing particle positions.

  • The particle positions data can be obtained by
    time, positions = trajectory.read_observable_particle_positions()
    

    where time is a list of simulation times and positions is a list of (N_t, 3)-shaped arrays, where N_t is the number of particles in particular time step.

  • The number of particles data can be obtained by
    time, counts = trajectory.read_observable_number_of_particles()
    

    where time is a list of simulation times and counts is an array containing the recorded number of particles per requested type.

  • The energy observable data can be obtained by
    time, energy = trajectory.read_observable_energy()
    

    where time is a list of simulation times and energy is a list of potential energy values.

  • The forces observable data can be obtained by
    time, forces = trajectory.read_observable_forces()
    

    where time is a list of simulation times and forces is a list of arrays containing the forces acting on each particle for each evaluated time step.

  • The reactions observable data can be obtained by
    time, reactions = trajectory.read_observable_reactions()
    

    where time is a list of simulation times and reactions is a list of lists containing the occurred reaction events for each evaluated time step. The reaction event data can be accessed just like in the callback function of the observable.

  • The reaction counts observable data can be obtained by
    time, counts = trajectory.read_observable_reaction_counts()
    

    where time is a list of simulation times and counts is a dictionary with the reaction names as keys and the corresponding counts as values, i.e.,

    counts['my_reaction']
    

    is an array of length N where N is the number of evaluations of the observable with the number of occurrences of my_reaction.

  • The virial observable data can be obtained by
    time, virials = trajectory.read_observable_virial()
    

    where time is a list of simulation times and virials contains the system’s pressure virial for each simulation time in that it was evaluated.

  • The pressure observable data can be obtained by
    time, pressure = trajectory.read_observable_pressure()
    

    where time is a list of simulation times and pressure contains the corresponding pressure per simulation time.

© Copyright 2020 AI4Science (former CMB) Group