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 Representation(object):
38 Set up the representation of all proteins and nucleic acid macromolecules.
40 Create the molecular hierarchies, representation,
41 sequence connectivity for the various involved proteins and
42 nucleic acid macromolecules:
44 Create a protein, DNA or RNA, represent it as a set of connected balls of appropriate
45 radii and number of residues, PDB at given resolution(s), or ideal helices.
47 How to use the SimplifiedModel class (typical use):
49 see test/test_hierarchy_contruction.py
53 1) Create a chain of helices and flexible parts
55 c_1_119 =self.add_component_necklace("prot1",1,119,20)
56 c_120_131 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(120,131))
57 c_132_138 =self.add_component_beads("prot1",[(132,138)])
58 c_139_156 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(139,156))
59 c_157_174 =self.add_component_beads("prot1",[(157,174)])
60 c_175_182 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(175,182))
61 c_183_194 =self.add_component_beads("prot1",[(183,194)])
62 c_195_216 =self.add_component_ideal_helix("prot1",resolutions=[1,10],resrange=(195,216))
63 c_217_250 =self.add_component_beads("prot1",[(217,250)])
66 self.set_rigid_body_from_hierarchies(c_120_131)
67 self.set_rigid_body_from_hierarchies(c_139_156)
68 self.set_rigid_body_from_hierarchies(c_175_182)
69 self.set_rigid_body_from_hierarchies(c_195_216)
71 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,
74 self.set_chain_of_super_rigid_bodies(clist,2,3)
76 self.set_super_rigid_bodies(["prot1"])
80 def __init__(self, m, upperharmonic=True, disorderedlength=True):
83 @param upperharmonic This flag uses either harmonic (False)
84 or upperharmonic (True) in the intra-pair
85 connectivity restraint.
86 @param disorderedlength This flag uses either disordered length
87 calculated for random coil peptides (True) or zero
88 surface-to-surface distance between beads (False)
89 as optimal distance for the sequence connectivity
94 self._file_dataset = {}
95 self._protocol_output = []
104 self.upperharmonic = upperharmonic
105 self.disorderedlength = disorderedlength
106 self.rigid_bodies = []
107 self.fixed_rigid_bodies = []
108 self.fixed_floppy_bodies = []
109 self.floppy_bodies = []
115 self.super_rigid_bodies = []
116 self.rigid_body_symmetries = []
117 self.output_level =
"low"
120 self.maxtrans_rb = 2.0
121 self.maxrot_rb = 0.04
122 self.maxtrans_srb = 2.0
123 self.maxrot_srb = 0.2
124 self.rigidbodiesarefixed =
False
125 self.floppybodiesarefixed =
False
126 self.maxtrans_fb = 3.0
127 self.resolution = 10.0
128 self.bblenght = 100.0
132 self.representation_is_modified =
False
133 self.unmodeledregions_cr_dict = {}
134 self.sortedsegments_cr_dict = {}
136 self.connected_intra_pairs = []
139 self.sequence_dict = {}
140 self.hier_geometry_pairs = {}
146 self.hier_representation = {}
147 self.hier_resolution = {}
150 self.reference_structures = {}
153 self.linker_restraints_dict = {}
154 self.threetoone = {
'ALA':
'A',
'ARG':
'R', 'ASN': 'N', 'ASP': 'D',
155 'CYS':
'C',
'GLU':
'E',
'GLN':
'Q',
'GLY':
'G',
156 'HIS':
'H',
'ILE':
'I',
'LEU':
'L',
'LYS':
'K',
157 'MET':
'M',
'PHE':
'F',
'PRO':
'P',
'SER':
'S',
158 'THR':
'T',
'TRP':
'W',
'TYR':
'Y',
'VAL':
'V',
'UNK':
'X'}
160 self.onetothree = dict((v, k)
for k, v
in self.threetoone.items())
165 """Associate some metadata with this modeling.
166 @param m an instance of IMP.pmi.metadata.Metadata or a subclass.
168 self._metadata.append(m)
171 """Associate a dataset with a filename.
172 This can be used to identify how the file was produced (in many
173 cases IMP can determine this automatically from a file header or
174 other metadata, but not always). For example, a manually-produced
175 PDB file (not from the PDB database or Modeller) can be
177 @param fname filename
178 @dataset the IMP.pmi.metadata.Dataset object to associate.
180 self._file_dataset[os.path.abspath(fname)] = dataset
183 """Get the dataset associated with a filename, or None.
184 @param fname filename
185 @return an IMP.pmi.metadata.Dataset, or None.
187 return self._file_dataset.get(os.path.abspath(fname),
None)
190 """Capture details of the modeling protocol.
191 @param p an instance of IMP.pmi.output.ProtocolOutput or a subclass.
193 self._protocol_output.append(p)
194 p._metadata = self._metadata
195 p._file_dataset = self._file_dataset
199 p._representation = weakref.proxy(self)
200 protocol_output = property(
lambda self: self._protocol_output[:])
202 def set_label(self, label):
205 def create_component(self, name, color=0.0):
207 protein_h.set_name(name)
208 self.hier_dict[name] = protein_h
209 self.hier_representation[name] = {}
210 self.hier_db.add_name(name)
211 self.prot.add_child(protein_h)
212 self.color_dict[name] = color
213 self.elements[name] = []
214 for p
in self._protocol_output:
215 p.create_component(name,
True)
218 """Create a component that isn't used in the modeling.
219 No coordinates or other structural data for this component will
220 be read or written, but a primary sequence can be assigned. This
221 is useful if the input experimental data is of a system larger
222 than that modeled. Any references to these non-modeled components
223 can then be correctly resolved later."""
224 self.elements[name] = []
225 for p
in self._protocol_output:
226 p.create_component(name,
False)
231 def add_component_name(self, *args, **kwargs):
232 self.create_component(*args, **kwargs)
234 def get_component_names(self):
235 return list(self.hier_dict.keys())
240 Add the primary sequence for a single component.
242 @param name Human-readable name of the component
243 @param filename Name of the FASTA file
244 @param id Identifier of the sequence in the FASTA file header
245 (if not provided, use `name` instead)
250 if id
not in record_dict:
251 raise KeyError(
"id %s not found in fasta file" % id)
252 length = len(record_dict[id])
253 self.sequence_dict[name] = str(record_dict[id])
256 self.sequence_dict[name]=offs_str+self.sequence_dict[name]
258 self.elements[name].append((length, length,
" ",
"end"))
259 for p
in self._protocol_output:
260 p.add_component_sequence(name, self.sequence_dict[name])
262 def autobuild_model(self, name, pdbname, chain,
263 resolutions=
None, resrange=
None,
265 color=
None, pdbresrange=
None, offset=0,
266 show=
False, isnucleicacid=
False,
269 self.representation_is_modified =
True
273 color = self.color_dict[name]
275 self.color_dict[name] = color
277 if resolutions
is None:
279 print(
"autobuild_model: constructing %s from pdb %s and chain %s" % (name, pdbname, str(chain)))
288 t.get_children()[0].get_children()[0]).
get_index()
290 t.get_children()[0].get_children()[-1]).
get_index()
296 if name
in self.sequence_dict:
297 resrange = (1, len(self.sequence_dict[name]))
299 resrange = (start + offset, end + offset)
301 if resrange[1]
in (-1,
'END'):
302 resrange = (resrange[0],end)
303 start = resrange[0] - offset
304 end = resrange[1] - offset
323 for n, g
in enumerate(gaps):
327 print(
"autobuild_model: constructing fragment %s from pdb" % (str((first, last))))
329 chain, resolutions=resolutions,
330 color=color, cacenters=
True,
331 resrange=(first, last),
332 offset=offset, isnucleicacid=isnucleicacid)
333 elif g[2] ==
"gap" and n > 0:
334 print(
"autobuild_model: constructing fragment %s as a bead" % (str((first, last))))
335 parts = self.hier_db.get_particles_at_closest_resolution(name,
340 first+offset, last+offset, missingbeadsize, incoord=xyz)
342 elif g[2] ==
"gap" and n == 0:
344 print(
"autobuild_model: constructing fragment %s as a bead" % (str((first, last))))
346 first+offset, last+offset, missingbeadsize, incoord=xyznter)
353 def autobuild_pdb_and_intervening_beads(self, *args, **kwargs):
354 r = self.autobuild_model(*args, **kwargs)
358 resrange=
None, offset=0, cacenters=
True, show=
False,
359 isnucleicacid=
False, readnonwateratoms=
False,
360 read_ca_cb_only=
False):
362 Add a component that has an associated 3D structure in a PDB file.
364 Reads the PDB, and constructs the fragments corresponding to contiguous
367 @return a list of hierarchies.
369 @param name (string) the name of the component
370 @param pdbname (string) the name of the PDB file
371 @param chain (string or integer) can be either a string (eg, "A")
372 or an integer (eg, 0 or 1) in case you want
373 to get the corresponding chain number in the PDB.
374 @param resolutions (integers) a list of integers that corresponds
375 to the resolutions that have to be generated
376 @param color (float from 0 to 1) the color applied to the
377 hierarchies generated
378 @param resrange (tuple of integers): the residue range to extract
379 from the PDB. It is a tuple (beg,end). If not specified,
380 all residues belonging to the specified chain are read.
381 @param offset (integer) specifies the residue index offset to be
382 applied when reading the PDB (the FASTA sequence is
383 assumed to start from residue 1, so use this parameter
384 if the PDB file does not start at residue 1)
385 @param cacenters (boolean) if True generates resolution=1 beads
386 centered on C-alpha atoms.
387 @param show (boolean) print out the molecular hierarchy at the end.
388 @param isnucleicacid (boolean) use True if you're reading a PDB
390 @param readnonwateratoms (boolean) if True fixes some pathological PDB.
391 @param read_ca_cb_only (boolean) if True, only reads CA/CB
394 self.representation_is_modified =
True
397 color = self.color_dict[name]
398 protein_h = self.hier_dict[name]
408 if type(chain) == str:
416 t.get_children()[0].get_children()[0]).
get_index()
418 t.get_children()[0].get_children()[-1]).
get_index()
419 c =
IMP.atom.Chain(IMP.atom.get_by_type(t, IMP.atom.CHAIN_TYPE)[0])
423 IMP.atom.get_by_type(t, IMP.atom.CHAIN_TYPE)[chain])
430 if not resrange
is None:
431 if resrange[0] > start:
433 if resrange[1] < end:
436 if not isnucleicacid:
440 residue_indexes=list(range(
443 atom_type=IMP.atom.AT_CA)
450 residue_indexes=list(range(
453 atom_type=IMP.atom.AT_P)
455 ps = sel.get_selected_particles()
457 raise ValueError(
"%s no residue found in pdb %s chain %s that overlaps with the queried stretch %s-%s" \
458 % (name, pdbname, str(chain), str(resrange[0]), str(resrange[1])))
466 if par.get_parent() != c0:
467 par.get_parent().remove_child(par)
469 start = start + offset
472 self.elements[name].append(
473 (start, end, pdbname.split(
"/")[-1] +
":" + chain,
"pdb"))
476 resolutions, isnucleicacid, c0, protein_h,
"pdb", color)
478 for p
in self._protocol_output:
479 p.add_pdb_element(name, start, end, offset, pdbname, chain,
493 for r
in residues.keys():
495 self.m.remove_particle(c0)
501 def add_component_ideal_helix(
509 self.representation_is_modified =
True
510 from math
import pi, cos, sin
512 protein_h = self.hier_dict[name]
515 color = self.color_dict[name]
519 self.elements[name].append((start, end,
" ",
"helix"))
521 for n, res
in enumerate(range(start, end + 1)):
522 if name
in self.sequence_dict:
524 rtstr = self.onetothree[
525 self.sequence_dict[name][res-1]]
545 x = 2.3 * cos(n * 2 * pi / 3.6)
546 y = 2.3 * sin(n * 2 * pi / 3.6)
547 z = 6.2 / 3.6 / 2 * n * 2 * pi / 3.6
556 resolutions,
False, c0, protein_h,
"helix", color)
565 """ add beads to the representation
566 @param name the component name
567 @param ds a list of tuples corresponding to the residue ranges
569 @param colors a list of colors associated to the beads
570 @param incoord the coordinate tuple corresponding to the position
575 self.representation_is_modified =
True
577 protein_h = self.hier_dict[name]
580 colors = [self.color_dict[name]]
583 for n, dss
in enumerate(ds):
584 ds_frag = (dss[0], dss[1])
585 self.elements[name].append((dss[0], dss[1],
" ",
"bead"))
587 if ds_frag[0] == ds_frag[1]:
589 if name
in self.sequence_dict:
591 rtstr = self.onetothree[
592 self.sequence_dict[name][ds_frag[0]-1]]
599 h.set_name(name +
'_%i_bead' % (ds_frag[0]))
600 prt.set_name(name +
'_%i_bead' % (ds_frag[0]))
604 h.set_name(name +
'_%i-%i_bead' % (ds_frag[0], ds_frag[1]))
605 prt.set_name(name +
'_%i-%i_bead' % (ds_frag[0], ds_frag[1]))
606 h.set_residue_indexes(list(range(ds_frag[0], ds_frag[1] + 1)))
607 resolution = len(h.get_residue_indexes())
608 if "Beads" not in self.hier_representation[name]:
610 root.set_name(
"Beads")
611 self.hier_representation[name][
"Beads"] = root
612 protein_h.add_child(root)
613 self.hier_representation[name][
"Beads"].add_child(h)
615 for kk
in range(ds_frag[0], ds_frag[1] + 1):
616 self.hier_db.add_particles(name, kk, resolution, [h])
639 ptem.set_radius(radius)
642 radius = 0.8 * (3.0 / 4.0 / pi * volume) ** (1.0 / 3.0)
644 ptem.set_radius(radius)
646 if not tuple(incoord)
is None:
647 ptem.set_coordinates(incoord)
652 self.floppy_bodies.append(prt)
656 for p
in self._protocol_output:
657 p.add_bead_element(name, ds[0][0], ds[-1][1], len(ds), outhiers[0])
664 Generates a string of beads with given length.
666 self.representation_is_modified =
True
674 [(chunk[0], chunk[-1])], colors=colors,incoord=incoord)
678 self, name, hierarchies=
None, selection_tuples=
None,
680 resolution=0.0, num_components=10,
681 inputfile=
None, outputfile=
None,
684 covariance_type=
'full', voxel_size=1.0,
686 sampled_points=1000000, num_iter=100,
688 multiply_by_total_mass=
True,
690 intermediate_map_fn=
None,
691 density_ps_to_copy=
None,
692 use_precomputed_gaussians=
False):
694 Sets up a Gaussian Mixture Model for this component.
695 Can specify input GMM file or it will be computed.
696 @param name component name
697 @param hierarchies set up GMM for some hierarchies
698 @param selection_tuples (list of tuples) example (first_residue,last_residue,component_name)
699 @param particles set up GMM for particles directly
700 @param resolution usual PMI resolution for selecting particles from the hierarchies
701 @param inputfile read the GMM from this file
702 @param outputfile fit and write the GMM to this file (text)
703 @param outputmap after fitting, create GMM density file (mrc)
704 @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
705 @param covariance_type for fitting the GMM. options are 'full', 'diagonal' and 'spherical'
706 @param voxel_size for creating the intermediate density map and output map.
707 lower number increases accuracy but also rasterizing time grows
708 @param out_hier_name name of the output density hierarchy
709 @param sampled_points number of points to sample. more will increase accuracy and fitting time
710 @param num_iter num GMM iterations. more will increase accuracy and fitting time
711 @param multiply_by_total_mass multiply the weights of the GMM by this value (only works on creation!)
712 @param transform for input file only, apply a transformation (eg for multiple copies same GMM)
713 @param intermediate_map_fn for debugging, this will write the intermediate (simulated) map
714 @param density_ps_to_copy in case you already created the appropriate GMM (eg, for beads)
715 @param use_precomputed_gaussians Set this flag and pass fragments - will use roughly spherical Gaussian setup
723 self.representation_is_modified =
True
725 protein_h = self.hier_dict[name]
726 if "Densities" not in self.hier_representation[name]:
728 root.set_name(
"Densities")
729 self.hier_representation[name][
"Densities"] = root
730 protein_h.add_child(root)
733 fragment_particles = []
734 if not particles
is None:
735 fragment_particles += particles
736 if not hierarchies
is None:
738 self, resolution=resolution,
739 hierarchies=hierarchies)
740 if not selection_tuples
is None:
741 for st
in selection_tuples:
742 fragment_particles += IMP.pmi.tools.select_by_tuple(
743 self, tupleselection=st,
744 resolution=resolution,
745 name_is_ambiguous=
False)
748 density_particles = []
751 inputfile, density_particles,
753 elif density_ps_to_copy:
754 for ip
in density_ps_to_copy:
760 density_particles.append(p)
761 elif use_precomputed_gaussians:
762 if len(fragment_particles) == 0:
763 print(
"add_component_density: no particle was selected")
765 for p
in fragment_particles:
768 raise Exception(
"The particles you selected must be Fragments and XYZs")
770 pos=
IMP.core.XYZ(self.m,p.get_particle_index()).get_coordinates()
775 raise Exception(
"We haven't created a bead file for",nres,
"residues")
782 if len(fragment_particles) == 0:
783 print(
"add_component_density: no particle was selected")
786 density_particles = IMP.isd.gmm_tools.sample_and_fit_to_particles(
795 multiply_by_total_mass,
801 s0.set_name(out_hier_name)
802 self.hier_representation[name][
"Densities"].add_child(s0)
804 for nps, p
in enumerate(density_particles):
806 p.set_name(s0.get_name() +
'_gaussian_%i' % nps)
809 def get_component_density(self, name):
810 return self.hier_representation[name][
"Densities"]
813 selection_tuples=
None,
818 '''Decorates all specified particles as Gaussians directly.
819 @param name component name
820 @param hierarchies set up GMM for some hierarchies
821 @param selection_tuples (list of tuples) example (first_residue,last_residue,component_name)
822 @param particles set up GMM for particles directly
823 @param resolution usual PMI resolution for selecting particles from the hierarchies
829 from math
import sqrt
830 self.representation_is_modified =
True
832 if particles
is None:
833 fragment_particles = []
835 fragment_particles = particles
837 if not hierarchies
is None:
839 self, resolution=resolution,
840 hierarchies=hierarchies)
842 if not selection_tuples
is None:
843 for st
in selection_tuples:
844 fragment_particles += IMP.pmi.tools.select_by_tuple(
845 self, tupleselection=st,
846 resolution=resolution,
847 name_is_ambiguous=
False)
849 if len(fragment_particles) == 0:
850 print(
"add all atom densities: no particle was selected")
854 print(
'setting up all atom gaussians num_particles',len(fragment_particles))
855 for n,p
in enumerate(fragment_particles):
863 print(
'setting up particle',p.get_name(),
" as individual gaussian particle")
865 if not output_map
is None:
866 print(
'writing map to', output_map)
874 Make a copy of a hierarchy and append it to a component.
877 self.representation_is_modified =
True
878 protein_h = self.hier_dict[name]
879 hierclone = IMP.atom.create_clone(hierarchy)
880 hierclone.set_name(hierclone.get_name() +
"_clone")
881 protein_h.add_child(hierclone)
882 outhier.append(hierclone)
888 for n, pmain
in enumerate(psmain):
894 self.hier_db.add_particles(
910 def dump_particle_descriptors(self):
916 particles_attributes={}
917 floppy_body_attributes={}
923 hparent=h.get_parent()
924 while hparent != hroot:
925 hparent=h.get_parent()
926 name+=
"|"+hparent.get_name()
928 particles_attributes[name]={
"COORDINATES":numpy.array(
IMP.core.XYZR(leaf.get_particle()).get_coordinates()),
934 rigid_body_attributes={}
935 for rb
in self.rigid_bodies:
937 rf=rb.get_reference_frame()
938 t=rf.get_transformation_to()
939 trans=t.get_translation()
941 rigid_body_attributes[name]={
"TRANSLATION":numpy.array(trans),
942 "ROTATION":numpy.array(rot.get_quaternion()),
943 "COORDINATES_NONRIGID_MEMBER":{},
944 "COORDINATES_RIGID_MEMBER":{}}
945 for mi
in rb.get_member_indexes():
946 rm=self.m.get_particle(mi)
948 name_part=rm.get_name()
950 rigid_body_attributes[name][
"COORDINATES_NONRIGID_MEMBER"][name_part]=numpy.array(xyz)
952 name_part=rm.get_name()
954 rigid_body_attributes[name][
"COORDINATES_RIGID_MEMBER"][name_part]=numpy.array(xyz)
958 pickle.dump(particles_attributes,
959 open(
"particles_attributes.pkl",
"wb"))
960 pickle.dump(rigid_body_attributes,
961 open(
"rigid_body_attributes.pkl",
"wb"))
965 def load_particle_descriptors(self):
971 particles_attributes = pickle.load(open(
"particles_attributes.pkl",
973 rigid_body_attributes = pickle.load(open(
"rigid_body_attributes.pkl",
983 hparent=h.get_parent()
984 while hparent != hroot:
985 hparent=h.get_parent()
986 name+=
"|"+hparent.get_name()
990 xyzr.set_coordinates(particles_attributes[name][
"COORDINATES"])
996 for rb
in self.rigid_bodies:
998 trans=rigid_body_attributes[name][
"TRANSLATION"]
999 rot=rigid_body_attributes[name][
"ROTATION"]
1002 rb.set_reference_frame(rf)
1003 coor_nrm_ref=rigid_body_attributes[name][
"COORDINATES_NONRIGID_MEMBER"]
1004 coor_rm_ref_dict=rigid_body_attributes[name][
"COORDINATES_RIGID_MEMBER"]
1007 for mi
in rb.get_member_indexes():
1008 rm=self.m.get_particle(mi)
1010 name_part=rm.get_name()
1011 xyz=coor_nrm_ref[name_part]
1013 self.m.set_attribute(fk, rm,xyz[n])
1015 name_part=rm.get_name()
1017 coor_rm_model.append(
IMP.core.XYZ(rm).get_coordinates())
1018 if len(coor_rm_model)==0:
continue
1024 def _compare_rmf_repr_names(self, rmfname, reprname, component_name):
1025 """Print a warning if particle names in RMF and model don't match"""
1026 def match_any_suffix():
1028 suffixes = [
"pdb",
"bead_floppy_body_rigid_body_member_floppy_body",
1029 "bead_floppy_body_rigid_body_member",
1032 if "%s_%s_%s" % (component_name, rmfname, s) == reprname:
1034 if rmfname != reprname
and not match_any_suffix():
1035 print(
"set_coordinates_from_rmf: WARNING rmf particle and "
1036 "representation particle names don't match %s %s"
1037 % (rmfname, reprname))
1041 rmf_component_name=
None,
1042 check_number_particles=
True,
1043 representation_name_to_rmf_name_map=
None,
1045 skip_gaussian_in_rmf=
False,
1046 skip_gaussian_in_representation=
False,
1048 force_rigid_update=
False):
1049 '''Read and replace coordinates from an RMF file.
1050 Replace the coordinates of particles with the same name.
1051 It assumes that the RMF and the representation have the particles
1053 @param component_name Component name
1054 @param rmf_component_name Name of the component in the RMF file
1055 (if not specified, use `component_name`)
1056 @param representation_name_to_rmf_name_map a dictionary that map
1057 the original rmf particle name to the recipient particle component name
1058 @param save_file: save a file with the names of particles of the component
1059 @param force_rigid_update: update the coordinates of rigid bodies
1060 (normally this should be called before rigid bodies are set up)
1064 prots = IMP.pmi.analysis.get_hiers_from_rmf(
1070 raise ValueError(
"cannot read hierarchy from rmf")
1074 if force_rigid_update:
1085 p, self.hier_dict.keys())
1086 if (protname
is None)
and (rmf_component_name
is not None):
1088 p, rmf_component_name)
1089 if (skip_gaussian_in_rmf):
1092 if (rmf_component_name
is not None)
and (protname == rmf_component_name):
1094 elif (rmf_component_name
is None)
and (protname == component_name):
1098 if (skip_gaussian_in_representation):
1109 reprnames=[p.get_name()
for p
in psrepr]
1110 rmfnames=[p.get_name()
for p
in psrmf]
1113 fl=open(component_name+
".txt",
"w")
1114 for i
in itertools.izip_longest(reprnames,rmfnames): fl.write(str(i[0])+
","+str(i[1])+
"\n")
1117 if check_number_particles
and not representation_name_to_rmf_name_map:
1118 if len(psrmf) != len(psrepr):
1119 fl=open(component_name+
".txt",
"w")
1120 for i
in itertools.izip_longest(reprnames,rmfnames): fl.write(str(i[0])+
","+str(i[1])+
"\n")
1121 raise ValueError(
"%s cannot proceed the rmf and the representation don't have the same number of particles; "
1122 "particles in rmf: %s particles in the representation: %s" % (str(component_name), str(len(psrmf)), str(len(psrepr))))
1125 if not representation_name_to_rmf_name_map:
1126 for n, prmf
in enumerate(psrmf):
1128 prmfname = prmf.get_name()
1129 preprname = psrepr[n].get_name()
1130 if force_rigid_update:
1136 raise ValueError(
"component %s cannot proceed if rigid bodies were initialized. Use the function before defining the rigid bodies" % component_name)
1138 self._compare_rmf_repr_names(prmfname, preprname,
1147 rbm.set_internal_coordinates(xyz)
1149 rb = rbm.get_rigid_body()
1151 raise ValueError(
"Cannot handle nested "
1153 rb.set_reference_frame_lazy(tr)
1160 g=gprmf.get_gaussian()
1161 grepr.set_gaussian(g)
1164 repr_name_particle_map={}
1165 rmf_name_particle_map={}
1167 rmf_name_particle_map[p.get_name()]=p
1171 for prepr
in psrepr:
1173 prmf=rmf_name_particle_map[representation_name_to_rmf_name_map[prepr.get_name()]]
1175 print(
"set_coordinates_from_rmf: WARNING missing particle name in representation_name_to_rmf_name_map, skipping...")
1183 If the root hierarchy does not exist, construct it.
1185 if "Res:" + str(int(resolution))
not in self.hier_representation[name]:
1187 root.set_name(name +
"_Res:" + str(int(resolution)))
1188 self.hier_representation[name][
1189 "Res:" + str(int(resolution))] = root
1190 protein_h.add_child(root)
1193 input_hierarchy, protein_h, type, color):
1195 Generate all needed coarse grained layers.
1197 @param name name of the protein
1198 @param resolutions list of resolutions
1199 @param protein_h root hierarchy
1200 @param input_hierarchy hierarchy to coarse grain
1201 @param type a string, typically "pdb" or "helix"
1205 if (1
in resolutions)
or (0
in resolutions):
1208 if 1
in resolutions:
1211 s1.set_name(
'%s_%i-%i_%s' % (name, start, end, type))
1213 self.hier_representation[name][
"Res:1"].add_child(s1)
1215 if 0
in resolutions:
1218 s0.set_name(
'%s_%i-%i_%s' % (name, start, end, type))
1220 self.hier_representation[name][
"Res:0"].add_child(s0)
1223 if not isnucleicacid:
1226 atom_type=IMP.atom.AT_CA)
1230 atom_type=IMP.atom.AT_P)
1232 for p
in sel.get_selected_particles():
1234 if 0
in resolutions:
1236 resclone0 = IMP.atom.create_clone(resobject)
1238 s0.add_child(resclone0)
1239 self.hier_db.add_particles(
1243 resclone0.get_children())
1245 chil = resclone0.get_children()
1254 if 1
in resolutions:
1256 resclone1 = IMP.atom.create_clone_one(resobject)
1258 s1.add_child(resclone1)
1259 self.hier_db.add_particles(name, resindex, 1, [resclone1])
1263 prt = resclone1.get_particle()
1264 prt.set_name(
'%s_%i_%s' % (name, resindex, type))
1286 for r
in resolutions:
1287 if r != 0
and r != 1:
1293 chil = s.get_children()
1295 s0.set_name(
'%s_%i-%i_%s' % (name, start, end, type))
1300 self.hier_representation[name][
1301 "Res:" + str(int(r))].add_child(s0)
1310 prt.set_name(
'%s_%i_%s' % (name, first, type))
1312 prt.set_name(
'%s_%i_%i_%s' % (name, first, last, type))
1314 self.hier_db.add_particles(name, kk, r, [prt])
1335 Get the hierarchies at the given resolution.
1337 The map between resolution and hierarchies is cached to accelerate
1338 the selection algorithm. The cache is invalidated when the
1339 representation was changed by any add_component_xxx.
1342 if self.representation_is_modified:
1343 rhbr = self.hier_db.get_all_root_hierarchies_by_resolution(
1345 self.hier_resolution[resolution] = rhbr
1346 self.representation_is_modified =
False
1349 if resolution
in self.hier_resolution:
1350 return self.hier_resolution[resolution]
1352 rhbr = self.hier_db.get_all_root_hierarchies_by_resolution(
1354 self.hier_resolution[resolution] = rhbr
1358 self, max_translation=300., max_rotation=2.0 * pi,
1359 avoidcollision=
True, cutoff=10.0, niterations=100,
1361 excluded_rigid_bodies=
None,
1362 ignore_initial_coordinates=
False,
1363 hierarchies_excluded_from_collision=
None):
1365 Shuffle configuration; used to restart the optimization.
1367 The configuration of the system is initialized by placing each
1368 rigid body and each bead randomly in a box with a side of
1369 `max_translation` angstroms, and far enough from each other to
1370 prevent any steric clashes. The rigid bodies are also randomly rotated.
1372 @param avoidcollision check if the particle/rigid body was
1373 placed close to another particle; uses the optional
1374 arguments cutoff and niterations
1375 @param bounding_box defined by ((x1,y1,z1),(x2,y2,z2))
1378 if excluded_rigid_bodies
is None:
1379 excluded_rigid_bodies = []
1380 if hierarchies_excluded_from_collision
is None:
1381 hierarchies_excluded_from_collision = []
1383 if len(self.rigid_bodies) == 0:
1384 print(
"shuffle_configuration: rigid bodies were not intialized")
1387 gcpf.set_distance(cutoff)
1389 hierarchies_excluded_from_collision_indexes = []
1398 if bounding_box
is not None:
1399 ((x1, y1, z1), (x2, y2, z2)) = bounding_box
1404 for h
in hierarchies_excluded_from_collision:
1408 allparticleindexes = list(
1409 set(allparticleindexes) - set(hierarchies_excluded_from_collision_indexes))
1411 print(hierarchies_excluded_from_collision)
1412 print(len(allparticleindexes),len(hierarchies_excluded_from_collision_indexes))
1414 print(
'shuffling', len(self.rigid_bodies) - len(excluded_rigid_bodies),
'rigid bodies')
1415 for rb
in self.rigid_bodies:
1416 if rb
not in excluded_rigid_bodies:
1418 rbindexes = rb.get_member_particle_indexes()
1420 set(rbindexes) - set(hierarchies_excluded_from_collision_indexes))
1421 otherparticleindexes = list(
1422 set(allparticleindexes) - set(rbindexes))
1424 if len(otherparticleindexes)
is None:
1428 while niter < niterations:
1429 if (ignore_initial_coordinates):
1435 if bounding_box
is not None:
1451 gcpf.get_close_pairs(
1453 otherparticleindexes,
1457 if (ignore_initial_coordinates):
1458 print (rb.get_name(),
IMP.core.XYZ(rb).get_coordinates())
1461 print(
"shuffle_configuration: rigid body placed close to other %d particles, trying again..." % npairs)
1462 print(
"shuffle_configuration: rigid body name: " + rb.get_name())
1463 if niter == niterations:
1464 raise ValueError(
"tried the maximum number of iterations to avoid collisions, increase the distance cutoff")
1468 print(
'shuffling', len(self.floppy_bodies),
'floppy bodies')
1469 for fb
in self.floppy_bodies:
1470 if (avoidcollision):
1475 otherparticleindexes = list(
1476 set(allparticleindexes) - set(fbindexes))
1477 if len(otherparticleindexes)
is None:
1495 while niter < niterations:
1496 if (ignore_initial_coordinates):
1502 if bounding_box
is not None:
1514 if (avoidcollision):
1517 gcpf.get_close_pairs(
1519 otherparticleindexes,
1523 if (ignore_initial_coordinates):
1524 print (fb.get_name(),
IMP.core.XYZ(fb).get_coordinates())
1527 print(
"shuffle_configuration: floppy body placed close to other %d particles, trying again..." % npairs)
1528 print(
"shuffle_configuration: floppy body name: " + fb.get_name())
1529 if niter == niterations:
1530 raise ValueError(
"tried the maximum number of iterations to avoid collisions, increase the distance cutoff")
1534 def set_current_coordinates_as_reference_for_rmsd(self, label="None"):
1538 self.reference_structures[label] = (
1542 def get_all_rmsds(self):
1545 for label
in self.reference_structures:
1547 current_coordinates = [
IMP.core.XYZ(p).get_coordinates()
1548 for p
in self.reference_structures[label][1]]
1549 reference_coordinates = self.reference_structures[label][0]
1550 if len(reference_coordinates) != len(current_coordinates):
1551 print(
"calculate_all_rmsds: reference and actual coordinates are not the same")
1554 current_coordinates,
1555 reference_coordinates)
1557 reference_coordinates,
1558 current_coordinates)
1562 reference_coordinates,
1563 current_coordinates)
1564 rmsds[label +
"_GlobalRMSD"] = rmsd_global
1565 rmsds[label +
"_RelativeDRMS"] = rmsd_relative
1568 def setup_component_geometry(self, name, color=None, resolution=1.0):
1570 color = self.color_dict[name]
1574 self.hier_geometry_pairs[name] = []
1575 protein_h = self.hier_dict[name]
1577 pbr = IMP.pmi.tools.sort_by_residues(pbr)
1579 for n
in range(len(pbr) - 1):
1580 self.hier_geometry_pairs[name].append((pbr[n], pbr[n + 1], color))
1583 self, name, resolution=10, scale=1.0):
1585 Generate restraints between contiguous fragments in the hierarchy.
1586 The linkers are generated at resolution 10 by default.
1593 protein_h = self.hier_dict[name]
1595 frs = self.hier_db.get_preroot_fragments_by_resolution(
1601 start = fr.get_children()[0]
1606 end = fr.get_children()[-1]
1612 SortedSegments.append((start, end, startres))
1613 SortedSegments = sorted(SortedSegments, key=itemgetter(2))
1616 for x
in range(len(SortedSegments) - 1):
1617 last = SortedSegments[x][1]
1618 first = SortedSegments[x + 1][0]
1625 residuegap = firstresn - lastresn - 1
1626 if self.disorderedlength
and (nreslast / 2 + nresfirst / 2 + residuegap) > 20.0:
1629 optdist = sqrt(5 / 3) * 1.93 * \
1630 (nreslast / 2 + nresfirst / 2 + residuegap) ** 0.6
1632 if self.upperharmonic:
1638 optdist = (0.0 + (float(residuegap) + 1.0) * 3.6) * scale
1639 if self.upperharmonic:
1645 pt0 = last.get_particle()
1646 pt1 = first.get_particle()
1649 print(
"Adding sequence connectivity restraint between", pt0.get_name(),
" and ", pt1.get_name(),
'of distance', optdist)
1650 sortedsegments_cr.add_restraint(r)
1651 self.linker_restraints_dict[
1652 "LinkerRestraint-" + pt0.get_name() +
"-" + pt1.get_name()] = r
1653 self.connected_intra_pairs.append((pt0, pt1))
1654 self.connected_intra_pairs.append((pt1, pt0))
1656 self.linker_restraints.add_restraint(sortedsegments_cr)
1657 self.linker_restraints.add_restraint(unmodeledregions_cr)
1659 self.sortedsegments_cr_dict[name] = sortedsegments_cr
1660 self.unmodeledregions_cr_dict[name] = unmodeledregions_cr
1662 def optimize_floppy_bodies(self, nsteps, temperature=1.0):
1664 pts = IMP.pmi.tools.ParticleToSampleList()
1665 for n, fb
in enumerate(self.floppy_bodies):
1666 pts.add_particle(fb,
"Floppy_Bodies", 1.0,
"Floppy_Body_" + str(n))
1667 if len(pts.get_particles_to_sample()) > 0:
1669 print(
"optimize_floppy_bodies: optimizing %i floppy bodies" % len(self.floppy_bodies))
1672 print(
"optimize_floppy_bodies: no particle to optimize")
1675 nSymmetry=
None, skip_gaussian_in_clones=
False):
1677 The copies must not contain rigid bodies.
1678 The symmetry restraints are applied at each leaf.
1682 self.representation_is_modified =
True
1683 ncopies = len(copies) + 1
1686 for k
in range(len(copies)):
1687 if (nSymmetry
is None):
1688 rotation_angle = 2.0 * pi / float(ncopies) * float(k + 1)
1691 rotation_angle = 2.0 * pi / float(nSymmetry) * float((k + 2) / 2)
1693 rotation_angle = -2.0 * pi / float(nSymmetry) * float((k + 1) / 2)
1701 for n, p
in enumerate(main_hiers):
1702 if (skip_gaussian_in_clones):
1711 self.m.add_score_state(c)
1712 print(
"Completed setting " + str(maincopy) +
" as a reference for " + str(copies[k]) \
1713 +
" by rotating it in " + str(rotation_angle / 2.0 / pi * 360) +
" degree around the " + str(rotational_axis) +
" axis.")
1716 def create_rigid_body_symmetry(self, particles_reference, particles_copy,label="None",
1719 self.representation_is_modified =
True
1721 mainparticles = particles_reference
1723 t=initial_transformation
1725 p.set_name(
"RigidBody_Symmetry")
1731 copyparticles = particles_copy
1735 for n, p
in enumerate(mainparticles):
1737 pc = copyparticles[n]
1739 mainpurged.append(p)
1745 copypurged.append(pc)
1752 for n, p
in enumerate(mainpurged):
1755 print(
"setting " + p.get_name() +
" as reference for " + pc.get_name())
1758 lc.add(pc.get_index())
1761 self.m.add_score_state(c)
1764 self.rigid_bodies.append(rb)
1765 self.rigid_body_symmetries.append(rb)
1766 rb.set_name(label+
".rigid_body_symmetry."+str(len(self.rigid_body_symmetries)))
1769 def create_amyloid_fibril_symmetry(self, maincopy, axial_copies,
1770 longitudinal_copies, axis=(0, 0, 1), translation_value=4.8):
1773 self.representation_is_modified =
True
1776 protein_h = self.hier_dict[maincopy]
1779 for ilc
in range(-longitudinal_copies, longitudinal_copies + 1):
1780 for iac
in range(axial_copies):
1781 copyname = maincopy +
"_a" + str(ilc) +
"_l" + str(iac)
1782 self.create_component(copyname, 0.0)
1783 for hier
in protein_h.get_children():
1785 copyhier = self.hier_dict[copyname]
1786 outhiers.append(copyhier)
1790 2 * pi / axial_copies * (float(iac)))
1791 translation_vector = tuple(
1792 [translation_value * float(ilc) * x
for x
in axis])
1793 print(translation_vector)
1798 for n, p
in enumerate(mainparts):
1805 lc.add(pc.get_index())
1807 self.m.add_score_state(c)
1813 Load coordinates in the current representation.
1814 This should be done only if the hierarchy self.prot is identical
1815 to the one as stored in the rmf i.e. all components were added.
1820 rh = RMF.open_rmf_file_read_only(rmfname)
1828 create the representation (i.e. hierarchies) from the rmf file.
1829 it will be stored in self.prot, which will be overwritten.
1830 load the coordinates from the rmf file at frameindex.
1832 rh = RMF.open_rmf_file_read_only(rmfname)
1838 for p
in self.prot.get_children():
1839 self.create_component(p.get_name())
1840 self.hier_dict[p.get_name()] = p
1842 still missing: save rigid bodies contained in the rmf in self.rigid_bodies
1843 save floppy bodies in self.floppy_bodies
1844 get the connectivity restraints
1849 Construct a rigid body from hierarchies (and optionally particles).
1851 @param hiers list of hierarchies to make rigid
1852 @param particles list of particles to add to the rigid body
1855 if particles
is None:
1858 rigid_parts = set(particles)
1861 print(
"set_rigid_body_from_hierarchies> setting up a new rigid body")
1868 print(
"set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1871 name += hier.get_name() +
"-"
1872 print(
"set_rigid_body_from_hierarchies> adding %s to the rigid body" % hier.get_name())
1874 if len(list(rigid_parts)) != 0:
1876 rb.set_coordinates_are_optimized(
True)
1877 rb.set_name(name +
"rigid_body")
1878 self.rigid_bodies.append(rb)
1882 print(
"set_rigid_body_from_hierarchies> rigid body could not be setup")
1886 Construct a rigid body from a list of subunits.
1888 Each subunit is a tuple that identifies the residue ranges and the
1889 component name (as used in create_component()).
1891 subunits: [(name_1,(first_residue_1,last_residue_1)),(name_2,(first_residue_2,last_residue_2)),.....]
1893 [name_1,name_2,(name_3,(first_residue_3,last_residue_3)),.....]
1895 example: ["prot1","prot2",("prot3",(1,10))]
1897 sometimes, we know about structure of an interaction
1898 and here we make such PPIs rigid
1903 if type(s) == type(tuple())
and len(s) == 2:
1907 residue_indexes=list(range(s[1][0],
1909 if len(sel.get_selected_particles()) == 0:
1910 print(
"set_rigid_bodies: selected particle does not exist")
1911 for p
in sel.get_selected_particles():
1915 print(
"set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1919 elif type(s) == type(str()):
1921 if len(sel.get_selected_particles()) == 0:
1922 print(
"set_rigid_bodies: selected particle does not exist")
1923 for p
in sel.get_selected_particles():
1927 print(
"set_rigid_body_from_hierarchies> WARNING particle %s already belongs to rigid body %s" % (p.get_name(), rb.get_name()))
1932 rb.set_coordinates_are_optimized(
True)
1933 rb.set_name(
''.join(str(subunits)) +
"_rigid_body")
1934 self.rigid_bodies.append(rb)
1937 def set_super_rigid_body_from_hierarchies(
1943 super_rigid_xyzs = set()
1944 super_rigid_rbs = set()
1946 print(
"set_super_rigid_body_from_hierarchies> setting up a new SUPER rigid body")
1953 super_rigid_rbs.add(rb)
1955 super_rigid_xyzs.add(p)
1956 print(
"set_rigid_body_from_hierarchies> adding %s to the rigid body" % hier.get_name())
1957 if len(super_rigid_rbs|super_rigid_xyzs) < min_size:
1960 self.super_rigid_bodies.append((super_rigid_xyzs, super_rigid_rbs))
1963 self.super_rigid_bodies.append(
1964 (super_rigid_xyzs, super_rigid_rbs, axis))
1966 def fix_rigid_bodies(self, rigid_bodies):
1967 self.fixed_rigid_bodies += rigid_bodies
1971 self, hiers, min_length=
None, max_length=
None, axis=
None):
1973 Make a chain of super rigid bodies from a list of hierarchies.
1975 Takes a linear list of hierarchies (they are supposed to be
1976 sequence-contiguous) and produces a chain of super rigid bodies
1977 with given length range, specified by min_length and max_length.
1980 hiers = IMP.pmi.tools.flatten_list(hiers)
1984 self.set_super_rigid_body_from_hierarchies(hs, axis, min_length)
1986 def set_super_rigid_bodies(self, subunits, coords=None):
1987 super_rigid_xyzs = set()
1988 super_rigid_rbs = set()
1991 if type(s) == type(tuple())
and len(s) == 3:
1995 residue_indexes=list(range(s[0],
1997 if len(sel.get_selected_particles()) == 0:
1998 print(
"set_rigid_bodies: selected particle does not exist")
1999 for p
in sel.get_selected_particles():
2002 super_rigid_rbs.add(rb)
2004 super_rigid_xyzs.add(p)
2005 elif type(s) == type(str()):
2007 if len(sel.get_selected_particles()) == 0:
2008 print(
"set_rigid_bodies: selected particle does not exist")
2009 for p
in sel.get_selected_particles():
2013 super_rigid_rbs.add(rb)
2015 super_rigid_xyzs.add(p)
2016 self.super_rigid_bodies.append((super_rigid_xyzs, super_rigid_rbs))
2020 Remove leaves of hierarchies from the floppy bodies list based
2021 on the component name
2024 ps=[h.get_particle()
for h
in hs]
2025 for p
in self.floppy_bodies:
2027 if p
in ps: self.floppy_bodies.remove(p)
2028 if p
in hs: self.floppy_bodies.remove(p)
2035 Remove leaves of hierarchies from the floppy bodies list.
2037 Given a list of hierarchies, get the leaves and remove the
2038 corresponding particles from the floppy bodies list. We need this
2039 function because sometimes
2040 we want to constrain the floppy bodies in a rigid body - for instance
2041 when you want to associate a bead with a density particle.
2043 for h
in hierarchies:
2046 if p
in self.floppy_bodies:
2047 print(
"remove_floppy_bodies: removing %s from floppy body list" % p.get_name())
2048 self.floppy_bodies.remove(p)
2051 def set_floppy_bodies(self):
2052 for p
in self.floppy_bodies:
2054 p.set_name(name +
"_floppy_body")
2056 print(
"I'm trying to make this particle flexible although it was assigned to a rigid body", p.get_name())
2059 rb.set_is_rigid_member(p.get_index(),
False)
2062 rb.set_is_rigid_member(p.get_particle_index(),
False)
2063 p.set_name(p.get_name() +
"_rigid_body_member")
2065 def set_floppy_bodies_from_hierarchies(self, hiers):
2070 self.floppy_bodies.append(p)
2077 selection tuples must be [(r1,r2,"name1"),(r1,r2,"name2"),....]
2078 @return the particles
2081 print(selection_tuples)
2082 for s
in selection_tuples:
2083 ps = IMP.pmi.tools.select_by_tuple(
2084 representation=self, tupleselection=tuple(s),
2085 resolution=
None, name_is_ambiguous=
False)
2089 def get_connected_intra_pairs(self):
2090 return self.connected_intra_pairs
2092 def set_rigid_bodies_max_trans(self, maxtrans):
2093 self.maxtrans_rb = maxtrans
2095 def set_rigid_bodies_max_rot(self, maxrot):
2096 self.maxrot_rb = maxrot
2098 def set_super_rigid_bodies_max_trans(self, maxtrans):
2099 self.maxtrans_srb = maxtrans
2101 def set_super_rigid_bodies_max_rot(self, maxrot):
2102 self.maxrot_srb = maxrot
2104 def set_floppy_bodies_max_trans(self, maxtrans):
2105 self.maxtrans_fb = maxtrans
2109 Fix rigid bodies in their actual position.
2110 The get_particles_to_sample() function will return
2111 just the floppy bodies (if they are not fixed).
2113 self.rigidbodiesarefixed = rigidbodiesarefixed
2117 Fix floppy bodies in their actual position.
2118 The get_particles_to_sample() function will return
2119 just the rigid bodies (if they are not fixed).
2121 self.floppybodiesarefixed=floppybodiesarefixed
2123 def draw_hierarchy_graph(self):
2125 print(
"Drawing hierarchy graph for " + c.get_name())
2126 IMP.pmi.output.get_graph_from_hierarchy(c)
2128 def get_geometries(self):
2131 for name
in self.hier_geometry_pairs:
2132 for pt
in self.hier_geometry_pairs[name]:
2146 def setup_bonds(self):
2149 for name
in self.hier_geometry_pairs:
2150 for pt
in self.hier_geometry_pairs[name]:
2165 def show_component_table(self, name):
2166 if name
in self.sequence_dict:
2167 lastresn = len(self.sequence_dict[name])
2170 residues = self.hier_db.get_residue_numbers(name)
2171 firstresn = min(residues)
2172 lastresn = max(residues)
2174 for nres
in range(firstresn, lastresn + 1):
2176 resolutions = self.hier_db.get_residue_resolutions(name, nres)
2178 for r
in resolutions:
2179 ps += self.hier_db.get_particles(name, nres, r)
2180 print(
"%20s %7s" % (name, nres),
" ".join([
"%20s %7s" % (str(p.get_name()),
2183 print(
"%20s %20s" % (name, nres),
"**** not represented ****")
2185 def draw_hierarchy_composition(self):
2187 ks = list(self.elements.keys())
2191 for k
in self.elements:
2192 for l
in self.elements[k]:
2197 self.draw_component_composition(k, max)
2199 def draw_component_composition(self, name, max=1000, draw_pdb_names=False):
2200 from matplotlib
import pyplot
2201 import matplotlib
as mpl
2203 tmplist = sorted(self.elements[k], key=itemgetter(0))
2205 endres = tmplist[-1][1]
2207 print(
"draw_component_composition: missing information for component %s" % name)
2209 fig = pyplot.figure(figsize=(26.0 * float(endres) / max + 2, 2))
2210 ax = fig.add_axes([0.05, 0.475, 0.9, 0.15])
2215 norm = mpl.colors.Normalize(vmin=5, vmax=10)
2219 for n, l
in enumerate(tmplist):
2223 if bounds[-1] != l[0]:
2224 colors.append(
"white")
2227 colors.append(
"#99CCFF")
2229 colors.append(
"#FFFF99")
2231 colors.append(
"#33CCCC")
2233 bounds.append(l[1] + 1)
2236 colors.append(
"#99CCFF")
2238 colors.append(
"#FFFF99")
2240 colors.append(
"#33CCCC")
2242 bounds.append(l[1] + 1)
2244 if bounds[-1] - 1 == l[0]:
2248 colors.append(
"white")
2251 bounds.append(bounds[-1])
2252 colors.append(
"white")
2253 cmap = mpl.colors.ListedColormap(colors)
2254 cmap.set_over(
'0.25')
2255 cmap.set_under(
'0.75')
2257 norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
2258 cb2 = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
2264 spacing=
'proportional',
2265 orientation=
'horizontal')
2274 mid = 1.0 / endres * float(l[0])
2279 l[2], xy=(mid, 1), xycoords=
'axes fraction',
2280 xytext=(mid + 0.025, float(npdb - 1) / 2.0 + 1.5), textcoords=
'axes fraction',
2281 arrowprops=dict(arrowstyle=
"->",
2282 connectionstyle=
"angle,angleA=0,angleB=90,rad=10"),
2284 extra_artists.append(t)
2287 title = ax.text(-0.005, 0.5, k, ha=
"right", va=
"center", rotation=90,
2290 extra_artists.append(title)
2292 labels = len(bounds) * [
" "]
2293 ax.set_xticklabels(labels)
2294 mid = 1.0 / endres * float(bounds[0])
2295 t = ax.annotate(bounds[0], xy=(mid, 0), xycoords=
'axes fraction',
2296 xytext=(mid - 0.01, -0.5), textcoords=
'axes fraction',)
2297 extra_artists.append(t)
2298 offsets = [0, -0.5, -1.0]
2300 for n
in range(1, len(bounds)):
2301 if bounds[n] == bounds[n - 1]:
2303 mid = 1.0 / endres * float(bounds[n])
2304 if (float(bounds[n]) - float(bounds[n - 1])) / max <= 0.01:
2306 offset = offsets[nclashes % 3]
2312 bounds[n], xy=(mid, 0), xycoords=
'axes fraction',
2313 xytext=(mid, -0.5 + offset), textcoords=
'axes fraction')
2316 bounds[n], xy=(mid, 0), xycoords=
'axes fraction',
2317 xytext=(mid, -0.5 + offset), textcoords=
'axes fraction', arrowprops=dict(arrowstyle=
"-"))
2318 extra_artists.append(t)
2320 cb2.add_lines(bounds, [
"black"] * len(bounds), [1] * len(bounds))
2324 k +
"structure.pdf",
2327 bbox_extra_artists=(extra_artists),
2328 bbox_inches=
'tight')
2331 def draw_coordinates_projection(self):
2332 import matplotlib.pyplot
as pp
2335 for name
in self.hier_geometry_pairs:
2336 for pt
in self.hier_geometry_pairs[name]:
2346 xpairs.append([x1, x2])
2347 ypairs.append([y1, y2])
2350 for xends, yends
in zip(xpairs, ypairs):
2355 pp.plot(xlist, ylist,
'b-', alpha=0.1)
2358 def get_prot_name_from_particle(self, particle):
2359 names = self.get_component_names()
2360 particle0 = particle
2362 while not name
in names:
2365 particle0 = h.get_particle()
2369 def get_particles_to_sample(self):
2379 if not self.rigidbodiesarefixed:
2380 for rb
in self.rigid_bodies:
2385 if rb
not in self.fixed_rigid_bodies:
2388 if not self.floppybodiesarefixed:
2389 for fb
in self.floppy_bodies:
2396 for srb
in self.super_rigid_bodies:
2399 rigid_bodies = list(srb[1])
2400 filtered_rigid_bodies = []
2401 for rb
in rigid_bodies:
2402 if rb
not in self.fixed_rigid_bodies:
2403 filtered_rigid_bodies.append(rb)
2404 srbtmp.append((srb[0], filtered_rigid_bodies))
2406 self.rigid_bodies = rbtmp
2407 self.floppy_bodies = fbtmp
2408 self.super_rigid_bodies = srbtmp
2410 ps[
"Rigid_Bodies_SimplifiedModel"] = (
2414 ps[
"Floppy_Bodies_SimplifiedModel"] = (
2417 ps[
"SR_Bodies_SimplifiedModel"] = (
2418 self.super_rigid_bodies,
2423 def set_output_level(self, level):
2424 self.output_level = level
2426 def _evaluate(self, deriv):
2427 """Evaluate the total score of all added restraints"""
2429 return r.evaluate(deriv)
2431 def get_output(self):
2435 output[
"SimplifiedModel_Total_Score_" +
2436 self.label] = str(self._evaluate(
False))
2437 output[
"SimplifiedModel_Linker_Score_" +
2438 self.label] = str(self.linker_restraints.unprotected_evaluate(
None))
2439 for name
in self.sortedsegments_cr_dict:
2440 partialscore = self.sortedsegments_cr_dict[name].evaluate(
False)
2441 score += partialscore
2443 "SimplifiedModel_Link_SortedSegments_" +
2448 partialscore = self.unmodeledregions_cr_dict[name].evaluate(
False)
2449 score += partialscore
2451 "SimplifiedModel_Link_UnmodeledRegions_" +
2456 for rb
in self.rigid_body_symmetries:
2458 output[name +
"_" +self.label]=str(rb.get_reference_frame().get_transformation_to())
2459 for name
in self.linker_restraints_dict:
2464 self.linker_restraints_dict[
2465 name].unprotected_evaluate(
2468 if len(self.reference_structures.keys()) != 0:
2469 rmsds = self.get_all_rmsds()
2472 "SimplifiedModel_" +
2475 self.label] = rmsds[
2478 if self.output_level ==
"high":
2481 output[
"Coordinates_" +
2482 p.get_name() +
"_" + self.label] = str(d)
2484 output[
"_TotalScore"] = str(score)
2487 def get_test_output(self):
2489 output = self.get_output()
2490 for n, p
in enumerate(self.get_particles_to_sample()):
2491 output[
"Particle_to_sample_" + str(n)] = str(p)
2493 output[
"Hierarchy_Dictionary"] = list(self.hier_dict.keys())
2494 output[
"Number_of_floppy_bodies"] = len(self.floppy_bodies)
2495 output[
"Number_of_rigid_bodies"] = len(self.rigid_bodies)
2496 output[
"Number_of_super_bodies"] = len(self.super_rigid_bodies)
2497 output[
"Selection_resolution_1"] = len(
2499 output[
"Selection_resolution_5"] = len(
2501 output[
"Selection_resolution_7"] = len(
2503 output[
"Selection_resolution_10"] = len(
2505 output[
"Selection_resolution_100"] = len(
2508 output[
"Selection_resolution=1"] = len(
2510 output[
"Selection_resolution=1,resid=10"] = len(
2512 for resolution
in self.hier_resolution:
2513 output[
"Hier_resolution_dictionary" +
2514 str(resolution)] = len(self.hier_resolution[resolution])
2515 for name
in self.hier_dict:
2517 "Selection_resolution=1,resid=10,name=" +
2525 "Selection_resolution=1,resid=10,name=" +
2527 ",ambiguous"] = len(
2532 name_is_ambiguous=
True,
2535 "Selection_resolution=1,resid=10,name=" +
2537 ",ambiguous"] = len(
2542 name_is_ambiguous=
True,
2545 "Selection_resolution=1,resrange=(10,20),name=" +
2554 "Selection_resolution=1,resrange=(10,20),name=" +
2556 ",ambiguous"] = len(
2561 name_is_ambiguous=
True,
2565 "Selection_resolution=10,resrange=(10,20),name=" +
2574 "Selection_resolution=10,resrange=(10,20),name=" +
2576 ",ambiguous"] = len(
2581 name_is_ambiguous=
True,
2585 "Selection_resolution=100,resrange=(10,20),name=" +
2594 "Selection_resolution=100,resrange=(10,20),name=" +
2596 ",ambiguous"] = len(
2601 name_is_ambiguous=
True,
2613 def __init__(self, *args, **kwargs):
2614 Representation.__init__(self, *args, **kwargs)
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 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.
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.
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.
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)
def deprecated_object
Python decorator to mark a class as deprecated.
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.
Set up the representation of all proteins and nucleic acid macromolecules.
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.
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.
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.