simularium / simulariumio

Python package that converts simulation outputs to the format consumed by the Simularium viewer website
Apache License 2.0
5 stars 3 forks source link

Feature/particle orientations #113

Closed blairlyons closed 2 years ago

blairlyons commented 2 years ago

Problem

Particles can only be drawn with spheres because the particles have no orientations. closes #40

Solution

Particles with geometrically-constrained edges (e.g. in ReaDDy data) can be mapped to structural data (e.g. from PDB files) to back-calculate orientations that allow geometry generated from that structural data to be drawn with reasonable accuracy.

This solution breaks the problem into multiple cases:

  1. Independent orientations - particles with two neighbors have fully determined orientations. To calculate them, use the vectors from the particle to each of its neighbors to form a basis.
  2. Random orientation - if a particle has no neighbors, it's orientation is fully undetermined, and the only thing to do is create a random orientation (Note: maybe a future PR should make the random rotation be an offset from the previous time step, for now it is independently random each time. However this might be roughly accurate given these timesteps are very large relative to molecular time).
  3. Dependent orientation - particles with one neighbor may have fully or partially determined orientations:
    • If their one neighbor has other neighbors, their orientation is fully determined by an offset from their neighbor's orientation
    • If their one neighbor has no other neighbors, both of these particles have to orient correctly relative to each other, but have a degree of freedom around the axis defined by their edge. (This case also applies to colinear neighbors but I've left that out for now)

For all of these cases, the orientations calculated from neighbor positions are meaningless on their own. In order to use them to orient geometry, we need to calculate the difference between the current orientation and the orientation of the particles used to generate the geometry (which I'm calling "zero orientations").

Type of change

Change summary:

Keyfiles:

  1. simulariumio/orientations/particle_rotation_calculator.py - ParticleRotationCalculator is the main particle orientation class, which contains all the data needed to calculate orientation for one particle at one time step. In __init__() it calculates independent and random orientations since they don't depend on neighbor orientations already being calculated. It also has calculate_dependent_rotation() which can be used after ParticleRotationCalculators are created for all the particle's neighbors. There's also get_euler_angles() to get the final orientation as an XYZ rotation for the simularium viewer.
  2. simulariumio/readdy/readdy_converter.py and simulariumio/readdy/readdy_data.py - add orientation calculation for ReaDDy particles.
  3. simulariumio/orientations/orientation_data.py and simulariumio/orientations/neighbor_data.py - data classes with some related methods.
  4. simulariumio/orientations/rotation_utility.py - helpers for calculating rotations, everything that uses scipy for linear algebra and rotations