Compute interatomic distances along path#
This example demonstrates how to compute the minimum interatomic distance for each frame in each path and plot the result. In this example we consider all the atoms, but you can choose some specific atoms using NSL.
First, open a trajectory in SAMSON or fetch one from RCSB PDB, e.g. SAMSON.fetchPDB('1d3z')
. Make sure to check the option to create the path.
import numpy as np
import matplotlib.pyplot as plt
def compute_min_interatomic_distance(atom_indexer, neighbor_search, rcutoff = SBQuantity.angstrom(2)):
'''
Compute the minimal interatomic distances between atoms in atom_indexer
Return result in angstrom units.
'''
neighbor_search.updateNeighborLists()
# initialize the minimum distance to rcutoff
min_distance = rcutoff
# go through all the atoms
for i, atom in enumerate(atom_indexer):
neighbors = neighbor_search.getNeighborVector(i)
for neighbor_atom in neighbors:
distance = (atom.getPosition() - neighbor_atom.getPosition()).norm()
if distance < min_distance:
min_distance = distance
return min_distance.angstrom.value
def compute_min_interatomic_distance_per_path(path, atom_indexer, rcutoff = SBQuantity.angstrom(2.0)):
'''
Compute interatomic distances between atoms in atom_indexer along the path
'''
# Create a particle system from the atom indexer
particle_system = SBParticleSystem(atom_indexer)
# Create the neighbor search for this particle system
neighbor_search = SBNeighborSearchParticleSystemGrid(particle_system, rcutoff)
neighbor_search.initializeNeighborLists()
# store the current step
current_step = path.currentStep
path.currentStep = 0
interatomic_length = []
# loop over path steps
for i in range(path.numberOfSteps):
# set the current step of the path
path.currentStep = i
interatomic_length.append( compute_min_interatomic_distance(atom_indexer, neighbor_search, rcutoff) )
# If you want to see in the viewport how the path changes, force SAMSON to process events
# Comment it for bigger systems, since it may slow down the computations
SAMSON.processEvents()
# restore the current step
path.currentStep = current_step
return interatomic_length
# get an indexer of all paths in the active document
path_indexer = SAMSON.getNodes('node.type path')
# get an indexer of all atoms in the active document
atom_indexer = SAMSON.getNodes('node.type atom')
# set the radius of cutoff
rcutoff = SBQuantity.angstrom(2.0)
# Compute min interatomic distance for each path in the document
interatomic_length_per_path = []
# loop over paths in the path indexer
for path in path_indexer:
value = compute_min_interatomic_distance_per_path(path, atom_indexer, rcutoff)
interatomic_length_per_path.append( value )
# Plot results using matplotlib
legend = []
for i, path in enumerate(path_indexer):
plt.plot(interatomic_length_per_path[i])
legend.append(path.name)
plt.legend(legend)
plt.ylabel('min interatomic distance, Å')
plt.xlabel('frame')
plt.tight_layout()
plt.show()