3 """@namespace IMP.pmi.representation
4 Representation of the system.
7 from __future__
import print_function
20 from math
import pi, sqrt
21 from operator
import itemgetter
26 def __init__(self, doi, root):
30 def get_fname(self, fname):
31 """Return a path relative to the top of the repository"""
32 return os.path.relpath(fname, self._root)
34 class _StateInfo(object):
35 """Score state-specific information about this representation."""
39 class Representation(object):
43 Set up the representation of all proteins and nucleic acid macromolecules.
45 Create the molecular hierarchies, representation,
46 sequence connectivity for the various involved proteins and
47 nucleic acid macromolecules:
49 Create a protein, DNA or RNA, represent it as a set of connected balls of appropriate
50 radii and number of residues, PDB at given resolution(s), or ideal helices.
52 How to use the SimplifiedModel class (typical use):
54 see test/test_hierarchy_contruction.py
58 1) Create a chain of helices and flexible parts
60 c_1_119 =self.add_component_necklace("prot1",1,119,20)
61 c_120_131 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(120,131))
62 c_132_138 =self.add_component_beads("prot1",[(132,138)])
63 c_139_156 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(139,156))
64 c_157_174 =self.add_component_beads("prot1",[(157,174)])
65 c_175_182 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(175,182))
66 c_183_194 =self.add_component_beads("prot1",[(183,194)])
67 c_195_216 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(195,216))
68 c_217_250 =self.add_component_beads("prot1",[(217,250)])
71 self.set_rigid_body_from_hierarchies(c_120_131)
72 self.set_rigid_body_from_hierarchies(c_139_156)
73 self.set_rigid_body_from_hierarchies(c_175_182)
74 self.set_rigid_body_from_hierarchies(c_195_216)
76 clist=[c_1_119,c_120_131,c_132_138,c_139_156,c_157_174,c_175_182,c_183_194,c_195_216,
79 self.set_chain_of_super_rigid_bodies(clist,2,3)
81 self.set_super_rigid_bodies(["prot1"])
85 def __init__(self, m, upperharmonic=True, disorderedlength=True):
88 @param upperharmonic This flag uses either harmonic (False)
89 or upperharmonic (True) in the intra-pair
90 connectivity restraint.
91 @param disorderedlength This flag uses either disordered length
92 calculated for random coil peptides (True) or zero
93 surface-to-surface distance between beads (False)
94 as optimal distance for the sequence connectivity
98 self.state = _StateInfo()
100 self._file_dataset = {}
101 self._protocol_output = []
102 self._non_modeled_components = {}
111 self.upperharmonic = upperharmonic
112 self.disorderedlength = disorderedlength
113 self.rigid_bodies = []
114 self.fixed_rigid_bodies = []
115 self.fixed_floppy_bodies = []
116 self.floppy_bodies = []
122 self.super_rigid_bodies = []
123 self.rigid_body_symmetries = []
124 self.output_level =
"low"
127 self.maxtrans_rb = 2.0
128 self.maxrot_rb = 0.04
129 self.maxtrans_srb = 2.0
130 self.maxrot_srb = 0.2
131 self.rigidbodiesarefixed =
False
132 self.floppybodiesarefixed =
False
133 self.maxtrans_fb = 3.0
134 self.resolution = 10.0
135 self.bblenght = 100.0
139 self.representation_is_modified =
False
140 self.unmodeledregions_cr_dict = {}
141 self.sortedsegments_cr_dict = {}
143 self.connected_intra_pairs = []
146 self.sequence_dict = {}
147 self.hier_geometry_pairs = {}
153 self.hier_representation = {}
154 self.hier_resolution = {}
157 self.reference_structures = {}
160 self.linker_restraints.set_was_used(
True)
161 self.linker_restraints_dict = {}
162 self.threetoone = {
'ALA':
'A',
'ARG':
'R', 'ASN': 'N', 'ASP': 'D',
163 'CYS':
'C',
'GLU':
'E',
'GLN':
'Q',
'GLY':
'G',
164 'HIS':
'H',
'ILE':
'I',
'LEU':
'L',
'LYS':
'K',
165 'MET':
'M',
'PHE':
'F',
'PRO':
'P',
'SER':
'S',
166 'THR':
'T',
'TRP':
'W',
'TYR':
'Y',
'VAL':
'V',
'UNK':
'X'}
168 self.onetothree = dict((v, k)
for k, v
in self.threetoone.items())
173 """Associate some metadata with this modeling.
174 @param m an instance of IMP.pmi.metadata.Metadata or a subclass.
176 self._metadata.append(m)
179 """Associate a dataset with a filename.
180 This can be used to identify how the file was produced (in many
181 cases IMP can determine this automatically from a file header or
182 other metadata, but not always). For example, a manually-produced
183 PDB file (not from the PDB database or Modeller) can be
185 @param fname filename
186 @dataset the ihm.dataset.Dataset object to associate.
188 self._file_dataset[os.path.abspath(fname)] = dataset
191 """Get the dataset associated with a filename, or None.
192 @param fname filename
193 @return an ihm.dataset.Dataset, or None.
195 return self._file_dataset.get(os.path.abspath(fname),
None)
198 """Capture details of the modeling protocol.
199 @param p an instance of IMP.pmi.output.ProtocolOutput or a subclass.
201 state = p._add_state(self)
202 self._protocol_output.append((p, state))
203 p._each_metadata.append(self._metadata)
204 p._file_datasets.append(self._file_dataset)
206 state.prot = self.prot
207 protocol_output = property(
lambda self:
208 [x[0]
for x
in self._protocol_output])
210 def set_label(self, label):
213 def create_component(self, name, color=0.0):
220 protein_h.set_name(name)
221 self.hier_dict[name] = protein_h
222 self.hier_representation[name] = {}
223 self.hier_db.add_name(name)
224 self.prot.add_child(protein_h)
225 self.color_dict[name] = color
226 self.elements[name] = []
227 for p, state
in self._protocol_output:
228 p.create_component(state, name,
True)
231 """Create a transformed view of a component.
232 This does not copy the coordinates or representation of the
233 component, and the transformed component is not visible to IMP,
234 but when the model is written to a ProtocolOutput, the transformed
235 component is added. This can be used to easily add symmetry-related
236 'copies' of a component without copying the underlying
238 for p, state
in self._protocol_output:
239 p.create_transformed_component(state, name, original, transform)
242 """Create a component that isn't used in the modeling.
243 No coordinates or other structural data for this component will
244 be read or written, but a primary sequence can be assigned. This
245 is useful if the input experimental data is of a system larger
246 than that modeled. Any references to these non-modeled components
247 can then be correctly resolved later."""
248 self._non_modeled_components[name] =
None
249 self.elements[name] = []
250 for p, state
in self._protocol_output:
251 p.create_component(state, name,
False)
256 def add_component_name(self, *args, **kwargs):
257 self.create_component(*args, **kwargs)
259 def get_component_names(self):
260 return list(self.hier_dict.keys())
265 Add the primary sequence for a single component.
267 @param name Human-readable name of the component
268 @param filename Name of the FASTA file
269 @param id Identifier of the sequence in the FASTA file header
270 (if not provided, use `name` instead)
275 if id
not in record_dict:
276 raise KeyError(
"id %s not found in fasta file" % id)
277 length = len(record_dict[id])
278 self.sequence_dict[name] = str(record_dict[id])
280 if name
not in self._non_modeled_components:
281 protein_h = self.hier_dict[name]
282 protein_h.set_sequence(self.sequence_dict[name])
285 self.sequence_dict[name]=offs_str+self.sequence_dict[name]
287 self.elements[name].append((length, length,
" ",
"end"))
288 for p, state
in self._protocol_output:
289 p.add_component_sequence(state, name, self.sequence_dict[name])
291 def autobuild_model(self, name, pdbname, chain,
292 resolutions=
None, resrange=
None,
294 color=
None, pdbresrange=
None, offset=0,
295 show=
False, isnucleicacid=
False,
298 self.representation_is_modified =
True
302 color = self.color_dict[name]
304 self.color_dict[name] = color
306 if resolutions
is None:
308 print(
"autobuild_model: constructing %s from pdb %s and chain %s" % (name, pdbname, str(chain)))
317 t.get_children()[0].get_children()[0]).
get_index()
319 t.get_children()[0].get_children()[-1]).
get_index()
325 if name
in self.sequence_dict:
326 resrange = (1, len(self.sequence_dict[name]))
328 resrange = (start + offset, end + offset)
330 if resrange[1]
in (-1,
'END'):
331 resrange = (resrange[0],end)
332 start = resrange[0] - offset
333 end = resrange[1] - offset
352 for n, g
in enumerate(gaps):
356 print(
"autobuild_model: constructing fragment %s from pdb" % (str((first, last))))
358 chain, resolutions=resolutions,
359 color=color, cacenters=
True,
360 resrange=(first, last),
361 offset=offset, isnucleicacid=isnucleicacid)
362 elif g[2] ==
"gap" and n > 0:
363 print(
"autobuild_model: constructing fragment %s as a bead" % (str((first, last))))
364 parts = self.hier_db.get_particles_at_closest_resolution(name,
369 first+offset, last+offset, missingbeadsize, incoord=xyz)
371 elif g[2] ==
"gap" and n == 0:
373 print(
"autobuild_model: constructing fragment %s as a bead" % (str((first, last))))
375 first+offset, last+offset, missingbeadsize, incoord=xyznter)
382 def autobuild_pdb_and_intervening_beads(self, *args, **kwargs):
383 r = self.autobuild_model(*args, **kwargs)
387 resrange=
None, offset=0, cacenters=
True, show=
False,
388 isnucleicacid=
False, readnonwateratoms=
False,
389 read_ca_cb_only=
False):
391 Add a component that has an associated 3D structure in a PDB file.
393 Reads the PDB, and constructs the fragments corresponding to contiguous
396 @return a list of hierarchies.
398 @param name (string) the name of the component
399 @param pdbname (string) the name of the PDB file
400 @param chain (string or integer) can be either a string (eg, "A")
401 or an integer (eg, 0 or 1) in case you want
402 to get the corresponding chain number in the PDB.
403 @param resolutions (integers) a list of integers that corresponds
404 to the resolutions that have to be generated
405 @param color (float from 0 to 1) the color applied to the
406 hierarchies generated
407 @param resrange (tuple of integers): the residue range to extract
408 from the PDB. It is a tuple (beg,end). If not specified,
409 all residues belonging to the specified chain are read.
410 @param offset (integer) specifies the residue index offset to be
411 applied when reading the PDB (the FASTA sequence is
412 assumed to start from residue 1, so use this parameter
413 if the PDB file does not start at residue 1)
414 @param cacenters (boolean) if True generates resolution=1 beads
415 centered on C-alpha atoms.
416 @param show (boolean) print out the molecular hierarchy at the end.
417 @param isnucleicacid (boolean) use True if you're reading a PDB
419 @param readnonwateratoms (boolean) if True fixes some pathological PDB.
420 @param read_ca_cb_only (boolean) if True, only reads CA/CB
423 self.representation_is_modified =
True
426 color = self.color_dict[name]
427 protein_h = self.hier_dict[name]
437 if type(chain) == str:
445 t.get_children()[0].get_children()[0]).
get_index()
447 t.get_children()[0].get_children()[-1]).
get_index()
448 c =
IMP.atom.Chain(IMP.atom.get_by_type(t, IMP.atom.CHAIN_TYPE)[0])
452 IMP.atom.get_by_type(t, IMP.atom.CHAIN_TYPE)[chain])
459 if not resrange
is None:
460 if resrange[0] > start:
462 if resrange[1] < end:
465 if not isnucleicacid:
469 residue_indexes=list(range(
472 atom_type=IMP.atom.AT_CA)
479 residue_indexes=list(range(
482 atom_type=IMP.atom.AT_P)
484 ps = sel.get_selected_particles()
486 raise ValueError(
"%s no residue found in pdb %s chain %s that overlaps with the queried stretch %s-%s" \
487 % (name, pdbname, str(chain), str(resrange[0]), str(resrange[1])))
495 if par.get_parent() != c0:
496 par.get_parent().remove_child(par)
498 start = start + offset
501 self.elements[name].append(
502 (start, end, pdbname.split(
"/")[-1] +
":" + chain,
"pdb"))
505 resolutions, isnucleicacid, c0, protein_h,
"pdb", color)
506 self._copy_pdb_provenance(t, hiers[0], offset)
508 for p, state
in self._protocol_output:
509 p.add_pdb_element(state, name, start, end, offset, pdbname, chain,
523 for r
in residues.keys():
525 self.m.remove_particle(c0)
531 def _copy_pdb_provenance(self, pdb, h, offset):
532 """Copy the provenance information from the PDB to our hierarchy"""
533 c =
IMP.atom.Chain(IMP.atom.get_by_type(pdb, IMP.atom.CHAIN_TYPE)[0])
540 def add_component_ideal_helix(
548 self.representation_is_modified =
True
549 from math
import pi, cos, sin
551 protein_h = self.hier_dict[name]
554 color = self.color_dict[name]
558 self.elements[name].append((start, end,
" ",
"helix"))
560 for n, res
in enumerate(range(start, end + 1)):
561 if name
in self.sequence_dict:
563 rtstr = self.onetothree[
564 self.sequence_dict[name][res-1]]
584 x = 2.3 * cos(n * 2 * pi / 3.6)
585 y = 2.3 * sin(n * 2 * pi / 3.6)
586 z = 6.2 / 3.6 / 2 * n * 2 * pi / 3.6
595 resolutions,
False, c0, protein_h,
"helix", color)
604 """ add beads to the representation
605 @param name the component name
606 @param ds a list of tuples corresponding to the residue ranges
608 @param colors a list of colors associated to the beads
609 @param incoord the coordinate tuple corresponding to the position
614 self.representation_is_modified =
True
616 protein_h = self.hier_dict[name]
619 colors = [self.color_dict[name]]
622 for n, dss
in enumerate(ds):
623 ds_frag = (dss[0], dss[1])
624 self.elements[name].append((dss[0], dss[1],
" ",
"bead"))
626 if ds_frag[0] == ds_frag[1]:
628 if name
in self.sequence_dict:
630 rtstr = self.onetothree[
631 self.sequence_dict[name][ds_frag[0]-1]]
638 h.set_name(name +
'_%i_bead' % (ds_frag[0]))
639 prt.set_name(name +
'_%i_bead' % (ds_frag[0]))
643 h.set_name(name +
'_%i-%i_bead' % (ds_frag[0], ds_frag[1]))
644 prt.set_name(name +
'_%i-%i_bead' % (ds_frag[0], ds_frag[1]))
645 h.set_residue_indexes(list(range(ds_frag[0], ds_frag[1] + 1)))
646 resolution = len(h.get_residue_indexes())
647 if "Beads" not in self.hier_representation[name]:
649 root.set_name(
"Beads")
650 self.hier_representation[name][
"Beads"] = root
651 protein_h.add_child(root)
652 self.hier_representation[name][
"Beads"].add_child(h)
654 for kk
in range(ds_frag[0], ds_frag[1] + 1):
655 self.hier_db.add_particles(name, kk, resolution, [h])
678 ptem.set_radius(radius)
681 radius = 0.8 * (3.0 / 4.0 / pi * volume) ** (1.0 / 3.0)
683 ptem.set_radius(radius)
685 if not tuple(incoord)
is None:
686 ptem.set_coordinates(incoord)
691 self.floppy_bodies.append(prt)
695 for p, state
in self._protocol_output:
696 p.add_bead_element(state, name, ds[0][0], ds[-1][1], len(ds),
704 Generates a string of beads with given length.
706 self.representation_is_modified =
True
714 [(chunk[0], chunk[-1])], colors=colors,incoord=incoord)
718 self, name, hierarchies=
None, selection_tuples=
None,
720 resolution=0.0, num_components=10,
721 inputfile=
None, outputfile=
None,
724 covariance_type=
'full', voxel_size=1.0,
726 sampled_points=1000000, num_iter=100,
728 multiply_by_total_mass=
True,
730 intermediate_map_fn=
None,
731 density_ps_to_copy=
None,
732 use_precomputed_gaussians=
False):
734 Sets up a Gaussian Mixture Model for this component.
735 Can specify input GMM file or it will be computed.
736 @param name component name
737 @param hierarchies set up GMM for some hierarchies
738 @param selection_tuples (list of tuples) example (first_residue,last_residue,component_name)
739 @param particles set up GMM for particles directly
740 @param resolution usual PMI resolution for selecting particles from the hierarchies
741 @param inputfile read the GMM from this file
742 @param outputfile fit and write the GMM to this file (text)
743 @param outputmap after fitting, create GMM density file (mrc)
744 @param kernel_type for creating the intermediate density (points are sampled to make GMM). Options are IMP.em.GAUSSIAN, IMP.em.SPHERE, and IMP.em.BINARIZED_SPHERE
745 @param covariance_type for fitting the GMM. options are 'full', 'diagonal' and 'spherical'
746 @param voxel_size for creating the intermediate density map and output map.
747 lower number increases accuracy but also rasterizing time grows
748 @param out_hier_name name of the output density hierarchy
749 @param sampled_points number of points to sample. more will increase accuracy and fitting time
750 @param num_iter num GMM iterations. more will increase accuracy and fitting time
751 @param multiply_by_total_mass multiply the weights of the GMM by this value (only works on creation!)
752 @param transform for input file only, apply a transformation (eg for multiple copies same GMM)
753 @param intermediate_map_fn for debugging, this will write the intermediate (simulated) map
754 @param density_ps_to_copy in case you already created the appropriate GMM (eg, for beads)
755 @param use_precomputed_gaussians Set this flag and pass fragments - will use roughly spherical Gaussian setup
763 self.representation_is_modified =
True
765 protein_h = self.hier_dict[name]
766 if "Densities" not in self.hier_representation[name]:
768 root.set_name(
"Densities")
769 self.hier_representation[name][
"Densities"] = root
770 protein_h.add_child(root)
773 fragment_particles = []
774 if not particles
is None:
775 fragment_particles += particles
776 if not hierarchies
is None:
778 self, resolution=resolution,
779 hierarchies=hierarchies)
780 if not selection_tuples
is None:
781 for st
in selection_tuples:
782 fragment_particles += IMP.pmi.tools.select_by_tuple(
783 self, tupleselection=st,
784 resolution=resolution,
785 name_is_ambiguous=
False)
788 density_particles = []
791 inputfile, density_particles,
793 elif density_ps_to_copy:
794 for ip
in density_ps_to_copy:
800 density_particles.append(p)
801 elif use_precomputed_gaussians:
802 if len(fragment_particles) == 0:
803 print(
"add_component_density: no particle was selected")
805 for p
in fragment_particles:
808 raise Exception(
"The particles you selected must be Fragments and XYZs")
810 pos=
IMP.core.XYZ(self.m,p.get_particle_index()).get_coordinates()
815 raise Exception(
"We haven't created a bead file for",nres,
"residues")
822 if len(fragment_particles) == 0:
823 print(
"add_component_density: no particle was selected")
826 density_particles = IMP.isd.gmm_tools.sample_and_fit_to_particles(
835 multiply_by_total_mass,
841 s0.set_name(out_hier_name)
842 self.hier_representation[name][
"Densities"].add_child(s0)
844 for nps, p
in enumerate(density_particles):
846 p.set_name(s0.get_name() +
'_gaussian_%i' % nps)
849 def get_component_density(self, name):
850 return self.hier_representation[name][
"Densities"]
853 selection_tuples=
None,
858 '''Decorates all specified particles as Gaussians directly.
859 @param name component name
860 @param hierarchies set up GMM for some hierarchies
861 @param selection_tuples (list of tuples) example (first_residue,last_residue,component_name)
862 @param particles set up GMM for particles directly
863 @param resolution usual PMI resolution for selecting particles from the hierarchies
869 from math
import sqrt
870 self.representation_is_modified =
True
872 if particles
is None:
873 fragment_particles = []
875 fragment_particles = particles
877 if not hierarchies
is None:
879 self, resolution=resolution,
880 hierarchies=hierarchies)
882 if not selection_tuples
is None:
883 for st
in selection_tuples:
884 fragment_particles += IMP.pmi.tools.select_by_tuple(
885 self, tupleselection=st,
886 resolution=resolution,
887 name_is_ambiguous=
False)
889 if len(fragment_particles) == 0:
890 print(
"add all atom densities: no particle was selected")
894 print(
'setting up all atom gaussians num_particles',len(fragment_particles))
895 for n,p
in enumerate(fragment_particles):
903 print(
'setting up particle',p.get_name(),
" as individual gaussian particle")
905 if not output_map
is None:
906 print(
'writing map to', output_map)
914 Make a copy of a hierarchy and append it to a component.
917 self.representation_is_modified =
True
918 protein_h = self.hier_dict[name]
919 hierclone = IMP.atom.create_clone(hierarchy)
920 hierclone.set_name(hierclone.get_name() +
"_clone")
921 protein_h.add_child(hierclone)
922 outhier.append(hierclone)
928 for n, pmain
in enumerate(psmain):
934 self.hier_db.add_particles(
950 def dump_particle_descriptors(self):
956 particles_attributes={}
957 floppy_body_attributes={}
963 hparent=h.get_parent()
964 while hparent != hroot:
965 hparent=h.get_parent()
966 name+=
"|"+hparent.get_name()
968 particles_attributes[name]={
"COORDINATES":numpy.array(
IMP.core.XYZR(leaf.get_particle()).get_coordinates()),
974 rigid_body_attributes={}
975 for rb
in self.rigid_bodies:
977 rf=rb.get_reference_frame()
978 t=rf.get_transformation_to()
979 trans=t.get_translation()
981 rigid_body_attributes[name]={
"TRANSLATION":numpy.array(trans),
982 "ROTATION":numpy.array(rot.get_quaternion()),
983 "COORDINATES_NONRIGID_MEMBER":{},
984 "COORDINATES_RIGID_MEMBER":{}}
985 for mi
in rb.get_member_indexes():
986 rm=self.m.get_particle(mi)
988 name_part=rm.get_name()
990 rigid_body_attributes[name][
"COORDINATES_NONRIGID_MEMBER"][name_part]=numpy.array(xyz)
992 name_part=rm.get_name()
994 rigid_body_attributes[name][
"COORDINATES_RIGID_MEMBER"][name_part]=numpy.array(xyz)
998 pickle.dump(particles_attributes,
999 open(
"particles_attributes.pkl",
"wb"))
1000 pickle.dump(rigid_body_attributes,
1001 open(
"rigid_body_attributes.pkl",
"wb"))
1005 def load_particle_descriptors(self):
1011 particles_attributes = pickle.load(open(
"particles_attributes.pkl",
1013 rigid_body_attributes = pickle.load(open(
"rigid_body_attributes.pkl",
1023 hparent=h.get_parent()
1024 while hparent != hroot:
1025 hparent=h.get_parent()
1026 name+=
"|"+hparent.get_name()
1030 xyzr.set_coordinates(particles_attributes[name][
"COORDINATES"])
1036 for rb
in self.rigid_bodies:
1038 trans=rigid_body_attributes[name][
"TRANSLATION"]
1039 rot=rigid_body_attributes[name][
"ROTATION"]
1042 rb.set_reference_frame(rf)
1043 coor_nrm_ref=rigid_body_attributes[name][
"COORDINATES_NONRIGID_MEMBER"]
1044 coor_rm_ref_dict=rigid_body_attributes[name][
"COORDINATES_RIGID_MEMBER"]
1047 for mi
in rb.get_member_indexes():
1048 rm=self.m.get_particle(mi)
1050 name_part=rm.get_name()
1051 xyz=coor_nrm_ref[name_part]
1053 self.m.set_attribute(fk, rm,xyz[n])
1055 name_part=rm.get_name()
1057 coor_rm_model.append(
IMP.core.XYZ(rm).get_coordinates())
1058 if len(coor_rm_model)==0:
continue
1064 def _compare_rmf_repr_names(self, rmfname, reprname, component_name):
1065 """Print a warning if particle names in RMF and model don't match"""
1066 def match_any_suffix():
1068 suffixes = [
"pdb",
"bead_floppy_body_rigid_body_member_floppy_body",
1069 "bead_floppy_body_rigid_body_member",
1072 if "%s_%s_%s" % (component_name, rmfname, s) == reprname:
1074 if rmfname != reprname
and not match_any_suffix():
1075 print(
"set_coordinates_from_rmf: WARNING rmf particle and "
1076 "representation particle names don't match %s %s"
1077 % (rmfname, reprname))
1081 rmf_component_name=
None,
1082 check_number_particles=
True,
1083 representation_name_to_rmf_name_map=
None,
1085 skip_gaussian_in_rmf=
False,
1086 skip_gaussian_in_representation=
False,
1088 force_rigid_update=
False):
1089 '''Read and replace coordinates from an RMF file.
1090 Replace the coordinates of particles with the same name.
1091 It assumes that the RMF and the representation have the particles
1093 @param component_name Component name
1094 @param rmf_component_name Name of the component in the RMF file
1095 (if not specified, use `component_name`)
1096 @param representation_name_to_rmf_name_map a dictionary that map
1097 the original rmf particle name to the recipient particle component name
1098 @param save_file: save a file with the names of particles of the component
1099 @param force_rigid_update: update the coordinates of rigid bodies
1100 (normally this should be called before rigid bodies are set up)
1105 prots = IMP.pmi.analysis.get_hiers_from_rmf(
1111 raise ValueError(
"cannot read hierarchy from rmf")
1115 if force_rigid_update:
1126 p, self.hier_dict.keys())
1127 if (protname
is None)
and (rmf_component_name
is not None):
1129 p, rmf_component_name)
1130 if (skip_gaussian_in_rmf):
1133 if (rmf_component_name
is not None)
and (protname == rmf_component_name):
1135 elif (rmf_component_name
is None)
and (protname == component_name):
1139 if (skip_gaussian_in_representation):
1150 reprnames=[p.get_name()
for p
in psrepr]
1151 rmfnames=[p.get_name()
for p
in psrmf]
1154 fl=open(component_name+
".txt",
"w")
1155 for i
in itertools.izip_longest(reprnames,rmfnames): fl.write(str(i[0])+
","+str(i[1])+
"\n")
1158 if check_number_particles
and not representation_name_to_rmf_name_map:
1159 if len(psrmf) != len(psrepr):
1160 fl=open(component_name+
".txt",
"w")
1161 for i
in itertools.izip_longest(reprnames,rmfnames): fl.write(str(i[0])+
","+str(i[1])+
"\n")
1162 raise ValueError(
"%s cannot proceed the rmf and the representation don't have the same number of particles; "
1163 "particles in rmf: %s particles in the representation: %s" % (str(component_name), str(len(psrmf)), str(len(psrepr))))
1166 if not representation_name_to_rmf_name_map:
1167 for n, prmf
in enumerate(psrmf):
1169 prmfname = prmf.get_name()
1170 preprname = psrepr[n].get_name()
1171 if force_rigid_update:
1177 raise ValueError(
"component %s cannot proceed if rigid bodies were initialized. Use the function before defining the rigid bodies" % component_name)
1179 self._compare_rmf_repr_names(prmfname, preprname,
1188 rbm.set_internal_coordinates(xyz)
1190 rb = rbm.get_rigid_body()
1192 raise ValueError(
"Cannot handle nested "
1194 rb.set_reference_frame_lazy(tr)
1201 g=gprmf.get_gaussian()
1202 grepr.set_gaussian(g)
1205 repr_name_particle_map={}
1206 rmf_name_particle_map={}
1208 rmf_name_particle_map[p.get_name()]=p
1212 for prepr
in psrepr:
1214 prmf=rmf_name_particle_map[representation_name_to_rmf_name_map[prepr.get_name()]]
1216 print(
"set_coordinates_from_rmf: WARNING missing particle name in representation_name_to_rmf_name_map, skipping...")
1225 If the root hierarchy does not exist, construct it.
1227 if "Res:" + str(int(resolution))
not in self.hier_representation[name]:
1229 root.set_name(name +
"_Res:" + str(int(resolution)))
1230 self.hier_representation[name][
1231 "Res:" + str(int(resolution))] = root
1232 protein_h.add_child(root)
1235 input_hierarchy, protein_h, type, color):
1237 Generate all needed coarse grained layers.
1239 @param name name of the protein
1240 @param resolutions list of resolutions
1241 @param protein_h root hierarchy
1242 @param input_hierarchy hierarchy to coarse grain
1243 @param type a string, typically "pdb" or "helix"
1247 if (1
in resolutions)
or (0
in resolutions):
1250 if 1
in resolutions:
1253 s1.set_name(
'%s_%i-%i_%s' % (name, start, end, type))
1255 self.hier_representation[name][
"Res:1"].add_child(s1)
1257 if 0
in resolutions:
1260 s0.set_name(
'%s_%i-%i_%s' % (name, start, end, type))
1262 self.hier_representation[name][
"Res:0"].add_child(s0)
1265 if not isnucleicacid:
1268 atom_type=IMP.atom.AT_CA)
1272 atom_type=IMP.atom.AT_P)
1274 for p
in sel.get_selected_particles():
1276 if 0
in resolutions:
1278 resclone0 = IMP.atom.create_clone(resobject)
1280 s0.add_child(resclone0)
1281 self.hier_db.add_particles(
1285 resclone0.get_children())
1287 chil = resclone0.get_children()
1296 if 1
in resolutions:
1298 resclone1 = IMP.atom.create_clone_one(resobject)
1300 s1.add_child(resclone1)
1301 self.hier_db.add_particles(name, resindex, 1, [resclone1])
1305 prt = resclone1.get_particle()
1306 prt.set_name(
'%s_%i_%s' % (name, resindex, type))
1328 for r
in resolutions:
1329 if r != 0
and r != 1:
1335 chil = s.get_children()
1337 s0.set_name(
'%s_%i-%i_%s' % (name, start, end, type))
1342 self.hier_representation[name][
1343 "Res:" + str(int(r))].add_child(s0)
1352 prt.set_name(
'%s_%i_%s' % (name, first, type))
1354 prt.set_name(
'%s_%i_%i_%s' % (name, first, last, type))
1356 self.hier_db.add_particles(name, kk, r, [prt])
1377 Get the hierarchies at the given resolution.
1379 The map between resolution and hierarchies is cached to accelerate
1380 the selection algorithm. The cache is invalidated when the
1381 representation was changed by any add_component_xxx.
1384 if self.representation_is_modified:
1385 rhbr = self.hier_db.get_all_root_hierarchies_by_resolution(
1387 self.hier_resolution[resolution] = rhbr
1388 self.representation_is_modified =
False
1391 if resolution
in self.hier_resolution:
1392 return self.hier_resolution[resolution]
1394 rhbr = self.hier_db.get_all_root_hierarchies_by_resolution(
1396 self.hier_resolution[resolution] = rhbr
1400 self, max_translation=300., max_rotation=2.0 * pi,
1401 avoidcollision=
True, cutoff=10.0, niterations=100,
1403 excluded_rigid_bodies=
None,
1404 ignore_initial_coordinates=
False,
1405 hierarchies_excluded_from_collision=
None):
1407 Shuffle configuration; used to restart the optimization.
1409 The configuration of the system is initialized by placing each
1410 rigid body and each bead randomly in a box with a side of
1411 `max_translation` angstroms, and far enough from each other to
1412 prevent any steric clashes. The rigid bodies are also randomly rotated.
1414 @param avoidcollision check if the particle/rigid body was
1415 placed close to another particle; uses the optional
1416 arguments cutoff and niterations
1417 @param bounding_box defined by ((x1,y1,z1),(x2,y2,z2))
1420 if excluded_rigid_bodies
is None:
1421 excluded_rigid_bodies = []
1422 if hierarchies_excluded_from_collision
is None:
1423 hierarchies_excluded_from_collision = []
1425 if len(self.rigid_bodies) == 0:
1426 print(
"shuffle_configuration: rigid bodies were not intialized")
1429 gcpf.set_distance(cutoff)
1431 hierarchies_excluded_from_collision_indexes = []
1440 if bounding_box
is not None:
1441 ((x1, y1, z1), (x2, y2, z2)) = bounding_box
1446 for h
in hierarchies_excluded_from_collision:
1450 allparticleindexes = list(
1451 set(allparticleindexes) - set(hierarchies_excluded_from_collision_indexes))
1453 print(hierarchies_excluded_from_collision)
1454 print(len(allparticleindexes),len(hierarchies_excluded_from_collision_indexes))
1456 print(
'shuffling', len(self.rigid_bodies) - len(excluded_rigid_bodies),
'rigid bodies')
1457 for rb
in self.rigid_bodies:
1458 if rb
not in excluded_rigid_bodies:
1460 rbindexes = rb.get_member_particle_indexes()
1462 set(rbindexes) - set(hierarchies_excluded_from_collision_indexes))
1463 otherparticleindexes = list(
1464 set(allparticleindexes) - set(rbindexes))
1466 if len(otherparticleindexes)
is None:
1470 while niter < niterations:
1471 if (ignore_initial_coordinates):
1477 if bounding_box
is not None:
1493 gcpf.get_close_pairs(
1495 otherparticleindexes,
1499 if (ignore_initial_coordinates):
1500 print (rb.get_name(),
IMP.core.XYZ(rb).get_coordinates())
1503 print(
"shuffle_configuration: rigid body placed close to other %d particles, trying again..." % npairs)
1504 print(
"shuffle_configuration: rigid body name: " + rb.get_name())
1505 if niter == niterations:
1506 raise ValueError(
"tried the maximum number of iterations to avoid collisions, increase the distance cutoff")
1510 print(
'shuffling', len(self.floppy_bodies),
'floppy bodies')
1511 for fb
in self.floppy_bodies:
1512 if (avoidcollision):
1517 otherparticleindexes = list(
1518 set(allparticleindexes) - set(fbindexes))
1519 if len(otherparticleindexes)
is None:
1537 while niter < niterations:
1538 if (ignore_initial_coordinates):
1544 if bounding_box
is not None:
1556 if (avoidcollision):
1559 gcpf.get_close_pairs(
1561 otherparticleindexes,
1565 if (ignore_initial_coordinates):
1566 print (fb.get_name(),
IMP.core.XYZ(fb).get_coordinates())
1569 print(
"shuffle_configuration: floppy body placed close to other %d particles, trying again..." % npairs)
1570 print(
"shuffle_configuration: floppy body name: " + fb.get_name())
1571 if niter == niterations:
1572 raise ValueError(
"tried the maximum number of iterations to avoid collisions, increase the distance cutoff")
1576 def set_current_coordinates_as_reference_for_rmsd(self, label="None"):
1580 self.reference_structures[label] = (
1584 def get_all_rmsds(self):
1587 for label
in self.reference_structures:
1589 current_coordinates = [
IMP.core.XYZ(p).get_coordinates()
1590 for p
in self.reference_structures[label][1]]
1591 reference_coordinates = self.reference_structures[label][0]
1592 if len(reference_coordinates) != len(current_coordinates):
1593 print(
"calculate_all_rmsds: reference and actual coordinates are not the same")
1596 current_coordinates,
1597 reference_coordinates)
1599 reference_coordinates,
1600 current_coordinates)
1604 reference_coordinates,
1605 current_coordinates)
1606 rmsds[label +
"_GlobalRMSD"] = rmsd_global
1607 rmsds[label +
"_RelativeDRMS"] = rmsd_relative
1610 def setup_component_geometry(self, name, color=None, resolution=1.0):
1612 color = self.color_dict[name]
1616 self.hier_geometry_pairs[name] = []
1617 protein_h = self.hier_dict[name]
1619 pbr = IMP.pmi.tools.sort_by_residues(pbr)
1621 for n
in range(len(pbr) - 1):
1622 self.hier_geometry_pairs[name].append((pbr[n], pbr[n + 1], color))
1625 self, name, resolution=10, scale=1.0):
1627 Generate restraints between contiguous fragments in the hierarchy.
1628 The linkers are generated at resolution 10 by default.
1635 protein_h = self.hier_dict[name]
1637 frs = self.hier_db.get_preroot_fragments_by_resolution(
1643 start = fr.get_children()[0]
1648 end = fr.get_children()[-1]
1654 SortedSegments.append((start, end, startres))
1655 SortedSegments = sorted(SortedSegments, key=itemgetter(2))
1658 for x
in range(len(SortedSegments) - 1):
1659 last = SortedSegments[x][1]
1660 first = SortedSegments[x + 1][0]
1667 residuegap = firstresn - lastresn - 1
1668 if self.disorderedlength
and (nreslast / 2 + nresfirst / 2 + residuegap) > 20.0:
1671 optdist = sqrt(5 / 3) * 1.93 * \
1672 (nreslast / 2 + nresfirst / 2 + residuegap) ** 0.6
1674 if self.upperharmonic:
1680 optdist = (0.0 + (float(residuegap) + 1.0) * 3.6) * scale
1681 if self.upperharmonic:
1687 pt0 = last.get_particle()
1688 pt1 = first.get_particle()
1691 print(
"Adding sequence connectivity restraint between", pt0.get_name(),
" and ", pt1.get_name(),
'of distance', optdist)
1692 sortedsegments_cr.add_restraint(r)
1693 self.linker_restraints_dict[
1694 "LinkerRestraint-" + pt0.get_name() +
"-" + pt1.get_name()] = r
1695 self.connected_intra_pairs.append((pt0, pt1))
1696 self.connected_intra_pairs.append((pt1, pt0))
1698 self.linker_restraints.add_restraint(sortedsegments_cr)
1699 self.linker_restraints.add_restraint(unmodeledregions_cr)
1701 self.sortedsegments_cr_dict[name] = sortedsegments_cr
1702 self.unmodeledregions_cr_dict[name] = unmodeledregions_cr
1704 def optimize_floppy_bodies(self, nsteps, temperature=1.0):
1706 pts = IMP.pmi.tools.ParticleToSampleList()
1707 for n, fb
in enumerate(self.floppy_bodies):
1708 pts.add_particle(fb,
"Floppy_Bodies", 1.0,
"Floppy_Body_" + str(n))
1709 if len(pts.get_particles_to_sample()) > 0:
1711 print(
"optimize_floppy_bodies: optimizing %i floppy bodies" % len(self.floppy_bodies))
1714 print(
"optimize_floppy_bodies: no particle to optimize")
1717 nSymmetry=
None, skip_gaussian_in_clones=
False):
1719 The copies must not contain rigid bodies.
1720 The symmetry restraints are applied at each leaf.
1724 self.representation_is_modified =
True
1725 ncopies = len(copies) + 1
1728 for k
in range(len(copies)):
1729 if (nSymmetry
is None):
1730 rotation_angle = 2.0 * pi / float(ncopies) * float(k + 1)
1733 rotation_angle = 2.0 * pi / float(nSymmetry) * float((k + 2) / 2)
1735 rotation_angle = -2.0 * pi / float(nSymmetry) * float((k + 1) / 2)
1743 for n, p
in enumerate(main_hiers):
1744 if (skip_gaussian_in_clones):
1753 self.m.add_score_state(c)
1754 print(
"Completed setting " + str(maincopy) +
" as a reference for "
1755 + str(copies[k]) +
" by rotating it by "
1756 + str(rotation_angle / 2.0 / pi * 360)
1757 +
" degrees around the " + str(rotational_axis) +
" axis.")
1760 def create_rigid_body_symmetry(self, particles_reference, particles_copy,label="None",
1763 self.representation_is_modified =
True
1765 mainparticles = particles_reference
1767 t=initial_transformation
1769 p.set_name(
"RigidBody_Symmetry")
1775 copyparticles = particles_copy
1779 for n, p
in enumerate(mainparticles):
1781 pc = copyparticles[n]
1783 mainpurged.append(p)
1789 copypurged.append(pc)
1796 for n, p
in enumerate(mainpurged):
1799 print(
"setting " + p.get_name() +
" as reference for " + pc.get_name())
1802 lc.add(pc.get_index())
1805 self.m.add_score_state(c)
1808 self.rigid_bodies.append(rb)
1809 self.rigid_body_symmetries.append(rb)
1810 rb.set_name(label+
".rigid_body_symmetry."+str(len(self.rigid_body_symmetries)))
1813 def create_amyloid_fibril_symmetry(self, maincopy, axial_copies,
1814 longitudinal_copies, axis=(0, 0, 1), translation_value=4.8):
1817 self.representation_is_modified =
True
1820 protein_h = self.hier_dict[maincopy]
1823 for ilc
in range(-longitudinal_copies, longitudinal_copies + 1):
1824 for iac
in range(axial_copies):
1825 copyname = maincopy +
"_a" + str(ilc) +
"_l" + str(iac)
1826 self.create_component(copyname, 0.0)
1827 for hier
in protein_h.get_children():
1829 copyhier = self.hier_dict[copyname]
1830 outhiers.append(copyhier)
1834 2 * pi / axial_copies * (float(iac)))
1835 translation_vector = tuple(
1836 [translation_value * float(ilc) * x
for x
in axis])
1837 print(translation_vector)
1842 for n, p
in enumerate(mainparts):
1849 lc.add(pc.get_index())
1851 self.m.add_score_state(c)
1857 Load coordinates in the current representation.
1858 This should be done only if the hierarchy self.prot is identical
1859 to the one as stored in the rmf i.e. all components were added.
1864 rh = RMF.open_rmf_file_read_only(rmfname)
1872 create the representation (i.e. hierarchies) from the rmf file.
1873 it will be stored in self.prot, which will be overwritten.
1874 load the coordinates from the rmf file at frameindex.
1876 rh = RMF.open_rmf_file_read_only(rmfname)
1882 for p
in self.prot.get_children():
1883 self.create_component(p.get_name())
1884 self.hier_dict[p.get_name()] = p
1886 still missing: save rigid bodies contained in the rmf in self.rigid_bodies
1887 save floppy bodies in self.floppy_bodies
1888 get the connectivity restraints
1893 Construct a rigid body from hierarchies (and optionally particles).
1895 @param hiers list of hierarchies to make rigid
1896 @param particles list of particles to add to the rigid body
1899 if particles
is None:
1902 rigid_parts = set(particles)
1905 print(
"set_rigid_body_from_hierarchies> setting up a new rigid body")
1912 print(
"set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1915 name += hier.get_name() +
"-"
1916 print(
"set_rigid_body_from_hierarchies> adding %s to the rigid body" % hier.get_name())
1918 if len(list(rigid_parts)) != 0:
1920 rb.set_coordinates_are_optimized(
True)
1921 rb.set_name(name +
"rigid_body")
1922 self.rigid_bodies.append(rb)
1926 print(
"set_rigid_body_from_hierarchies> rigid body could not be setup")
1930 Construct a rigid body from a list of subunits.
1932 Each subunit is a tuple that identifies the residue ranges and the
1933 component name (as used in create_component()).
1935 subunits: [(name_1,(first_residue_1,last_residue_1)),(name_2,(first_residue_2,last_residue_2)),.....]
1937 [name_1,name_2,(name_3,(first_residue_3,last_residue_3)),.....]
1939 example: ["prot1","prot2",("prot3",(1,10))]
1941 sometimes, we know about structure of an interaction
1942 and here we make such PPIs rigid
1947 if type(s) == type(tuple())
and len(s) == 2:
1951 residue_indexes=list(range(s[1][0],
1953 if len(sel.get_selected_particles()) == 0:
1954 print(
"set_rigid_bodies: selected particle does not exist")
1955 for p
in sel.get_selected_particles():
1959 print(
"set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1963 elif type(s) == type(str()):
1965 if len(sel.get_selected_particles()) == 0:
1966 print(
"set_rigid_bodies: selected particle does not exist")
1967 for p
in sel.get_selected_particles():
1971 print(
"set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1976 rb.set_coordinates_are_optimized(
True)
1977 rb.set_name(
''.join(str(subunits)) +
"_rigid_body")
1978 self.rigid_bodies.append(rb)
1981 def set_super_rigid_body_from_hierarchies(
1987 super_rigid_xyzs = set()
1988 super_rigid_rbs = set()
1990 print(
"set_super_rigid_body_from_hierarchies> setting up a new SUPER rigid body")
1997 super_rigid_rbs.add(rb)
1999 super_rigid_xyzs.add(p)
2000 print(
"set_rigid_body_from_hierarchies> adding %s to the rigid body" % hier.get_name())
2001 if len(super_rigid_rbs|super_rigid_xyzs) < min_size:
2004 self.super_rigid_bodies.append((super_rigid_xyzs, super_rigid_rbs))
2007 self.super_rigid_bodies.append(
2008 (super_rigid_xyzs, super_rigid_rbs, axis))
2010 def fix_rigid_bodies(self, rigid_bodies):
2011 self.fixed_rigid_bodies += rigid_bodies
2015 self, hiers, min_length=
None, max_length=
None, axis=
None):
2017 Make a chain of super rigid bodies from a list of hierarchies.
2019 Takes a linear list of hierarchies (they are supposed to be
2020 sequence-contiguous) and produces a chain of super rigid bodies
2021 with given length range, specified by min_length and max_length.
2024 hiers = IMP.pmi.tools.flatten_list(hiers)
2028 self.set_super_rigid_body_from_hierarchies(hs, axis, min_length)
2030 def set_super_rigid_bodies(self, subunits, coords=None):
2031 super_rigid_xyzs = set()
2032 super_rigid_rbs = set()
2035 if type(s) == type(tuple())
and len(s) == 3:
2039 residue_indexes=list(range(s[0],
2041 if len(sel.get_selected_particles()) == 0:
2042 print(
"set_rigid_bodies: selected particle does not exist")
2043 for p
in sel.get_selected_particles():
2046 super_rigid_rbs.add(rb)
2048 super_rigid_xyzs.add(p)
2049 elif type(s) == type(str()):
2051 if len(sel.get_selected_particles()) == 0:
2052 print(
"set_rigid_bodies: selected particle does not exist")
2053 for p
in sel.get_selected_particles():
2057 super_rigid_rbs.add(rb)
2059 super_rigid_xyzs.add(p)
2060 self.super_rigid_bodies.append((super_rigid_xyzs, super_rigid_rbs))
2064 Remove leaves of hierarchies from the floppy bodies list based
2065 on the component name
2068 ps=[h.get_particle()
for h
in hs]
2069 for p
in self.floppy_bodies:
2071 if p
in ps: self.floppy_bodies.remove(p)
2072 if p
in hs: self.floppy_bodies.remove(p)
2079 Remove leaves of hierarchies from the floppy bodies list.
2081 Given a list of hierarchies, get the leaves and remove the
2082 corresponding particles from the floppy bodies list. We need this
2083 function because sometimes
2084 we want to constrain the floppy bodies in a rigid body - for instance
2085 when you want to associate a bead with a density particle.
2087 for h
in hierarchies:
2090 if p
in self.floppy_bodies:
2091 print(
"remove_floppy_bodies: removing %s from floppy body list" % p.get_name())
2092 self.floppy_bodies.remove(p)
2095 def set_floppy_bodies(self):
2096 for p
in self.floppy_bodies:
2098 p.set_name(name +
"_floppy_body")
2100 print(
"I'm trying to make this particle flexible although it was assigned to a rigid body", p.get_name())
2103 rb.set_is_rigid_member(p.get_index(),
False)
2106 rb.set_is_rigid_member(p.get_particle_index(),
False)
2107 p.set_name(p.get_name() +
"_rigid_body_member")
2109 def set_floppy_bodies_from_hierarchies(self, hiers):
2114 self.floppy_bodies.append(p)
2121 selection tuples must be [(r1,r2,"name1"),(r1,r2,"name2"),....]
2122 @return the particles
2125 print(selection_tuples)
2126 for s
in selection_tuples:
2127 ps = IMP.pmi.tools.select_by_tuple(
2128 representation=self, tupleselection=tuple(s),
2129 resolution=
None, name_is_ambiguous=
False)
2133 def get_connected_intra_pairs(self):
2134 return self.connected_intra_pairs
2136 def set_rigid_bodies_max_trans(self, maxtrans):
2137 self.maxtrans_rb = maxtrans
2139 def set_rigid_bodies_max_rot(self, maxrot):
2140 self.maxrot_rb = maxrot
2142 def set_super_rigid_bodies_max_trans(self, maxtrans):
2143 self.maxtrans_srb = maxtrans
2145 def set_super_rigid_bodies_max_rot(self, maxrot):
2146 self.maxrot_srb = maxrot
2148 def set_floppy_bodies_max_trans(self, maxtrans):
2149 self.maxtrans_fb = maxtrans
2153 Fix rigid bodies in their actual position.
2154 The get_particles_to_sample() function will return
2155 just the floppy bodies (if they are not fixed).
2157 self.rigidbodiesarefixed = rigidbodiesarefixed
2161 Fix floppy bodies in their actual position.
2162 The get_particles_to_sample() function will return
2163 just the rigid bodies (if they are not fixed).
2165 self.floppybodiesarefixed=floppybodiesarefixed
2167 def draw_hierarchy_graph(self):
2169 print(
"Drawing hierarchy graph for " + c.get_name())
2170 IMP.pmi.output.get_graph_from_hierarchy(c)
2172 def get_geometries(self):
2175 for name
in self.hier_geometry_pairs:
2176 for pt
in self.hier_geometry_pairs[name]:
2190 def setup_bonds(self):
2193 for name
in self.hier_geometry_pairs:
2194 for pt
in self.hier_geometry_pairs[name]:
2209 def show_component_table(self, name):
2210 if name
in self.sequence_dict:
2211 lastresn = len(self.sequence_dict[name])
2214 residues = self.hier_db.get_residue_numbers(name)
2215 firstresn = min(residues)
2216 lastresn = max(residues)
2218 for nres
in range(firstresn, lastresn + 1):
2220 resolutions = self.hier_db.get_residue_resolutions(name, nres)
2222 for r
in resolutions:
2223 ps += self.hier_db.get_particles(name, nres, r)
2224 print(
"%20s %7s" % (name, nres),
" ".join([
"%20s %7s" % (str(p.get_name()),
2227 print(
"%20s %20s" % (name, nres),
"**** not represented ****")
2229 def draw_hierarchy_composition(self):
2231 ks = list(self.elements.keys())
2235 for k
in self.elements:
2236 for l
in self.elements[k]:
2241 self.draw_component_composition(k, max)
2243 def draw_component_composition(self, name, max=1000, draw_pdb_names=False):
2244 from matplotlib
import pyplot
2245 import matplotlib
as mpl
2247 tmplist = sorted(self.elements[k], key=itemgetter(0))
2249 endres = tmplist[-1][1]
2251 print(
"draw_component_composition: missing information for component %s" % name)
2253 fig = pyplot.figure(figsize=(26.0 * float(endres) / max + 2, 2))
2254 ax = fig.add_axes([0.05, 0.475, 0.9, 0.15])
2259 norm = mpl.colors.Normalize(vmin=5, vmax=10)
2263 for n, l
in enumerate(tmplist):
2267 if bounds[-1] != l[0]:
2268 colors.append(
"white")
2271 colors.append(
"#99CCFF")
2273 colors.append(
"#FFFF99")
2275 colors.append(
"#33CCCC")
2277 bounds.append(l[1] + 1)
2280 colors.append(
"#99CCFF")
2282 colors.append(
"#FFFF99")
2284 colors.append(
"#33CCCC")
2286 bounds.append(l[1] + 1)
2288 if bounds[-1] - 1 == l[0]:
2292 colors.append(
"white")
2295 bounds.append(bounds[-1])
2296 colors.append(
"white")
2297 cmap = mpl.colors.ListedColormap(colors)
2298 cmap.set_over(
'0.25')
2299 cmap.set_under(
'0.75')
2301 norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
2302 cb2 = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
2308 spacing=
'proportional',
2309 orientation=
'horizontal')
2318 mid = 1.0 / endres * float(l[0])
2323 l[2], xy=(mid, 1), xycoords=
'axes fraction',
2324 xytext=(mid + 0.025, float(npdb - 1) / 2.0 + 1.5), textcoords=
'axes fraction',
2325 arrowprops=dict(arrowstyle=
"->",
2326 connectionstyle=
"angle,angleA=0,angleB=90,rad=10"),
2328 extra_artists.append(t)
2331 title = ax.text(-0.005, 0.5, k, ha=
"right", va=
"center", rotation=90,
2334 extra_artists.append(title)
2336 labels = len(bounds) * [
" "]
2337 ax.set_xticklabels(labels)
2338 mid = 1.0 / endres * float(bounds[0])
2339 t = ax.annotate(bounds[0], xy=(mid, 0), xycoords=
'axes fraction',
2340 xytext=(mid - 0.01, -0.5), textcoords=
'axes fraction',)
2341 extra_artists.append(t)
2342 offsets = [0, -0.5, -1.0]
2344 for n
in range(1, len(bounds)):
2345 if bounds[n] == bounds[n - 1]:
2347 mid = 1.0 / endres * float(bounds[n])
2348 if (float(bounds[n]) - float(bounds[n - 1])) / max <= 0.01:
2350 offset = offsets[nclashes % 3]
2356 bounds[n], xy=(mid, 0), xycoords=
'axes fraction',
2357 xytext=(mid, -0.5 + offset), textcoords=
'axes fraction')
2360 bounds[n], xy=(mid, 0), xycoords=
'axes fraction',
2361 xytext=(mid, -0.5 + offset), textcoords=
'axes fraction', arrowprops=dict(arrowstyle=
"-"))
2362 extra_artists.append(t)
2364 cb2.add_lines(bounds, [
"black"] * len(bounds), [1] * len(bounds))
2368 k +
"structure.pdf",
2371 bbox_extra_artists=(extra_artists),
2372 bbox_inches=
'tight')
2375 def draw_coordinates_projection(self):
2376 import matplotlib.pyplot
as pp
2379 for name
in self.hier_geometry_pairs:
2380 for pt
in self.hier_geometry_pairs[name]:
2390 xpairs.append([x1, x2])
2391 ypairs.append([y1, y2])
2394 for xends, yends
in zip(xpairs, ypairs):
2399 pp.plot(xlist, ylist,
'b-', alpha=0.1)
2402 def get_prot_name_from_particle(self, particle):
2403 names = self.get_component_names()
2404 particle0 = particle
2406 while not name
in names:
2409 particle0 = h.get_particle()
2413 def get_particles_to_sample(self):
2423 if not self.rigidbodiesarefixed:
2424 for rb
in self.rigid_bodies:
2429 if rb
not in self.fixed_rigid_bodies:
2432 if not self.floppybodiesarefixed:
2433 for fb
in self.floppy_bodies:
2440 for srb
in self.super_rigid_bodies:
2443 rigid_bodies = list(srb[1])
2444 filtered_rigid_bodies = []
2445 for rb
in rigid_bodies:
2446 if rb
not in self.fixed_rigid_bodies:
2447 filtered_rigid_bodies.append(rb)
2448 srbtmp.append((srb[0], filtered_rigid_bodies))
2450 self.rigid_bodies = rbtmp
2451 self.floppy_bodies = fbtmp
2452 self.super_rigid_bodies = srbtmp
2454 ps[
"Rigid_Bodies_SimplifiedModel"] = (
2458 ps[
"Floppy_Bodies_SimplifiedModel"] = (
2461 ps[
"SR_Bodies_SimplifiedModel"] = (
2462 self.super_rigid_bodies,
2467 def set_output_level(self, level):
2468 self.output_level = level
2470 def _evaluate(self, deriv):
2471 """Evaluate the total score of all added restraints"""
2473 return r.evaluate(deriv)
2475 def get_output(self):
2479 output[
"SimplifiedModel_Total_Score_" +
2480 self.label] = str(self._evaluate(
False))
2481 output[
"SimplifiedModel_Linker_Score_" +
2482 self.label] = str(self.linker_restraints.unprotected_evaluate(
None))
2483 for name
in self.sortedsegments_cr_dict:
2484 partialscore = self.sortedsegments_cr_dict[name].evaluate(
False)
2485 score += partialscore
2487 "SimplifiedModel_Link_SortedSegments_" +
2492 partialscore = self.unmodeledregions_cr_dict[name].evaluate(
False)
2493 score += partialscore
2495 "SimplifiedModel_Link_UnmodeledRegions_" +
2500 for rb
in self.rigid_body_symmetries:
2502 output[name +
"_" +self.label]=str(rb.get_reference_frame().get_transformation_to())
2503 for name
in self.linker_restraints_dict:
2508 self.linker_restraints_dict[
2509 name].unprotected_evaluate(
2512 if len(self.reference_structures.keys()) != 0:
2513 rmsds = self.get_all_rmsds()
2516 "SimplifiedModel_" +
2519 self.label] = rmsds[
2522 if self.output_level ==
"high":
2525 output[
"Coordinates_" +
2526 p.get_name() +
"_" + self.label] = str(d)
2528 output[
"_TotalScore"] = str(score)
2531 def get_test_output(self):
2533 output = self.get_output()
2534 for n, p
in enumerate(self.get_particles_to_sample()):
2535 output[
"Particle_to_sample_" + str(n)] = str(p)
2537 output[
"Hierarchy_Dictionary"] = list(self.hier_dict.keys())
2538 output[
"Number_of_floppy_bodies"] = len(self.floppy_bodies)
2539 output[
"Number_of_rigid_bodies"] = len(self.rigid_bodies)
2540 output[
"Number_of_super_bodies"] = len(self.super_rigid_bodies)
2541 output[
"Selection_resolution_1"] = len(
2543 output[
"Selection_resolution_5"] = len(
2545 output[
"Selection_resolution_7"] = len(
2547 output[
"Selection_resolution_10"] = len(
2549 output[
"Selection_resolution_100"] = len(
2552 output[
"Selection_resolution=1"] = len(
2554 output[
"Selection_resolution=1,resid=10"] = len(
2556 for resolution
in self.hier_resolution:
2557 output[
"Hier_resolution_dictionary" +
2558 str(resolution)] = len(self.hier_resolution[resolution])
2559 for name
in self.hier_dict:
2561 "Selection_resolution=1,resid=10,name=" +
2569 "Selection_resolution=1,resid=10,name=" +
2571 ",ambiguous"] = len(
2576 name_is_ambiguous=
True,
2579 "Selection_resolution=1,resid=10,name=" +
2581 ",ambiguous"] = len(
2586 name_is_ambiguous=
True,
2589 "Selection_resolution=1,resrange=(10,20),name=" +
2598 "Selection_resolution=1,resrange=(10,20),name=" +
2600 ",ambiguous"] = len(
2605 name_is_ambiguous=
True,
2609 "Selection_resolution=10,resrange=(10,20),name=" +
2618 "Selection_resolution=10,resrange=(10,20),name=" +
2620 ",ambiguous"] = len(
2625 name_is_ambiguous=
True,
2629 "Selection_resolution=100,resrange=(10,20),name=" +
2638 "Selection_resolution=100,resrange=(10,20),name=" +
2640 ",ambiguous"] = len(
2645 name_is_ambiguous=
True,
def link_components_to_rmf
Load coordinates in the current representation.
Select non water and non hydrogen atoms.
double get_volume_from_residue_type(ResidueType rt)
Return an estimate for the volume of a given residue.
def add_metadata
Associate some metadata with this modeling.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
A decorator to associate a particle with a part of a protein/DNA/RNA.
static Gaussian setup_particle(Model *m, ParticleIndex pi)
void show_molecular_hierarchy(Hierarchy h)
Print out the molecular hierarchy.
double get_drms(const Vector3DsOrXYZs0 &m1, const Vector3DsOrXYZs1 &m2)
Apply a SingletonFunction to a SingletonContainer to maintain an invariant.
atom::Hierarchies create_hierarchies(RMF::FileConstHandle fh, Model *m)
def shuffle_configuration
Shuffle configuration; used to restart the optimization.
A member of a rigid body, it has internal (local) coordinates.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Set of python classes to create a multi-state, multi-resolution IMP hierarchy.
static Provenanced setup_particle(Model *m, ParticleIndex pi, Provenance p)
static Atom setup_particle(Model *m, ParticleIndex pi, Atom other)
static Fragment setup_particle(Model *m, ParticleIndex pi)
Upper bound harmonic function (non-zero when feature > mean)
static Symmetric setup_particle(Model *m, ParticleIndex pi, Float symmetric)
def set_coordinates_from_rmf
Read and replace coordinates from an RMF file.
static XYZR setup_particle(Model *m, ParticleIndex pi)
A decorator for a particle which has bonds.
Select atoms which are selected by both selectors.
Rotation3D get_random_rotation_3d(const Rotation3D ¢er, double distance)
Pick a rotation at random near the provided one.
double get_mass(ResidueType c)
Get the mass from the residue type.
def create_non_modeled_component
Create a component that isn't used in the modeling.
Color get_rgb_color(double f)
Return the color for f from the RGB color map.
double get_mass_from_number_of_residues(unsigned int num_aa)
Estimate the mass of a protein from the number of amino acids.
Provenance create_clone(Provenance p)
Clone provenance (including previous provenance)
def set_rigid_bodies_as_fixed
Fix rigid bodies in their actual position.
def get_particles_from_selection_tuples
selection tuples must be [(r1,r2,"name1"),(r1,r2,"name2"),....
Add symmetric attribute to a particle.
double get_ball_radius_from_volume_3d(double volume)
Return the radius of a sphere with a given volume.
def setup_component_sequence_connectivity
Generate restraints between contiguous fragments in the hierarchy.
def create_rotational_symmetry
The copies must not contain rigid bodies.
Add uncertainty to a particle.
A score on the distance between the surfaces of two spheres.
static Residue setup_particle(Model *m, ParticleIndex pi, ResidueType t, int index, int insertion_code)
static bool get_is_setup(const IMP::ParticleAdaptor &p)
static bool get_is_setup(const IMP::ParticleAdaptor &p)
static XYZ setup_particle(Model *m, ParticleIndex pi)
void read_pdb(TextInput input, int model, Hierarchy h)
def remove_floppy_bodies
Remove leaves of hierarchies from the floppy bodies list.
Vector3D get_random_vector_in(const Cylinder3D &c)
Generate a random vector in a cylinder with uniform density.
static Uncertainty setup_particle(Model *m, ParticleIndex pi, Float uncertainty)
def remove_floppy_bodies_from_component
Remove leaves of hierarchies from the floppy bodies list based on the component name.
Add resolution to a particle.
Bond create_bond(Bonded a, Bonded b, Bond o)
Connect the two wrapped particles by a custom bond.
Object used to hold a set of restraints.
static Molecule setup_particle(Model *m, ParticleIndex pi)
Rotation3D get_rotation_about_axis(const Vector3D &axis, double angle)
Generate a Rotation3D object from a rotation around an axis.
Class for storing model, its restraints, constraints, and particles.
def create_transformed_component
Create a transformed view of a component.
Select all CB ATOM records.
A Gaussian distribution in 3D.
static bool get_is_setup(Model *m, ParticleIndex pi)
static Hierarchy setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor children=ParticleIndexesAdaptor())
Create a Hierarchy of level t by adding the needed attributes.
ParticleIndexPairs get_indexes(const ParticlePairsTemp &ps)
def set_rigid_bodies
Construct a rigid body from a list of subunits.
double get_volume_from_mass(double m, ProteinDensityReference ref=ALBER)
Estimate the volume of a protein from its mass.
The standard decorator for manipulating molecular structures.
Ints get_index(const ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
Store a list of ParticleIndexes.
def deprecated_method
Python decorator to mark a method as deprecated.
A decorator for a particle representing an atom.
void transform(XYZ a, const algebra::Transformation3D &tr)
Apply a transformation to the particle.
static Mass setup_particle(Model *m, ParticleIndex pi, Float mass)
static Bonded setup_particle(Model *m, ParticleIndex pi)
def add_protocol_output
Capture details of the modeling protocol.
static bool get_is_setup(Model *m, ParticleIndex pi)
double get_rmsd(const Vector3DsOrXYZs0 &m1, const Vector3DsOrXYZs1 &m2)
def add_all_atom_densities
Decorates all specified particles as Gaussians directly.
def coarse_hierarchy
Generate all needed coarse grained layers.
def add_component_pdb
Add a component that has an associated 3D structure in a PDB file.
Track creation of a system fragment from a PDB file.
Basic utilities for handling cryo-electron microscopy 3D density maps.
void load_frame(RMF::FileConstHandle file, RMF::FrameID frame)
Load the given RMF frame into the state of the linked objects.
A decorator for a particle with x,y,z coordinates.
static bool get_is_setup(Model *m, ParticleIndex pi)
static Colored setup_particle(Model *m, ParticleIndex pi, Color color)
def set_chain_of_super_rigid_bodies
Make a chain of super rigid bodies from a list of hierarchies.
def add_component_sequence
Add the primary sequence for a single component.
Tools for clustering and cluster analysis.
static Resolution setup_particle(Model *m, ParticleIndex pi, Float resolution)
def create_components_from_rmf
still not working.
Transformation3D get_identity_transformation_3d()
Return a transformation that does not do anything.
Find all nearby pairs by testing all pairs.
Classes for writing output files and processing them.
Simple implementation of segments in 3D.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
A decorator for a residue.
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...
static bool get_is_setup(const IMP::ParticleAdaptor &p)
def add_component_density
Sets up a Gaussian Mixture Model for this component.
Sample using Monte Carlo.
The general base class for IMP exceptions.
Hierarchy create_simplified_along_backbone(Chain input, const IntRanges &residue_segments, bool keep_detailed=false)
def get_file_dataset
Get the dataset associated with a filename, or None.
IMP::core::RigidBody create_rigid_body(Hierarchy h)
static Reference setup_particle(Model *m, ParticleIndex pi, ParticleIndexAdaptor reference)
Rotation3D get_identity_rotation_3d()
Return a rotation that does not do anything.
void link_hierarchies(RMF::FileConstHandle fh, const atom::Hierarchies &hs)
Class to handle individual particles of a Model object.
Bond get_bond(Bonded a, Bonded b)
Get the bond between two particles.
std::string get_data_path(std::string file_name)
Return the full path to one of this module's data files.
Select atoms which are selected by either or both selectors.
def get_hierarchies_at_given_resolution
Get the hierarchies at the given resolution.
Store info for a chain of a protein.
Applies a PairScore to a Pair.
Select all CA ATOM records.
Python classes to represent, score, sample and analyze models.
static bool get_is_setup(Model *m, ParticleIndex pi)
double get_resolution(Model *m, ParticleIndex pi)
Estimate the resolution of the hierarchy as used by Representation.
A decorator for a rigid body.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
A dictionary-like wrapper for reading and storing sequence data.
Transformation3D get_transformation_aligning_first_to_second(Vector3Ds a, Vector3Ds b)
Output IMP model data in various file formats.
Functionality for loading, creating, manipulating and scoring atomic structures.
Tag part of the system to track how it was created.
static Chain setup_particle(Model *m, ParticleIndex pi, std::string id)
Hierarchies get_leaves(const Selection &h)
def add_component_necklace
Generates a string of beads with given length.
An exception for an invalid value being passed to IMP.
def set_file_dataset
Associate a dataset with a filename.
def set_floppy_bodies_as_fixed
Fix floppy bodies in their actual position.
Select hierarchy particles identified by the biological name.
static RigidBody setup_particle(Model *m, ParticleIndex pi, ParticleIndexesAdaptor ps)
Select all ATOM and HETATM records with the given chain ids.
Support for the RMF file format for storing hierarchical molecular data and markup.
static bool get_is_setup(Model *m, ParticleIndex pi)
def set_rigid_body_from_hierarchies
Construct a rigid body from hierarchies (and optionally particles).
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Transformation3D get_random_local_transformation(Vector3D origin, double max_translation=5., double max_angle_in_rad=0.26)
Get a local transformation.
def check_root
If the root hierarchy does not exist, construct it.
def add_component_beads
add beads to the representation
Inferential scoring building on methods developed as part of the Inferential Structure Determination ...
def add_component_hierarchy_clone
Make a copy of a hierarchy and append it to a component.
Harmonic function (symmetric about the mean)
A decorator for a particle with x,y,z coordinates and a radius.