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