1 from __future__
import print_function, division
7 from collections
import defaultdict
13 """Take iterable of TempResidues and return compatified string"""
16 idxs = [r.get_index()
for r
in res]
19 cur_range=[idxs[0],idxs[0]]
21 if idx!=cur_range[1]+1:
22 all_ranges.append(cur_range)
25 all_ranges.append(cur_range)
27 for nr,r
in enumerate(all_ranges):
28 ret+=
'%i-%i'%(r[0],r[1])
29 if nr<len(all_ranges)-1:
33 def get_structure(model,pdb_fn,chain_id,res_range=None,offset=0,model_num=None,ca_only=False):
34 """read a structure from a PDB file and return a list of residues
35 @param model The IMP model
36 @param pdb_fn The file to read (in traditional PDB or mmCIF format)
37 @param chain_id Chain ID to read
38 @param res_range Add only a specific set of residues.
39 res_range[0] is the starting and res_range[1] is the ending residue index
40 The ending residue can be "END", that will take everything to the end of the sequence.
42 @param offset Apply an offset to the residue indexes of the PDB file
43 @param model_num Read multi-model PDB and return that model
44 @param ca_only Read only CA atoms (by default, all non-waters are read)
48 read_file = IMP.atom.read_pdb
49 read_multi_file = IMP.atom.read_multimodel_pdb
50 if pdb_fn.endswith(
'.cif'):
51 read_file = IMP.atom.read_mmcif
52 read_multi_file = IMP.atom.read_multimodel_mmcif
56 mh = read_file(pdb_fn,model,
60 mhs = read_multi_file(pdb_fn,model,sel)
61 if model_num>=len(mhs):
62 raise Exception(
"you requested model num "+str(model_num)+\
63 " but the PDB file only contains "+str(len(mhs))+
" models")
66 if res_range==[]
or res_range
is None:
77 atom_type=IMP.atom.AT_P)
80 if sel_p.get_selected_particles():
81 "WARNING: detected nucleotides. Selecting phosphorous instead of CA"
84 for p
in sel.get_selected_particles():
86 res.set_index(res.get_index() + offset)
90 "no residues selected from %s in range %s" % (pdb_fn, res_range),
94 def build_bead(model,residues,input_coord=None):
95 """Generates a single bead"""
103 if ds_frag[0] == ds_frag[-1]:
104 rt = residues[0].get_residue_type()
106 h.set_name(
'%i_bead' % (ds_frag[0]))
107 prt.set_name(
'%i_bead' % (ds_frag[0]))
114 ptem.set_radius(radius)
117 h.set_name(
'%i-%i_bead' % (ds_frag[0], ds_frag[-1]))
118 prt.set_name(
'%i-%i_bead' % (ds_frag[0], ds_frag[-1]))
119 h.set_residue_indexes(range(ds_frag[0], ds_frag[-1] + 1))
121 radius = 0.8 * (3.0 / 4.0 / pi * volume) ** (1.0 / 3.0)
122 ptem.set_radius(radius)
126 if tuple(input_coord)
is not None:
127 ptem.set_coordinates(input_coord)
132 def build_necklace(model,residues, resolution, input_coord=None):
133 """Generates a string of beads with given length"""
136 out_hiers.append(build_bead(model,chunk, input_coord=input_coord))
139 def build_ca_centers(model,residues):
140 """Create a bead on the CA position with coarsened size and mass"""
142 for tempres
in residues:
143 residue = tempres.get_hierarchy()
145 rp1.set_name(
"Residue_%i"%residue.get_index())
146 rt = residue.get_residue_type()
158 get_selected_particles()
160 get_selected_particles()
163 central_atom=calpha[0]
167 raise(
"build_ca_centers: weird selection (no Ca, no nucleotide P or ambiguous selection found)")
172 out_hiers.append(this_res)
175 def setup_bead_as_gaussian(mh):
176 """Setup bead as spherical gaussian, using radius as variance"""
177 p = mh.get_particle()
186 def show_representation(node):
190 resolutions = repr.get_resolutions()
191 for r
in resolutions:
192 print(
'---- resolution %i ----' %r)
198 def _get_color_for_representation(rep):
199 """Return an IMP.display.Color object (or None) for the given
201 if rep.color
is not None:
202 if isinstance(rep.color, float):
204 elif isinstance(rep.color, str):
206 elif hasattr(rep.color,
'__iter__')
and len(rep.color)==3:
211 raise TypeError(
"Color must be Chimera color name, a hex "
212 "string, a float or (r,g,b) tuple")
215 def _add_fragment_provenance(fragment, first_residue, rephandler):
216 """Track the original source of a fragment's structure.
217 If the residues in the given fragment were extracted from a PDB
218 file, add suitable provenance information to the Model (the name
219 of that file, chain ID, and residue index offset)."""
220 pdb_element = rephandler.pdb_for_residue.get(first_residue.get_index())
222 m = fragment.get_model()
224 pdb_element.filename, pdb_element.chain_id, pdb_element.offset)
228 def build_representation(parent, rep, coord_finder, rephandler):
229 """Create requested representation.
230 For beads, identifies continuous segments and sets up as Representation.
231 If any volume-based representations (e.g.,densities) are requested,
232 will instead create a single Representation node.
233 All reps are added as children of the passed parent.
234 @param parent The Molecule to which we'll add add representations
235 @param rep What to build. An instance of pmi::topology::_Representation
236 @param coord_finder A _FindCloseStructure object to help localize beads
241 model = parent.hier.get_model()
242 color = _get_color_for_representation(rep)
246 primary_resolution = min(rep.bead_resolutions)
251 if rep.density_residues_per_component:
253 num_components = len(rep.residues)//rep.density_residues_per_component+1
254 rep_dict = defaultdict(list)
258 built_reps.append(root_representation)
259 res_nums = [r.get_index()
for r
in rep.residues]
262 density_frag.get_particle().set_name(
"Densities %i"%rep.density_residues_per_component)
265 if os.path.exists(rep.density_prefix+
'.txt')
and not rep.density_force_compute:
269 if len(density_ps)!=num_components
or not os.path.exists(rep.density_prefix+
'.txt')
or rep.density_force_compute:
272 for r
in rep.residues:
284 mass_multiplier=total_mass)
287 if rep.density_voxel_size>0.0:
289 rep.density_voxel_size,fast=
True)
291 for n, d
in enumerate(density_ps):
292 d.set_name(
'Density #%d' % n)
293 density_frag.add_child(d)
294 root_representation.add_representation(density_frag,
296 rep.density_residues_per_component)
300 rsort = sorted(list(rep.residues),key=
lambda r:r.get_index())
302 prev_structure = rsort[0].get_has_structure()
305 for nr,r
in enumerate(rsort):
306 if r.get_index()!=prev_idx+1
or r.get_has_structure()!=prev_structure
or force_break:
307 segments.append(cur_seg)
311 prev_idx = r.get_index()
312 prev_structure = r.get_has_structure()
313 if r.get_index()-1
in rep.bead_extra_breaks:
316 segments.append(cur_seg)
321 for frag_res
in segments:
322 res_nums = [r.get_index()
for r
in frag_res]
323 rrange =
"%i-%i"%(res_nums[0],res_nums[-1])
324 name =
"Frag_"+rrange
326 name_all +=rrange+
','
334 built_reps.append(this_representation)
335 for resolution
in rep.bead_resolutions:
338 this_resolution.set_name(
"%s: Res %i"%(name,resolution))
339 if frag_res[0].get_has_structure():
340 _add_fragment_provenance(this_resolution, frag_res[0],
343 if resolution==atomic_res:
344 for residue
in frag_res:
345 this_resolution.add_child(residue.get_hierarchy())
346 elif resolution==ca_res
and rep.bead_ca_centers:
347 beads = build_ca_centers(model,frag_res)
349 this_resolution.add_child(bead)
352 for residue
in frag_res:
353 tempc.add_child(IMP.atom.create_clone(residue.hier))
355 for bead
in beads.get_children():
356 this_resolution.add_child(bead)
361 input_coord = coord_finder.find_nearest_coord(min(r.get_index()
for r
in frag_res))
362 if input_coord
is None:
363 input_coord = rep.bead_default_coord
364 beads = build_necklace(model,
369 this_resolution.add_child(bead)
379 rep_dict[resolution]+=this_resolution.get_children()
381 if resolution==primary_resolution:
382 this_representation.add_child(this_resolution)
384 this_representation.add_representation(this_resolution,
388 if rep.setup_particles_as_densities:
390 setup_bead_as_gaussian(p)
391 this_resolution.set_name(this_resolution.get_name()+
' Densities %i'%resolution)
392 this_representation.add_representation(this_resolution,
397 root_representation.set_name(name_all.strip(
',')+
": Base")
398 d = root_representation.get_representations(IMP.atom.DENSITIES)
399 d[0].set_name(
'%s: '%name_all + d[0].get_name())
400 for resolution
in rep.bead_resolutions:
403 [r.get_index()
for r
in rep.residues])
404 this_resolution.set_name(
"%s: Res %i"%(name_all,resolution))
405 for hier
in rep_dict[resolution]:
406 this_resolution.add_child(hier)
407 if resolution==primary_resolution:
408 root_representation.add_child(this_resolution)
410 root_representation.add_representation(this_resolution,
double get_volume_from_residue_type(ResidueType rt)
Return an estimate for the volume of a given residue.
static Gaussian setup_particle(Model *m, ParticleIndex pi)
void show_molecular_hierarchy(Hierarchy h)
Print out the molecular hierarchy.
static Fragment setup_particle(Model *m, ParticleIndex pi)
double get_mass(const Selection &s)
Get the total mass of a hierarchy, in Daltons.
static XYZR setup_particle(Model *m, ParticleIndex pi)
Select atoms which are selected by both selectors.
double get_mass(ResidueType c)
Get the mass from the residue type.
static StructureProvenance setup_particle(Model *m, ParticleIndex pi, std::string filename, std::string chain_id, int residue_offset)
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.
double get_ball_radius_from_volume_3d(double volume)
Return the radius of a sphere with a given volume.
static Residue setup_particle(Model *m, ParticleIndex pi, ResidueType t, int index, int insertion_code)
static Representation setup_particle(Model *m, ParticleIndex pi)
GenericHierarchies get_leaves(Hierarchy mhd)
Get all the leaves of the bit of hierarchy.
Warning related to handling of structures.
A Gaussian distribution in 3D.
A decorator for a representation.
double get_volume_from_mass(double m, ProteinDensityReference ref=ALBER)
Estimate the volume of a protein from its mass.
Ints get_index(const ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
A decorator for a particle representing an atom.
static Mass setup_particle(Model *m, ParticleIndex pi, Float mass)
PDBSelector * get_default_pdb_selector()
A decorator for a particle with x,y,z coordinates.
static Colored setup_particle(Model *m, ParticleIndex pi, Color color)
A decorator for a residue.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Hierarchy create_simplified_along_backbone(Chain input, const IntRanges &residue_segments, bool keep_detailed=false)
Rotation3D get_identity_rotation_3d()
Return a rotation that does not do anything.
Class to handle individual particles of a Model object.
Select all CA ATOM records.
Python classes to represent, score, sample and analyze models.
Functionality for loading, creating, manipulating and scoring atomic structures.
void add_provenance(Model *m, ParticleIndex pi, Provenance p)
Add provenance to part of the model.
static Chain setup_particle(Model *m, ParticleIndex pi, std::string id)
An exception for an invalid value being passed to IMP.
Select hierarchy particles identified by the biological name.
Select all ATOM and HETATM records with the given chain ids.
A decorator for a particle with x,y,z coordinates and a radius.