IMP logo
IMP Reference Guide  2.5.0
The Integrative Modeling Platform
system_tools.py
1 """@namespace IMP.pmi.topology.system_tools
2  Tools to help build structures
3 """
4 
5 from __future__ import print_function
6 import IMP
7 import IMP.atom
8 import IMP.pmi
9 from math import pi
10 
11 def list_chunks_iterator(input_list, length):
12  """ Yield successive length-sized chunks from a list.
13  """
14  for i in range(0, len(input_list), length):
15  yield input_list[i:i + length]
16 
17 def get_structure(mdl,pdb_fn,chain_id,res_range=[],offset=0,model_num=None,ca_only=False):
18  """read a structure from a PDB file and return a list of residues
19  @param mdl The IMP model
20  @param pdb_fn The file to read
21  @param chain_id Chain ID to read
22  @param res_range Add only a specific set of residues
23  @param offset Apply an offset to the residue indexes of the PDB file
24  @param model_num Read multi-model PDB and return that model
25  @param ca_only Read only CA atoms (by default, all non-waters are read)
26  """
28  if ca_only:
30  if model_num is None:
31  mh=IMP.atom.read_pdb(pdb_fn,mdl,sel)
32  else:
33  mhs=IMP.atom.read_multimodel_pdb(pdb_fn,mdl,sel)
34  if model_num>=len(mhs):
35  raise Exception("you requested model num "+str(model_num)+\
36  " but the PDB file only contains "+str(len(mhs))+" models")
37  mh=mhs[model_num]
38 
39  # first update using offset:
40  for rr in IMP.atom.get_by_type(mh,IMP.atom.RESIDUE_TYPE):
41  IMP.atom.Residue(rr).set_index(IMP.atom.Residue(rr).get_index()+offset)
42 
43  if res_range==[]:
44  sel=IMP.atom.Selection(mh,chain=chain_id,atom_type=IMP.atom.AtomType('CA'))
45  else:
46  sel=IMP.atom.Selection(mh,chain=chain_id,residue_indexes=range(res_range[0],res_range[1]+1),
47  atom_type=IMP.atom.AtomType('CA'))
48  ret=[]
49  for p in sel.get_selected_particles():
50  res=IMP.atom.Residue(IMP.atom.Atom(p).get_parent())
51  ret.append(res)
52  return ret
53 
54 def build_bead(model,residues,input_coord=None):
55  """Generates a single bead"""
56 
57  ds_frag = (residues[0].get_index(), residues[-1].get_index())
58  prt = IMP.Particle(model)
60  ptem = IMP.core.XYZR(prt)
61  mass = IMP.atom.get_mass_from_number_of_residues(len(residues))
62 
63  if ds_frag[0] == ds_frag[-1]:
64  rt=residues[0].get_residue_type()
65  h =IMP.atom.Residue.setup_particle(prt, rt, ds_frag[0])
66  h.set_name('%i_bead' % (ds_frag[0]))
67  prt.set_name('%i_bead' % (ds_frag[0]))
68  try:
70  except IMP.ValueException:
72  IMP.atom.ResidueType("ALA"))
74  ptem.set_radius(radius)
75  else:
77  h.set_name('%i-%i_bead' % (ds_frag[0], ds_frag[-1]))
78  prt.set_name('%i-%i_bead' % (ds_frag[0], ds_frag[-1]))
79  h.set_residue_indexes(range(ds_frag[0], ds_frag[-1] + 1))
80  volume = IMP.atom.get_volume_from_mass(mass)
81  radius = 0.8 * (3.0 / 4.0 / pi * volume) ** (1.0 / 3.0)
82  ptem.set_radius(radius)
83 
85  try:
86  if not tuple(input_coord) is None:
87  ptem.set_coordinates(input_coord)
88  except TypeError:
89  pass
90 
91  return h
92 
93 def build_necklace(model,residues, resolution, input_coord=None):
94  """Generates a string of beads with given length"""
95  out_hiers = []
96  for chunk in list(list_chunks_iterator(residues, resolution)):
97  out_hiers.append(build_bead(model,chunk, input_coord=input_coord))
98  return out_hiers
99 
100 
101 
102 def build_along_backbone(mdl,root,residues,rep_type,ca_centers=True):
103  """Group residues along the backbone, adding beads as needed.
104  Currently this first groups into contiguous fragment regions ('folders')
105  with identical sets of resolutions. However this behavior may change.
106  The current resolutions used are 0 for atomic, and N for N residues
107  per ball (see @ref pmi_resolution).
108  @param mdl the model
109  @param root the hierarchy to which all the fragments and resolutions will be added
110  @param residues list of PMI Residues, labeled with resolution
111  @param rep_type Representation type (currently supports IMP.atom.BALLS)
112  @param ca_centers If true, when making residue beads, will place the bead at the CA position
113  """
114  allowed_reps=[IMP.atom.BALLS]
115  if rep_type not in allowed_reps:
116  print("Only supported representation types are",allowed_types)
117  prev_rep = None
118  prev_atomic = False
119  cur_fragment=[]
120  fragments=[]
121 
122  # group into fragments with identical resolutions
123  for res in residues:
124  if prev_rep is None:
125  prev_rep = res.representations
126  prev_atomic = res.get_has_coordinates()
127  rep = res.representations
128  if rep==prev_rep and res.get_has_coordinates()==prev_atomic:
129  cur_fragment.append(res)
130  else:
131  fragments.append(cur_fragment)
132  cur_fragment=[res]
133  prev_rep=rep
134  prev_atomic=res.get_has_coordinates()
135  fragments.append(cur_fragment)
136 
137  # build the representations within each fragment
138  for frag_res in fragments:
139  if len(frag_res[0].representations)==0:
140  continue
141  res_nums=[r.get_index() for r in frag_res]
142  name = "frag_%i-%i"%(res_nums[0],res_nums[-1])
143  if frag_res[0].get_has_coordinates():
144  this_rep=frag_res[0].representations
145  if len(this_rep)==0:
146  continue
147  frag = IMP.atom.Fragment.setup_particle(mdl,mdl.add_particle(name),res_nums)
148  root.add_child(frag)
149 
150  primary_rep_num=min(this_rep['balls'])
151  frep = IMP.atom.Representation.setup_particle(frag,primary_rep_num)
152  if 'balls' in this_rep:
153  # if atomic, add the residues as child (inside another fragment - check RMF)
154  if 0 in this_rep['balls']:
155  f=IMP.atom.Fragment.setup_particle(mdl,mdl.add_particle("resolution 0"),
156  res_nums)
157  for residue in frag_res:
158  f.add_child(residue.hier)
159  frag.add_child(f)
160 
161  # add one-residue-per-bead
162  if 1 in this_rep['balls']:
163  res1=IMP.atom.Fragment.setup_particle(mdl,mdl.add_particle("resolution 1"),res_nums)
164  for residue in frag_res:
165  if ca_centers==True:
166  rp1 = IMP.Particle(mdl)
167  rp1.set_name("Residue_%i"%residue.get_index())
168  rt=residue.get_residue_type()
169  res1.add_child(IMP.atom.Residue.setup_particle(rp1,residue.hier))
170  try:
172  except IMP.ValueException:
174  IMP.atom.ResidueType("ALA"))
175  try:
176  mass = IMP.atom.get_mass(rt)
177  except:
179  calpha = IMP.atom.Selection(residue.hier,atom_type=IMP.atom.AT_CA). \
180  get_selected_particles()[0]
182  shape = IMP.algebra.Sphere3D(IMP.core.XYZ(calpha).get_coordinates(),radius)
185  if primary_rep_num==1:
186  frag.add_child(res1)
187  else:
188  frep.add_representation(res1,IMP.atom.BALLS,1)
189 
190  # add all other resolutions
191  for resolution in set(this_rep['balls']) - set([0,1]):
192  resx=IMP.atom.Fragment.setup_particle(mdl,mdl.add_particle("resolution "+str(resolution)),res_nums)
193 
194  # we create a dummy chain hierarchy and copy
195  # residues in it, beacuse the chain is required by simplified_along_backbone
196  c=IMP.atom.Chain.setup_particle(mdl,mdl.add_particle("dummy chain"),"X")
197  for residue in frag_res:
198  c.add_child(residue.hier)
200  for ch in sh.get_children():
201  resx.add_child(ch)
202  if primary_rep_num==resolution:
203  frag.add_child(resx)
204  else:
205  frep.add_representation(resx,IMP.atom.BALLS,resolution)
206  del sh
207  del c
208 
209 
210  else:
211  # here frag_res is a continuous list of non-atomic residues with the same resolutions
212  this_resolutions=frag_res[0].representations['balls']
213  # check that we have only one resolution for now
214  if len(this_resolutions) > 1 :
215  raise ValueError("build_along_backbone Error: residues with missing atomic coordinate should be associated with only one resolution")
216  if len(this_resolutions) == 0 :
217  print("build_along_backbone Error: no structure but trying to build resolution 0")
218  exit()
219  this_resolution=list(this_resolutions)[0]
220 
221  # create a root hierarchy node for the beads
222  frag = IMP.atom.Fragment.setup_particle(mdl,mdl.add_particle(name),res_nums)
223  root.add_child(frag)
224  frep = IMP.atom.Representation.setup_particle(frag,this_resolution)
225  hiers=build_necklace(mdl,frag_res,this_resolution)
226  for h in hiers:
227  frag.add_child(h)
228 
229 def show_representation(node):
230  print(node)
232  repr = IMP.atom.Representation(node)
233  resolutions = repr.get_resolutions()
234  for r in resolutions:
235  print('---- resolution %i ----' %r)
236  IMP.atom.show_molecular_hierarchy(repr.get_representation(r))
237  return True
238  else:
239  return False
240 
241 def recursive_show_representations(root):
242  pass
double get_volume_from_residue_type(ResidueType rt)
Return an estimate for the volume of a given residue.
void show_molecular_hierarchy(Hierarchy h)
Print out the molecular hierarchy.
static Fragment setup_particle(Model *m, ParticleIndex pi)
Definition: Fragment.h:63
double get_mass(const Selection &s)
Get the total mass of a hierarchy, in Daltons.
static XYZR setup_particle(Model *m, ParticleIndex pi)
Definition: XYZR.h:48
double get_mass_from_number_of_residues(unsigned int num_aa)
Estimate the mass of a protein from the number of amino acids.
def build_bead
Generates a single bead.
Definition: system_tools.py:54
double get_ball_radius_from_volume_3d(double volume)
Return the radius of a sphere with a given volume.
Definition: Sphere3D.h:35
def build_along_backbone
Group residues along the backbone, adding beads as needed.
The type of an atom.
static Residue setup_particle(Model *m, ParticleIndex pi, ResidueType t, int index, int insertion_code)
Definition: Residue.h:157
static Representation setup_particle(Model *m, ParticleIndex pi)
void read_pdb(TextInput input, int model, Hierarchy h)
def get_structure
read a structure from a PDB file and return a list of residues
Definition: system_tools.py:23
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.
Definition: atom/Atom.h:234
static Mass setup_particle(Model *m, ParticleIndex pi, Float mass)
Definition: Mass.h:44
Hierarchies get_by_type(Hierarchy mhd, GetByType t)
Gather all the molecular particles of a certain level in the hierarchy.
The type for a residue.
PDBSelector * get_default_pdb_selector()
Definition: pdb.h:344
def list_chunks_iterator
Yield successive length-sized chunks from a list.
Definition: system_tools.py:11
A decorator for a particle with x,y,z coordinates.
Definition: XYZ.h:30
A decorator for a residue.
Definition: Residue.h:134
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Hierarchies read_multimodel_pdb(TextInput input, Model *model, PDBSelector *selector=get_default_pdb_selector())
The general base class for IMP exceptions.
Definition: exception.h:49
Hierarchy create_simplified_along_backbone(Chain input, const IntRanges &residue_segments, bool keep_detailed=false)
Class to handle individual model particles.
Definition: Particle.h:37
def build_necklace
Generates a string of beads with given length.
Definition: system_tools.py:93
Select all CA ATOM records.
Definition: pdb.h:76
Python classes to represent, score, sample and analyze models.
Functionality for loading, creating, manipulating and scoring atomic structures.
static Chain setup_particle(Model *m, ParticleIndex pi, std::string id)
Definition: Chain.h:41
An exception for an invalid value being passed to IMP.
Definition: exception.h:137
Select hierarchy particles identified by the biological name.
Definition: Selection.h:65
A decorator for a particle with x,y,z coordinates and a radius.
Definition: XYZR.h:27