IMP logo
IMP Reference Guide  2.12.0
The Integrative Modeling Platform
output.py
1 """@namespace IMP.pmi.output
2  Classes for writing output files and processing them.
3 """
4 
5 from __future__ import print_function, division
6 import IMP
7 import IMP.atom
8 import IMP.core
9 import IMP.pmi
10 import IMP.pmi.tools
11 import IMP.pmi.io
12 import os
13 import sys
14 import ast
15 import RMF
16 import numpy as np
17 import operator
18 import string
19 try:
20  import cPickle as pickle
21 except ImportError:
22  import pickle
23 
24 class _ChainIDs(object):
25  """Map indices to multi-character chain IDs.
26  We label the first 26 chains A-Z, then we move to two-letter
27  chain IDs: AA through AZ, then BA through BZ, through to ZZ.
28  This continues with longer chain IDs."""
29  def __getitem__(self, ind):
30  chars = string.ascii_uppercase
31  lc = len(chars)
32  ids = []
33  while ind >= lc:
34  ids.append(chars[ind % lc])
35  ind = ind // lc - 1
36  ids.append(chars[ind])
37  return "".join(reversed(ids))
38 
39 
40 class ProtocolOutput(object):
41  """Base class for capturing a modeling protocol.
42  Unlike simple output of model coordinates, a complete
43  protocol includes the input data used, details on the restraints,
44  sampling, and clustering, as well as output models.
45  Use via IMP.pmi.topology.System.add_protocol_output().
46 
47  @see IMP.pmi.mmcif.ProtocolOutput for a concrete subclass that outputs
48  mmCIF files.
49  """
50  pass
51 
52 def _flatten(seq):
53  for elt in seq:
54  if isinstance(elt, (tuple, list)):
55  for elt2 in _flatten(elt):
56  yield elt2
57  else:
58  yield elt
59 
60 class Output(object):
61  """Class for easy writing of PDBs, RMFs, and stat files
62 
63  @note Model should be updated prior to writing outputs.
64  """
65  def __init__(self, ascii=True,atomistic=False):
66  self.dictionary_pdbs = {}
67  self.dictionary_rmfs = {}
68  self.dictionary_stats = {}
69  self.dictionary_stats2 = {}
70  self.best_score_list = None
71  self.nbestscoring = None
72  self.suffixes = []
73  self.replica_exchange = False
74  self.ascii = ascii
75  self.initoutput = {}
76  self.residuetypekey = IMP.StringKey("ResidueName")
77  # 1-character chain IDs, suitable for PDB output
78  self.chainids = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
79  # Multi-character chain IDs, suitable for mmCIF output
80  self.multi_chainids = _ChainIDs()
81  self.dictchain = {} # keys are molecule names, values are chain ids
82  self.particle_infos_for_pdb = {}
83  self.atomistic=atomistic
84  self.use_pmi2 = False
85 
86  def get_pdb_names(self):
87  """Get a list of all PDB files being output by this instance"""
88  return list(self.dictionary_pdbs.keys())
89 
90  def get_rmf_names(self):
91  return list(self.dictionary_rmfs.keys())
92 
93  def get_stat_names(self):
94  return list(self.dictionary_stats.keys())
95 
96  def _init_dictchain(self, name, prot, multichar_chain=False):
97  self.dictchain[name] = {}
98  self.use_pmi2 = False
99 
100  # attempt to find PMI objects.
101  if IMP.pmi.get_is_canonical(prot):
102  self.use_pmi2 = True
103  self.atomistic = True #detects automatically
104  for n,mol in enumerate(IMP.atom.get_by_type(prot,IMP.atom.MOLECULE_TYPE)):
105  chid = IMP.atom.Chain(mol).get_id()
106  self.dictchain[name][IMP.pmi.get_molecule_name_and_copy(mol)] = chid
107  else:
108  chainids = self.multi_chainids if multichar_chain else self.chainids
109  for n, i in enumerate(self.dictionary_pdbs[name].get_children()):
110  self.dictchain[name][i.get_name()] = chainids[n]
111 
112  def init_pdb(self, name, prot):
113  """Init PDB Writing.
114  @param name The PDB filename
115  @param prot The hierarchy to write to this pdb file
116  @note if the PDB name is 'System' then will use Selection to get molecules
117  """
118  flpdb = open(name, 'w')
119  flpdb.close()
120  self.dictionary_pdbs[name] = prot
121  self._init_dictchain(name, prot)
122 
123  def write_psf(self,filename,name):
124  flpsf=open(filename,'w')
125  flpsf.write("PSF CMAP CHEQ"+"\n")
126  index_residue_pair_list={}
127  (particle_infos_for_pdb, geometric_center)=self.get_particle_infos_for_pdb_writing(name)
128  nparticles=len(particle_infos_for_pdb)
129  flpsf.write(str(nparticles)+" !NATOM"+"\n")
130  for n,p in enumerate(particle_infos_for_pdb):
131  atom_index=n+1
132  residue_type=p[2]
133  chain=p[3]
134  resid=p[4]
135  flpsf.write('{0:8d}{1:1s}{2:4s}{3:1s}{4:4s}{5:1s}{6:4s}{7:1s}{8:4s}{9:1s}{10:4s}{11:14.6f}{12:14.6f}{13:8d}{14:14.6f}{15:14.6f}'.format(atom_index," ",chain," ",str(resid)," ",'"'+residue_type.get_string()+'"'," ","C"," ","C",1.0,0.0,0,0.0,0.0))
136  flpsf.write('\n')
137  #flpsf.write(str(atom_index)+" "+str(chain)+" "+str(resid)+" "+str(residue_type).replace('"','')+" C C "+"1.0 0.0 0 0.0 0.0\n")
138  if chain not in index_residue_pair_list:
139  index_residue_pair_list[chain]=[(atom_index,resid)]
140  else:
141  index_residue_pair_list[chain].append((atom_index,resid))
142 
143 
144  #now write the connectivity
145  indexes_pairs=[]
146  for chain in sorted(index_residue_pair_list.keys()):
147 
148  ls=index_residue_pair_list[chain]
149  #sort by residue
150  ls=sorted(ls, key=lambda tup: tup[1])
151  #get the index list
152  indexes=[x[0] for x in ls]
153  # get the contiguous pairs
154  indexes_pairs+=list(IMP.pmi.tools.sublist_iterator(indexes,lmin=2,lmax=2))
155  nbonds=len(indexes_pairs)
156  flpsf.write(str(nbonds)+" !NBOND: bonds"+"\n")
157 
158  # save bonds in fixed column format
159  for i in range(0,len(indexes_pairs),4):
160  for bond in indexes_pairs[i:i+4]:
161  flpsf.write('{0:8d}{1:8d}'.format(*bond))
162  flpsf.write('\n')
163 
164  del particle_infos_for_pdb
165  flpsf.close()
166 
167  def write_pdb(self,name,
168  appendmode=True,
169  translate_to_geometric_center=False,
170  write_all_residues_per_bead=False):
171  if appendmode:
172  flpdb = open(name, 'a')
173  else:
174  flpdb = open(name, 'w')
175 
176  (particle_infos_for_pdb,
177  geometric_center) = self.get_particle_infos_for_pdb_writing(name)
178 
179  if not translate_to_geometric_center:
180  geometric_center = (0, 0, 0)
181 
182  for n,tupl in enumerate(particle_infos_for_pdb):
183  (xyz, atom_type, residue_type,
184  chain_id, residue_index, all_indexes, radius) = tupl
185  if atom_type is None:
186  atom_type = IMP.atom.AT_CA
187  if ( (write_all_residues_per_bead) and (all_indexes is not None) ):
188  for residue_number in all_indexes:
189  flpdb.write(IMP.atom.get_pdb_string((xyz[0] - geometric_center[0],
190  xyz[1] - geometric_center[1],
191  xyz[2] - geometric_center[2]),
192  n+1, atom_type, residue_type,
193  chain_id, residue_number,' ',1.00,radius))
194  else:
195  flpdb.write(IMP.atom.get_pdb_string((xyz[0] - geometric_center[0],
196  xyz[1] - geometric_center[1],
197  xyz[2] - geometric_center[2]),
198  n+1, atom_type, residue_type,
199  chain_id, residue_index,' ',1.00,radius))
200  flpdb.write("ENDMDL\n")
201  flpdb.close()
202 
203  del particle_infos_for_pdb
204 
205  def get_prot_name_from_particle(self, name, p):
206  """Get the protein name from the particle.
207  This is done by traversing the hierarchy."""
208  if self.use_pmi2:
209  return IMP.pmi.get_molecule_name_and_copy(p), True
210  else:
212  p, self.dictchain[name])
213 
214  def get_particle_infos_for_pdb_writing(self, name):
215  # index_residue_pair_list={}
216 
217  # the resindexes dictionary keep track of residues that have been already
218  # added to avoid duplication
219  # highest resolution have highest priority
220  resindexes_dict = {}
221 
222  # this dictionary dill contain the sequence of tuples needed to
223  # write the pdb
224  particle_infos_for_pdb = []
225 
226  geometric_center = [0, 0, 0]
227  atom_count = 0
228  atom_index = 0
229 
230  if self.use_pmi2:
231  # select highest resolution
232  ps = IMP.atom.Selection(self.dictionary_pdbs[name],resolution=0).get_selected_particles()
233  else:
234  ps = IMP.atom.get_leaves(self.dictionary_pdbs[name])
235 
236  for n, p in enumerate(ps):
237  protname, is_a_bead = self.get_prot_name_from_particle(name, p)
238 
239  if protname not in resindexes_dict:
240  resindexes_dict[protname] = []
241 
242  if IMP.atom.Atom.get_is_setup(p) and self.atomistic:
243  residue = IMP.atom.Residue(IMP.atom.Atom(p).get_parent())
244  rt = residue.get_residue_type()
245  resind = residue.get_index()
246  atomtype = IMP.atom.Atom(p).get_atom_type()
247  xyz = list(IMP.core.XYZ(p).get_coordinates())
248  radius = IMP.core.XYZR(p).get_radius()
249  geometric_center[0] += xyz[0]
250  geometric_center[1] += xyz[1]
251  geometric_center[2] += xyz[2]
252  atom_count += 1
253  particle_infos_for_pdb.append((xyz,
254  atomtype, rt, self.dictchain[name][protname], resind, None, radius))
255  resindexes_dict[protname].append(resind)
256 
258 
259  residue = IMP.atom.Residue(p)
260  resind = residue.get_index()
261  # skip if the residue was already added by atomistic resolution
262  # 0
263  if resind in resindexes_dict[protname]:
264  continue
265  else:
266  resindexes_dict[protname].append(resind)
267  rt = residue.get_residue_type()
268  xyz = IMP.core.XYZ(p).get_coordinates()
269  radius = IMP.core.XYZR(p).get_radius()
270  geometric_center[0] += xyz[0]
271  geometric_center[1] += xyz[1]
272  geometric_center[2] += xyz[2]
273  atom_count += 1
274  particle_infos_for_pdb.append((xyz, None,
275  rt, self.dictchain[name][protname], resind, None, radius))
276 
277  elif IMP.atom.Fragment.get_is_setup(p) and not is_a_bead:
278  resindexes = IMP.pmi.tools.get_residue_indexes(p)
279  resind = resindexes[len(resindexes) // 2]
280  if resind in resindexes_dict[protname]:
281  continue
282  else:
283  resindexes_dict[protname].append(resind)
284  rt = IMP.atom.ResidueType('BEA')
285  xyz = IMP.core.XYZ(p).get_coordinates()
286  radius = IMP.core.XYZR(p).get_radius()
287  geometric_center[0] += xyz[0]
288  geometric_center[1] += xyz[1]
289  geometric_center[2] += xyz[2]
290  atom_count += 1
291  particle_infos_for_pdb.append((xyz, None,
292  rt, self.dictchain[name][protname], resind, resindexes, radius))
293 
294  else:
295  if is_a_bead:
296  rt = IMP.atom.ResidueType('BEA')
297  resindexes = IMP.pmi.tools.get_residue_indexes(p)
298  if len(resindexes) > 0:
299  resind = resindexes[len(resindexes) // 2]
300  xyz = IMP.core.XYZ(p).get_coordinates()
301  radius = IMP.core.XYZR(p).get_radius()
302  geometric_center[0] += xyz[0]
303  geometric_center[1] += xyz[1]
304  geometric_center[2] += xyz[2]
305  atom_count += 1
306  particle_infos_for_pdb.append((xyz, None,
307  rt, self.dictchain[name][protname], resind, resindexes, radius))
308 
309  if atom_count > 0:
310  geometric_center = (geometric_center[0] / atom_count,
311  geometric_center[1] / atom_count,
312  geometric_center[2] / atom_count)
313 
314  # sort by chain ID, then residue index. Longer chain IDs (e.g. AA)
315  # should always come after shorter (e.g. Z)
316  particle_infos_for_pdb = sorted(particle_infos_for_pdb,
317  key=lambda x: (len(x[3]), x[3], x[4]))
318 
319  return (particle_infos_for_pdb, geometric_center)
320 
321 
322  def write_pdbs(self, appendmode=True):
323  for pdb in self.dictionary_pdbs.keys():
324  self.write_pdb(pdb, appendmode)
325 
326  def init_pdb_best_scoring(self,
327  suffix,
328  prot,
329  nbestscoring,
330  replica_exchange=False):
331  # save only the nbestscoring conformations
332  # create as many pdbs as needed
333 
334  self.suffixes.append(suffix)
335  self.replica_exchange = replica_exchange
336  if not self.replica_exchange:
337  # common usage
338  # if you are not in replica exchange mode
339  # initialize the array of scores internally
340  self.best_score_list = []
341  else:
342  # otherwise the replicas must communicate
343  # through a common file to know what are the best scores
344  self.best_score_file_name = "best.scores.rex.py"
345  self.best_score_list = []
346  with open(self.best_score_file_name, "w") as best_score_file:
347  best_score_file.write(
348  "self.best_score_list=" + str(self.best_score_list) + "\n")
349 
350  self.nbestscoring = nbestscoring
351  for i in range(self.nbestscoring):
352  name = suffix + "." + str(i) + ".pdb"
353  flpdb = open(name, 'w')
354  flpdb.close()
355  self.dictionary_pdbs[name] = prot
356  self._init_dictchain(name, prot)
357 
358  def write_pdb_best_scoring(self, score):
359  if self.nbestscoring is None:
360  print("Output.write_pdb_best_scoring: init_pdb_best_scoring not run")
361 
362  # update the score list
363  if self.replica_exchange:
364  # read the self.best_score_list from the file
365  with open(self.best_score_file_name) as fh:
366  exec(fh.read())
367 
368  if len(self.best_score_list) < self.nbestscoring:
369  self.best_score_list.append(score)
370  self.best_score_list.sort()
371  index = self.best_score_list.index(score)
372  for suffix in self.suffixes:
373  for i in range(len(self.best_score_list) - 2, index - 1, -1):
374  oldname = suffix + "." + str(i) + ".pdb"
375  newname = suffix + "." + str(i + 1) + ".pdb"
376  # rename on Windows fails if newname already exists
377  if os.path.exists(newname):
378  os.unlink(newname)
379  os.rename(oldname, newname)
380  filetoadd = suffix + "." + str(index) + ".pdb"
381  self.write_pdb(filetoadd, appendmode=False)
382 
383  else:
384  if score < self.best_score_list[-1]:
385  self.best_score_list.append(score)
386  self.best_score_list.sort()
387  self.best_score_list.pop(-1)
388  index = self.best_score_list.index(score)
389  for suffix in self.suffixes:
390  for i in range(len(self.best_score_list) - 1, index - 1, -1):
391  oldname = suffix + "." + str(i) + ".pdb"
392  newname = suffix + "." + str(i + 1) + ".pdb"
393  os.rename(oldname, newname)
394  filenametoremove = suffix + \
395  "." + str(self.nbestscoring) + ".pdb"
396  os.remove(filenametoremove)
397  filetoadd = suffix + "." + str(index) + ".pdb"
398  self.write_pdb(filetoadd, appendmode=False)
399 
400  if self.replica_exchange:
401  # write the self.best_score_list to the file
402  with open(self.best_score_file_name, "w") as best_score_file:
403  best_score_file.write(
404  "self.best_score_list=" + str(self.best_score_list) + '\n')
405 
406  def init_rmf(self, name, hierarchies, rs=None, geometries=None, listofobjects=None):
407  """
408  Initialize an RMF file
409 
410  @param name the name of the RMF file
411  @param hierarchies the hierarchies to be included (it is a list)
412  @param rs optional, the restraint sets (it is a list)
413  @param geometries optional, the geometries (it is a list)
414  @param listofobjects optional, the list of objects for the stat (it is a list)
415  """
416  rh = RMF.create_rmf_file(name)
417  IMP.rmf.add_hierarchies(rh, hierarchies)
418  cat=None
419  outputkey_rmfkey=None
420 
421  if rs is not None:
423  if geometries is not None:
424  IMP.rmf.add_geometries(rh,geometries)
425  if listofobjects is not None:
426  cat = rh.get_category("stat")
427  outputkey_rmfkey={}
428  for l in listofobjects:
429  if not "get_output" in dir(l):
430  raise ValueError("Output: object %s doesn't have get_output() method" % str(l))
431  output=l.get_output()
432  for outputkey in output:
433  rmftag=RMF.string_tag
434  if isinstance(output[outputkey], float):
435  rmftag = RMF.float_tag
436  elif isinstance(output[outputkey], int):
437  rmftag = RMF.int_tag
438  elif isinstance(output[outputkey], str):
439  rmftag = RMF.string_tag
440  else:
441  rmftag = RMF.string_tag
442  rmfkey=rh.get_key(cat, outputkey, rmftag)
443  outputkey_rmfkey[outputkey]=rmfkey
444  outputkey_rmfkey["rmf_file"]=rh.get_key(cat, "rmf_file", RMF.string_tag)
445  outputkey_rmfkey["rmf_frame_index"]=rh.get_key(cat, "rmf_frame_index", RMF.int_tag)
446 
447  self.dictionary_rmfs[name] = (rh,cat,outputkey_rmfkey,listofobjects)
448 
449  def add_restraints_to_rmf(self, name, objectlist):
450  for o in _flatten(objectlist):
451  try:
452  rs = o.get_restraint_for_rmf()
453  except:
454  rs = o.get_restraint()
456  self.dictionary_rmfs[name][0],
457  rs.get_restraints())
458 
459  def add_geometries_to_rmf(self, name, objectlist):
460  for o in objectlist:
461  geos = o.get_geometries()
462  IMP.rmf.add_geometries(self.dictionary_rmfs[name][0], geos)
463 
464  def add_particle_pair_from_restraints_to_rmf(self, name, objectlist):
465  for o in objectlist:
466 
467  pps = o.get_particle_pairs()
468  for pp in pps:
470  self.dictionary_rmfs[name][0],
472 
473  def write_rmf(self, name):
474  IMP.rmf.save_frame(self.dictionary_rmfs[name][0])
475  if self.dictionary_rmfs[name][1] is not None:
476  cat=self.dictionary_rmfs[name][1]
477  outputkey_rmfkey=self.dictionary_rmfs[name][2]
478  listofobjects=self.dictionary_rmfs[name][3]
479  for l in listofobjects:
480  output=l.get_output()
481  for outputkey in output:
482  rmfkey=outputkey_rmfkey[outputkey]
483  try:
484  self.dictionary_rmfs[name][0].get_root_node().set_value(rmfkey,output[outputkey])
485  except NotImplementedError:
486  continue
487  rmfkey = outputkey_rmfkey["rmf_file"]
488  self.dictionary_rmfs[name][0].get_root_node().set_value(rmfkey, name)
489  rmfkey = outputkey_rmfkey["rmf_frame_index"]
490  nframes=self.dictionary_rmfs[name][0].get_number_of_frames()
491  self.dictionary_rmfs[name][0].get_root_node().set_value(rmfkey, nframes-1)
492  self.dictionary_rmfs[name][0].flush()
493 
494  def close_rmf(self, name):
495  rh = self.dictionary_rmfs[name][0]
496  del self.dictionary_rmfs[name]
497  del rh
498 
499  def write_rmfs(self):
500  for rmfinfo in self.dictionary_rmfs.keys():
501  self.write_rmf(rmfinfo[0])
502 
503  def init_stat(self, name, listofobjects):
504  if self.ascii:
505  flstat = open(name, 'w')
506  flstat.close()
507  else:
508  flstat = open(name, 'wb')
509  flstat.close()
510 
511  # check that all objects in listofobjects have a get_output method
512  for l in listofobjects:
513  if not "get_output" in dir(l):
514  raise ValueError("Output: object %s doesn't have get_output() method" % str(l))
515  self.dictionary_stats[name] = listofobjects
516 
517  def set_output_entry(self, key, value):
518  self.initoutput.update({key: value})
519 
520  def write_stat(self, name, appendmode=True):
521  output = self.initoutput
522  for obj in self.dictionary_stats[name]:
523  d = obj.get_output()
524  # remove all entries that begin with _ (private entries)
525  dfiltered = dict((k, v) for k, v in d.items() if k[0] != "_")
526  output.update(dfiltered)
527 
528  if appendmode:
529  writeflag = 'a'
530  else:
531  writeflag = 'w'
532 
533  if self.ascii:
534  flstat = open(name, writeflag)
535  flstat.write("%s \n" % output)
536  flstat.close()
537  else:
538  flstat = open(name, writeflag + 'b')
539  cPickle.dump(output, flstat, 2)
540  flstat.close()
541 
542  def write_stats(self):
543  for stat in self.dictionary_stats.keys():
544  self.write_stat(stat)
545 
546  def get_stat(self, name):
547  output = {}
548  for obj in self.dictionary_stats[name]:
549  output.update(obj.get_output())
550  return output
551 
552  def write_test(self, name, listofobjects):
553 # write the test:
554 # output=output.Output()
555 # output.write_test("test_modeling11_models.rmf_45492_11Sep13_veena_imp-020713.dat",outputobjects)
556 # run the test:
557 # output=output.Output()
558 # output.test("test_modeling11_models.rmf_45492_11Sep13_veena_imp-020713.dat",outputobjects)
559  flstat = open(name, 'w')
560  output = self.initoutput
561  for l in listofobjects:
562  if not "get_test_output" in dir(l) and not "get_output" in dir(l):
563  raise ValueError("Output: object %s doesn't have get_output() or get_test_output() method" % str(l))
564  self.dictionary_stats[name] = listofobjects
565 
566  for obj in self.dictionary_stats[name]:
567  try:
568  d = obj.get_test_output()
569  except:
570  d = obj.get_output()
571  # remove all entries that begin with _ (private entries)
572  dfiltered = dict((k, v) for k, v in d.items() if k[0] != "_")
573  output.update(dfiltered)
574  #output.update({"ENVIRONMENT": str(self.get_environment_variables())})
575  #output.update(
576  # {"IMP_VERSIONS": str(self.get_versions_of_relevant_modules())})
577  flstat.write("%s \n" % output)
578  flstat.close()
579 
580  def test(self, name, listofobjects, tolerance=1e-5):
581  output = self.initoutput
582  for l in listofobjects:
583  if not "get_test_output" in dir(l) and not "get_output" in dir(l):
584  raise ValueError("Output: object %s doesn't have get_output() or get_test_output() method" % str(l))
585  for obj in listofobjects:
586  try:
587  output.update(obj.get_test_output())
588  except:
589  output.update(obj.get_output())
590  #output.update({"ENVIRONMENT": str(self.get_environment_variables())})
591  #output.update(
592  # {"IMP_VERSIONS": str(self.get_versions_of_relevant_modules())})
593 
594  flstat = open(name, 'r')
595 
596  passed=True
597  for l in flstat:
598  test_dict = ast.literal_eval(l)
599  for k in test_dict:
600  if k in output:
601  old_value = str(test_dict[k])
602  new_value = str(output[k])
603  try:
604  float(old_value)
605  is_float = True
606  except ValueError:
607  is_float = False
608 
609  if is_float:
610  fold = float(old_value)
611  fnew = float(new_value)
612  diff = abs(fold - fnew)
613  if diff > tolerance:
614  print("%s: test failed, old value: %s new value %s; "
615  "diff %f > %f" % (str(k), str(old_value),
616  str(new_value), diff,
617  tolerance), file=sys.stderr)
618  passed=False
619  elif test_dict[k] != output[k]:
620  if len(old_value) < 50 and len(new_value) < 50:
621  print("%s: test failed, old value: %s new value %s"
622  % (str(k), old_value, new_value), file=sys.stderr)
623  passed=False
624  else:
625  print("%s: test failed, omitting results (too long)"
626  % str(k), file=sys.stderr)
627  passed=False
628 
629  else:
630  print("%s from old objects (file %s) not in new objects"
631  % (str(k), str(name)), file=sys.stderr)
632  flstat.close()
633  return passed
634 
635  def get_environment_variables(self):
636  import os
637  return str(os.environ)
638 
639  def get_versions_of_relevant_modules(self):
640  import IMP
641  versions = {}
642  versions["IMP_VERSION"] = IMP.get_module_version()
643  versions["PMI_VERSION"] = IMP.pmi.get_module_version()
644  try:
645  import IMP.isd2
646  versions["ISD2_VERSION"] = IMP.isd2.get_module_version()
647  except (ImportError):
648  pass
649  try:
650  import IMP.isd_emxl
651  versions["ISD_EMXL_VERSION"] = IMP.isd_emxl.get_module_version()
652  except (ImportError):
653  pass
654  return versions
655 
656 #-------------------
657  def init_stat2(
658  self,
659  name,
660  listofobjects,
661  extralabels=None,
662  listofsummedobjects=None):
663  # this is a new stat file that should be less
664  # space greedy!
665  # listofsummedobjects must be in the form [([obj1,obj2,obj3,obj4...],label)]
666  # extralabels
667 
668  if listofsummedobjects is None:
669  listofsummedobjects = []
670  if extralabels is None:
671  extralabels = []
672  flstat = open(name, 'w')
673  output = {}
674  stat2_keywords = {"STAT2HEADER": "STAT2HEADER"}
675  stat2_keywords.update(
676  {"STAT2HEADER_ENVIRON": str(self.get_environment_variables())})
677  stat2_keywords.update(
678  {"STAT2HEADER_IMP_VERSIONS": str(self.get_versions_of_relevant_modules())})
679  stat2_inverse = {}
680 
681  for l in listofobjects:
682  if not "get_output" in dir(l):
683  raise ValueError("Output: object %s doesn't have get_output() method" % str(l))
684  else:
685  d = l.get_output()
686  # remove all entries that begin with _ (private entries)
687  dfiltered = dict((k, v)
688  for k, v in d.items() if k[0] != "_")
689  output.update(dfiltered)
690 
691  # check for customizable entries
692  for l in listofsummedobjects:
693  for t in l[0]:
694  if not "get_output" in dir(t):
695  raise ValueError("Output: object %s doesn't have get_output() method" % str(t))
696  else:
697  if "_TotalScore" not in t.get_output():
698  raise ValueError("Output: object %s doesn't have _TotalScore entry to be summed" % str(t))
699  else:
700  output.update({l[1]: 0.0})
701 
702  for k in extralabels:
703  output.update({k: 0.0})
704 
705  for n, k in enumerate(output):
706  stat2_keywords.update({n: k})
707  stat2_inverse.update({k: n})
708 
709  flstat.write("%s \n" % stat2_keywords)
710  flstat.close()
711  self.dictionary_stats2[name] = (
712  listofobjects,
713  stat2_inverse,
714  listofsummedobjects,
715  extralabels)
716 
717  def write_stat2(self, name, appendmode=True):
718  output = {}
719  (listofobjects, stat2_inverse, listofsummedobjects,
720  extralabels) = self.dictionary_stats2[name]
721 
722  # writing objects
723  for obj in listofobjects:
724  od = obj.get_output()
725  dfiltered = dict((k, v) for k, v in od.items() if k[0] != "_")
726  for k in dfiltered:
727  output.update({stat2_inverse[k]: od[k]})
728 
729  # writing summedobjects
730  for l in listofsummedobjects:
731  partial_score = 0.0
732  for t in l[0]:
733  d = t.get_output()
734  partial_score += float(d["_TotalScore"])
735  output.update({stat2_inverse[l[1]]: str(partial_score)})
736 
737  # writing extralabels
738  for k in extralabels:
739  if k in self.initoutput:
740  output.update({stat2_inverse[k]: self.initoutput[k]})
741  else:
742  output.update({stat2_inverse[k]: "None"})
743 
744  if appendmode:
745  writeflag = 'a'
746  else:
747  writeflag = 'w'
748 
749  flstat = open(name, writeflag)
750  flstat.write("%s \n" % output)
751  flstat.close()
752 
753  def write_stats2(self):
754  for stat in self.dictionary_stats2.keys():
755  self.write_stat2(stat)
756 
757 
758 class OutputStatistics(object):
759  """Collect statistics from ProcessOutput.get_fields().
760  Counters of the total number of frames read, plus the models that
761  passed the various filters used in get_fields(), are provided."""
762  def __init__(self):
763  self.total = 0
764  self.passed_get_every = 0
765  self.passed_filterout = 0
766  self.passed_filtertuple = 0
767 
768 
769 class ProcessOutput(object):
770  """A class for reading stat files (either rmf or ascii v1 and v2)"""
771  def __init__(self, filename):
772  self.filename = filename
773  self.isstat1 = False
774  self.isstat2 = False
775  self.isrmf = False
776 
777  if self.filename is None:
778  raise ValueError("No file name provided. Use -h for help")
779 
780  try:
781  #let's see if that is an rmf file
782  rh = RMF.open_rmf_file_read_only(self.filename)
783  self.isrmf=True
784  cat=rh.get_category('stat')
785  rmf_klist=rh.get_keys(cat)
786  self.rmf_names_keys=dict([(rh.get_name(k),k) for k in rmf_klist])
787  del rh
788 
789  except IOError:
790  f = open(self.filename, "r")
791  # try with an ascii stat file
792  # get the keys from the first line
793  for line in f.readlines():
794  d = ast.literal_eval(line)
795  self.klist = list(d.keys())
796  # check if it is a stat2 file
797  if "STAT2HEADER" in self.klist:
798  self.isstat2 = True
799  for k in self.klist:
800  if "STAT2HEADER" in str(k):
801  # if print_header: print k, d[k]
802  del d[k]
803  stat2_dict = d
804  # get the list of keys sorted by value
805  kkeys = [k[0]
806  for k in sorted(stat2_dict.items(), key=operator.itemgetter(1))]
807  self.klist = [k[1]
808  for k in sorted(stat2_dict.items(), key=operator.itemgetter(1))]
809  self.invstat2_dict = {}
810  for k in kkeys:
811  self.invstat2_dict.update({stat2_dict[k]: k})
812  else:
813  IMP.handle_use_deprecated("statfile v1 is deprecated. "
814  "Please convert to statfile v2.\n")
815  self.isstat1 = True
816  self.klist.sort()
817 
818  break
819  f.close()
820 
821 
822  def get_keys(self):
823  if self.isrmf:
824  return sorted(self.rmf_names_keys.keys())
825  else:
826  return self.klist
827 
828  def show_keys(self, ncolumns=2, truncate=65):
829  IMP.pmi.tools.print_multicolumn(self.get_keys(), ncolumns, truncate)
830 
831  def get_fields(self, fields, filtertuple=None, filterout=None, get_every=1,
832  statistics=None):
833  '''
834  Get the desired field names, and return a dictionary.
835  Namely, "fields" are the queried keys in the stat file (eg. ["Total_Score",...])
836  The returned data structure is a dictionary, where each key is a field and the value
837  is the time series (ie, frame ordered series)
838  of that field (ie, {"Total_Score":[Score_0,Score_1,Score_2,Score_3,...],....} )
839 
840  @param fields (list of strings) queried keys in the stat file (eg. "Total_Score"....)
841  @param filterout specify if you want to "grep" out something from
842  the file, so that it is faster
843  @param filtertuple a tuple that contains
844  ("TheKeyToBeFiltered",relationship,value)
845  where relationship = "<", "==", or ">"
846  @param get_every only read every Nth line from the file
847  @param statistics if provided, accumulate statistics in an
848  OutputStatistics object
849  '''
850 
851  if statistics is None:
852  statistics = OutputStatistics()
853  outdict = {}
854  for field in fields:
855  outdict[field] = []
856 
857  # print fields values
858  if self.isrmf:
859  rh = RMF.open_rmf_file_read_only(self.filename)
860  nframes=rh.get_number_of_frames()
861  for i in range(nframes):
862  statistics.total += 1
863  # "get_every" and "filterout" not enforced for RMF
864  statistics.passed_get_every += 1
865  statistics.passed_filterout += 1
866  IMP.rmf.load_frame(rh, RMF.FrameID(i))
867  if not filtertuple is None:
868  keytobefiltered = filtertuple[0]
869  relationship = filtertuple[1]
870  value = filtertuple[2]
871  datavalue=rh.get_root_node().get_value(self.rmf_names_keys[keytobefiltered])
872  if self.isfiltered(datavalue,relationship,value): continue
873 
874  statistics.passed_filtertuple += 1
875  for field in fields:
876  outdict[field].append(rh.get_root_node().get_value(self.rmf_names_keys[field]))
877 
878  else:
879  f = open(self.filename, "r")
880  line_number = 0
881 
882  for line in f.readlines():
883  statistics.total += 1
884  if not filterout is None:
885  if filterout in line:
886  continue
887  statistics.passed_filterout += 1
888  line_number += 1
889 
890  if line_number % get_every != 0:
891  if line_number == 1 and self.isstat2:
892  statistics.total -= 1
893  statistics.passed_filterout -= 1
894  continue
895  statistics.passed_get_every += 1
896  #if line_number % 1000 == 0:
897  # print "ProcessOutput.get_fields: read line %s from file %s" % (str(line_number), self.filename)
898  try:
899  d = ast.literal_eval(line)
900  except:
901  print("# Warning: skipped line number " + str(line_number) + " not a valid line")
902  continue
903 
904  if self.isstat1:
905 
906  if not filtertuple is None:
907  keytobefiltered = filtertuple[0]
908  relationship = filtertuple[1]
909  value = filtertuple[2]
910  datavalue=d[keytobefiltered]
911  if self.isfiltered(datavalue, relationship, value): continue
912 
913  statistics.passed_filtertuple += 1
914  [outdict[field].append(d[field]) for field in fields]
915 
916  elif self.isstat2:
917  if line_number == 1:
918  statistics.total -= 1
919  statistics.passed_filterout -= 1
920  statistics.passed_get_every -= 1
921  continue
922 
923  if not filtertuple is None:
924  keytobefiltered = filtertuple[0]
925  relationship = filtertuple[1]
926  value = filtertuple[2]
927  datavalue=d[self.invstat2_dict[keytobefiltered]]
928  if self.isfiltered(datavalue, relationship, value): continue
929 
930  statistics.passed_filtertuple += 1
931  [outdict[field].append(d[self.invstat2_dict[field]]) for field in fields]
932 
933  f.close()
934 
935  return outdict
936 
937  def isfiltered(self,datavalue,relationship,refvalue):
938  dofilter=False
939  try:
940  fdatavalue=float(datavalue)
941  except ValueError:
942  raise ValueError("ProcessOutput.filter: datavalue cannot be converted into a float")
943 
944  if relationship == "<":
945  if float(datavalue) >= refvalue:
946  dofilter=True
947  if relationship == ">":
948  if float(datavalue) <= refvalue:
949  dofilter=True
950  if relationship == "==":
951  if float(datavalue) != refvalue:
952  dofilter=True
953  return dofilter
954 
955 
957  """ class to allow more advanced handling of RMF files.
958  It is both a container and a IMP.atom.Hierarchy.
959  - it is iterable (while loading the corresponding frame)
960  - Item brackets [] load the corresponding frame
961  - slice create an iterator
962  - can relink to another RMF file
963  """
964  def __init__(self,model,rmf_file_name):
965  """
966  @param model: the IMP.Model()
967  @param rmf_file_name: str, path of the rmf file
968  """
969  self.model=model
970  try:
971  self.rh_ref = RMF.open_rmf_file_read_only(rmf_file_name)
972  except TypeError:
973  raise TypeError("Wrong rmf file name or type: %s"% str(rmf_file_name))
974  hs = IMP.rmf.create_hierarchies(self.rh_ref, self.model)
975  IMP.rmf.load_frame(self.rh_ref, RMF.FrameID(0))
976  self.root_hier_ref = hs[0]
977  IMP.atom.Hierarchy.__init__(self, self.root_hier_ref)
978  self.model.update()
979  self.ColorHierarchy=None
980 
981 
982  def link_to_rmf(self,rmf_file_name):
983  """
984  Link to another RMF file
985  """
986  self.rh_ref = RMF.open_rmf_file_read_only(rmf_file_name)
987  IMP.rmf.link_hierarchies(self.rh_ref, [self])
988  if self.ColorHierarchy:
989  self.ColorHierarchy.method()
990  RMFHierarchyHandler.set_frame(self,0)
991 
992  def set_frame(self,index):
993  try:
994  IMP.rmf.load_frame(self.rh_ref, RMF.FrameID(index))
995  except:
996  print("skipping frame %s:%d\n"%(self.current_rmf, index))
997  self.model.update()
998 
999  def get_number_of_frames(self):
1000  return self.rh_ref.get_number_of_frames()
1001 
1002  def __getitem__(self,int_slice_adaptor):
1003  if isinstance(int_slice_adaptor, int):
1004  self.set_frame(int_slice_adaptor)
1005  return int_slice_adaptor
1006  elif isinstance(int_slice_adaptor, slice):
1007  return self.__iter__(int_slice_adaptor)
1008  else:
1009  raise TypeError("Unknown Type")
1010 
1011  def __len__(self):
1012  return self.get_number_of_frames()
1013 
1014  def __iter__(self,slice_key=None):
1015  if slice_key is None:
1016  for nframe in range(len(self)):
1017  yield self[nframe]
1018  else:
1019  for nframe in list(range(len(self)))[slice_key]:
1020  yield self[nframe]
1021 
1022 class CacheHierarchyCoordinates(object):
1023  def __init__(self,StatHierarchyHandler):
1024  self.xyzs=[]
1025  self.nrms=[]
1026  self.rbs=[]
1027  self.nrm_coors={}
1028  self.xyz_coors={}
1029  self.rb_trans={}
1030  self.current_index=None
1031  self.rmfh=StatHierarchyHandler
1032  rbs,xyzs=IMP.pmi.tools.get_rbs_and_beads([self.rmfh])
1033  self.model=self.rmfh.get_model()
1034  self.rbs=rbs
1035  for xyz in xyzs:
1037  nrm=IMP.core.NonRigidMember(xyz)
1038  self.nrms.append(nrm)
1039  else:
1040  fb=IMP.core.XYZ(xyz)
1041  self.xyzs.append(fb)
1042 
1043  def do_store(self,index):
1044  self.rb_trans[index]={}
1045  self.nrm_coors[index]={}
1046  self.xyz_coors[index]={}
1047  for rb in self.rbs:
1048  self.rb_trans[index][rb]=rb.get_reference_frame()
1049  for nrm in self.nrms:
1050  self.nrm_coors[index][nrm]=nrm.get_internal_coordinates()
1051  for xyz in self.xyzs:
1052  self.xyz_coors[index][xyz]=xyz.get_coordinates()
1053  self.current_index=index
1054 
1055  def do_update(self,index):
1056  if self.current_index!=index:
1057  for rb in self.rbs:
1058  rb.set_reference_frame(self.rb_trans[index][rb])
1059  for nrm in self.nrms:
1060  nrm.set_internal_coordinates(self.nrm_coors[index][nrm])
1061  for xyz in self.xyzs:
1062  xyz.set_coordinates(self.xyz_coors[index][xyz])
1063  self.current_index=index
1064  self.model.update()
1065 
1066  def get_number_of_frames(self):
1067  return len(self.rb_trans.keys())
1068 
1069  def __getitem__(self,index):
1070  if isinstance(index, int):
1071  return index in self.rb_trans.keys()
1072  else:
1073  raise TypeError("Unknown Type")
1074 
1075  def __len__(self):
1076  return self.get_number_of_frames()
1077 
1078 
1079 
1080 
1082  """ class to link stat files to several rmf files """
1083  def __init__(self,model=None,stat_file=None,number_best_scoring_models=None,score_key=None,StatHierarchyHandler=None,cache=None):
1084  """
1085 
1086  @param model: IMP.Model()
1087  @param stat_file: either 1) a list or 2) a single stat file names (either rmfs or ascii, or pickled data or pickled cluster), 3) a dictionary containing an rmf/ascii
1088  stat file name as key and a list of frames as values
1089  @param number_best_scoring_models:
1090  @param StatHierarchyHandler: copy constructor input object
1091  @param cache: cache coordinates and rigid body transformations.
1092  """
1093 
1094  if not StatHierarchyHandler is None:
1095  #overrides all other arguments
1096  #copy constructor: create a copy with different RMFHierarchyHandler
1097  self.model=StatHierarchyHandler.model
1098  self.data=StatHierarchyHandler.data
1099  self.number_best_scoring_models=StatHierarchyHandler.number_best_scoring_models
1100  self.is_setup=True
1101  self.current_rmf=StatHierarchyHandler.current_rmf
1102  self.current_frame=None
1103  self.current_index=None
1104  self.score_threshold=StatHierarchyHandler.score_threshold
1105  self.score_key=StatHierarchyHandler.score_key
1106  self.cache=StatHierarchyHandler.cache
1107  RMFHierarchyHandler.__init__(self, self.model,self.current_rmf)
1108  if self.cache:
1109  self.cache=CacheHierarchyCoordinates(self)
1110  else:
1111  self.cache=None
1112  self.set_frame(0)
1113 
1114  else:
1115  #standard constructor
1116  self.model=model
1117  self.data=[]
1118  self.number_best_scoring_models=number_best_scoring_models
1119  self.cache=cache
1120 
1121  if score_key is None:
1122  self.score_key="Total_Score"
1123  else:
1124  self.score_key=score_key
1125  self.is_setup=None
1126  self.current_rmf=None
1127  self.current_frame=None
1128  self.current_index=None
1129  self.score_threshold=None
1130 
1131  if isinstance(stat_file, str):
1132  self.add_stat_file(stat_file)
1133  elif isinstance(stat_file, list):
1134  for f in stat_file:
1135  self.add_stat_file(f)
1136 
1137  def add_stat_file(self,stat_file):
1138  try:
1139  '''check that it is not a pickle file with saved data from a previous calculation'''
1140  self.load_data(stat_file)
1141 
1142  if self.number_best_scoring_models:
1143  scores = self.get_scores()
1144  max_score = sorted(scores)[0:min(len(self), self.number_best_scoring_models)][-1]
1145  self.do_filter_by_score(max_score)
1146 
1147  except pickle.UnpicklingError:
1148  '''alternatively read the ascii stat files'''
1149  try:
1150  scores,rmf_files,rmf_frame_indexes,features = self.get_info_from_stat_file(stat_file, self.score_threshold)
1151  except (KeyError, SyntaxError):
1152  # in this case check that is it an rmf file, probably without stat stored in
1153  try:
1154  # let's see if that is an rmf file
1155  rh = RMF.open_rmf_file_read_only(stat_file)
1156  nframes = rh.get_number_of_frames()
1157  scores=[0.0]*nframes
1158  rmf_files=[stat_file]*nframes
1159  rmf_frame_indexes=range(nframes)
1160  features={}
1161  except:
1162  return
1163 
1164 
1165  if len(set(rmf_files)) > 1:
1166  raise ("Multiple RMF files found")
1167 
1168  if not rmf_files:
1169  print("StatHierarchyHandler: Error: Trying to set none as rmf_file (probably empty stat file), aborting")
1170  return
1171 
1172  for n,index in enumerate(rmf_frame_indexes):
1173  featn_dict=dict([(k,features[k][n]) for k in features])
1174  self.data.append(IMP.pmi.output.DataEntry(stat_file,rmf_files[n],index,scores[n],featn_dict))
1175 
1176  if self.number_best_scoring_models:
1177  scores=self.get_scores()
1178  max_score=sorted(scores)[0:min(len(self),self.number_best_scoring_models)][-1]
1179  self.do_filter_by_score(max_score)
1180 
1181  if not self.is_setup:
1182  RMFHierarchyHandler.__init__(self, self.model,self.get_rmf_names()[0])
1183  if self.cache:
1184  self.cache=CacheHierarchyCoordinates(self)
1185  else:
1186  self.cache=None
1187  self.is_setup=True
1188  self.current_rmf=self.get_rmf_names()[0]
1189 
1190  self.set_frame(0)
1191 
1192  def save_data(self,filename='data.pkl'):
1193  with open(filename, 'wb') as fl:
1194  pickle.dump(self.data, fl)
1195 
1196  def load_data(self,filename='data.pkl'):
1197  with open(filename, 'rb') as fl:
1198  data_structure=pickle.load(fl)
1199  #first check that it is a list
1200  if not isinstance(data_structure, list):
1201  raise TypeError("%filename should contain a list of IMP.pmi.output.DataEntry or IMP.pmi.output.Cluster" % filename)
1202  # second check the types
1203  if all(isinstance(item, IMP.pmi.output.DataEntry) for item in data_structure):
1204  self.data=data_structure
1205  elif all(isinstance(item, IMP.pmi.output.Cluster) for item in data_structure):
1206  nmodels=0
1207  for cluster in data_structure:
1208  nmodels+=len(cluster)
1209  self.data=[None]*nmodels
1210  for cluster in data_structure:
1211  for n,data in enumerate(cluster):
1212  index=cluster.members[n]
1213  self.data[index]=data
1214  else:
1215  raise TypeError("%filename should contain a list of IMP.pmi.output.DataEntry or IMP.pmi.output.Cluster" % filename)
1216 
1217  def set_frame(self,index):
1218  if self.cache is not None and self.cache[index]:
1219  self.cache.do_update(index)
1220  else:
1221  nm=self.data[index].rmf_name
1222  fidx=self.data[index].rmf_index
1223  if nm != self.current_rmf:
1224  self.link_to_rmf(nm)
1225  self.current_rmf=nm
1226  self.current_frame=-1
1227  if fidx!=self.current_frame:
1228  RMFHierarchyHandler.set_frame(self, fidx)
1229  self.current_frame=fidx
1230  if self.cache is not None:
1231  self.cache.do_store(index)
1232 
1233  self.current_index = index
1234 
1235  def __getitem__(self,int_slice_adaptor):
1236  if isinstance(int_slice_adaptor, int):
1237  self.set_frame(int_slice_adaptor)
1238  return self.data[int_slice_adaptor]
1239  elif isinstance(int_slice_adaptor, slice):
1240  return self.__iter__(int_slice_adaptor)
1241  else:
1242  raise TypeError("Unknown Type")
1243 
1244  def __len__(self):
1245  return len(self.data)
1246 
1247  def __iter__(self,slice_key=None):
1248  if slice_key is None:
1249  for i in range(len(self)):
1250  yield self[i]
1251  else:
1252  for i in range(len(self))[slice_key]:
1253  yield self[i]
1254 
1255  def do_filter_by_score(self,maximum_score):
1256  self.data=[d for d in self.data if d.score<=maximum_score]
1257 
1258  def get_scores(self):
1259  return [d.score for d in self.data]
1260 
1261  def get_feature_series(self,feature_name):
1262  return [d.features[feature_name] for d in self.data]
1263 
1264  def get_feature_names(self):
1265  return self.data[0].features.keys()
1266 
1267  def get_rmf_names(self):
1268  return [d.rmf_name for d in self.data]
1269 
1270  def get_stat_files_names(self):
1271  return [d.stat_file for d in self.data]
1272 
1273  def get_rmf_indexes(self):
1274  return [d.rmf_index for d in self.data]
1275 
1276  def get_info_from_stat_file(self, stat_file, score_threshold=None):
1277  po=ProcessOutput(stat_file)
1278  fs=po.get_keys()
1279  models = IMP.pmi.io.get_best_models([stat_file],
1280  score_key=self.score_key,
1281  feature_keys=fs,
1282  rmf_file_key="rmf_file",
1283  rmf_file_frame_key="rmf_frame_index",
1284  prefiltervalue=score_threshold,
1285  get_every=1)
1286 
1287 
1288 
1289  scores = [float(y) for y in models[2]]
1290  rmf_files = models[0]
1291  rmf_frame_indexes = models[1]
1292  features=models[3]
1293  return scores, rmf_files, rmf_frame_indexes,features
1294 
1295 
1296 class DataEntry(object):
1297  '''
1298  A class to store data associated to a model
1299  '''
1300  def __init__(self,stat_file=None,rmf_name=None,rmf_index=None,score=None,features=None):
1301  self.rmf_name=rmf_name
1302  self.rmf_index=rmf_index
1303  self.score=score
1304  self.features=features
1305  self.stat_file=stat_file
1306 
1307  def __repr__(self):
1308  s= "IMP.pmi.output.DataEntry\n"
1309  s+="---- stat file %s \n"%(self.stat_file)
1310  s+="---- rmf file %s \n"%(self.rmf_name)
1311  s+="---- rmf index %s \n"%(str(self.rmf_index))
1312  s+="---- score %s \n"%(str(self.score))
1313  s+="---- number of features %s \n"%(str(len(self.features.keys())))
1314  return s
1315 
1316 
1317 class Cluster(object):
1318  '''
1319  A container for models organized into clusters
1320  '''
1321  def __init__(self,cid=None):
1322  self.cluster_id=cid
1323  self.members=[]
1324  self.precision=None
1325  self.center_index=None
1326  self.members_data={}
1327 
1328  def add_member(self,index,data=None):
1329  self.members.append(index)
1330  self.members_data[index]=data
1331  self.average_score=self.compute_score()
1332 
1333  def compute_score(self):
1334  try:
1335  score=sum([d.score for d in self])/len(self)
1336  except AttributeError:
1337  score=None
1338  return score
1339 
1340  def __repr__(self):
1341  s= "IMP.pmi.output.Cluster\n"
1342  s+="---- cluster_id %s \n"%str(self.cluster_id)
1343  s+="---- precision %s \n"%str(self.precision)
1344  s+="---- average score %s \n"%str(self.average_score)
1345  s+="---- number of members %s \n"%str(len(self.members))
1346  s+="---- center index %s \n"%str(self.center_index)
1347  return s
1348 
1349  def __getitem__(self,int_slice_adaptor):
1350  if isinstance(int_slice_adaptor, int):
1351  index=self.members[int_slice_adaptor]
1352  return self.members_data[index]
1353  elif isinstance(int_slice_adaptor, slice):
1354  return self.__iter__(int_slice_adaptor)
1355  else:
1356  raise TypeError("Unknown Type")
1357 
1358  def __len__(self):
1359  return len(self.members)
1360 
1361  def __iter__(self,slice_key=None):
1362  if slice_key is None:
1363  for i in range(len(self)):
1364  yield self[i]
1365  else:
1366  for i in range(len(self))[slice_key]:
1367  yield self[i]
1368 
1369  def __add__(self, other):
1370  self.members+=other.members
1371  self.members_data.update(other.members_data)
1372  self.average_score=self.compute_score()
1373  self.precision=None
1374  self.center_index=None
1375  return self
1376 
1377 
1378 def plot_clusters_populations(clusters):
1379  indexes=[]
1380  populations=[]
1381  for cluster in clusters:
1382  indexes.append(cluster.cluster_id)
1383  populations.append(len(cluster))
1384 
1385  import matplotlib.pyplot as plt
1386  fig, ax = plt.subplots()
1387  ax.bar(indexes, populations, 0.5, color='r') #, yerr=men_std)
1388  ax.set_ylabel('Population')
1389  ax.set_xlabel(('Cluster index'))
1390  plt.show()
1391 
1392 def plot_clusters_precisions(clusters):
1393  indexes=[]
1394  precisions=[]
1395  for cluster in clusters:
1396  indexes.append(cluster.cluster_id)
1397 
1398  prec=cluster.precision
1399  print(cluster.cluster_id,prec)
1400  if prec is None:
1401  prec=0.0
1402  precisions.append(prec)
1403 
1404  import matplotlib.pyplot as plt
1405  fig, ax = plt.subplots()
1406  ax.bar(indexes, precisions, 0.5, color='r') #, yerr=men_std)
1407  ax.set_ylabel('Precision [A]')
1408  ax.set_xlabel(('Cluster index'))
1409  plt.show()
1410 
1411 def plot_clusters_scores(clusters):
1412  indexes=[]
1413  values=[]
1414  for cluster in clusters:
1415  indexes.append(cluster.cluster_id)
1416  values.append([])
1417  for data in cluster:
1418  values[-1].append(data.score)
1419 
1420  plot_fields_box_plots("scores.pdf", values, indexes, frequencies=None,
1421  valuename="Scores", positionname="Cluster index", xlabels=None,scale_plot_length=1.0)
1422 
1423 class CrossLinkIdentifierDatabase(object):
1424  def __init__(self):
1425  self.clidb=dict()
1426 
1427  def check_key(self,key):
1428  if key not in self.clidb:
1429  self.clidb[key]={}
1430 
1431  def set_unique_id(self,key,value):
1432  self.check_key(key)
1433  self.clidb[key]["XLUniqueID"]=str(value)
1434 
1435  def set_protein1(self,key,value):
1436  self.check_key(key)
1437  self.clidb[key]["Protein1"]=str(value)
1438 
1439  def set_protein2(self,key,value):
1440  self.check_key(key)
1441  self.clidb[key]["Protein2"]=str(value)
1442 
1443  def set_residue1(self,key,value):
1444  self.check_key(key)
1445  self.clidb[key]["Residue1"]=int(value)
1446 
1447  def set_residue2(self,key,value):
1448  self.check_key(key)
1449  self.clidb[key]["Residue2"]=int(value)
1450 
1451  def set_idscore(self,key,value):
1452  self.check_key(key)
1453  self.clidb[key]["IDScore"]=float(value)
1454 
1455  def set_state(self,key,value):
1456  self.check_key(key)
1457  self.clidb[key]["State"]=int(value)
1458 
1459  def set_sigma1(self,key,value):
1460  self.check_key(key)
1461  self.clidb[key]["Sigma1"]=str(value)
1462 
1463  def set_sigma2(self,key,value):
1464  self.check_key(key)
1465  self.clidb[key]["Sigma2"]=str(value)
1466 
1467  def set_psi(self,key,value):
1468  self.check_key(key)
1469  self.clidb[key]["Psi"]=str(value)
1470 
1471  def get_unique_id(self,key):
1472  return self.clidb[key]["XLUniqueID"]
1473 
1474  def get_protein1(self,key):
1475  return self.clidb[key]["Protein1"]
1476 
1477  def get_protein2(self,key):
1478  return self.clidb[key]["Protein2"]
1479 
1480  def get_residue1(self,key):
1481  return self.clidb[key]["Residue1"]
1482 
1483  def get_residue2(self,key):
1484  return self.clidb[key]["Residue2"]
1485 
1486  def get_idscore(self,key):
1487  return self.clidb[key]["IDScore"]
1488 
1489  def get_state(self,key):
1490  return self.clidb[key]["State"]
1491 
1492  def get_sigma1(self,key):
1493  return self.clidb[key]["Sigma1"]
1494 
1495  def get_sigma2(self,key):
1496  return self.clidb[key]["Sigma2"]
1497 
1498  def get_psi(self,key):
1499  return self.clidb[key]["Psi"]
1500 
1501  def set_float_feature(self,key,value,feature_name):
1502  self.check_key(key)
1503  self.clidb[key][feature_name]=float(value)
1504 
1505  def set_int_feature(self,key,value,feature_name):
1506  self.check_key(key)
1507  self.clidb[key][feature_name]=int(value)
1508 
1509  def set_string_feature(self,key,value,feature_name):
1510  self.check_key(key)
1511  self.clidb[key][feature_name]=str(value)
1512 
1513  def get_feature(self,key,feature_name):
1514  return self.clidb[key][feature_name]
1515 
1516  def write(self,filename):
1517  with open(filename, 'wb') as handle:
1518  pickle.dump(self.clidb,handle)
1519 
1520  def load(self,filename):
1521  with open(filename, 'rb') as handle:
1522  self.clidb=pickle.load(handle)
1523 
1524 def plot_fields(fields, framemin=None, framemax=None):
1525  import matplotlib as mpl
1526  mpl.use('Agg')
1527  import matplotlib.pyplot as plt
1528 
1529  plt.rc('lines', linewidth=4)
1530  fig, axs = plt.subplots(nrows=len(fields))
1531  fig.set_size_inches(10.5, 5.5 * len(fields))
1532  plt.rc('axes', color_cycle=['r'])
1533 
1534  n = 0
1535  for key in fields:
1536  if framemin is None:
1537  framemin = 0
1538  if framemax is None:
1539  framemax = len(fields[key])
1540  x = list(range(framemin, framemax))
1541  y = [float(y) for y in fields[key][framemin:framemax]]
1542  if len(fields) > 1:
1543  axs[n].plot(x, y)
1544  axs[n].set_title(key, size="xx-large")
1545  axs[n].tick_params(labelsize=18, pad=10)
1546  else:
1547  axs.plot(x, y)
1548  axs.set_title(key, size="xx-large")
1549  axs.tick_params(labelsize=18, pad=10)
1550  n += 1
1551 
1552  # Tweak spacing between subplots to prevent labels from overlapping
1553  plt.subplots_adjust(hspace=0.3)
1554  plt.show()
1555 
1556 
1558  name, values_lists, valuename=None, bins=40, colors=None, format="png",
1559  reference_xline=None, yplotrange=None, xplotrange=None,normalized=True,
1560  leg_names=None):
1561 
1562  '''Plot a list of histograms from a value list.
1563  @param name the name of the plot
1564  @param value_lists the list of list of values eg: [[...],[...],[...]]
1565  @param valuename the y-label
1566  @param bins the number of bins
1567  @param colors If None, will use rainbow. Else will use specific list
1568  @param format output format
1569  @param reference_xline plot a reference line parallel to the y-axis
1570  @param yplotrange the range for the y-axis
1571  @param normalized whether the histogram is normalized or not
1572  @param leg_names names for the legend
1573  '''
1574 
1575  import matplotlib as mpl
1576  mpl.use('Agg')
1577  import matplotlib.pyplot as plt
1578  import matplotlib.cm as cm
1579  fig = plt.figure(figsize=(18.0, 9.0))
1580 
1581  if colors is None:
1582  colors = cm.rainbow(np.linspace(0, 1, len(values_lists)))
1583  for nv,values in enumerate(values_lists):
1584  col=colors[nv]
1585  if leg_names is not None:
1586  label=leg_names[nv]
1587  else:
1588  label=str(nv)
1589  h=plt.hist(
1590  [float(y) for y in values],
1591  bins=bins,
1592  color=col,
1593  normed=normalized,histtype='step',lw=4,
1594  label=label)
1595 
1596  # plt.title(name,size="xx-large")
1597  plt.tick_params(labelsize=12, pad=10)
1598  if valuename is None:
1599  plt.xlabel(name, size="xx-large")
1600  else:
1601  plt.xlabel(valuename, size="xx-large")
1602  plt.ylabel("Frequency", size="xx-large")
1603 
1604  if not yplotrange is None:
1605  plt.ylim()
1606  if not xplotrange is None:
1607  plt.xlim(xplotrange)
1608 
1609  plt.legend(loc=2)
1610 
1611  if not reference_xline is None:
1612  plt.axvline(
1613  reference_xline,
1614  color='red',
1615  linestyle='dashed',
1616  linewidth=1)
1617 
1618  plt.savefig(name + "." + format, dpi=150, transparent=True)
1619  plt.show()
1620 
1621 
1622 def plot_fields_box_plots(name, values, positions, frequencies=None,
1623  valuename="None", positionname="None", xlabels=None,scale_plot_length=1.0):
1624  '''
1625  Plot time series as boxplots.
1626  fields is a list of time series, positions are the x-values
1627  valuename is the y-label, positionname is the x-label
1628  '''
1629 
1630  import matplotlib as mpl
1631  mpl.use('Agg')
1632  import matplotlib.pyplot as plt
1633  from matplotlib.patches import Polygon
1634 
1635  bps = []
1636  fig = plt.figure(figsize=(float(len(positions))*scale_plot_length, 5.0))
1637  fig.canvas.set_window_title(name)
1638 
1639  ax1 = fig.add_subplot(111)
1640 
1641  plt.subplots_adjust(left=0.1, right=0.990, top=0.95, bottom=0.4)
1642 
1643  bps.append(plt.boxplot(values, notch=0, sym='', vert=1,
1644  whis=1.5, positions=positions))
1645 
1646  plt.setp(bps[-1]['boxes'], color='black', lw=1.5)
1647  plt.setp(bps[-1]['whiskers'], color='black', ls=":", lw=1.5)
1648 
1649  if frequencies is not None:
1650  for n,v in enumerate(values):
1651  plist=[positions[n]]*len(v)
1652  ax1.plot(plist, v, 'gx', alpha=0.7, markersize=7)
1653 
1654  # print ax1.xaxis.get_majorticklocs()
1655  if not xlabels is None:
1656  ax1.set_xticklabels(xlabels)
1657  plt.xticks(rotation=90)
1658  plt.xlabel(positionname)
1659  plt.ylabel(valuename)
1660 
1661  plt.savefig(name+".pdf",dpi=150)
1662  plt.show()
1663 
1664 
1665 def plot_xy_data(x,y,title=None,out_fn=None,display=True,set_plot_yaxis_range=None,
1666  xlabel=None,ylabel=None):
1667  import matplotlib as mpl
1668  mpl.use('Agg')
1669  import matplotlib.pyplot as plt
1670  plt.rc('lines', linewidth=2)
1671 
1672  fig, ax = plt.subplots(nrows=1)
1673  fig.set_size_inches(8,4.5)
1674  if title is not None:
1675  fig.canvas.set_window_title(title)
1676 
1677  #plt.rc('axes', color='r')
1678  ax.plot(x,y,color='r')
1679  if set_plot_yaxis_range is not None:
1680  x1,x2,y1,y2=plt.axis()
1681  y1=set_plot_yaxis_range[0]
1682  y2=set_plot_yaxis_range[1]
1683  plt.axis((x1,x2,y1,y2))
1684  if title is not None:
1685  ax.set_title(title)
1686  if xlabel is not None:
1687  ax.set_xlabel(xlabel)
1688  if ylabel is not None:
1689  ax.set_ylabel(ylabel)
1690  if out_fn is not None:
1691  plt.savefig(out_fn+".pdf")
1692  if display:
1693  plt.show()
1694  plt.close(fig)
1695 
1696 def plot_scatter_xy_data(x,y,labelx="None",labely="None",
1697  xmin=None,xmax=None,ymin=None,ymax=None,
1698  savefile=False,filename="None.eps",alpha=0.75):
1699 
1700  import matplotlib as mpl
1701  mpl.use('Agg')
1702  import matplotlib.pyplot as plt
1703  import sys
1704  from matplotlib import rc
1705  #rc('font', **{'family':'serif','serif':['Palatino']})
1706  rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})
1707  #rc('text', usetex=True)
1708 
1709  fig, axs = plt.subplots(1)
1710 
1711  axs0 = axs
1712 
1713  axs0.set_xlabel(labelx, size="xx-large")
1714  axs0.set_ylabel(labely, size="xx-large")
1715  axs0.tick_params(labelsize=18, pad=10)
1716 
1717  plot2 = []
1718 
1719  plot2.append(axs0.plot(x, y, 'o', color='k',lw=2, ms=0.1, alpha=alpha, c="w"))
1720 
1721  axs0.legend(
1722  loc=0,
1723  frameon=False,
1724  scatterpoints=1,
1725  numpoints=1,
1726  columnspacing=1)
1727 
1728  fig.set_size_inches(8.0, 8.0)
1729  fig.subplots_adjust(left=0.161, right=0.850, top=0.95, bottom=0.11)
1730  if (not ymin is None) and (not ymax is None):
1731  axs0.set_ylim(ymin,ymax)
1732  if (not xmin is None) and (not xmax is None):
1733  axs0.set_xlim(xmin,xmax)
1734 
1735  #plt.show()
1736  if savefile:
1737  fig.savefig(filename, dpi=300)
1738 
1739 
1740 def get_graph_from_hierarchy(hier):
1741  graph = []
1742  depth_dict = {}
1743  depth = 0
1744  (graph, depth, depth_dict) = recursive_graph(
1745  hier, graph, depth, depth_dict)
1746 
1747  # filters node labels according to depth_dict
1748  node_labels_dict = {}
1749  node_size_dict = {}
1750  for key in depth_dict:
1751  node_size_dict = 10 / depth_dict[key]
1752  if depth_dict[key] < 3:
1753  node_labels_dict[key] = key
1754  else:
1755  node_labels_dict[key] = ""
1756  draw_graph(graph, labels_dict=node_labels_dict)
1757 
1758 
1759 def recursive_graph(hier, graph, depth, depth_dict):
1760  depth = depth + 1
1761  nameh = IMP.atom.Hierarchy(hier).get_name()
1762  index = str(hier.get_particle().get_index())
1763  name1 = nameh + "|#" + index
1764  depth_dict[name1] = depth
1765 
1766  children = IMP.atom.Hierarchy(hier).get_children()
1767 
1768  if len(children) == 1 or children is None:
1769  depth = depth - 1
1770  return (graph, depth, depth_dict)
1771 
1772  else:
1773  for c in children:
1774  (graph, depth, depth_dict) = recursive_graph(
1775  c, graph, depth, depth_dict)
1776  nameh = IMP.atom.Hierarchy(c).get_name()
1777  index = str(c.get_particle().get_index())
1778  namec = nameh + "|#" + index
1779  graph.append((name1, namec))
1780 
1781  depth = depth - 1
1782  return (graph, depth, depth_dict)
1783 
1784 
1785 def draw_graph(graph, labels_dict=None, graph_layout='spring',
1786  node_size=5, node_color=None, node_alpha=0.3,
1787  node_text_size=11, fixed=None, pos=None,
1788  edge_color='blue', edge_alpha=0.3, edge_thickness=1,
1789  edge_text_pos=0.3,
1790  validation_edges=None,
1791  text_font='sans-serif',
1792  out_filename=None):
1793 
1794  import matplotlib as mpl
1795  mpl.use('Agg')
1796  import networkx as nx
1797  import matplotlib.pyplot as plt
1798  from math import sqrt, pi
1799 
1800  # create networkx graph
1801  G = nx.Graph()
1802 
1803  # add edges
1804  if isinstance(edge_thickness, list):
1805  for edge,weight in zip(graph,edge_thickness):
1806  G.add_edge(edge[0], edge[1], weight=weight)
1807  else:
1808  for edge in graph:
1809  G.add_edge(edge[0], edge[1])
1810 
1811  if node_color==None:
1812  node_color_rgb=(0,0,0)
1813  node_color_hex="000000"
1814  else:
1816  tmpcolor_rgb=[]
1817  tmpcolor_hex=[]
1818  for node in G.nodes():
1819  cctuple=cc.rgb(node_color[node])
1820  tmpcolor_rgb.append((cctuple[0]/255,cctuple[1]/255,cctuple[2]/255))
1821  tmpcolor_hex.append(node_color[node])
1822  node_color_rgb=tmpcolor_rgb
1823  node_color_hex=tmpcolor_hex
1824 
1825  # get node sizes if dictionary
1826  if isinstance(node_size, dict):
1827  tmpsize=[]
1828  for node in G.nodes():
1829  size=sqrt(node_size[node])/pi*10.0
1830  tmpsize.append(size)
1831  node_size=tmpsize
1832 
1833  for n,node in enumerate(G.nodes()):
1834  color=node_color_hex[n]
1835  size=node_size[n]
1836  nx.set_node_attributes(G, "graphics", {node : {'type': 'ellipse','w': size, 'h': size,'fill': '#'+color, 'label': node}})
1837  nx.set_node_attributes(G, "LabelGraphics", {node : {'type': 'text','text':node, 'color':'#000000', 'visible':'true'}})
1838 
1839  for edge in G.edges():
1840  nx.set_edge_attributes(G, "graphics", {edge : {'width': 1,'fill': '#000000'}})
1841 
1842  for ve in validation_edges:
1843  print(ve)
1844  if (ve[0],ve[1]) in G.edges():
1845  print("found forward")
1846  nx.set_edge_attributes(G, "graphics", {ve : {'width': 1,'fill': '#00FF00'}})
1847  elif (ve[1],ve[0]) in G.edges():
1848  print("found backward")
1849  nx.set_edge_attributes(G, "graphics", {(ve[1],ve[0]) : {'width': 1,'fill': '#00FF00'}})
1850  else:
1851  G.add_edge(ve[0], ve[1])
1852  print("not found")
1853  nx.set_edge_attributes(G, "graphics", {ve : {'width': 1,'fill': '#FF0000'}})
1854 
1855  # these are different layouts for the network you may try
1856  # shell seems to work best
1857  if graph_layout == 'spring':
1858  print(fixed, pos)
1859  graph_pos = nx.spring_layout(G,k=1.0/8.0,fixed=fixed,pos=pos)
1860  elif graph_layout == 'spectral':
1861  graph_pos = nx.spectral_layout(G)
1862  elif graph_layout == 'random':
1863  graph_pos = nx.random_layout(G)
1864  else:
1865  graph_pos = nx.shell_layout(G)
1866 
1867 
1868  # draw graph
1869  nx.draw_networkx_nodes(G, graph_pos, node_size=node_size,
1870  alpha=node_alpha, node_color=node_color_rgb,
1871  linewidths=0)
1872  nx.draw_networkx_edges(G, graph_pos, width=edge_thickness,
1873  alpha=edge_alpha, edge_color=edge_color)
1874  nx.draw_networkx_labels(
1875  G, graph_pos, labels=labels_dict, font_size=node_text_size,
1876  font_family=text_font)
1877  if out_filename:
1878  plt.savefig(out_filename)
1879  nx.write_gml(G,'out.gml')
1880  plt.show()
1881 
1882 
1883 def draw_table():
1884 
1885  # still an example!
1886 
1887  from ipyD3 import d3object
1888  from IPython.display import display
1889 
1890  d3 = d3object(width=800,
1891  height=400,
1892  style='JFTable',
1893  number=1,
1894  d3=None,
1895  title='Example table with d3js',
1896  desc='An example table created created with d3js with data generated with Python.')
1897  data = [
1898  [1277.0,
1899  654.0,
1900  288.0,
1901  1976.0,
1902  3281.0,
1903  3089.0,
1904  10336.0,
1905  4650.0,
1906  4441.0,
1907  4670.0,
1908  944.0,
1909  110.0],
1910  [1318.0,
1911  664.0,
1912  418.0,
1913  1952.0,
1914  3581.0,
1915  4574.0,
1916  11457.0,
1917  6139.0,
1918  7078.0,
1919  6561.0,
1920  2354.0,
1921  710.0],
1922  [1783.0,
1923  774.0,
1924  564.0,
1925  1470.0,
1926  3571.0,
1927  3103.0,
1928  9392.0,
1929  5532.0,
1930  5661.0,
1931  4991.0,
1932  2032.0,
1933  680.0],
1934  [1301.0,
1935  604.0,
1936  286.0,
1937  2152.0,
1938  3282.0,
1939  3369.0,
1940  10490.0,
1941  5406.0,
1942  4727.0,
1943  3428.0,
1944  1559.0,
1945  620.0],
1946  [1537.0,
1947  1714.0,
1948  724.0,
1949  4824.0,
1950  5551.0,
1951  8096.0,
1952  16589.0,
1953  13650.0,
1954  9552.0,
1955  13709.0,
1956  2460.0,
1957  720.0],
1958  [5691.0,
1959  2995.0,
1960  1680.0,
1961  11741.0,
1962  16232.0,
1963  14731.0,
1964  43522.0,
1965  32794.0,
1966  26634.0,
1967  31400.0,
1968  7350.0,
1969  3010.0],
1970  [1650.0,
1971  2096.0,
1972  60.0,
1973  50.0,
1974  1180.0,
1975  5602.0,
1976  15728.0,
1977  6874.0,
1978  5115.0,
1979  3510.0,
1980  1390.0,
1981  170.0],
1982  [72.0, 60.0, 60.0, 10.0, 120.0, 172.0, 1092.0, 675.0, 408.0, 360.0, 156.0, 100.0]]
1983  data = [list(i) for i in zip(*data)]
1984  sRows = [['January',
1985  'February',
1986  'March',
1987  'April',
1988  'May',
1989  'June',
1990  'July',
1991  'August',
1992  'September',
1993  'October',
1994  'November',
1995  'Deecember']]
1996  sColumns = [['Prod {0}'.format(i) for i in range(1, 9)],
1997  [None, '', None, None, 'Group 1', None, None, 'Group 2']]
1998  d3.addSimpleTable(data,
1999  fontSizeCells=[12, ],
2000  sRows=sRows,
2001  sColumns=sColumns,
2002  sRowsMargins=[5, 50, 0],
2003  sColsMargins=[5, 20, 10],
2004  spacing=0,
2005  addBorders=1,
2006  addOutsideBorders=-1,
2007  rectWidth=45,
2008  rectHeight=0
2009  )
2010  html = d3.render(mode=['html', 'show'])
2011  display(html)
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: Residue.h:156
A container for models organized into clusters.
Definition: output.py:1317
A class for reading stat files (either rmf or ascii v1 and v2)
Definition: output.py:769
atom::Hierarchies create_hierarchies(RMF::FileConstHandle fh, Model *m)
RMF::FrameID save_frame(RMF::FileHandle file, std::string name="")
Save the current state of the linked objects as a new RMF frame.
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: atom/Atom.h:241
def plot_field_histogram
Plot a list of histograms from a value list.
Definition: output.py:1557
def plot_fields_box_plots
Plot time series as boxplots.
Definition: output.py:1622
Utility classes and functions for reading and storing PMI files.
def get_best_models
Given a list of stat files, read them all and find the best models.
Miscellaneous utilities.
Definition: tools.py:1
A class to store data associated to a model.
Definition: output.py:1296
void handle_use_deprecated(std::string message)
std::string get_module_version()
Change color code to hexadecimal to rgb.
Definition: tools.py:788
void write_pdb(const Selection &mhd, TextOutput out, unsigned int model=1)
Collect statistics from ProcessOutput.get_fields().
Definition: output.py:758
def get_prot_name_from_particle
Return the component name provided a particle and a list of names.
Definition: tools.py:534
def get_fields
Get the desired field names, and return a dictionary.
Definition: output.py:831
static bool get_is_setup(Model *m, ParticleIndex pi)
Definition: Fragment.h:46
def link_to_rmf
Link to another RMF file.
Definition: output.py:982
std::string get_molecule_name_and_copy(atom::Hierarchy h)
Walk up a PMI2 hierarchy/representations and get the "molname.copynum".
Definition: pmi/utilities.h:85
The standard decorator for manipulating molecular structures.
Ints get_index(const ParticlesTemp &particles, const Subset &subset, const Subsets &excluded)
def init_pdb
Init PDB Writing.
Definition: output.py:112
int get_number_of_frames(const ::npctransport_proto::Assignment &config, double time_step)
A decorator for a particle representing an atom.
Definition: atom/Atom.h:234
Base class for capturing a modeling protocol.
Definition: output.py:40
The type for a residue.
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.
Definition: XYZ.h:30
A base class for Keys.
Definition: Key.h:44
void add_hierarchies(RMF::NodeHandle fh, const atom::Hierarchies &hs)
Class for easy writing of PDBs, RMFs, and stat files.
Definition: output.py:60
void add_geometries(RMF::NodeHandle parent, const display::GeometriesTemp &r)
Add geometries to a given parent node.
void add_restraints(RMF::NodeHandle fh, const Restraints &hs)
A decorator for a particle that is part of a rigid body but not rigid.
Definition: rigid_bodies.h:750
bool get_is_canonical(atom::Hierarchy h)
Walk up a PMI2 hierarchy/representations and check if the root is named System.
Definition: pmi/utilities.h:91
Display a segment connecting a pair of particles.
Definition: XYZR.h:170
A decorator for a residue.
Definition: Residue.h:135
Basic functionality that is expected to be used by a wide variety of IMP users.
def get_pdb_names
Get a list of all PDB files being output by this instance.
Definition: output.py:86
def get_prot_name_from_particle
Get the protein name from the particle.
Definition: output.py:205
class to link stat files to several rmf files
Definition: output.py:1081
class to allow more advanced handling of RMF files.
Definition: output.py:956
void link_hierarchies(RMF::FileConstHandle fh, const atom::Hierarchies &hs)
void add_geometry(RMF::FileHandle file, display::Geometry *r)
Add a single geometry to the file.
Store info for a chain of a protein.
Definition: Chain.h:61
Python classes to represent, score, sample and analyze models.
Functionality for loading, creating, manipulating and scoring atomic structures.
def get_rbs_and_beads
Returns unique objects in original order.
Definition: tools.py:1193
Hierarchies get_leaves(const Selection &h)
Select hierarchy particles identified by the biological name.
Definition: Selection.h:66
def init_rmf
Initialize an RMF file.
Definition: output.py:406
def get_residue_indexes
Retrieve the residue indexes for the given particle.
Definition: tools.py:554
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: rigid_bodies.h:752
std::string get_module_version()
def sublist_iterator
Yield all sublists of length >= lmin and <= lmax.
Definition: tools.py:627
A decorator for a particle with x,y,z coordinates and a radius.
Definition: XYZR.h:27