IMP  2.4.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  """
27  if ca_only:
29  if model_num is None:
30  mh=IMP.atom.read_pdb(pdb_fn,mdl,sel)
31  else:
32  mhs=IMP.atom.read_multimodel_pdb(pdb_fn,mdl,sel)
33  if model_num>=len(mhs):
34  raise Exception("you requested model num "+str(model_num)+\
35  " but the PDB file only contains "+str(len(mhs))+" models")
36  mh=mhs[model_num]
37 
38  # first update using offset:
39  for rr in IMP.atom.get_by_type(mh,IMP.atom.RESIDUE_TYPE):
40  IMP.atom.Residue(rr).set_index(IMP.atom.Residue(rr).get_index()+offset)
41 
42  if res_range==[]:
43  sel=IMP.atom.Selection(mh,chain=chain_id,atom_type=IMP.atom.AtomType('CA'))
44  else:
45  sel=IMP.atom.Selection(mh,chain=chain_id,residue_indexes=range(res_range[0],res_range[1]+1),
46  atom_type=IMP.atom.AtomType('CA'))
47  ret=[]
48  for p in sel.get_selected_particles():
49  res=IMP.atom.Residue(IMP.atom.Atom(p).get_parent())
50  ret.append(res)
51  return ret
52 
53 def build_bead(model,residues,input_coord=None):
54  """Generates a single bead
55  """
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:
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  '''
95  Generates a string of beads with given length
96  '''
97  outhiers = []
98  for chunk in list(list_chunks_iterator(residues, resolution)):
99  outhiers.append(build_bead(model,chunk, input_coord=input_coord))
100  return outhiers
101 
102 
103 
104 def build_along_backbone(mdl,root,residues,rep_type,ca_centers=True):
105  """Group residues along the backbone, adding beads as needed.
106  Currently this first groups into contiguous fragment regions ('folders')
107  with identical sets of resolutions. However this behavior may
108  The current resolutions used are 0 for atomic, and N for N residues
109  per ball (see @ref pmi_resolution).
110  @param mdl the model
111  @param root the hierarchy to which all the fragments and resolutions will be added
112  @param residues list of PMI Residues, labeled with resolution
113  @param rep_type Representation type (currently supports IMP.atom.BALLS)
114  @param ca_centers If true, when making residue beads, will place the bead at the CA position
115  """
116  allowed_reps=[IMP.atom.BALLS]
117  if rep_type not in allowed_reps:
118  print("Only supported representation types are",allowed_types)
119  prev_rep = None
120  prev_atomic = False
121  cur_fragment=[]
122  fragments=[]
123 
124  # group into fragments with identical resolutions
125  for res in residues:
126  if prev_rep is None:
127  prev_rep = res.representations
128  prev_atomic = res.get_has_coordinates()
129  rep = res.representations
130  if rep==prev_rep and res.get_has_coordinates()==prev_atomic:
131  cur_fragment.append(res)
132  else:
133  fragments.append(cur_fragment)
134  cur_fragment=[res]
135  prev_rep=rep
136  prev_atomic=res.get_has_coordinates()
137  fragments.append(cur_fragment)
138 
139  # build the representations within each fragment
140 
141  for frag_res in fragments:
142  if len(frag_res[0].representations)==0:
143  continue
144  res_nums=[r.get_index() for r in frag_res]
145  name = "frag_%i-%i"%(res_nums[0],res_nums[-1])
146  if frag_res[0].get_has_coordinates():
147  this_rep=frag_res[0].representations
148  if len(this_rep)==0:
149  continue
150  frag = IMP.atom.Fragment.setup_particle(mdl,mdl.add_particle(name),res_nums)
151  root.add_child(frag)
152 
153  primary_rep_num=min(this_rep['balls'])
154  frep = IMP.atom.Representation.setup_particle(frag,primary_rep_num)
155  if 'balls' in this_rep:
156  # if atomic, add the residues as child (inside another fragment - check RMF)
157  if 0 in this_rep['balls']:
158  f=IMP.atom.Fragment.setup_particle(mdl,mdl.add_particle("resolution 0"),
159  res_nums)
160  for residue in frag_res:
161  f.add_child(residue.hier)
162  frag.add_child(f)
163 
164  # add one-residue-per-bead
165  if 1 in this_rep['balls']:
166  res1=IMP.atom.Fragment.setup_particle(mdl,mdl.add_particle("resolution 1"),res_nums)
167  for residue in frag_res:
168  if ca_centers==True:
169  rp1 = IMP.Particle(mdl)
170  rp1.set_name("Residue_%i"%residue.get_index())
171  rt=residue.get_residue_type()
172  res1.add_child(IMP.atom.Residue.setup_particle(rp1,residue.hier))
173  try:
177  IMP.atom.ResidueType("ALA"))
178  try:
179  mass = IMP.atom.get_mass(rt)
180  except:
182  calpha = IMP.atom.Selection(residue.hier,atom_type=IMP.atom.AT_CA). \
183  get_selected_particles()[0]
185  shape = IMP.algebra.Sphere3D(IMP.core.XYZ(calpha).get_coordinates(),radius)
188  if primary_rep_num==1:
189  frag.add_child(res1)
190  else:
191  frep.add_representation(res1,IMP.atom.BALLS,1)
192 
193  # add all other resolutions
194  for resolution in set(this_rep['balls']) - set([0,1]):
195  resx=IMP.atom.Fragment.setup_particle(mdl,mdl.add_particle("resolution "+str(resolution)),res_nums)
196 
197  # we create a dummy chain hierarchy and copy
198  # residues in it, beacuse the chain is required by simplified_along_backbone
199  c=IMP.atom.Chain.setup_particle(mdl,mdl.add_particle("dummy chain"),"X")
200  for residue in frag_res:
201  c.add_child(residue.hier)
203  for ch in sh.get_children():
204  resx.add_child(ch)
205  if primary_rep_num==resolution:
206  frag.add_child(resx)
207  else:
208  frep.add_representation(resx,IMP.atom.BALLS,resolution)
209  del sh
210  del c
211 
212 
213  else:
214  # frag_res is a continuous list of non-atomic residues with the same resolutions
215  this_resolutions=frag_res[0].representations['balls']
216  # check that we have only one resolution for now
217  if len(this_resolutions) > 1 :
218  print("build_along_backbone Error: residues with missing atomic coordinate should be associated with only one resolution")
219  exit()
220  this_resolution=this_resolutions.pop()
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
static Residue setup_particle(kernel::Model *m, ParticleIndex pi, ResidueType t, int index, int insertion_code)
Definition: Residue.h:157
double get_volume_from_residue_type(ResidueType rt)
Return an estimate for the volume of a given residue.
Hierarchies read_multimodel_pdb(base::TextInput input, kernel::Model *model, PDBSelector *selector=get_default_pdb_selector())
void show_molecular_hierarchy(Hierarchy h)
Print out the molecular hierarchy.
Ints get_index(const kernel::ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
double get_mass(const Selection &s)
Get the total mass of a hierarchy, in Daltons.
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:53
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.
def get_structure
read a structure from a PDB file and return a list of residues
Definition: system_tools.py:20
static bool get_is_setup(const IMP::kernel::ParticleAdaptor &p)
static XYZR setup_particle(kernel::Model *m, ParticleIndex pi)
Definition: XYZR.h:48
A decorator for a representation.
double get_volume_from_mass(double m, ProteinDensityReference ref=ALBER)
Estimate the volume of a protein from its mass.
A decorator for a particle representing an atom.
Definition: atom/Atom.h:234
Hierarchies get_by_type(Hierarchy mhd, GetByType t)
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
static Chain setup_particle(kernel::Model *m, ParticleIndex pi, std::string id)
Definition: Chain.h:41
Class to handle individual model particles.
static Mass setup_particle(kernel::Model *m, ParticleIndex pi, Float mass)
Definition: Mass.h:44
A decorator for a residue.
Definition: Residue.h:134
static Representation setup_particle(kernel::Model *m, ParticleIndex pi)
Hierarchy create_simplified_along_backbone(Chain input, const IntRanges &residue_segments, bool keep_detailed=false)
def build_necklace
Generates a string of beads with given length.
Definition: system_tools.py:93
static Fragment setup_particle(kernel::Model *m, ParticleIndex pi)
Definition: Fragment.h:63
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.
void read_pdb(base::TextInput input, int model, Hierarchy h)
Select hierarchy particles identified by the biological name.
Definition: Selection.h:62
An exception for an invalid value being passed to IMP.
Definition: exception.h:137
A decorator for a particle with x,y,z coordinates and a radius.
Definition: XYZR.h:27