IMP logo
IMP Reference Guide  2.11.1
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.representation.Representation.add_protocol_output()
46  (for PMI 1) or
47  IMP.pmi.topology.System.add_protocol_output() (for PMI 2).
48 
49  @see IMP.pmi.mmcif.ProtocolOutput for a concrete subclass that outputs
50  mmCIF files.
51  """
52  pass
53 
54 def _flatten(seq):
55  for elt in seq:
56  if isinstance(elt, (tuple, list)):
57  for elt2 in _flatten(elt):
58  yield elt2
59  else:
60  yield elt
61 
62 class Output(object):
63  """Class for easy writing of PDBs, RMFs, and stat files
64 
65  @note Model should be updated prior to writing outputs.
66  """
67  def __init__(self, ascii=True,atomistic=False):
68  self.dictionary_pdbs = {}
69  self.dictionary_rmfs = {}
70  self.dictionary_stats = {}
71  self.dictionary_stats2 = {}
72  self.best_score_list = None
73  self.nbestscoring = None
74  self.suffixes = []
75  self.replica_exchange = False
76  self.ascii = ascii
77  self.initoutput = {}
78  self.residuetypekey = IMP.StringKey("ResidueName")
79  # 1-character chain IDs, suitable for PDB output
80  self.chainids = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
81  # Multi-character chain IDs, suitable for mmCIF output
82  self.multi_chainids = _ChainIDs()
83  self.dictchain = {} # keys are molecule names, values are chain ids
84  self.particle_infos_for_pdb = {}
85  self.atomistic=atomistic
86  self.use_pmi2 = False
87 
88  def get_pdb_names(self):
89  """Get a list of all PDB files being output by this instance"""
90  return list(self.dictionary_pdbs.keys())
91 
92  def get_rmf_names(self):
93  return list(self.dictionary_rmfs.keys())
94 
95  def get_stat_names(self):
96  return list(self.dictionary_stats.keys())
97 
98  def _init_dictchain(self, name, prot, multichar_chain=False):
99  self.dictchain[name] = {}
100  self.use_pmi2 = False
101 
102  # attempt to find PMI objects.
103  if IMP.pmi.get_is_canonical(prot):
104  self.use_pmi2 = True
105  self.atomistic = True #detects automatically
106  for n,mol in enumerate(IMP.atom.get_by_type(prot,IMP.atom.MOLECULE_TYPE)):
107  chid = IMP.atom.Chain(mol).get_id()
108  self.dictchain[name][IMP.pmi.get_molecule_name_and_copy(mol)] = chid
109  else:
110  chainids = self.multi_chainids if multichar_chain else self.chainids
111  for n, i in enumerate(self.dictionary_pdbs[name].get_children()):
112  self.dictchain[name][i.get_name()] = chainids[n]
113 
114  def init_pdb(self, name, prot):
115  """Init PDB Writing.
116  @param name The PDB filename
117  @param prot The hierarchy to write to this pdb file
118  @note if the PDB name is 'System' then will use Selection to get molecules
119  """
120  flpdb = open(name, 'w')
121  flpdb.close()
122  self.dictionary_pdbs[name] = prot
123  self._init_dictchain(name, prot)
124 
125  def write_psf(self,filename,name):
126  flpsf=open(filename,'w')
127  flpsf.write("PSF CMAP CHEQ"+"\n")
128  index_residue_pair_list={}
129  (particle_infos_for_pdb, geometric_center)=self.get_particle_infos_for_pdb_writing(name)
130  nparticles=len(particle_infos_for_pdb)
131  flpsf.write(str(nparticles)+" !NATOM"+"\n")
132  for n,p in enumerate(particle_infos_for_pdb):
133  atom_index=n+1
134  residue_type=p[2]
135  chain=p[3]
136  resid=p[4]
137  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))
138  flpsf.write('\n')
139  #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")
140  if chain not in index_residue_pair_list:
141  index_residue_pair_list[chain]=[(atom_index,resid)]
142  else:
143  index_residue_pair_list[chain].append((atom_index,resid))
144 
145 
146  #now write the connectivity
147  indexes_pairs=[]
148  for chain in sorted(index_residue_pair_list.keys()):
149 
150  ls=index_residue_pair_list[chain]
151  #sort by residue
152  ls=sorted(ls, key=lambda tup: tup[1])
153  #get the index list
154  indexes=[x[0] for x in ls]
155  # get the contiguous pairs
156  indexes_pairs+=list(IMP.pmi.tools.sublist_iterator(indexes,lmin=2,lmax=2))
157  nbonds=len(indexes_pairs)
158  flpsf.write(str(nbonds)+" !NBOND: bonds"+"\n")
159 
160  # save bonds in fixed column format
161  for i in range(0,len(indexes_pairs),4):
162  for bond in indexes_pairs[i:i+4]:
163  flpsf.write('{0:8d}{1:8d}'.format(*bond))
164  flpsf.write('\n')
165 
166  del particle_infos_for_pdb
167  flpsf.close()
168 
169  def write_pdb(self,name,
170  appendmode=True,
171  translate_to_geometric_center=False,
172  write_all_residues_per_bead=False):
173  if appendmode:
174  flpdb = open(name, 'a')
175  else:
176  flpdb = open(name, 'w')
177 
178  (particle_infos_for_pdb,
179  geometric_center) = self.get_particle_infos_for_pdb_writing(name)
180 
181  if not translate_to_geometric_center:
182  geometric_center = (0, 0, 0)
183 
184  for n,tupl in enumerate(particle_infos_for_pdb):
185  (xyz, atom_type, residue_type,
186  chain_id, residue_index, all_indexes, radius) = tupl
187  if atom_type is None:
188  atom_type = IMP.atom.AT_CA
189  if ( (write_all_residues_per_bead) and (all_indexes is not None) ):
190  for residue_number in all_indexes:
191  flpdb.write(IMP.atom.get_pdb_string((xyz[0] - geometric_center[0],
192  xyz[1] - geometric_center[1],
193  xyz[2] - geometric_center[2]),
194  n+1, atom_type, residue_type,
195  chain_id, residue_number,' ',1.00,radius))
196  else:
197  flpdb.write(IMP.atom.get_pdb_string((xyz[0] - geometric_center[0],
198  xyz[1] - geometric_center[1],
199  xyz[2] - geometric_center[2]),
200  n+1, atom_type, residue_type,
201  chain_id, residue_index,' ',1.00,radius))
202  flpdb.write("ENDMDL\n")
203  flpdb.close()
204 
205  del particle_infos_for_pdb
206 
207  def get_prot_name_from_particle(self, name, p):
208  """Get the protein name from the particle.
209  This is done by traversing the hierarchy."""
210  if self.use_pmi2:
211  return IMP.pmi.get_molecule_name_and_copy(p), True
212  else:
214  p, self.dictchain[name])
215 
216  def get_particle_infos_for_pdb_writing(self, name):
217  # index_residue_pair_list={}
218 
219  # the resindexes dictionary keep track of residues that have been already
220  # added to avoid duplication
221  # highest resolution have highest priority
222  resindexes_dict = {}
223 
224  # this dictionary dill contain the sequence of tuples needed to
225  # write the pdb
226  particle_infos_for_pdb = []
227 
228  geometric_center = [0, 0, 0]
229  atom_count = 0
230  atom_index = 0
231 
232  if self.use_pmi2:
233  # select highest resolution
234  ps = IMP.atom.Selection(self.dictionary_pdbs[name],resolution=0).get_selected_particles()
235  else:
236  ps = IMP.atom.get_leaves(self.dictionary_pdbs[name])
237 
238  for n, p in enumerate(ps):
239  protname, is_a_bead = self.get_prot_name_from_particle(name, p)
240 
241  if protname not in resindexes_dict:
242  resindexes_dict[protname] = []
243 
244  if IMP.atom.Atom.get_is_setup(p) and self.atomistic:
245  residue = IMP.atom.Residue(IMP.atom.Atom(p).get_parent())
246  rt = residue.get_residue_type()
247  resind = residue.get_index()
248  atomtype = IMP.atom.Atom(p).get_atom_type()
249  xyz = list(IMP.core.XYZ(p).get_coordinates())
250  radius = IMP.core.XYZR(p).get_radius()
251  geometric_center[0] += xyz[0]
252  geometric_center[1] += xyz[1]
253  geometric_center[2] += xyz[2]
254  atom_count += 1
255  particle_infos_for_pdb.append((xyz,
256  atomtype, rt, self.dictchain[name][protname], resind, None, radius))
257  resindexes_dict[protname].append(resind)
258 
260 
261  residue = IMP.atom.Residue(p)
262  resind = residue.get_index()
263  # skip if the residue was already added by atomistic resolution
264  # 0
265  if resind in resindexes_dict[protname]:
266  continue
267  else:
268  resindexes_dict[protname].append(resind)
269  rt = residue.get_residue_type()
270  xyz = IMP.core.XYZ(p).get_coordinates()
271  radius = IMP.core.XYZR(p).get_radius()
272  geometric_center[0] += xyz[0]
273  geometric_center[1] += xyz[1]
274  geometric_center[2] += xyz[2]
275  atom_count += 1
276  particle_infos_for_pdb.append((xyz, None,
277  rt, self.dictchain[name][protname], resind, None, radius))
278 
279  elif IMP.atom.Fragment.get_is_setup(p) and not is_a_bead:
280  resindexes = IMP.pmi.tools.get_residue_indexes(p)
281  resind = resindexes[len(resindexes) // 2]
282  if resind in resindexes_dict[protname]:
283  continue
284  else:
285  resindexes_dict[protname].append(resind)
286  rt = IMP.atom.ResidueType('BEA')
287  xyz = IMP.core.XYZ(p).get_coordinates()
288  radius = IMP.core.XYZR(p).get_radius()
289  geometric_center[0] += xyz[0]
290  geometric_center[1] += xyz[1]
291  geometric_center[2] += xyz[2]
292  atom_count += 1
293  particle_infos_for_pdb.append((xyz, None,
294  rt, self.dictchain[name][protname], resind, resindexes, radius))
295 
296  else:
297  if is_a_bead:
298  rt = IMP.atom.ResidueType('BEA')
299  resindexes = IMP.pmi.tools.get_residue_indexes(p)
300  if len(resindexes) > 0:
301  resind = resindexes[len(resindexes) // 2]
302  xyz = IMP.core.XYZ(p).get_coordinates()
303  radius = IMP.core.XYZR(p).get_radius()
304  geometric_center[0] += xyz[0]
305  geometric_center[1] += xyz[1]
306  geometric_center[2] += xyz[2]
307  atom_count += 1
308  particle_infos_for_pdb.append((xyz, None,
309  rt, self.dictchain[name][protname], resind, resindexes, radius))
310 
311  if atom_count > 0:
312  geometric_center = (geometric_center[0] / atom_count,
313  geometric_center[1] / atom_count,
314  geometric_center[2] / atom_count)
315 
316  # sort by chain ID, then residue index. Longer chain IDs (e.g. AA)
317  # should always come after shorter (e.g. Z)
318  particle_infos_for_pdb = sorted(particle_infos_for_pdb,
319  key=lambda x: (len(x[3]), x[3], x[4]))
320 
321  return (particle_infos_for_pdb, geometric_center)
322 
323 
324  def write_pdbs(self, appendmode=True):
325  for pdb in self.dictionary_pdbs.keys():
326  self.write_pdb(pdb, appendmode)
327 
328  def init_pdb_best_scoring(self,
329  suffix,
330  prot,
331  nbestscoring,
332  replica_exchange=False):
333  # save only the nbestscoring conformations
334  # create as many pdbs as needed
335 
336  self.suffixes.append(suffix)
337  self.replica_exchange = replica_exchange
338  if not self.replica_exchange:
339  # common usage
340  # if you are not in replica exchange mode
341  # initialize the array of scores internally
342  self.best_score_list = []
343  else:
344  # otherwise the replicas must communicate
345  # through a common file to know what are the best scores
346  self.best_score_file_name = "best.scores.rex.py"
347  self.best_score_list = []
348  with open(self.best_score_file_name, "w") as best_score_file:
349  best_score_file.write(
350  "self.best_score_list=" + str(self.best_score_list) + "\n")
351 
352  self.nbestscoring = nbestscoring
353  for i in range(self.nbestscoring):
354  name = suffix + "." + str(i) + ".pdb"
355  flpdb = open(name, 'w')
356  flpdb.close()
357  self.dictionary_pdbs[name] = prot
358  self._init_dictchain(name, prot)
359 
360  def write_pdb_best_scoring(self, score):
361  if self.nbestscoring is None:
362  print("Output.write_pdb_best_scoring: init_pdb_best_scoring not run")
363 
364  # update the score list
365  if self.replica_exchange:
366  # read the self.best_score_list from the file
367  exec(open(self.best_score_file_name).read())
368 
369  if len(self.best_score_list) < self.nbestscoring:
370  self.best_score_list.append(score)
371  self.best_score_list.sort()
372  index = self.best_score_list.index(score)
373  for suffix in self.suffixes:
374  for i in range(len(self.best_score_list) - 2, index - 1, -1):
375  oldname = suffix + "." + str(i) + ".pdb"
376  newname = suffix + "." + str(i + 1) + ".pdb"
377  # rename on Windows fails if newname already exists
378  if os.path.exists(newname):
379  os.unlink(newname)
380  os.rename(oldname, newname)
381  filetoadd = suffix + "." + str(index) + ".pdb"
382  self.write_pdb(filetoadd, appendmode=False)
383 
384  else:
385  if score < self.best_score_list[-1]:
386  self.best_score_list.append(score)
387  self.best_score_list.sort()
388  self.best_score_list.pop(-1)
389  index = self.best_score_list.index(score)
390  for suffix in self.suffixes:
391  for i in range(len(self.best_score_list) - 1, index - 1, -1):
392  oldname = suffix + "." + str(i) + ".pdb"
393  newname = suffix + "." + str(i + 1) + ".pdb"
394  os.rename(oldname, newname)
395  filenametoremove = suffix + \
396  "." + str(self.nbestscoring) + ".pdb"
397  os.remove(filenametoremove)
398  filetoadd = suffix + "." + str(index) + ".pdb"
399  self.write_pdb(filetoadd, appendmode=False)
400 
401  if self.replica_exchange:
402  # write the self.best_score_list to the file
403  with open(self.best_score_file_name, "w") as best_score_file:
404  best_score_file.write(
405  "self.best_score_list=" + str(self.best_score_list) + '\n')
406 
407  def init_rmf(self, name, hierarchies, rs=None, geometries=None, listofobjects=None):
408  """
409  This function initialize an RMF file
410 
411  @param name the name of the RMF file
412  @param hierarchies the hiearchies to be included (it is a list)
413  @param rs optional, the restraint sets (it is a list)
414  @param geometries optional, the geometries (it is a list)
415  @param listofobjects optional, the list of objects for the stat (it is a list)
416  """
417  rh = RMF.create_rmf_file(name)
418  IMP.rmf.add_hierarchies(rh, hierarchies)
419  cat=None
420  outputkey_rmfkey=None
421 
422  if rs is not None:
424  if geometries is not None:
425  IMP.rmf.add_geometries(rh,geometries)
426  if listofobjects is not None:
427  cat = rh.get_category("stat")
428  outputkey_rmfkey={}
429  for l in listofobjects:
430  if not "get_output" in dir(l):
431  raise ValueError("Output: object %s doesn't have get_output() method" % str(l))
432  output=l.get_output()
433  for outputkey in output:
434  rmftag=RMF.string_tag
435  if isinstance(output[outputkey], float):
436  rmftag = RMF.float_tag
437  elif isinstance(output[outputkey], int):
438  rmftag = RMF.int_tag
439  elif isinstance(output[outputkey], str):
440  rmftag = RMF.string_tag
441  else:
442  rmftag = RMF.string_tag
443  rmfkey=rh.get_key(cat, outputkey, rmftag)
444  outputkey_rmfkey[outputkey]=rmfkey
445  outputkey_rmfkey["rmf_file"]=rh.get_key(cat, "rmf_file", RMF.string_tag)
446  outputkey_rmfkey["rmf_frame_index"]=rh.get_key(cat, "rmf_frame_index", RMF.int_tag)
447 
448  self.dictionary_rmfs[name] = (rh,cat,outputkey_rmfkey,listofobjects)
449 
450  def add_restraints_to_rmf(self, name, objectlist):
451  for o in _flatten(objectlist):
452  try:
453  rs = o.get_restraint_for_rmf()
454  except:
455  rs = o.get_restraint()
457  self.dictionary_rmfs[name][0],
458  rs.get_restraints())
459 
460  def add_geometries_to_rmf(self, name, objectlist):
461  for o in objectlist:
462  geos = o.get_geometries()
463  IMP.rmf.add_geometries(self.dictionary_rmfs[name][0], geos)
464 
465  def add_particle_pair_from_restraints_to_rmf(self, name, objectlist):
466  for o in objectlist:
467 
468  pps = o.get_particle_pairs()
469  for pp in pps:
471  self.dictionary_rmfs[name][0],
473 
474  def write_rmf(self, name):
475  IMP.rmf.save_frame(self.dictionary_rmfs[name][0])
476  if self.dictionary_rmfs[name][1] is not None:
477  cat=self.dictionary_rmfs[name][1]
478  outputkey_rmfkey=self.dictionary_rmfs[name][2]
479  listofobjects=self.dictionary_rmfs[name][3]
480  for l in listofobjects:
481  output=l.get_output()
482  for outputkey in output:
483  rmfkey=outputkey_rmfkey[outputkey]
484  try:
485  self.dictionary_rmfs[name][0].get_root_node().set_value(rmfkey,output[outputkey])
486  except NotImplementedError:
487  continue
488  rmfkey = outputkey_rmfkey["rmf_file"]
489  self.dictionary_rmfs[name][0].get_root_node().set_value(rmfkey, name)
490  rmfkey = outputkey_rmfkey["rmf_frame_index"]
491  nframes=self.dictionary_rmfs[name][0].get_number_of_frames()
492  self.dictionary_rmfs[name][0].get_root_node().set_value(rmfkey, nframes-1)
493  self.dictionary_rmfs[name][0].flush()
494 
495  def close_rmf(self, name):
496  rh = self.dictionary_rmfs[name][0]
497  del self.dictionary_rmfs[name]
498  del rh
499 
500  def write_rmfs(self):
501  for rmfinfo in self.dictionary_rmfs.keys():
502  self.write_rmf(rmfinfo[0])
503 
504  def init_stat(self, name, listofobjects):
505  if self.ascii:
506  flstat = open(name, 'w')
507  flstat.close()
508  else:
509  flstat = open(name, 'wb')
510  flstat.close()
511 
512  # check that all objects in listofobjects have a get_output method
513  for l in listofobjects:
514  if not "get_output" in dir(l):
515  raise ValueError("Output: object %s doesn't have get_output() method" % str(l))
516  self.dictionary_stats[name] = listofobjects
517 
518  def set_output_entry(self, key, value):
519  self.initoutput.update({key: value})
520 
521  def write_stat(self, name, appendmode=True):
522  output = self.initoutput
523  for obj in self.dictionary_stats[name]:
524  d = obj.get_output()
525  # remove all entries that begin with _ (private entries)
526  dfiltered = dict((k, v) for k, v in d.items() if k[0] != "_")
527  output.update(dfiltered)
528 
529  if appendmode:
530  writeflag = 'a'
531  else:
532  writeflag = 'w'
533 
534  if self.ascii:
535  flstat = open(name, writeflag)
536  flstat.write("%s \n" % output)
537  flstat.close()
538  else:
539  flstat = open(name, writeflag + 'b')
540  cPickle.dump(output, flstat, 2)
541  flstat.close()
542 
543  def write_stats(self):
544  for stat in self.dictionary_stats.keys():
545  self.write_stat(stat)
546 
547  def get_stat(self, name):
548  output = {}
549  for obj in self.dictionary_stats[name]:
550  output.update(obj.get_output())
551  return output
552 
553  def write_test(self, name, listofobjects):
554 # write the test:
555 # output=output.Output()
556 # output.write_test("test_modeling11_models.rmf_45492_11Sep13_veena_imp-020713.dat",outputobjects)
557 # run the test:
558 # output=output.Output()
559 # output.test("test_modeling11_models.rmf_45492_11Sep13_veena_imp-020713.dat",outputobjects)
560  flstat = open(name, 'w')
561  output = self.initoutput
562  for l in listofobjects:
563  if not "get_test_output" in dir(l) and not "get_output" in dir(l):
564  raise ValueError("Output: object %s doesn't have get_output() or get_test_output() method" % str(l))
565  self.dictionary_stats[name] = listofobjects
566 
567  for obj in self.dictionary_stats[name]:
568  try:
569  d = obj.get_test_output()
570  except:
571  d = obj.get_output()
572  # remove all entries that begin with _ (private entries)
573  dfiltered = dict((k, v) for k, v in d.items() if k[0] != "_")
574  output.update(dfiltered)
575  #output.update({"ENVIRONMENT": str(self.get_environment_variables())})
576  #output.update(
577  # {"IMP_VERSIONS": str(self.get_versions_of_relevant_modules())})
578  flstat.write("%s \n" % output)
579  flstat.close()
580 
581  def test(self, name, listofobjects, tolerance=1e-5):
582  output = self.initoutput
583  for l in listofobjects:
584  if not "get_test_output" in dir(l) and not "get_output" in dir(l):
585  raise ValueError("Output: object %s doesn't have get_output() or get_test_output() method" % str(l))
586  for obj in listofobjects:
587  try:
588  output.update(obj.get_test_output())
589  except:
590  output.update(obj.get_output())
591  #output.update({"ENVIRONMENT": str(self.get_environment_variables())})
592  #output.update(
593  # {"IMP_VERSIONS": str(self.get_versions_of_relevant_modules())})
594 
595  flstat = open(name, 'r')
596 
597  passed=True
598  for l in flstat:
599  test_dict = ast.literal_eval(l)
600  for k in test_dict:
601  if k in output:
602  old_value = str(test_dict[k])
603  new_value = str(output[k])
604  try:
605  float(old_value)
606  is_float = True
607  except ValueError:
608  is_float = False
609 
610  if is_float:
611  fold = float(old_value)
612  fnew = float(new_value)
613  diff = abs(fold - fnew)
614  if diff > tolerance:
615  print("%s: test failed, old value: %s new value %s; "
616  "diff %f > %f" % (str(k), str(old_value),
617  str(new_value), diff,
618  tolerance), file=sys.stderr)
619  passed=False
620  elif test_dict[k] != output[k]:
621  if len(old_value) < 50 and len(new_value) < 50:
622  print("%s: test failed, old value: %s new value %s"
623  % (str(k), old_value, new_value), file=sys.stderr)
624  passed=False
625  else:
626  print("%s: test failed, omitting results (too long)"
627  % str(k), file=sys.stderr)
628  passed=False
629 
630  else:
631  print("%s from old objects (file %s) not in new objects"
632  % (str(k), str(name)), file=sys.stderr)
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:155
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:1145
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:862
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: 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:114
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:62
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:709
bool get_is_canonical(atom::Hierarchy h)
Walk up a PMI2 hierarchy/representations and check if the root is named System.
Definition: utilities.h:91
Display a segment connecting a pair of particles.
Definition: XYZR.h:170
A decorator for a residue.
Definition: Residue.h:134
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:88
def get_prot_name_from_particle
Get the protein name from the particle.
Definition: output.py:207
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:1550
Hierarchies get_leaves(const Selection &h)
Select hierarchy particles identified by the biological name.
Definition: Selection.h:66
def init_rmf
This function initialize an RMF file.
Definition: output.py:407
def get_residue_indexes
Retrieve the residue indexes for the given particle.
Definition: tools.py:882
static bool get_is_setup(const IMP::ParticleAdaptor &p)
Definition: rigid_bodies.h:711
std::string get_module_version()
def sublist_iterator
Yield all sublists of length >= lmin and <= lmax.
Definition: tools.py:955
A decorator for a particle with x,y,z coordinates and a radius.
Definition: XYZR.h:27