1 """@namespace IMP.em2d.buildxlinks
2 Utility functions to handle cross links.
12 log = logging.getLogger(
"buildxlinks")
19 from sets
import Set
as set
26 Class defining a cross-link
29 def __init__(self, id1, chain1, residue1,
30 id2, chain2, residue2,
34 @param[in] id1 Id of the first component of the cross-link
35 @param[in] chain1 Chain of the first component
36 @param[in] residue1 Residue cross-linked in the first component
37 @param[in] id2 Id of the second component of the cross-link
38 @param[in] chain2 chain1 Chain of the second component
39 @param[in] residue2 Residue cross-linked in the second component
40 @param[in] distance Maximum distance
43 self.first_chain = chain1
44 self.first_residue = residue1
46 self.second_chain = chain2
47 self.second_residue = residue2
48 self.distance = distance
51 xl =
Xlink( self.first_id, self.first_chain, self.first_residue,
52 self.second_id, self.second_chain, self.second_residue,
56 def __eq__(self, other):
57 if self.first_id != other.first_id
or \
58 self.second_id != other.second_id
or \
59 self.first_chain != other.first_chain
or \
60 self.second_chain != other.second_chain
or \
61 self.first_residue != other.first_residue
or \
62 self.second_residue != other.second_residue
or \
63 abs(other.distance-self.distance) > 0.01:
69 swaps the order of the residues in the restraint
71 self.first_id, self.second_id = self.second_id, self.first_id
72 self.first_residue, self.second_residue = \
73 self.second_residue, self.first_residue
74 self.first_chain, self.second_chain = \
75 self.second_chain, self.first_chain
79 s =
"Cross Link: %s %s %d - %s %s %d. Distance %f" % (self.first_id,
80 self.first_chain, self.first_residue,
81 self.second_id, self.second_chain,
82 self.second_residue, self.distance )
87 Generate a unique name for the restraint.
88 @note: The name cannot start with a number, upsets sqlite
90 name =
"cl_%s_%s%d_%s_%s%d" % (self.first_id, self.first_chain,
91 self.first_residue, self.second_id,
92 self.second_chain, self.second_residue)
99 Build a set of nodes and edges from the set of crosslinking
101 @param xlinks_dict a XlinksDict class
106 for key
in xlinks_dict.keys():
109 edge = [key[0],key[1]]
111 if edge
not in edges:
113 log.debug(
"Subunits %s", subunits)
114 log.debug(
"Edges %s", edges)
115 return subunits, edges
119 Description of crosslinking restraints as a python
121 The keys are a pair with the ids of the cross-linked subunits.
122 Note: The pairs are considered in alphabetic order
126 Add a xlink. It is ensured that the id of the first element is
127 is lower that the second
129 if xlink.second_id < xlink.first_id:
131 key = (xlink.first_id, xlink.second_id)
132 if key
not in self.keys():
134 self[key].append(xlink)
138 @param pair_ids Ids fo the subunits that are cross-linked
141 xlinks_list = self[pair_ids]
142 ys = [xl.clone()
for xl
in xlinks_list]
146 xlinks_list = self[(pair_ids[1], pair_ids[0])]
147 ys = [xl.clone()
for xl
in xlinks_list]
160 return self[pair_ids]
162 print pair_ids,"NOT FOUND, swapping to",(pair_ids[1], pair_ids[0])
163 # If not found, invert the pair
164 xlinks_list = self[(pair_ids[1], pair_ids[0])]
165 # swap the xlinks, so the first element of the pair corresponds to the
166 # first id in the xlink
167 for xl in xlinks_list:
169 for xl in xlinks_list:
176 Compute the order of the docking experiments. The order is derived
177 from the cross-linking restraints:
178 1) The subunit with the highest number of cross-linkns with others
179 works as the first receptor (A)
180 2) All the subunits cross-linked with A are docked into A.
181 3) The next receptor (B) is the subunit that has the highest number of
183 4) All the subunits cross-linked to B are docked into B (expect A)
184 5) The procedure is repeated until there are no more cross-links
192 Instead of setting the xlink restraints, init the graph directly
193 Example of what to pass with the structure in 3sfd
194 G.add_nodes_from(["A", "B", "C", "D"])
195 G.add_edges_from([("B","C"), ("B","A"), ("B","D"), ("C","D")])
196 ("B","C") means that there are cross-links between B and C
198 self.G.add_nodes_from(subunits)
199 self.G.add_edges_from(edges)
203 Sets the xlinks used for computing the docking order
204 @param xlinks_dict XlinksDict class
210 """ return the order to dock components from the cross links """
212 degs = self.G.degree(self.G.nodes())
213 log.debug(
"Degrees: %s",degs )
214 sorted_degrees = [(v,k)
for v,k
in zip(degs.values(),degs.keys())]
215 sorted_degrees.sort()
216 sorted_degrees.reverse()
218 receptors_considered = []
219 for degree, node
in sorted_degrees:
220 for n
in self.G.neighbors(node):
221 if not n
in receptors_considered:
222 docking_pairs.append((node, n))
223 receptors_considered.append(node)
224 log.info(
"The suggested order for the docking pairs is %s",
231 Puts two subunits together using the Xlinkins restraints. The solutions
232 offered by this class are just an initial position of the components
235 def clear_xlinks(self):
236 self.xlinks_list = []
240 Sets the xlinks used for the computation fo the intial rough
242 @param xlinks_list A list of Xlink classes
243 residue1 belongs to the receptor and residue2 belongs to the ligand
245 self.xlinks_list = xlinks_list
249 Set the name of the PDB files of the receptor and the ligand
255 self.h_receptor = atom.read_pdb(fn_receptor, self.m_receptor, sel)
257 self.h_ligand = atom.read_pdb(fn_ligand, self.m_ligand, sel)
261 Set the hierarchies (atom.Hierarchy objects) for the receptor and
266 self.h_receptor = h_receptor
267 self.h_ligand = h_ligand
271 Sets the rigid bodies (core.RigidBody objects) for the receptor and
276 self.rb_receptor = rb_receptor
277 self.rb_ligand = rb_ligand
281 Movest the ligand close to the receptor based on the xlinks
282 provided by set_xlinks()
284 log.debug(
"Moving ligand close to the receptor using the xlinks")
285 n = len(self.xlinks_list)
293 Get the particle representing a residue in a hierarchy
294 @param h atom.Hierarchy containing the residue
295 @param ch The chain id
296 @param res index of the residue
299 return s.get_selected_particles()[0]
303 Get the coordinates for a residue in a molecular hierarchy
304 @param h atom.Hierarchy object
305 @param ch The chain id
306 @param res Residue index
309 return core.XYZ(p).get_coordinates()
313 Write a pdb file the coordinates of the ligand
316 atom.write_pdb(self.h_ligand, fn)
320 Put the residues in a random distance between 0 and the maximum
321 cross-linkin distance
323 xl = self.xlinks_list[0]
326 sph = alg.Sphere3D(center, xl.distance)
327 v = alg.get_random_vector_in(sph)
328 ref = self.rb_ligand.get_reference_frame()
329 coords = ref.get_transformation_to().get_translation()
330 R = ref.get_transformation_to().get_rotation()
333 log.debug(
"Ligand residue before moving %s", lig)
334 displacement = v - lig
335 T = alg.Transformation3D(R, coords + displacement)
336 self.rb_ligand.set_reference_frame(alg.ReferenceFrame3D(T))
339 log.debug(
"ligand after moving %s", new_coords)
344 Function equivalent to move_one_xlink() for the case where there
345 are more than one cross-link restraints available.
346 Puts the ligand residues as close as possible to the receptor
351 for xl
in self.xlinks_list:
358 log.debug(
"Receptor residues before moving %s", rec_coords)
359 log.debug(
"Ligand residues before moving %s", lig_coords)
360 ref = self.rb_ligand.get_reference_frame()
361 Tr = alg.get_transformation_aligning_first_to_second(lig_coords,
363 T = ref.get_transformation_to()
364 newT = alg.compose(Tr, T)
365 self.rb_ligand.set_reference_frame(alg.ReferenceFrame3D(newT))
367 moved_lig_coords = []
368 for xl
in self.xlinks_list:
371 moved_lig_coords.append(c)
372 log.debug(
"Ligand residues after moving %s", moved_lig_coords)
def get_residue_coordinates
Get the coordinates for a residue in a molecular hierarchy.
void show(const cv::Mat &m, std::ostream &out=std::cout)
Prints a OpenCV matrix.
def swap
swaps the order of the residues in the restraint
Utility functions to extract min/max from the inputs.
def move_xlinks
Function equivalent to move_one_xlink() for the case where there are more than one cross-link restrai...
def set_components_and_connections
Instead of setting the xlink restraints, init the graph directly Example of what to pass with the str...
def set_xlinks
Sets the xlinks used for computing the docking order.
def set_rigid_bodies
Sets the rigid bodies (core.RigidBody objects) for the receptor and the ligand.
Puts two subunits together using the Xlinkins restraints.
Select all non-alternative ATOM records.
def move_ligand
Movest the ligand close to the receptor based on the xlinks provided by set_xlinks() ...
def set_xlinks
Sets the xlinks used for the computation fo the intial rough docking solution.
def get_docking_order
return the order to dock components from the cross links
def get_residue_particle
Get the particle representing a residue in a hierarchy.
def build_xlinks_graph
Build a set of nodes and edges from the set of crosslinking restraints.
def move_one_xlink
Put the residues in a random distance between 0 and the maximum cross-linkin distance.
A decorator for a particle with x,y,z coordinates.
def write_ligand
Write a pdb file the coordinates of the ligand.
def set_pdbs
Set the name of the PDB files of the receptor and the ligand.
Compute the order of the docking experiments.
See IMP.core for more information.
See IMP.algebra for more information.
Class defining a cross-link.
Description of crosslinking restraints as a python dictionary.
def set_hierarchies
Set the hierarchies (atom.Hierarchy objects) for the receptor and the ligand.
See IMP.atom for more information.
def get_name
Generate a unique name for the restraint.
Class for storing model, its restraints, constraints, and particles.