1 """@namespace IMP.pmi.restraints.crosslinking
2 Restraints for handling crosslinking data.
5 from __future__
import print_function
17 from collections
import defaultdict
26 """Setup cross-link distance restraints from mass spectrometry data.
27 The noise in the data and the structural uncertainty of cross-linked amino-acids
28 is inferred using Bayes theory of probability
29 @note Wraps an IMP::isd::CrossLinkMSRestraint
31 def __init__(self, representation=None,
33 CrossLinkDataBase=
None,
39 attributes_for_label=
None,
42 @param representation DEPRECATED The IMP.pmi.representation.Representation
43 object that contain the molecular system
44 @param root_hier The canonical hierarchy containing all the states
45 @param CrossLinkDataBase The IMP.pmi.io.crosslink.CrossLinkDataBase
46 object that contains the cross-link dataset
47 @param length maximal cross-linker length (including the residue sidechains)
48 @param resolution what representation resolution should the cross-link
49 restraint be applied to.
50 @param slope The slope of a distance-linear scoring function that
51 funnels the score when the particles are
52 too far away. Suggested value 0.02.
53 @param label the extra text to label the restraint so that it is
54 searchable in the output
55 @param filelabel automatically generated file containing missing/included/excluded
56 cross-links will be labeled using this text
57 @param attributes_for_label
58 @param weight Weight of restraint
62 if representation
is not None:
64 if type(representation) != list:
65 representations = [representation]
67 representations = representation
68 model = representations[0].prot.get_model()
69 elif root_hier
is not None:
71 model = root_hier.get_model()
73 raise Exception(
"You must pass either representation or root_hier")
75 super(CrossLinkingMassSpectrometryRestraint, self).
__init__(
76 model, weight=weight, label=label)
78 if CrossLinkDataBase
is None:
79 raise Exception(
"You must pass a CrossLinkDataBase")
81 raise TypeError(
"CrossLinkingMassSpectrometryRestraint: CrossLinkDataBase should be an IMP.pmi.io.crosslink.CrossLinkDataBase object")
82 self.CrossLinkDataBase = CrossLinkDataBase
84 if resolution==0
or resolution
is None:
85 raise Exception(
"You must pass a resolution and it can't be zero")
87 indb = open(
"included." + filelabel +
".xl.db",
"w")
88 exdb = open(
"excluded." + filelabel +
".xl.db",
"w")
89 midb = open(
"missing." + filelabel +
".xl.db",
"w")
91 self.rs.set_name(self.rs.get_name() +
"_Data")
92 self.rspsi = self._create_restraint_set(
"PriorPsi")
93 self.rssig = self._create_restraint_set(
"PriorSig")
94 self.rslin = self._create_restraint_set(
"Linear")
98 self.linear.set_slope(0.0)
101 self.psi_is_sampled =
True
102 self.sigma_is_sampled =
True
103 self.psi_dictionary={}
104 self.sigma_dictionary={}
106 self.outputlevel =
"low"
110 xl_groups = [p.get_cross_link_group(self)
111 for p, state
in IMP.pmi.tools._all_protocol_outputs(
112 representations, root_hier)]
116 copies_to_add = defaultdict(int)
117 print(
'gathering copies')
118 for xlid
in self.CrossLinkDataBase.xlid_iterator():
119 for xl
in self.CrossLinkDataBase[xlid]:
120 r1 = xl[self.CrossLinkDataBase.residue1_key]
121 c1 = xl[self.CrossLinkDataBase.protein1_key]
122 r2 = xl[self.CrossLinkDataBase.residue2_key]
123 c2 = xl[self.CrossLinkDataBase.protein2_key]
124 for c,r
in ((c1,r1),(c2,r2)):
125 if c
in copies_to_add:
131 resolution=resolution).get_selected_particles()
133 copies_to_add[c] = len(sel)-1
135 for molname
in copies_to_add:
136 if copies_to_add[molname]==0:
139 self.CrossLinkDataBase.set_value(self.CrossLinkDataBase.protein1_key,molname+
'.0',fo1)
141 self.CrossLinkDataBase.set_value(self.CrossLinkDataBase.protein2_key,molname+
'.0',fo2)
142 for ncopy
in range(copies_to_add[molname]):
143 self.CrossLinkDataBase.clone_protein(
'%s.0'%molname,
'%s.%i'%(molname,ncopy+1))
144 print(
'done pmi2 prelims')
146 for xlid
in self.CrossLinkDataBase.xlid_iterator():
147 new_contribution=
True
148 for xl
in self.CrossLinkDataBase[xlid]:
150 r1 = xl[self.CrossLinkDataBase.residue1_key]
151 c1 = xl[self.CrossLinkDataBase.protein1_key]
152 r2 = xl[self.CrossLinkDataBase.residue2_key]
153 c2 = xl[self.CrossLinkDataBase.protein2_key]
156 ex_xls = [(p[0].add_experimental_cross_link(r1, c1, r2, c2,
159 zip(IMP.pmi.tools._all_protocol_outputs(
160 representations, root_hier),
164 iterlist = range(len(IMP.atom.get_by_type(root_hier,IMP.atom.STATE_TYPE)))
166 iterlist = representations
167 for nstate, r
in enumerate(iterlist):
169 xl[self.CrossLinkDataBase.state_key]=nstate
170 xl[self.CrossLinkDataBase.data_set_name_key]=self.label
178 name1,copy1 = c1.split(
'.')
180 name2,copy2 = c2.split(
'.')
184 copy_index=int(copy1),
186 resolution=resolution).get_selected_particles()
190 copy_index=int(copy2),
192 resolution=resolution).get_selected_particles()
199 resolution=resolution,
201 name_is_ambiguous=
False,
205 resolution=resolution,
207 name_is_ambiguous=
False,
211 raise ValueError(
"residue %d of chain %s selects multiple particles %s" % (r1, c1, str(ps1)))
214 "CrossLinkingMassSpectrometryRestraint: "
215 "residue %d of chain %s is not there" % (r1, c1),
217 midb.write(str(xl) +
"\n")
221 raise ValueError(
"residue %d of chain %s selects multiple particles %s" % (r2, c2, str(ps2)))
224 "CrossLinkingMassSpectrometryRestraint: "
225 "residue %d of chain %s is not there" % (r2, c2),
227 midb.write(str(xl) +
"\n")
233 if p1 == p2
and r1 == r2:
235 "CrossLinkingMassSpectrometryRestraint: "
236 "same particle and same residue, skipping "
241 print(
"generating a new crosslink restraint")
242 new_contribution=
False
247 restraints.append(dr)
250 if self.CrossLinkDataBase.sigma1_key
not in xl.keys():
252 xl[self.CrossLinkDataBase.sigma1_key]=sigma1name
254 sigma1name=xl[self.CrossLinkDataBase.sigma1_key]
257 if self.CrossLinkDataBase.sigma2_key
not in xl.keys():
259 xl[self.CrossLinkDataBase.sigma2_key]=sigma2name
261 sigma2name=xl[self.CrossLinkDataBase.sigma2_key]
264 if self.CrossLinkDataBase.psi_key
not in xl.keys():
266 xl[self.CrossLinkDataBase.psi_key]=psiname
268 psiname=xl[self.CrossLinkDataBase.psi_key]
273 p1i = p1.get_particle_index()
275 p2i = p2.get_particle_index()
278 xl[
"Particle_sigma1"]=sigma1
280 xl[
"Particle_sigma2"]=sigma2
282 xl[
"Particle_psi"]=psi
284 dr.add_contribution((p1i, p2i), (s1i, s2i), psii)
287 print(
"--------------")
288 print(
"CrossLinkingMassSpectrometryRestraint: generating cross-link restraint between")
289 print(
"CrossLinkingMassSpectrometryRestraint: residue %d of chain %s and residue %d of chain %s" % (r1, c1, r2, c2))
290 print(
"CrossLinkingMassSpectrometryRestraint: with sigma1 %s sigma2 %s psi %s" % (sigma1name, sigma2name, psiname))
291 print(
"CrossLinkingMassSpectrometryRestraint: between particles %s and %s" % (p1.get_name(), p2.get_name()))
292 print(
"==========================================\n")
293 for p, ex_xl
in zip(IMP.pmi.tools._all_protocol_outputs(
294 representations, root_hier),
296 p[0].add_cross_link(p[1], ex_xl[0], p1, p2, length,
297 sigma1, sigma2, psi, ex_xl[1])
304 xl[
"IntraRigidBody"]=
True
306 xl[
"IntraRigidBody"]=
False
308 xl_label=self.CrossLinkDataBase.get_short_cross_link_string(xl)
309 xl[
"ShortLabel"]=xl_label
310 dr.set_name(xl_label)
314 pr.set_name(xl_label)
315 self.rslin.add_restraint(pr)
317 self.xl_list.append(xl)
319 indb.write(str(xl) +
"\n")
321 if len(self.xl_list) == 0:
322 raise SystemError(
"CrossLinkingMassSpectrometryRestraint: no crosslink was constructed")
323 self.xl_restraints = restraints
325 self.rs.add_restraint(lw)
327 def __set_dataset(self, ds):
328 self.CrossLinkDataBase.dataset = ds
329 dataset = property(
lambda self: self.CrossLinkDataBase.dataset,
333 """ get the hierarchy """
337 """ get the restraint set """
341 """ get the restraints in a list """
342 return self.xl_restraints
345 """ get the dummy restraints to be displayed in the rmf file """
349 """ Get a list of tuples containing the particle pairs """
351 for i
in range(len(self.pairs)):
352 p0 = self.pairs[i][0]
353 p1 = self.pairs[i][1]
354 ppairs.append((p0, p1))
358 """ Set the output level of the output """
359 self.outputlevel = level
362 """ Switch on/off the sampling of psi particles """
363 self.psi_is_sampled = is_sampled
366 """ Switch on/off the sampling of sigma particles """
367 self.sigma_is_sampled = is_sampled
371 """ This is called internally. Creates a nuisance
372 on the structural uncertainty """
373 if name
in self.sigma_dictionary:
374 return self.sigma_dictionary[name][0]
377 sigmaminnuis = 0.0000001
378 sigmamaxnuis = 1000.0
382 sigma = IMP.pmi.tools.SetupNuisance(self.model, sigmainit,
383 sigmaminnuis, sigmamaxnuis, self.sigma_is_sampled).get_particle()
384 self.sigma_dictionary[name] = (
387 self.sigma_is_sampled)
388 self.rssig.add_restraint(
398 """ This is called internally. Creates a nuisance
399 on the data uncertainty """
400 if name
in self.psi_dictionary:
401 return self.psi_dictionary[name][0]
404 psiminnuis = 0.0000001
405 psimaxnuis = 0.4999999
409 psi = IMP.pmi.tools.SetupNuisance(self.model, psiinit,
410 psiminnuis, psimaxnuis,
411 self.psi_is_sampled).get_particle()
412 self.psi_dictionary[name] = (
417 self.rspsi.add_restraint(
429 """ Get the output of the restraint to be used by the IMP.pmi.output object"""
430 output = super(CrossLinkingMassSpectrometryRestraint, self).
get_output()
432 for xl
in self.xl_list:
434 xl_label=xl[
"ShortLabel"]
438 output[
"CrossLinkingMassSpectrometryRestraint_Score_" +
439 xl_label] = str(-log(ln.unprotected_evaluate(
None)))
443 output[
"CrossLinkingMassSpectrometryRestraint_Distance_" +
447 for psiname
in self.psi_dictionary:
448 output[
"CrossLinkingMassSpectrometryRestraint_Psi_" +
449 str(psiname) + self._label_suffix] = str(
450 self.psi_dictionary[psiname][0].get_scale())
452 for sigmaname
in self.sigma_dictionary:
453 output[
"CrossLinkingMassSpectrometryRestraint_Sigma_" +
454 str(sigmaname) + self._label_suffix] = str(
455 self.sigma_dictionary[sigmaname][0].get_scale())
461 """ Get all need data to construct a mover in IMP.pmi.dof class"""
463 if self.sigma_is_sampled:
464 for sigmaname
in self.sigma_dictionary:
465 mover_name=
"Nuisances_CrossLinkingMassSpectrometryRestraint_Sigma_" + str(sigmaname) +
"_" + self.label
466 particle=self.sigma_dictionary[sigmaname][0]
467 maxstep=(self.sigma_dictionary[sigmaname][1])
470 mv.set_name(mover_name)
473 if self.psi_is_sampled:
474 for psiname
in self.psi_dictionary:
475 mover_name=
"Nuisances_CrossLinkingMassSpectrometryRestraint_Psi_" + str(psiname) +
"_" + self.label
476 particle=self.psi_dictionary[psiname][0]
477 maxstep=(self.psi_dictionary[psiname][1])
480 mv.set_name(mover_name)
487 """ Get the particles to be sampled by the IMP.pmi.sampler object """
489 if self.sigma_is_sampled:
490 for sigmaname
in self.sigma_dictionary:
491 ps[
"Nuisances_CrossLinkingMassSpectrometryRestraint_Sigma_" +
492 str(sigmaname) + self._label_suffix] =\
493 ([self.sigma_dictionary[sigmaname][0]],
494 self.sigma_dictionary[sigmaname][1])
496 if self.psi_is_sampled:
497 for psiname
in self.psi_dictionary:
498 ps[
"Nuisances_CrossLinkingMassSpectrometryRestraint_Psi_" +
499 str(psiname) + self._label_suffix] =\
500 ([self.psi_dictionary[psiname][0]], self.psi_dictionary[psiname][1])
506 """Setup cross-link distance restraints at atomic level
507 The "atomic" aspect is that it models the particle uncertainty with a Gaussian
508 The noise in the data and the structural uncertainty of cross-linked amino-acids
509 is inferred using Bayes' theory of probability
510 @note Wraps an IMP::isd::AtomicCrossLinkMSRestraint
520 nuisances_are_optimized=
True,
527 Automatically creates one "sigma" per crosslinked residue and one "psis" per pair.
528 Other nuisance options are available.
529 @note Will return an error if the data+extra_sel don't specify two particles per XL pair.
530 @param root_hier The root hierarchy on which you'll do selection
531 @param xldb CrossLinkDataBase object
532 @param atom_type Can either be "NZ" or "CA"
533 @param length The XL linker length
534 @param slope Linear term to add to the restraint function to help when far away
535 @param nstates The number of states to model. Defaults to the number of states in root.
536 @param label The output label for the restraint
537 @param nuisances_are_optimized Whether to optimize nuisances
538 @param sigma_init The initial value for all the sigmas
539 @param psi_init The initial value for all the psis
540 @param one_psi Use a single psi for all restraints (if False, creates one per XL)
541 @param filelabel automatically generated file containing missing/included/excluded
542 cross-links will be labeled using this text
543 @param weight Weight of restraint
548 self.root = root_hier
549 rname =
"AtomicXLRestraint"
550 super(AtomicCrossLinkMSRestraint, self).
__init__(
551 self.root.get_model(), name=
"AtomicXLRestraint", label=label,
555 self.sigma_is_sampled = nuisances_are_optimized
556 self.psi_is_sampled = nuisances_are_optimized
558 if atom_type
not in(
"NZ",
"CA"):
559 raise Exception(
"AtomicXLRestraint: atom_type must be NZ or CA")
560 self.atom_type = atom_type
561 self.nstates = nstates
563 self.nstates = len(IMP.atom.get_by_type(self.root,IMP.atom.STATE_TYPE))
564 elif nstates!=len(IMP.atom.get_by_type(self.root,IMP.atom.STATE_TYPE)):
565 print(
"Warning: nstates is not the same as the number of states in root")
567 self.rs_psi = self._create_restraint_set(
"psi")
568 self.rs_sig = self._create_restraint_set(
"sigma")
569 self.rs_lin = self._create_restraint_set(
"linear")
571 self.psi_dictionary = {}
572 self.sigma_dictionary = {}
574 self.particles=defaultdict(set)
575 self.one_psi = one_psi
576 self.bonded_pairs = []
578 print(
'creating a single psi for all XLs')
580 print(
'creating one psi for each XL')
583 if filelabel
is not None:
584 indb = open(
"included." + filelabel +
".xl.db",
"w")
585 exdb = open(
"excluded." + filelabel +
".xl.db",
"w")
586 midb = open(
"missing." + filelabel +
".xl.db",
"w")
592 # read ahead to get the number of XL's per residue
593 num_xls_per_res=defaultdict(int)
594 for unique_id in data:
595 for nstate in range(self.nstates):
596 for xl in data[unique_id]:
597 num_xls_per_res[str(xl.r1)]+=1
598 num_xls_per_res[str(xl.r2)]+=1
600 # Will setup two sigmas based on promiscuity of the residue
602 self.sig_low = setup_nuisance(self.m,self.rs_nuis,init_val=sigma_init,min_val=1.0,
603 max_val=100.0,is_opt=self.nuis_opt)
604 self.sig_high = setup_nuisance(self.m,self.rs_nuis,init_val=sigma_init,min_val=1.0,
605 max_val=100.0,is_opt=self.nuis_opt)
607 self._create_sigma(
'sigma',sigma_init)
609 self._create_psi(
'psi',psi_init)
611 for xlid
in self.xldb.xlid_iterator():
612 self._create_psi(xlid,psi_init)
616 for xlid
in self.xldb.xlid_iterator():
619 psip = self.psi_dictionary[
'psi'][0].get_particle_index()
621 psip = self.psi_dictionary[unique_id][0].get_particle_index()
630 for nstate
in self.nstates:
631 for xl
in self.xldb[xlid]:
632 r1 = xl[self.xldb.residue1_key]
633 c1 = xl[self.xldb.protein1_key].strip()
634 r2 = xl[self.xldb.residue2_key]
635 c2 = xl[self.xldb.protein2_key].strip()
642 residue_index=r1).get_selected_particles()
647 residue_index=r2).get_selected_particles()
649 warnings.warn(
"AtomicXLRestraint: residue %d of "
650 "chain %s is not there" % (r1, c1),
652 if filelabel
is not None:
653 midb.write(str(xl) +
"\n")
657 warnings.warn(
"AtomicXLRestraint: residue %d of "
658 "chain %s is not there" % (r2, c2),
660 if filelabel
is not None:
661 midb.write(str(xl) +
"\n")
667 num1=num_xls_per_res[str(xl.r1)]
668 num2=num_xls_per_res[str(xl.r2)]
669 if num1<sig_threshold:
673 if num2<sig_threshold:
678 sig1 = self.sigma_dictionary[
'sigma'][0]
679 sig2 = self.sigma_dictionary[
'sigma'][0]
682 for p1,p2
in itertools.product(ps1,ps2):
685 self.particles[nstate]|=set((p1,p2))
686 r.add_contribution([p1.get_index(),p2.get_index()],
687 [sig1.get_particle_index(),sig2.get_particle_index()])
690 if num_contributions>0:
691 print(
'XL:',xlid,
'num contributions:',num_contributions)
694 raise Exception(
"You didn't create any XL restraints")
695 print(
'created',len(xlrs),
'XL restraints')
696 rname = self.rs.get_name()
698 self.rs.set_name(rname)
699 self.rs.set_weight(self.weight)
700 self.restraint_sets = [self.rs] + self.restraint_sets[1:]
702 def get_hierarchy(self):
705 def _create_sigma(self, name,sigmainit):
706 """ This is called internally. Creates a nuisance
707 on the structural uncertainty """
708 if name
in self.sigma_dictionary:
709 return self.sigma_dictionary[name][0]
711 sigmaminnuis = 0.0000001
712 sigmamaxnuis = 1000.0
716 sigma = IMP.pmi.tools.SetupNuisance(self.model,
720 self.sigma_is_sampled).get_particle()
721 self.sigma_dictionary[name] = (
724 self.sigma_is_sampled)
725 self.rs_sig.add_restraint(
734 def _create_psi(self, name,psiinit):
735 """ This is called internally. Creates a nuisance
736 on the data uncertainty """
737 if name
in self.psi_dictionary:
738 return self.psi_dictionary[name][0]
740 psiminnuis = 0.0000001
741 psimaxnuis = 0.4999999
745 psi = IMP.pmi.tools.SetupNuisance(self.model,
749 self.psi_is_sampled).get_particle()
750 self.psi_dictionary[name] = (
755 self.rs_psi.add_restraint(
767 """ create dummy harmonic restraints for each XL but don't add to model
768 Makes it easy to see each contribution to each XL in RMF
770 class MyGetRestraint(object):
779 for nxl
in range(self.get_number_of_restraints()):
780 xl=IMP.isd.AtomicCrossLinkMSRestraint.get_from(self.rs.get_restraint(nxl))
782 for ncontr
in range(xl.get_number_of_contributions()):
783 ps=xl.get_contribution(ncontr)
785 'xl%i_contr%i'%(nxl,ncontr))
787 dummy_rs.append(MyGetRestraint(rs))
792 """ Get the particles to be sampled by the IMP.pmi.sampler object """
794 if self.sigma_is_sampled:
795 for sigmaname
in self.sigma_dictionary:
796 ps[
"Nuisances_AtomicCrossLinkingMSRestraint_Sigma_" +
797 str(sigmaname) + self._label_suffix] = \
798 ([self.sigma_dictionary[sigmaname][0]],
799 self.sigma_dictionary[sigmaname][1])
800 if self.psi_is_sampled:
801 for psiname
in self.psi_dictionary:
802 ps[
"Nuisances_CrossLinkingMassSpectrometryRestraint_Psi_" +
803 str(psiname) + self._label_suffix] =\
804 ([self.psi_dictionary[psiname][0]], self.psi_dictionary[psiname][1])
807 def get_bonded_pairs(self):
808 return self.bonded_pairs
810 def get_number_of_restraints(self):
811 return self.rs.get_number_of_restraints()
814 return 'XL restraint with '+str(len(self.rs.get_restraint(0).get_number_of_restraints())) \
818 """Read a stat file and load all the sigmas.
819 This is potentially quite stupid.
820 It's also a hack since the sigmas should be stored in the RMF file.
821 Also, requires one sigma and one psi for ALL XLs.
824 sig_val = float(subprocess.check_output([
"process_output.py",
"-f",in_fn,
825 "-s",
"AtomicXLRestraint_sigma"]).split(
'\n>')[1+nframe])
826 psi_val = float(subprocess.check_output([
"process_output.py",
"-f",in_fn,
827 "-s",
"AtomicXLRestraint_psi"]).split(
'\n>')[1+nframe])
828 for nxl
in range(self.rs.get_number_of_restraints()):
829 xl=IMP.isd.AtomicCrossLinkMSRestraint.get_from(self.rs.get_restraint(nxl))
832 for contr
in range(xl.get_number_of_contributions()):
833 sig1,sig2=xl.get_contribution_sigmas(contr)
836 print(
'loaded nuisances from file')
839 max_prob_for_violation=0.1,
840 min_dist_for_violation=1e9,
842 limit_to_chains=
None,
844 """Create CMM files, one for each state, of all crosslinks.
845 will draw in GREEN if non-violated in all states (or if only one state)
846 will draw in PURPLE if non-violated only in a subset of states (draws nothing elsewhere)
847 will draw in RED in ALL states if all violated
848 (if only one state, you'll only see green and red)
850 @param out_prefix Output xlink files prefix
851 @param max_prob_for_violation It's a violation if the probability is below this
852 @param min_dist_for_violation It's a violation if the min dist is above this
853 @param coarsen Use CA positions
854 @param limit_to_chains Try to visualize just these chains
855 @param exclude_to_chains Try to NOT visualize these chains
857 print(
'going to calculate violations and plot CMM files')
859 all_dists = [s[
"low_dist"]
for s
in all_stats]
865 cmds = defaultdict(set)
866 for nstate
in range(self.nstates):
867 outf=open(out_prefix+str(nstate)+
'.cmm',
'w')
868 outf.write(
'<marker_set name="xlinks_state%i"> \n' % nstate)
871 print(
'will limit to',limit_to_chains)
872 print(
'will exclude',exclude_chains)
877 for nxl
in range(self.rs.get_number_of_restraints()):
881 for nstate
in range(self.nstates):
882 prob = state_info[nstate][nxl][
"prob"]
883 low_dist = state_info[nstate][nxl][
"low_dist"]
884 if prob<max_prob_for_violation
or low_dist>min_dist_for_violation:
892 if len(npass)==self.nstates:
894 elif len(nviol)==self.nstates:
898 print(nxl,
'state dists:',[state_info[nstate][nxl][
"low_dist"]
for nstate
in range(self.nstates)],
899 'viol states:',nviol,
'all viol?',all_viol)
900 for nstate
in range(self.nstates):
902 r=0.365; g=0.933; b=0.365;
905 r=0.980; g=0.302; b=0.247;
912 r=0.365; g=0.933; b=0.365;
914 pp = state_info[nstate][nxl][
"low_pp"]
923 cmds[nstate].add((ch1,r1))
924 cmds[nstate].add((ch2,r2))
926 outf = out_fns[nstate]
928 outf.write(
'<marker id= "%d" x="%.3f" y="%.3f" z="%.3f" radius="0.8" '
929 'r="%.2f" g="%.2f" b="%.2f"/> \n' % (nv,c1[0],c1[1],c1[2],r,g,b))
930 outf.write(
'<marker id= "%d" x="%.3f" y="%.3f" z="%.3f" radius="0.8" '
931 'r="%.2f" g="%.2f" b="%.2f"/> \n' % (nv+1,c2[0],c2[1],c2[2],r,g,b))
932 outf.write(
'<link id1= "%d" id2="%d" radius="0.8" '
933 'r="%.2f" g="%.2f" b="%.2f"/> \n' % (nv,nv+1,r,g,b))
936 for nstate
in range(self.nstates):
937 out_fns[nstate].write(
'</marker_set>\n')
938 out_fns[nstate].close()
940 for ch,r
in cmds[nstate]:
941 cmd+=
'#%i:%i.%s '%(nstate,r,ch)
945 def _get_contribution_info(self,xl,ncontr,use_CA=False):
946 """Return the particles at that contribution. If requested will return CA's instead"""
947 idx1=xl.get_contribution(ncontr)[0]
948 idx2=xl.get_contribution(ncontr)[1]
956 return idx1,idx2,dist
958 def get_best_stats(self,limit_to_state=None,limit_to_chains=None,exclude_chains='',use_CA=False):
959 ''' return the probability, best distance, two coords, and possibly the psi for each xl
960 @param limit_to_state Only examine contributions from one state
961 @param limit_to_chains Returns the particles for certain "easy to visualize" chains
962 @param exclude_chains Even if you limit, don't let one end be in this list.
963 Only works if you also limit chains
964 @param use_CA Limit to CA particles
967 for nxl
in range(self.rs.get_number_of_restraints()):
969 xl=IMP.isd.AtomicCrossLinkMSRestraint.get_from(self.rs.get_restraint(nxl))
976 for contr
in range(xl.get_number_of_contributions()):
977 pp = xl.get_contribution(contr)
984 if limit_to_state
is not None:
986 if nstate!=limit_to_state:
988 state_contrs.append(contr)
991 if limit_to_chains
is not None:
994 if (c1
in limit_to_chains
or c2
in limit_to_chains)
and (
995 c1
not in exclude_chains
and c2
not in exclude_chains):
996 if dist<low_dist_lim:
1003 if limit_to_state
is not None:
1004 this_info[
"prob"] = xl.evaluate_for_contributions(state_contrs,
None)
1006 this_info[
"prob"] = xl.unprotected_evaluate(
None)
1007 if limit_to_chains
is not None:
1008 this_info[
"low_pp"] = low_pp_lim
1010 this_info[
"low_pp"] = low_pp
1012 this_info[
"low_dist"] = low_dist
1013 if not self.one_psi:
1015 this_info[
"psi"] = pval
1016 ret.append(this_info)
1019 def print_stats(self):
1022 for nxl,s
in enumerate(stats):
1024 print(s[
"low_dist"])
1028 output = super(AtomicCrossLinkMSRestraint, self).
get_output()
1039 for nxl,s
in enumerate(stats):
1040 if s[
'low_dist']>20.0:
1042 output[
"AtomicXLRestraint_%i_%s"%(nxl,
"Prob")]=str(s[
'prob'])
1043 output[
"AtomicXLRestraint_%i_%s"%(nxl,
"BestDist")]=str(s[
'low_dist'])
1044 if not self.one_psi:
1045 output[
"AtomicXLRestraint_%i_%s"%(nxl,
"psi")]=str(s[
'psi'])
1046 output[
"AtomicXLRestraint_NumViol"] = str(bad_count)
1050 @
IMP.deprecated_object(
"2.5",
"Use IMP.pmi.restraints.crosslinking.CrossLinkingMassSpectrometryRestraint instead.")
1051 class ISDCrossLinkMS(IMP.pmi.restraints._NuisancesBase):
1072 automatic_sigma_classification=
False,
1073 attributes_for_label=
None):
1083 if type(representation) != list:
1084 representations = [representation]
1086 representations = representation
1088 if columnmapping
is None:
1090 columnmapping[
"Protein1"] = 0
1091 columnmapping[
"Protein2"] = 1
1092 columnmapping[
"Residue1"] = 2
1093 columnmapping[
"Residue2"] = 3
1094 columnmapping[
"IDScore"] = 4
1095 columnmapping[
"XLUniqueID"] = 5
1101 db = IMP.pmi.tools.get_db_from_csv(restraints_file)
1103 db = IMP.pmi.tools.open_file_or_inline_text(restraints_file)
1105 indb = open(
"included." + filelabel +
".xl.db",
"w")
1106 exdb = open(
"excluded." + filelabel +
".xl.db",
"w")
1107 midb = open(
"missing." + filelabel +
".xl.db",
"w")
1109 self.m = representations[0].prot.get_model()
1119 self.sigma_dictionary = {}
1120 self.psi_dictionary = {}
1121 self.psi_is_sampled =
True
1122 self.sigma_is_sampled =
True
1124 if os.path.exists(restraints_file):
1125 l = ihm.location.InputFileLocation(restraints_file,
1126 details=
"Crosslinks")
1127 self.dataset = ihm.dataset.CXMSDataset(l)
1131 xl_groups = [p.get_cross_link_group(self)
1132 for p, state
in representations[0]._protocol_output]
1137 self.ids_map = IMP.pmi.tools.map()
1138 self.ids_map.set_map_element(20.0, 0.05)
1139 self.ids_map.set_map_element(65.0, 0.01)
1141 self.ids_map = ids_map
1143 if radius_map
is None:
1144 self.radius_map = IMP.pmi.tools.map()
1145 if automatic_sigma_classification:
1146 self.radius_map.set_map_element(10, 10)
1147 self.radius_map.set_map_element(1, 1)
1149 self.radius_map = radius_map
1151 self.outputlevel =
"low"
1155 self.linear.set_slope(slope)
1158 protein1 = columnmapping[
"Protein1"]
1159 protein2 = columnmapping[
"Protein2"]
1160 residue1 = columnmapping[
"Residue1"]
1161 residue2 = columnmapping[
"Residue2"]
1162 idscore = columnmapping[
"IDScore"]
1164 xluniqueid = columnmapping[
"XLUniqueID"]
1174 uniqueid_restraints_map = {}
1176 for nxl, entry
in enumerate(db):
1178 if not jackknifing
is None:
1185 raise NotImplementedError(
"jackknifing not yet implemented")
1188 tokens = entry.split()
1193 if (tokens[0] ==
"#"):
1196 r1 = int(tokens[residue1])
1197 c1 = tokens[protein1]
1198 r2 = int(tokens[residue2])
1199 c2 = tokens[protein2]
1201 if offset_dict
is not None:
1202 if c1
in offset_dict: r1+=offset_dict[c1]
1203 if c2
in offset_dict: r2+=offset_dict[c2]
1205 if rename_dict
is not None:
1206 if c1
in rename_dict: c1=rename_dict[c1]
1207 if c2
in rename_dict: c2=rename_dict[c2]
1212 ids = float(tokens[idscore])
1213 if xluniqueid
is None:
1216 xlid = tokens[xluniqueid]
1218 print(
"this line was not accessible " + str(entry))
1219 if residue1
not in entry: print(str(residue1)+
" keyword not in database")
1220 if residue2
not in entry: print(str(residue2)+
" keyword not in database")
1221 if protein1
not in entry: print(str(protein1)+
" keyword not in database")
1222 if protein2
not in entry: print(str(protein2)+
" keyword not in database")
1223 if idscore
not in entry: print(str(idscore)+
" keyword not in database")
1224 if xluniqueid
not in entry: print(str(xluniqueid)+
" keyword not in database")
1228 if filters
is not None:
1230 exdb.write(str(entry) +
"\n")
1234 r1 = int(entry[residue1])
1235 c1 = entry[protein1]
1236 r2 = int(entry[residue2])
1237 c2 = entry[protein2]
1239 if offset_dict
is not None:
1240 if c1
in offset_dict: r1+=offset_dict[c1]
1241 if c2
in offset_dict: r2+=offset_dict[c2]
1243 if rename_dict
is not None:
1244 if c1
in rename_dict: c1=rename_dict[c1]
1245 if c2
in rename_dict: c2=rename_dict[c2]
1251 ids = float(entry[idscore])
1253 ids = entry[idscore]
1254 if xluniqueid
is None:
1257 xlid = entry[xluniqueid]
1260 print(
"this line was not accessible " + str(entry))
1261 if residue1
not in entry: print(str(residue1)+
" keyword not in database")
1262 if residue2
not in entry: print(str(residue2)+
" keyword not in database")
1263 if protein1
not in entry: print(str(protein1)+
" keyword not in database")
1264 if protein2
not in entry: print(str(protein2)+
" keyword not in database")
1265 if idscore
not in entry: print(str(idscore)+
" keyword not in database")
1266 if xluniqueid
not in entry: print(str(xluniqueid)+
" keyword not in database")
1270 ex_xls = [(p[0].add_experimental_cross_link(r1, c1, r2, c2,
1272 for p, group
in zip(representations[0]._protocol_output,
1275 for nstate, r
in enumerate(representations):
1280 resolution=resolution,
1282 name_is_ambiguous=
False,
1286 resolution=resolution,
1288 name_is_ambiguous=
False,
1292 raise ValueError(
"residue %d of chain %s selects multiple particles %s" % (r1, c1, str(ps1)))
1294 warnings.warn(
"ISDCrossLinkMS: residue %d of chain %s "
1295 "is not there" % (r1, c1),
1297 midb.write(str(entry) +
"\n")
1301 raise ValueError(
"residue %d of chain %s selects multiple particles %s" % (r2, c2, str(ps2)))
1303 warnings.warn(
"ISDCrossLinkMS: residue %d of chain %s "
1304 "is not there" % (r2, c2),
1306 midb.write(str(entry) +
"\n")
1312 if (p1 == p2)
and (r1 == r2) :
1313 warnings.warn(
"ISDCrossLinkMS Restraint: on the identical "
1314 "bead particles and the identical residues, "
1315 "thus skipping this cross-link.",
1319 if xlid
in uniqueid_restraints_map:
1320 print(
"Appending a crosslink restraint into the uniqueID %s" % str(xlid))
1321 dr = uniqueid_restraints_map[xlid]
1323 print(
"Generating a NEW crosslink restraint with a uniqueID %s" % str(xlid))
1328 restraints.append(dr)
1329 uniqueid_restraints_map[xlid] = dr
1331 mappedr1 = self.radius_map.get_map_element(
1333 sigma1 = self.get_sigma(mappedr1)[0]
1334 mappedr2 = self.radius_map.get_map_element(
1336 sigma2 = self.get_sigma(mappedr2)[0]
1338 psival = self.ids_map.get_map_element(ids)
1339 psi = self.get_psi(psival)[0]
1342 p1i = p1.get_particle_index()
1343 p2i = p2.get_particle_index()
1351 dr.add_contribution((p1i, p2i), (s1i, s2i), psii)
1352 print(
"--------------")
1353 print(
"ISDCrossLinkMS: generating cross-link restraint between")
1354 print(
"ISDCrossLinkMS: residue %d of chain %s and residue %d of chain %s" % (r1, c1, r2, c2))
1355 print(
"ISDCrossLinkMS: with sigma1 %f sigma2 %f psi %s" % (mappedr1, mappedr2, psival))
1356 print(
"ISDCrossLinkMS: between particles %s and %s" % (p1.get_name(), p2.get_name()))
1357 print(
"==========================================\n")
1358 indb.write(str(entry) +
"\n")
1359 for p, ex_xl
in zip(representations[0]._protocol_output,
1361 p[0].add_cross_link(p[1], ex_xl[0], p1, p2, length,
1362 sigma1, sigma2, psi, ex_xl[1])
1369 xlattribute =
"intrarb"
1371 xlattribute =
"interrb"
1374 if not attributes_for_label
is None:
1375 for a
in attributes_for_label:
1376 xlattribute = xlattribute +
"_" + str(entry[a])
1378 xlattribute = xlattribute +
"-State:" + str(nstate)
1381 xlattribute +
"-" + c1 +
":" + str(r1) +
"-" + c2 +
":" + str(r2) +
"_" + self.label)
1386 xlattribute +
"-" + c1 +
":" + str(r1) +
"-" + c2 +
":" + str(r2) +
"_" + self.label)
1387 self.rslin.add_restraint(pr)
1407 self.rs.add_restraint(lw)
1410 model = property(
lambda s: s.m)
1413 self.weight = weight
1414 self.rs.set_weight(weight)
1416 def set_slope_linear_term(self, slope):
1417 self.linear.set_slope(slope)
1429 def get_hierarchies(self):
1432 def get_restraint_sets(self):
1441 def get_restraints(self):
1443 for r
in self.rs.get_restraints():
1444 rlist.append(IMP.core.PairRestraint.get_from(r))
1447 def get_particle_pairs(self):
1449 for i
in range(len(self.pairs)):
1450 p0 = self.pairs[i][0]
1451 p1 = self.pairs[i][1]
1452 ppairs.append((p0, p1))
1455 def set_output_level(self, level="low"):
1457 self.outputlevel = level
1459 def set_psi_is_sampled(self, is_sampled=True):
1460 self.psi_is_sampled = is_sampled
1462 def set_sigma_is_sampled(self, is_sampled=True):
1463 self.sigma_is_sampled = is_sampled
1465 def get_label(self,pairs_index):
1466 resid1 = self.pairs[pairs_index][3]
1467 chain1 = self.pairs[pairs_index][4]
1468 resid2 = self.pairs[pairs_index][5]
1469 chain2 = self.pairs[pairs_index][6]
1470 attribute = self.pairs[pairs_index][7]
1471 rad1 = self.pairs[pairs_index][8]
1472 rad2 = self.pairs[pairs_index][9]
1473 psi = self.pairs[pairs_index][10]
1474 xlid= self.pairs[pairs_index][11]
1475 label = attribute +
"-" + \
1476 str(resid1) +
":" + chain1 +
"_" + str(resid2) +
":" + \
1477 chain2 +
"-" + str(rad1) +
"-" + str(rad2) +
"-" + str(psi)
1480 def write_db(self,filename):
1481 cldb=IMP.pmi.output.CrossLinkIdentifierDatabase()
1483 for pairs_index
in range(len(self.pairs)):
1485 resid1 = self.pairs[pairs_index][3]
1486 chain1 = self.pairs[pairs_index][4]
1487 resid2 = self.pairs[pairs_index][5]
1488 chain2 = self.pairs[pairs_index][6]
1489 attribute = self.pairs[pairs_index][7]
1490 rad1 = self.pairs[pairs_index][8]
1491 rad2 = self.pairs[pairs_index][9]
1492 psi = self.pairs[pairs_index][10]
1493 xlid= self.pairs[pairs_index][11]
1494 nstate=self.pairs[pairs_index][12]
1495 ids=self.pairs[pairs_index][13]
1497 label=self.get_label(pairs_index)
1498 cldb.set_unique_id(label,xlid)
1499 cldb.set_protein1(label,chain1)
1500 cldb.set_protein2(label,chain2)
1501 cldb.set_residue1(label,resid1)
1502 cldb.set_residue2(label,resid2)
1503 cldb.set_idscore(label,ids)
1504 cldb.set_state(label,nstate)
1505 cldb.set_sigma1(label,rad1)
1506 cldb.set_sigma2(label,rad2)
1507 cldb.set_psi(label,psi)
1508 cldb.write(filename)
1515 score = self.weight * self.rs.unprotected_evaluate(
None)
1516 output[
"_TotalScore"] = str(score)
1517 output[
"ISDCrossLinkMS_Data_Score_" + self.label] = str(score)
1518 output[
"ISDCrossLinkMS_PriorSig_Score_" +
1519 self.label] = self.rssig.unprotected_evaluate(
None)
1520 output[
"ISDCrossLinkMS_PriorPsi_Score_" +
1521 self.label] = self.rspsi.unprotected_evaluate(
None)
1522 output[
"ISDCrossLinkMS_Linear_Score_" +
1523 self.label] = self.rslin.unprotected_evaluate(
None)
1524 for i
in range(len(self.pairs)):
1526 label=self.get_label(i)
1527 ln = self.pairs[i][2]
1528 p0 = self.pairs[i][0]
1529 p1 = self.pairs[i][1]
1530 output[
"ISDCrossLinkMS_Score_" +
1531 label +
"_" + self.label] = str(self.weight * -log(ln.unprotected_evaluate(
None)))
1535 output[
"ISDCrossLinkMS_Distance_" +
1539 for psiindex
in self.psi_dictionary:
1540 output[
"ISDCrossLinkMS_Psi_" +
1541 str(psiindex) +
"_" + self.label] = str(self.psi_dictionary[psiindex][0].get_scale())
1543 for resolution
in self.sigma_dictionary:
1544 output[
"ISDCrossLinkMS_Sigma_" +
1545 str(resolution) +
"_" + self.label] = str(self.sigma_dictionary[resolution][0].get_scale())
1552 for resolution
in self.sigma_dictionary:
1553 if self.sigma_dictionary[resolution][2]
and self.sigma_is_sampled:
1554 ps[
"Nuisances_ISDCrossLinkMS_Sigma_" + str(resolution) +
"_" + self.label] =\
1555 ([self.sigma_dictionary[resolution][0]],
1556 self.sigma_dictionary[resolution][1])
1557 if self.psi_is_sampled:
1558 for psiindex
in self.psi_dictionary:
1559 if self.psi_dictionary[psiindex][2]:
1560 ps[
"Nuisances_ISDCrossLinkMS_Psi_" +
1561 str(psiindex) +
"_" + self.label] = ([self.psi_dictionary[psiindex][0]], self.psi_dictionary[psiindex][1])
1565 class CysteineCrossLinkRestraint(object):
1566 def __init__(self, representations, filename, cbeta=False,
1567 betatuple=(0.03, 0.1),
1568 disttuple=(0.0, 25.0, 1000),
1569 omegatuple=(1.0, 1000.0, 50),
1570 sigmatuple=(0.3, 0.3, 1),
1572 sigmaissampled=
False,
1573 weightissampled=
True,
1574 epsilonissampled=
True
1581 self.representations = representations
1582 self.m = self.representations[0].prot.get_model()
1585 self.epsilonmaxtrans = 0.01
1586 self.sigmamaxtrans = 0.1
1587 self.betamaxtrans = 0.01
1588 self.weightmaxtrans = 0.1
1590 self.outputlevel =
"low"
1591 self.betaissampled = betaissampled
1592 self.sigmaissampled = sigmaissampled
1593 self.weightissampled = weightissampled
1594 self.epsilonissampled = epsilonissampled
1596 betalower = betatuple[0]
1597 betaupper = betatuple[1]
1604 self.beta = IMP.pmi.tools.SetupNuisance(
1609 betaissampled).get_particle(
1612 self.sigma = IMP.pmi.tools.SetupNuisance(
1617 sigmaissampled).get_particle()
1619 self.weight = IMP.pmi.tools.SetupWeight(
1621 weightissampled).get_particle(
1625 fl = IMP.pmi.tools.open_file_or_inline_text(filename)
1634 if t[5]
in self.epsilons:
1635 if 1.0 - float(t[4]) <= self.epsilons[t[5]].get_upper():
1636 self.epsilons[t[5]].set_upper(1.0 - float(t[4]))
1638 self.epsilons[t[5]] = IMP.pmi.tools.SetupNuisance(self.m,
1639 0.01, 0.01, 1.0 - float(t[4]), epsilonissampled).get_particle()
1640 up = self.epsilons[t[5]].get_upper()
1641 low = self.epsilons[t[5]].get_lower()
1643 self.epsilons[t[5]].set_upper(low)
1645 data.append((int(t[0]), t[1], int(t[2]), t[3], float(t[4]), t[5]))
1649 crossdata = IMP.pmi.tools.get_cross_link_data(
1650 "cysteine",
"cysteine_CA_FES.txt.standard",
1651 disttuple, omegatuple, sigmatuple, disttuple[1], disttuple[1], 1)
1653 crossdata = IMP.pmi.tools.get_cross_link_data(
1654 "cysteine",
"cysteine_CB_FES.txt.standard",
1655 disttuple, omegatuple, sigmatuple, disttuple[1], disttuple[1], 1)
1658 fmod_grid = IMP.pmi.tools.get_grid(0.0, 1.0, 300,
True)
1659 omega2_grid = IMP.pmi.tools.get_log_grid(0.001, 10000.0, 100)
1660 beta_grid = IMP.pmi.tools.get_log_grid(betalower, betaupper, betangrid)
1663 print(
"--------------")
1664 print(
"CysteineCrossLink: attempting to create a restraint " + str(d))
1684 self.epsilons[epslabel],
1690 for i, representation
in enumerate(self.representations):
1697 resolution=1, name=chain1,
1698 name_is_ambiguous=
False, residue=resid1)[0]
1704 resolution=1, name=chain2,
1705 name_is_ambiguous=
False, residue=resid2)[0]
1714 for t
in range(-1, 2):
1716 resolution=1, name=chain1,
1717 name_is_ambiguous=
False, residue=resid1 + t)
1723 print(
"\033[93m CysteineCrossLink: missing representation for residue %d of chain %s \033[0m" % (resid1 + t, chain1))
1726 resolution=1, name=chain2,
1727 name_is_ambiguous=
False, residue=resid2 + t)
1733 print(
"\033[93m CysteineCrossLink: missing representation for residue %d of chain %s \033[0m" % (resid2 + t, chain2))
1736 if (p1
is not None and p2
is not None):
1737 ccl.add_contribution(p1, p2)
1741 print(
"Distance_" + str(resid1) +
"_" + chain1 +
":" + str(resid2) +
"_" + chain2,
IMP.core.get_distance(d1, d2))
1744 if (len(p1) == 3
and len(p2) == 3):
1745 p11n = p1[0].get_name()
1746 p12n = p1[1].get_name()
1747 p13n = p1[2].get_name()
1748 p21n = p2[0].get_name()
1749 p22n = p2[1].get_name()
1750 p23n = p2[2].get_name()
1752 print(
"CysteineCrossLink: generating CB cysteine cross-link restraint between")
1753 print(
"CysteineCrossLink: residue %d of chain %s and residue %d of chain %s" % (resid1, chain1, resid2, chain2))
1754 print(
"CysteineCrossLink: between particles %s %s %s and %s %s %s" % (p11n, p12n, p13n, p21n, p22n, p23n))
1756 ccl.add_contribution(p1, p2)
1759 self.rs.add_restraint(ccl)
1760 ccl.set_name(
"CysteineCrossLink_" + str(resid1)
1761 +
"_" + chain1 +
":" + str(resid2) +
"_" + chain2)
1771 if self.epsilonissampled:
1772 for eps
in self.epsilons.keys():
1773 ps[
"Nuisances_CysteineCrossLinkRestraint_epsilon_" + eps +
"_" +
1774 self.label] = ([self.epsilons[eps]], self.epsilonmaxtrans)
1775 if self.betaissampled:
1776 ps[
"Nuisances_CysteineCrossLinkRestraint_beta_" +
1777 self.label] = ([self.beta], self.betamaxtrans)
1778 if self.weightissampled:
1779 ps[
"Weights_CysteineCrossLinkRestraint_" +
1780 self.label] = ([self.weight], self.weightmaxtrans)
1781 if self.sigmaissampled:
1782 ps[
"Nuisances_CysteineCrossLinkRestraint_" +
1783 self.label] = ([self.sigma], self.sigmamaxtrans)
1786 def set_output_level(self, level="low"):
1788 self.outputlevel = level
1793 def get_sigma(self):
1798 score = self.rs.unprotected_evaluate(
None)
1799 output[
"_TotalScore"] = str(score)
1800 output[
"CysteineCrossLinkRestraint_Score_" + self.label] = str(score)
1801 output[
"CysteineCrossLinkRestraint_sigma_" +
1802 self.label] = str(self.sigma.get_scale())
1803 for eps
in self.epsilons.keys():
1804 output[
"CysteineCrossLinkRestraint_epsilon_" + eps +
"_" +
1805 self.label] = str(self.epsilons[eps].get_scale())
1806 output[
"CysteineCrossLinkRestraint_beta_" +
1807 self.label] = str(self.beta.get_scale())
1808 for n
in range(self.weight.get_number_of_states()):
1809 output[
"CysteineCrossLinkRestraint_weights_" +
1810 str(n) +
"_" + self.label] = str(self.weight.get_weight(n))
1812 if self.outputlevel ==
"high":
1813 for rst
in self.rs.get_restraints():
1814 output[
"CysteineCrossLinkRestraint_Total_Frequency_" +
1815 IMP.isd.CysteineCrossLinkRestraint.get_from(rst).get_name() +
1816 "_" + self.label] = IMP.isd.CysteineCrossLinkRestraint.get_from(rst).get_model_frequency()
1817 output[
"CysteineCrossLinkRestraint_Standard_Error_" +
1818 IMP.isd.CysteineCrossLinkRestraint.get_from(
1821 + self.label] = IMP.isd.CysteineCrossLinkRestraint.get_from(rst).get_standard_error()
1822 if len(self.representations) > 1:
1823 for i
in range(len(self.prots)):
1824 output[
"CysteineCrossLinkRestraint_Frequency_Contribution_" +
1825 IMP.isd.CysteineCrossLinkRestraint.get_from(rst).get_name() +
1826 "_State_" + str(i) +
"_" + self.label] = IMP.isd.CysteineCrossLinkRestraint.get_from(rst).get_frequencies()[i]
def set_sigma_is_sampled
Switch on/off the sampling of sigma particles.
Setup cross-link distance restraints from mass spectrometry data.
A restraint for ambiguous cross-linking MS data and multiple state approach.
def get_best_stats
return the probability, best distance, two coords, and possibly the psi for each xl ...
def get_hierarchies
get the hierarchy
def add_to_model
Add the restraint to the model.
Various classes to hold sets of particles.
def get_particles_to_sample
Get the particles to be sampled by the IMP.pmi.sampler object.
Restrain atom pairs based on a set of crosslinks.
Handles cross-link data sets.
def set_weight
Set the weight to apply to all internal restraints.
Add scale parameter to particle.
Add uncertainty to a particle.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
double get_distance(XYZR a, XYZR b)
Compute the sphere distance between a and b.
def get_particles_to_sample
Get the particles to be sampled by the IMP.pmi.sampler object.
def get_restraint_for_rmf
Get the restraint for visualization in an RMF file.
Object used to hold a set of restraints.
Class for storing model, its restraints, constraints, and particles.
Classes to handle different kinds of restraints.
Warning related to handling of structures.
def set_output_level
Set the output level of the output.
The standard decorator for manipulating molecular structures.
Ints get_index(const ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
def get_restraints
get the restraints in a list
A decorator for a particle representing an atom.
This class allows to create filter functions that can be passed to the CrossLinkDataBase in this way:...
def get_movers
Get all need data to construct a mover in IMP.pmi.dof class.
def get_particle_pairs
Get a list of tuples containing the particle pairs.
def create_psi
This is called internally.
A decorator for a particle with x,y,z coordinates.
def create_sigma
This is called internally.
def set_label
Set the unique label used in outputs and particle/restraint names.
int get_state_index(Hierarchy h)
Walk up the hierarchy to find the current state.
def plot_violations
Create CMM files, one for each state, of all crosslinks.
Modify a set of continuous variables using a normal distribution.
Classes for writing output files and processing them.
def deprecated_object
Python decorator to mark a class as deprecated.
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 create_restraints_for_rmf
create dummy harmonic restraints for each XL but don't add to model Makes it easy to see each contrib...
The general base class for IMP exceptions.
Setup cross-link distance restraints at atomic level The "atomic" aspect is that it models the part...
Residue get_residue(Atom d, bool nothrow=false)
Return the Residue containing this atom.
Calculate the -Log of a list of restraints.
double get_distance(const VectorD< D > &v1, const VectorD< D > &v2)
Compute the distance between two vectors.
def get_restraint_sets
get the restraint set
Applies a PairScore to a Pair.
def get_restraint
Get the primary restraint set.
def get_output
Get the output of the restraint to be used by the IMP.pmi.output object.
def get_restraint_for_rmf
get the dummy restraints to be displayed in the rmf file
Functionality for loading, creating, manipulating and scoring atomic structures.
std::string get_chain_id(Hierarchy h)
Walk up the hierarchy to determine the chain id.
def load_nuisances_from_stat_file
Read a stat file and load all the sigmas.
Select hierarchy particles identified by the biological name.
this class handles a cross-link dataset and do filtering operations, adding cross-links, merge datasets...
def get_output
Get outputs to write to stat files.
def set_psi_is_sampled
Switch on/off the sampling of psi particles.
Base class for PMI restraints, which wrap IMP.Restraint(s).
Inferential scoring building on methods developed as part of the Inferential Structure Determination ...
A restraint for cysteine cross-linking data.