IMP logo
IMP Reference Guide  2.5.0
The Integrative Modeling Platform
pmi/restraints/proteomics.py
1 """@namespace IMP.pmi.restraints.proteomics
2 Restraints for handling various kinds of proteomics data.
3 """
4 
5 from __future__ import print_function
6 import IMP
7 import IMP.core
8 import IMP.algebra
9 import IMP.atom
10 import IMP.container
11 import IMP.pmi.tools
12 
13 class ConnectivityRestraint(object):
14 
15  '''
16  generate a connectivity restraint between domains
17  setting up the restraint
18  example:
19  cr=restraints.ConnectivityRestraint(simo,["CCC",(1,100,"TTT"),(100,150,"AAA")])
20  cr.add_to_model()
21  cr.set_label("CR1")
22  Multistate support =No
23  Selection type=selection tuple
24  Resolution=Yes
25  '''
26 
27  def __init__(
28  self,
29  representation,
30  selection_tuples,
31  kappa=10.0,
32  resolution=None,
33  label="None"):
34 
35  self.weight = 1.0
36  self.kappa = kappa
37  self.label = label
38  if self.label == "None":
39  self.label = str(selection_tuples)
40  self.m = representation.prot.get_model()
41  self.rs = IMP.RestraintSet(self.m, label)
42 
43  sels = []
44 
45  for s in selection_tuples:
46  particles = IMP.pmi.tools.select_by_tuple(representation, s,
47  resolution=resolution, name_is_ambiguous=True)
48  sel = IMP.atom.Selection(particles)
49  sels.append(sel)
50 
52  sels,
53  self.kappa,
54  self.label)
55  self.rs.add_restraint(cr)
56 
57  def set_label(self, label):
58  self.label = label
59  self.rs.set_name(label)
60  for r in self.rs.get_restraints():
61  r.set_name(label)
62 
63  def add_to_model(self):
65 
66  def get_restraint(self):
67  return self.rs
68 
69  def get_restraints(self):
70  rlist = []
71  for r in self.rs.get_restraints():
72  rlist.append(IMP.core.PairRestraint.get_from(r))
73  return rlist
74 
75  def set_weight(self, weight):
76  self.weight = weight
77  self.rs.set_weight(weight)
78 
79  def get_output(self):
80  self.m.update()
81  output = {}
82  score = self.weight * self.rs.unprotected_evaluate(None)
83  output["_TotalScore"] = str(score)
84  output["ConnectivityRestraint_" + self.label] = str(score)
85  return output
86 
87 #
88 class CompositeRestraint(object):
89 
90  '''
91  handleparticles is a selection tuple
92  compositeparticles is a list of selection tuples
93  '''
94  import IMP.pmi
95 
96  def __init__(
97  self,
98  representation,
99  handleparticles_tuples,
100  compositeparticles_tuple_list,
101  cut_off=5.0,
102  lam=1.0,
103  plateau=0.0,
104  resolution=None,
105  label="None"):
106 
107  # composite particles: all particles beside the handle
108  self.label = label
109  self.m = representation.prot.get_model()
110  self.rs = IMP.RestraintSet(self.m, 'cr')
111 
112  self.handleparticles = []
113  for s in handleparticles_tuples:
114  self.handleparticles += IMP.pmi.tools.select_by_tuple(representation, s,
115  resolution=resolution, name_is_ambiguous=True)
116  self.compositeparticles=[]
117  compositeparticle_list = []
118  for list in compositeparticles_tuple_list:
119  tmplist = []
120  for s in list:
121  tmplist += IMP.pmi.tools.select_by_tuple(
122  representation, s,
123  resolution=resolution, name_is_ambiguous=True)
124  compositeparticle_list.append(tmplist)
125  self.compositeparticles+=tmplist
126 
127 
129  self.m,
130  self.handleparticles,
131  cut_off,
132  lam,
133  True,
134  plateau)
135 
136  for ps in compositeparticle_list:
137  # composite particles is a list of list of particles
138  ln.add_composite_particle(ps)
139 
140  self.rs.add_restraint(ln)
141 
142  def set_label(self, label):
143  self.label = label
144 
145  def get_handle_particles(self):
146  return self.handleparticles
147 
148  def get_composite_particles(self):
149  return self.compositeparticles
150 
151  def get_restraint(self):
152  return self.rs
153 
154  def add_to_model(self):
155  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
156 
157  def get_output(self):
158  self.m.update()
159  output = {}
160  score = self.rs.unprotected_evaluate(None)
161  output["_TotalScore"] = str(score)
162  output["CompositeRestraint_" + self.label] = str(score)
163  return output
164 
165 
166 #
168 
169  '''
170  this restraint allows ambiguous crosslinking between multiple copies
171  excluding between symmetric copies
172  It allows name ambiguity
173  '''
174 
175  def __init__(
176  self,
177  representation,
178  restraints_file,
179  cut_off=5.0,
180  lam=1.0,
181  plateau=0.01,
182  resolution=None,
183  label="None"):
184 
185  self.weight = 1.0
186  self.m = representation.prot.get_model()
187  self.rs = IMP.RestraintSet(self.m, 'data')
188  self.label = "None"
189  self.pairs = []
190 
191  self.outputlevel = "low"
192  self.cut_off = cut_off
193  self.lam = lam
194  self.plateau = plateau
195 
196  fl = IMP.pmi.tools.open_file_or_inline_text(restraints_file)
197 
198  for line in fl:
199 
200  tokens = line.split()
201  # skip character
202  if (tokens[0] == "#"):
203  continue
204  r1 = int(tokens[2])
205  c1 = tokens[0]
206  r2 = int(tokens[3])
207  c2 = tokens[1]
208 
209  ps1 = IMP.pmi.tools.select(
210  representation,
211  resolution=resolution,
212  name=c1,
213  name_is_ambiguous=True,
214  residue=r1)
215  hrc1 = [representation.hier_db.particle_to_name[p] for p in ps1]
216  ps1nosym = [
217  p for p in ps1 if IMP.pmi.Symmetric(
218  p).get_symmetric(
219  ) == 0]
220  hrc1nosym = [representation.hier_db.particle_to_name[p]
221  for p in ps1nosym]
222 
223  if len(ps1) == 0:
224  print("AmbiguousCompositeRestraint: WARNING> residue %d of chain %s is not there" % (r1, c1))
225  continue
226 
227  ps2 = IMP.pmi.tools.select(
228  representation,
229  resolution=resolution,
230  name=c2,
231  name_is_ambiguous=True,
232  residue=r2)
233  hrc2 = [representation.hier_db.particle_to_name[p] for p in ps2]
234  ps2nosym = [
235  p for p in ps2 if IMP.pmi.Symmetric(
236  p).get_symmetric(
237  ) == 0]
238  hrc2nosym = [representation.hier_db.particle_to_name[p]
239  for p in ps2nosym]
240 
241  if len(ps2) == 0:
242  print("AmbiguousCompositeRestraint: WARNING> residue %d of chain %s is not there" % (r2, c2))
243  continue
244 
246  self.m,
247  ps1nosym,
248  self.cut_off,
249  self.lam,
250  True,
251  self.plateau)
252  cr.add_composite_particle(ps2)
253 
254  self.rs.add_restraint(cr)
255  self.pairs.append(
256  (ps1nosym,
257  hrc1nosym,
258  c1,
259  r1,
260  ps2,
261  hrc2,
262  c2,
263  r2,
264  cr))
265 
267  self.m,
268  ps1,
269  self.cut_off,
270  self.lam,
271  True,
272  self.plateau)
273  cr.add_composite_particle(ps2nosym)
274 
275  self.rs.add_restraint(cr)
276  self.pairs.append(
277  (ps1,
278  hrc1,
279  c1,
280  r1,
281  ps2nosym,
282  hrc2nosym,
283  c2,
284  r2,
285  cr))
286 
287  def plot_restraint(
288  self,
289  maxdist=100,
290  npoints=100):
291  import IMP.pmi.output as output
292 
293  p1 = IMP.Particle(self.m)
294  p2 = IMP.Particle(self.m)
298  self.m,
299  [p1],
300  self.cut_off,
301  self.lam,
302  True,
303  self.plateau)
304  cr.add_composite_particle([p2])
305  dists = []
306  scores = []
307  for i in range(npoints):
308  d2.set_coordinates(
309  IMP.algebra.Vector3D(maxdist / npoints * float(i), 0, 0))
310  dists.append(IMP.core.get_distance(d1, d2))
311  scores.append(cr.unprotected_evaluate(None))
312  output.plot_xy_data(dists, scores)
313 
314  def set_label(self, label):
315  self.label = label
316  self.rs.set_name(label)
317  for r in self.rs.get_restraints():
318  r.set_name(label)
319 
320  def add_to_model(self):
321  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
322 
323  def get_hierarchies(self):
324  return self.prot
325 
326  def get_restraint_sets(self):
327  return self.rs
328 
329  def get_restraint(self):
330  return self.rs
331 
332  def set_output_level(self, level="low"):
333  # this might be "low" or "high"
334  self.outputlevel = level
335 
336  def set_weight(self, weight):
337  self.weight = weight
338  self.rs.set_weight(weight)
339 
340  def get_output(self):
341  # content of the crosslink database pairs
342  # self.pairs.append((p1,p2,dr,r1,c1,r2,c2))
343  self.m.update()
344 
345  output = {}
346  score = self.weight * self.rs.unprotected_evaluate(None)
347  output["_TotalScore"] = str(score)
348  output["AmbiguousCompositeRestraint_Score_" + self.label] = str(score)
349  for n, p in enumerate(self.pairs):
350 
351  ps1 = p[0]
352  hrc1 = p[1]
353  c1 = p[2]
354  r1 = p[3]
355  ps2 = p[4]
356  hrc2 = p[5]
357  c2 = p[6]
358  r2 = p[7]
359  cr = p[8]
360  for n1, p1 in enumerate(ps1):
361  name1 = hrc1[n1]
362 
363  for n2, p2 in enumerate(ps2):
364  name2 = hrc2[n2]
365  d1 = IMP.core.XYZR(p1)
366  d2 = IMP.core.XYZR(p2)
367  label = str(r1) + ":" + name1 + "_" + str(r2) + ":" + name2
368  output["AmbiguousCompositeRestraint_Distance_" +
369  label] = str(IMP.core.get_distance(d1, d2))
370 
371  label = str(r1) + ":" + c1 + "_" + str(r2) + ":" + c2
372  output["AmbiguousCompositeRestraint_Score_" +
373  label] = str(self.weight * cr.unprotected_evaluate(None))
374 
375  return output
376 
377 
378 #
379 class SimplifiedPEMAP(object):
380 
381  def __init__(
382  self,
383  representation,
384  restraints_file,
385  expdistance,
386  strength,
387  resolution=None):
388 
389  self.m = representation.prot.get_model()
390  self.rs = IMP.RestraintSet(self.m, 'data')
391  self.label = "None"
392  self.pairs = []
393 
394  self.outputlevel = "low"
395  self.expdistance = expdistance
396  self.strength = strength
397 
398  fl = IMP.pmi.tools.open_file_or_inline_text(restraints_file)
399 
400  for line in fl:
401 
402  tokens = line.split()
403  # skip character
404  if (tokens[0] == "#"):
405  continue
406  r1 = int(tokens[2])
407  c1 = tokens[0]
408  r2 = int(tokens[3])
409  c2 = tokens[1]
410  pcc = float(tokens[4])
411 
412  ps1 = IMP.pmi.tools.select(
413  representation,
414  resolution=resolution,
415  name=c1,
416  name_is_ambiguous=False,
417  residue=r1)
418  if len(ps1) == 0:
419  print("SimplifiedPEMAP: WARNING> residue %d of chain %s is not there (w/ %d %s)" % (r1, c1, r2, c2))
420  continue
421  if len(ps1) > 1:
422  print("SimplifiedPEMAP: WARNING> residue %d of chain %s selected multiple particles" % (r1, c1))
423  continue
424 
425  ps2 = IMP.pmi.tools.select(
426  representation,
427  resolution=resolution,
428  name=c2,
429  name_is_ambiguous=False,
430  residue=r2)
431  if len(ps2) == 0:
432  print("SimplifiedPEMAP: WARNING> residue %d of chain %s is not there (w/ %d %s)" % (r1, c1, r2, c2))
433  continue
434  if len(ps2) > 1:
435  print("SimplifiedPEMAP: WARNING> residue %d of chain %s selected multiple particles" % (r2, c2))
436  continue
437 
438  p1 = ps1[0]
439  p2 = ps2[0]
440 
441  # This is harmonic potential for the pE-MAP data
442  upperdist = self.get_upper_bond(pcc)
443  limit = self.strength * (upperdist + 15) ** 2 + 10.0
445  upperdist,
446  self.strength,
447  upperdist +
448  15,
449  limit)
450 
451  # This is harmonic for the X-link
452  #hub= IMP.core.TruncatedHarmonicBound(17.0,self.strength,upperdist+15,limit)
453 
455  dr = IMP.core.PairRestraint(df, (p1, p2))
456  self.rs.add_restraint(dr)
457  self.pairs.append((p1, p2, dr, r1, c1, r2, c2))
458 
459  # Lower-bound restraint
460  lowerdist = self.get_lower_bond(pcc)
461  limit = self.strength * (lowerdist - 15) ** 2 + 10.0
463  lowerdist,
464  self.strength,
465  lowerdist +
466  15,
467  limit)
468 
469  # This is harmonic for the X-link
470  #hub2= IMP.core.TruncatedHarmonicBound(17.0,self.strength,upperdist+15,limit)
471 
473  dr2 = IMP.core.PairRestraint(df2, (p1, p2))
474  self.rs.add_restraint(dr2)
475  self.pairs.append((p1, p2, dr2, r1, c1, r2, c2))
476 
477  def get_upper_bond(self, pearsoncc):
478  # return (pearsoncc-1.)/-0.0075
479  return (pearsoncc - .5) / (-0.005415)
480 
481  def get_lower_bond(self, pearsoncc):
482  return (pearsoncc - 1.) / -0.0551
483 
484  def set_label(self, label):
485  self.label = label
486 
487  def add_to_model(self):
488  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
489 
490  def get_hierarchies(self):
491  return self.prot
492 
493  def get_restraint_sets(self):
494  return self.rs
495 
496  def set_output_level(self, level="low"):
497  # this might be "low" or "high"
498  self.outputlevel = level
499 
500  def get_output(self):
501  # content of the crosslink database pairs
502  # self.pairs.append((p1,p2,dr,r1,c1,r2,c2))
503  self.m.update()
504 
505  output = {}
506  score = self.rs.unprotected_evaluate(None)
507  output["_TotalScore"] = str(score)
508  output["SimplifiedPEMAP_Score_" + self.label] = str(score)
509  for i in range(len(self.pairs)):
510 
511  p0 = self.pairs[i][0]
512  p1 = self.pairs[i][1]
513  crosslinker = 'standard'
514  ln = self.pairs[i][2]
515  resid1 = self.pairs[i][3]
516  chain1 = self.pairs[i][4]
517  resid2 = self.pairs[i][5]
518  chain2 = self.pairs[i][6]
519 
520  label = str(resid1) + ":" + chain1 + "_" + \
521  str(resid2) + ":" + chain2
522  output["SimplifiedPEMAP_Score_" + crosslinker + "_" +
523  label] = str(ln.unprotected_evaluate(None))
524 
525  d0 = IMP.core.XYZ(p0)
526  d1 = IMP.core.XYZ(p1)
527  output["SimplifiedPEMAP_Distance_" +
528  label] = str(IMP.core.get_distance(d0, d1))
529 
530  return output
531 
532 
534 
535  '''
536  generates and wraps a IMP.pmi.ConnectivityRestraint between domains
537  example:
538  cr=restraints.ConnectivityNetworkRestraint(simo,["CCC",(1,100,"TTT"),(100,150,"AAA")])
539  cr.add_to_model()
540  cr.set_label("CR1")
541 
542  Multistate support =No
543  Selection type=selection tuple
544  Resolution=Yes
545  '''
546 
547  def __init__(
548  self,
549  representation,
550  selection_tuples,
551  kappa=10.0,
552  resolution=1.0,
553  label="None"):
554 
555  self.weight = 1.0
556  self.kappa = kappa
557  self.label = label
558  if self.label == "None":
559  self.label = str(selection_tuples)
560 
561  self.m = representation.m
562  self.rs = IMP.RestraintSet(self.m, label)
563 
564  cr=CompositeNetworkRestraint(self.m)
565 
566  for s in selection_tuples:
567  particles = IMP.pmi.tools.select_by_tuple(representation, s,
568  resolution=resolution,
569  name_is_ambiguous=False)
570 
571  cr.add_particles([p.get_particle() for p in particles])
572 
573  self.rs.add_restraint(cr)
574 
575  def set_label(self, label):
576  self.label = label
577  self.rs.set_name(label)
578  for r in self.rs.get_restraints():
579  r.set_name(label)
580 
581  def add_to_model(self):
582  IMP.pmi.tools.add_restraint_to_model(self.m, self.rs)
583 
584  def get_restraint(self):
585  return self.rs
586 
587  def get_restraints(self):
588  rlist = []
589  for r in self.rs.get_restraints():
590  rlist.append(IMP.core.PairRestraint.get_from(r))
591  return rlist
592 
593  def set_weight(self, weight):
594  self.weight = weight
595  self.rs.set_weight(weight)
596 
597  def get_output(self):
598  self.m.update()
599  output = {}
600  score = self.weight * self.rs.unprotected_evaluate(None)
601  output["_TotalScore"] = str(score)
602  output["ConnectivityNetworkRestraint_" + self.label] = str(score)
603  return output
604 
605 
606 
607 
609  '''
610  a python restraint that computes the score for a composite of proteins
611  Authors: G. Bouvier, R. Pellarin. Pasteur Institute.
612  '''
613 
614  import numpy
615  import math
616 
617  def __init__(self,m,slope=1.0,theta=5.0,plateau=0.01,linear_slope=0.01):
618  '''
619  input a list of particles, the slope and theta of the sigmoid potential
620  theta is the cutoff distance for a protein-protein contact
621  '''
622  IMP.Restraint.__init__(self, m, "ConnectivityNetworkRestraint %1%")
623  self.slope=slope
624  self.theta=theta
625  self.linear_slope=linear_slope
626  self.plateau=plateau
627  self.particles_blocks=[]
628  self.particle_list=[]
629 
630  def get_number_of_particle_blocks(self):
631  return len(self.particles_blocks)
632 
633  def get_number_of_particles_for_block(self,block_index):
634  return len(self.particles_blocks[block_index])
635 
636  def add_particles(self,particles):
637  self.particles_blocks.append(particles)
638  self.particle_list+=particles
639 
640  def get_full_graph(self):
641  '''
642  get the full graph of distances between every particle pair
643  '''
644  import networkx
645  import scipy.spatial
646 
647  pdist_array = self.numpy.array(IMP.pmi.get_list_of_bipartite_minimum_sphere_distance(self.particles_blocks))
648  pdist_mat=scipy.spatial.distance.squareform(pdist_array)
649  pdist_mat[pdist_mat < 0] = 0
650  graph = networkx.Graph(pdist_mat)
651  return graph
652 
654  """
655  return the minimum spanning tree
656  """
657  import networkx
658  graph = self.get_full_graph()
659  graph = networkx.minimum_spanning_tree(graph)
660  return graph
661 
662  def sigmoid(self,x):
663  '''
664  a sigmoid function that scores the probability of a contact
665  between two proteins
666  '''
667  #return 1 - (x)**self.slope/ float(((x)**self.slope + self.theta**self.slope))
668  argvalue=(x-self.theta)/self.slope
669  return 1.0-(1.0-self.plateau)/(1.0+self.math.exp(-argvalue))
670 
671  def unprotected_evaluate(self,da):
672  graph = self.get_minimum_spanning_tree()
673  score = 0.0
674  for e in graph.edges():
675  dist=graph.get_edge_data(*e)['weight']
676  prob=self.sigmoid(dist)
677  score+=-self.numpy.log(prob)
678  score+=self.linear_slope*dist
679  return score
680 
681  def do_get_inputs(self):
682  return self.particle_list
A function that is harmonic over an interval.
this restraint allows ambiguous crosslinking between multiple copies excluding between symmetric copi...
void add_particles(RMF::FileHandle fh, const ParticlesTemp &hs)
Various classes to hold sets of particles.
static XYZR setup_particle(Model *m, ParticleIndex pi)
Definition: XYZR.h:48
def get_full_graph
get the full graph of distances between every particle pair
Miscellaneous utilities.
Definition: tools.py:1
Add symmetric attribute to a particle.
Definition: Symmetric.h:23
A score on the distance between the surfaces of two spheres.
double get_distance(XYZR a, XYZR b)
Compute the sphere distance between a and b.
Definition: XYZR.h:87
Object used to hold a set of restraints.
Definition: RestraintSet.h:36
generates and wraps a IMP.pmi.ConnectivityRestraint between domains example: cr=restraints.ConnectivityNetworkRestraint(simo,["CCC",(1,100,"TTT"),(100,150,"AAA")]) cr.add_to_model() cr.set_label("CR1")
def add_restraint_to_model
Add a PMI restraint to the model.
Definition: tools.py:22
A restraint for ambiguous cross-linking MS data and multiple state approach.
A decorator for a particle with x,y,z coordinates.
Definition: XYZ.h:30
handleparticles is a selection tuple compositeparticles is a list of selection tuples ...
Classes for writing output files and processing them.
Definition: output.py:1
Basic functionality that is expected to be used by a wide variety of IMP users.
General purpose algebraic and geometric methods that are expected to be used by a wide variety of IMP...
def __init__
input a list of particles, the slope and theta of the sigmoid potential theta is the cutoff distance ...
VectorD< 3 > Vector3D
Definition: VectorD.h:395
Class to handle individual model particles.
Definition: Particle.h:37
Floats get_list_of_bipartite_minimum_sphere_distance(const ParticlesTemps &pss)
Definition: utilities.h:58
def sigmoid
a sigmoid function that scores the probability of a contact between two proteins
Restraint * create_connectivity_restraint(const Selections &s, double x0, double k, std::string name="Connectivity%1%")
Create a restraint connecting the selections.
Applies a PairScore to a Pair.
Definition: PairRestraint.h:29
def select
this function uses representation=SimplifiedModel it returns the corresponding selected particles rep...
Definition: tools.py:662
Python classes to represent, score, sample and analyze models.
Functionality for loading, creating, manipulating and scoring atomic structures.
Select hierarchy particles identified by the biological name.
Definition: Selection.h:65
virtual ModelObjectsTemp do_get_inputs() const =0
A restraint is a term in an IMP ScoringFunction.
Definition: Restraint.h:52
A decorator for a particle with x,y,z coordinates and a radius.
Definition: XYZR.h:27