Source code for simularium_readdy_models.actin.arp_data

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
import math

from ..common import ReaddyUtil
from .actin_structure import ActinStructure


[docs]class ArpData: """ Arp branch nucleator data """ arp_id = -1 position = None bound = False nucleated = False daughter_fiber = None assigned = False distance_from_mother_pointed = math.inf def __init__( self, arp_id, position, bound=True, nucleated=False, daughter_fiber=None ): self.arp_id = arp_id self.position = position self.bound = bound self.nucleated = nucleated self.daughter_fiber = daughter_fiber self.assigned = False self.distance_from_mother_pointed = math.inf
[docs] def get_closest_actin_index( self, particle_ids, actin_arp_ids, mother_fiber, particles ): """ get the index of the closest actin monomer to the arp position excluding the barbed end (because that monomer would also be bound to this arp) """ min_distance = math.inf closest_actin_index = -1 for index in range(len(particle_ids) - 1): particle_id = particle_ids[index] if ( "actin" in particles[particle_id].type_name and particle_id not in actin_arp_ids ): distance = np.linalg.norm( particles[particle_id].position - self.position ) if distance < min_distance: closest_actin_index = index min_distance = distance if mother_fiber is not None and self.daughter_fiber is not None: # if this arp is nucleated, check that the branch will grow roughly # in the correct direction, otherwise chose a neighbor actin # so the branch grows the other direction closest_actin_pos = particles[particle_ids[closest_actin_index]].position v_daughter = self.daughter_fiber.get_nearest_segment_direction( closest_actin_pos ) closest_actin_axis_pos = mother_fiber.get_nearest_position( closest_actin_pos ) v_closest = closest_actin_pos - closest_actin_axis_pos dot = ( v_daughter[0] * v_closest[0] + v_daughter[1] * v_closest[1] + v_daughter[2] * v_closest[2] ) if dot < 0: if closest_actin_index < len(particle_ids) - 2: closest_actin_index += 1 elif closest_actin_index > 0: closest_actin_index -= 1 else: raise Exception( "Failed to find actin_arp2 that would nucleate branch " "in correct direction" ) return closest_actin_index
[docs] def get_bound_arp_rotation(self, mother_fiber, actin_arp2_pos): """ get the difference in the arp's current orientation compared to the initial orientation as a rotation matrix """ v_mother = mother_fiber.get_nearest_segment_direction(self.position) actin_arp2_axis_pos = mother_fiber.get_nearest_position(actin_arp2_pos) v_actin_arp2 = ReaddyUtil.normalize(actin_arp2_pos - actin_arp2_axis_pos) current_orientation = ReaddyUtil.get_orientation_from_vectors( v_mother, v_actin_arp2 ) return np.matmul( current_orientation, np.linalg.inv(ActinStructure.bound_arp_orientation()) )
[docs] def get_bound_monomer_position(self, actin_arp2_pos, mother_fiber, monomer_type): """ get the offset vector in the arp's local space for the nearby monomers """ offset_vector = ( ActinStructure.branch_monomer_position(monomer_type) - ActinStructure.mother_branch_position() ) rotation = self.get_bound_arp_rotation(mother_fiber, actin_arp2_pos) return actin_arp2_pos + np.squeeze(np.array(np.dot(rotation, offset_vector)))
[docs] def get_nucleated_arp_rotation(self, v_mother, v_daughter): """ get the difference in the arp's current orientation compared to the initial orientation as a rotation matrix """ branch_angle = ReaddyUtil.get_angle_between_vectors(v_mother, v_daughter) # rotate daughter axis to ideal branch angle axis = np.cross(v_mother, v_daughter) angle = ActinStructure.branch_angle() - branch_angle v_daughter = ReaddyUtil.rotate(v_daughter, axis, angle) current_orientation = ReaddyUtil.get_orientation_from_vectors( v_mother, v_daughter ) return np.matmul( current_orientation, np.linalg.inv(ActinStructure.nucleated_arp_orientation()), )
[docs] def get_local_nucleated_monomer_position(self, v_mother, v_daughter, monomer_type): """ get the offset vector in the arp's local space for the nearby monomers """ offset_vector = ( ActinStructure.branch_monomer_position(monomer_type) - ActinStructure.mother_branch_position() ) rotation = self.get_nucleated_arp_rotation(v_mother, v_daughter) return np.squeeze(np.array(np.dot(rotation, offset_vector)))
[docs] @staticmethod def rotate_position_to_match_branch_angle( monomer_position, branch_angle, arp_mother_position, branch_normal ): """ rotate a monomer position near a branch to match the actual branch angle (angles in radians) """ angle = ActinStructure.branch_angle() - branch_angle pivot = ( arp_mother_position + ActinStructure.actin_distance_from_axis() * branch_normal ) v = monomer_position - pivot return pivot + ReaddyUtil.rotate(v, branch_normal, angle)