IMP logo
IMP Reference Guide  develop.a05c3d0975,2025/10/11
The Integrative Modeling Platform
bff/tools/__init__.py
1 """@namespace IMP.bff.tools
2  Utility functions.
3 """
4 
5 import IMP
6 import IMP.core
7 import IMP.atom
8 import IMP.bff
9 
10 import typing
11 import numpy as np
12 import scipy.stats
13 
14 
16  used_avs: typing.List[IMP.bff.AV],
17  dye_radius: float = 3.5
18 ):
19  """Decorate the accessible volume particles
20  with a mass and radii, so that they appear
21  in the rmf file"""
22  for dye in used_avs:
23  # Add radius and mass to dye
24  p_dye = dye.get_particle()
25  if not IMP.core.XYZR.get_is_setup(p_dye):
26  p_dye = IMP.core.XYZR.setup_particle(p_dye)
27  p_dye.set_radius(dye_radius)
28  else:
29  p_dye = IMP.core.XYZR(p_dye)
30  if not IMP.atom.Mass.get_is_setup(p_dye):
32 
33  # add dye to atom hier
34  p_att = dye.get_source()
35  h_att = IMP.atom.Hierarchy(p_att)
37  h_dye = IMP.atom.Hierarchy(p_dye)
38  h_att.add_child(h_dye)
39  # create bond between dye and source
40  if not IMP.atom.Bonded.get_is_setup(p_dye):
42  if not IMP.atom.Bonded.get_is_setup(p_att):
44  if not IMP.atom.get_bond(IMP.atom.Bonded(p_dye),
45  IMP.atom.Bonded(p_att)):
47  IMP.atom.Bonded(p_dye), IMP.atom.Bonded(p_att), 1)
48 
49 
50 class FRETDistanceConverter(object):
51 
52  _forster_radius_: float = 52.0
53 
54  # current center-to-center distance
55  _dist_center_center_: float = 50.0
56 
57  # Variables for distance distribution computation
58  _distances_: np.ndarray = None # distance array for distance distribution
59  _fret_efficiencies_: np.ndarray = None # FRET efficiency array corre
60  _density_: np.ndarray = None
61 
62  # lookup table to cache the computation
63  _d_mean_: np.ndarray = None
64  _d_mean_fret_: np.ndarray = None
65  _e_mean_: np.ndarray = None
66 
67  def _update_fret_efficiencies_(self, forster_radius: float):
68  RDA = self._distances_
69  R0 = forster_radius
70  self._fret_efficiencies_ = 1. / (1 + (RDA / R0)**6.0)
71 
72  def _update_lookup(self):
73  self._d_mean_ = np.empty_like(self._distances_)
74  self._d_mean_fret_ = np.empty_like(self._distances_)
75  self._e_mean_ = np.empty_like(self._distances_)
76  for i, d in enumerate(self._distances_):
77  self._update_density(d, self._sigma_)
78  self._d_mean_[i] = self.calc_distance_mean()
79  self._d_mean_fret_[i] = self.calc_distance_mean_fret()
80  self._e_mean_[i] = self.calc_fret_efficiency_mean()
81 
82  def _update_density(self, dcc: float, w: float):
83  """Update the distance distribution
84 
85  @param dcc center-to-center distance
86  @param w parameter controlling the distribution width
87  """
88  d = self._distances_
89  n1 = scipy.stats.norm(-dcc, w)
90  n2 = scipy.stats.norm(dcc, w)
91  p = n1.pdf(d) + n2.pdf(d)
92  p /= p.sum()
93  self._density_ = p
94 
95  @property
96  def dist_center_center(self):
97  return self._dist_center_center_
98 
99  @dist_center_center.setter
100  def dist_center_center(self, v):
101  self._dist_center_center_ = v
102 
103  @property
104  def sigma(self):
105  return self._sigma_
106 
107  @sigma.setter
108  def sigma(self, v: float):
109  self._sigma_ = v
110  self._update_lookup()
111 
112  @property
113  def forster_radius(self):
114  return self._forster_radius_
115 
116  @forster_radius.setter
117  def forster_radius(self, v: float):
118  self._forster_radius_ = v
119  self._update_fret_efficiencies_(v)
120  self._update_lookup()
121 
122  def calc_distance_mean(self):
123  p = self._density_
124  v = self._distances_
125  return p @ v
126 
127  def calc_fret_efficiency_mean(self):
128  p = self._density_
129  v = self._fret_efficiencies_
130  return p @ v
131 
132  def calc_distance_mean_fret(self):
133  E = self.calc_fret_efficiency_mean()
134  R0 = self.forster_radius
135  return R0 * (1. / E - 1.)**(1. / 6.)
136 
137  @property
138  def fret_efficiency_mean(self):
139  return np.interp(self.dist_center_center, self._distances_,
140  self._e_mean_)
141 
142  @property
143  def distance_mean(self):
144  return np.interp(self.dist_center_center, self._distances_,
145  self._d_mean_)
146 
147  @property
148  def distance_mean_fret(self):
149  return np.interp(self.dist_center_center, self._distances_,
150  self._d_mean_fret_)
151 
152  def __call__(self, value: float, distance_type: int):
153  self.dist_center_center = value
154  if distance_type == IMP.bff.DYE_PAIR_DISTANCE_MEAN:
155  return self.distance_mean
156  elif distance_type == IMP.bff.DYE_PAIR_DISTANCE_E:
157  return self.distance_mean_fret
158  elif distance_type == IMP.bff.DYE_PAIR_DISTANCE_MP:
159  return value
160 
161  def __init__(
162  self,
163  forster_radius: float = 52.0,
164  sigma: float = 6.0,
165  distance_range: typing.Tuple[float, float] = (1.0, 100.0),
166  n_distances: int = 128
167  ):
168  self._forster_radius_ = forster_radius
169  self._sigma_ = sigma
170  self._distances_ = np.linspace(
171  *distance_range, n_distances, dtype=np.float64)
172  self._density_ = np.zeros_like(self._distances_)
173  self._update_fret_efficiencies_(self._forster_radius_)
174  self._update_lookup()
175 
176 
177 def read_xlink_table(fn: str) -> typing.Dict[int, typing.Dict]:
178  """Read a xlink table
179 
180  :param fn: filename of the xlink table
181  :return:
182  """
183  # Read the xlink table
184  xlinks = {} # dict of the xlinks, the keys are used to address the xlinks
185  xlink_idx = 0
186  with open(fn, 'r') as fp:
187  lines = fp.readlines()
188  for line in lines[1:]:
189  try:
190  line = line.strip()
191  protein_1, residue_1, protein_2, residue_2 = line.split(',')
192  residue_1 = int(residue_1)
193  residue_2 = int(residue_2)
194  d = {
195  'protein_1': protein_1,
196  'protein_2': protein_2,
197  'residue_1': residue_1,
198  'residue_2': residue_2
199  }
200  xlinks[xlink_idx] = d
201  xlink_idx += 1
202  except ValueError:
203  pass
204  return xlinks
A decorator for a particle with accessible volume (AV).
Definition: AV.h:94
def read_xlink_table
Read a xlink table.
static XYZR setup_particle(Model *m, ParticleIndex pi)
Definition: XYZR.h:48
A decorator for a particle which has bonds.
static bool get_is_setup(Model *m, ParticleIndex pi)
Definition: Mass.h:34
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: XYZR.h:47
Bond create_bond(Bonded a, Bonded b, Bond o)
Connect the two wrapped particles by a custom bond.
static Hierarchy setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor children=ParticleIndexesAdaptor())
Create a Hierarchy of level t by adding the needed attributes.
The standard decorator for manipulating molecular structures.
static Mass setup_particle(Model *m, ParticleIndex pi, Float mass)
Definition: Mass.h:48
static Bonded setup_particle(Model *m, ParticleIndex pi)
Basic functionality that is expected to be used by a wide variety of IMP users.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Bond get_bond(Bonded a, Bonded b)
Get the bond between two particles.
Functionality for loading, creating, manipulating and scoring atomic structures.
Bayesian Fluorescence Framework.
def display_mean_av_positions
Decorate the accessible volume particles with a mass and radii, so that they appear in the rmf file...
A decorator for a particle with x,y,z coordinates and a radius.
Definition: XYZR.h:27