IMP  2.3.0
The Integrative Modeling Platform
sampling.py
1 
2 import IMP
3 import IMP.algebra as alg
4 import IMP.em2d.solutions_io as solutions_io
5 import IMP.em2d.imp_general.io as io
6 import IMP.em2d.Database as Database
7 import itertools
8 import logging
9 import os
10 
11 log = logging.getLogger("sampling")
12 
13 #
14 """
15 
16  Functions required for sampling in a 2D/3D grid
17 
18 """
19 #
20 
21 
22 def create_sampling_grid_3d(diameter, n_axis_points):
23  """
24  Creates a grid of positions (Vector3Ds), centered at 0.
25  @param diameter The shape of the grid is a sphere with this diameter.
26  @param n_axis_points Number of points used alogn an axis for the grid.
27  The axis X Y and Z will contain n_axis_points, equispaced.
28  The other regions of space will contain only the points allowed by
29  the size of the spere.
30  """
31  radius = diameter / 2.0
32  step = diameter / n_axis_points
33  points = [-radius + step * n for n in range(n_axis_points + 1)]
34  # filter points closer than 1A
35  points = filter(lambda x: abs(x) > 1, points)
36  log.info("Points along the axis %s", points)
37  positions = []
38  for x, y, z in itertools.product(points, points, points):
39  d = (x ** 2. + y ** 2. + z ** 2.) ** .5
40  # allow 1% margin. Avoids approximation problems
41  if(d < (1.01 * radius)):
42  positions.append(alg.Vector3D(x, y, z))
43  return positions
44 
45 
46 def create_sampling_grid_2d(diameter, n_axis_points):
47  """
48  Creates a grid of positions (Vector3Ds), centered at 0.
49  The shape of the grid is a circle with diameter given by the parameter.
50  n_axis_points is the number of points along an axis: The axis X Y
51  will contain n_axis_points, equispaced. The other regions of space will
52  contain only the points allowed by the size of the circle.
53  """
54  if(diameter < 0):
55  raise ValueError("create_sampling_grid_2d: Negative diameter.")
56  if(n_axis_points < 1):
57  raise ValueError("create_sampling_grid_2d: Less than one axis point.")
58  radius = diameter / 2.0
59  step = diameter / n_axis_points
60  points = [-radius + step * n for n in range(n_axis_points + 1)]
61  log.info("Points along the axis %s", points)
62  positions = []
63  for x, y in itertools.product(points, points):
64  d = (x ** 2. + y ** 2.) ** .5
65  # allow 1% margin. Avoids approximation problems
66  if(d < (1.01 * radius)):
67  positions.append(alg.Vector3D(x, y, 0.0))
68  return positions
69 
70 
71 def get_orientations_nearby(rotation, n, f):
72  """
73  Rotations nearby a given one. They are got intepolating with
74  the rotations of the uniform coverage. The parameter f
75  (0 <= f <= 1) must be close to 0 to get orientations
76  that are close to the given orientation
77  - Values from 0.1 (tight cluster) to 0.4 (loose)
78  seem to be ok
79  n - number of rotations requested
80  """
81  log.debug("Computing nearby rotations around %s", rotation)
82  unif = alg.get_uniform_cover_rotations_3d(n)
83  id_rot = alg.get_identity_rotation_3d()
84  oris = []
85  for rot in unif:
86  r = alg.get_interpolated(rot, id_rot, f)
87  r = alg.compose(r, rotation)
88  oris.append(r)
89  return oris
90 
91 
92 class SamplingSchema:
93 
94  def __init__(self, n_components, fixed, anchored):
95  """
96  Build a set of orientations and positions for sampling with DOMINO
97  @param n_components Number of components in the assembly
98  @param fixed List of True/False values. If fixed == True
99  for a component its position is not changed.
100  @param anchor A list of True/False values. If anchor = True,
101  the component is set at (0,0,0) without rotating it.
102  """
103  if(n_components < 1):
104  raise ValueError(
105  "SamplingSchema: Requesting less than 1 components.")
106 
107  self.anchored = anchored
108  self.fixed = fixed
109  self.n_components = n_components
110 
111  def get_sampling_transformations(self, i):
112  return self.transformations[i]
113 
114  def read_from_database(self, fn_database, fields=["reference_frames"],
115  max_number=False, orderby=False):
116  """
117  Read orientations and positions from a database file.
118  self.anchored and self.fixed overwrite
119  the positions and orientations read from the database
120  """
121  if not os.path.exists(fn_database):
122  raise IOError("read_from_database: Database file not found. "
123  "Are you perhaps trying to run the DOMINO optimization without "
124  "having the database yet?")
125 
126  db = solutions_io.ResultsDB()
127  db.connect(fn_database)
128  data = db.get_solutions(fields, max_number, orderby)
129  db.close()
130  self.transformations = [[] for T in range(self.n_components)]
131  # Each record contains a reference frame for each of the
132  # components. But here the states considered make sense as columns.
133  # Each rigidbody is considered to have all the states in a column.
134  for d in data:
135  texts = d[0].split("/")
136  for i, t in zip(range(self.n_components), texts):
137  T = io.TextToTransformation3D(t).get_transformation()
138  self.transformations[i].append(T)
139 
140  # Set the anchored components
141  for i in range(self.n_components):
142  if self.anchored[i]:
143  origin = alg.Transformation3D(alg.get_identity_rotation_3d(),
144  alg.Vector3D(0.0, 0.0, 0.))
145  self.transformations[i] = [origin]
146 
147  # If fixed, only the first state is kept
148  for i in range(self.n_components):
149  if self.fixed[i]:
150  if len(self.transformations[i]) == 0:
151  raise ValueError("There are positions to keep fixed")
152  self.transformations[i] = [self.transformations[i][0]]
Utility functions to manage SQL databases with sqlite3.
Definition: Database.py:1
Utility functions to store and retrieve solution information.
Definition: solutions_io.py:1
General purpose algebraic and geometric methods that are expected to be used by a wide variety of IMP...