IMP  2.0.1
The Integrative Modeling Platform
Analysis.py
1 #!/usr/bin/env ptyhon
2 
3 import matplotlib.pyplot
4 from numpy import *
5 from IMP.isd.History import History
6 
7 class Analysis:
8  """Class that produces analysis-related output, and is able to parse the
9  output of a file produced by the Statistics class.
10  """
11 
12  def create_entry(self, h, lineno, el):
13  """adds a new entry to the hierarchy by parsing a title entry"""
14  if lineno == len(self.correspondences):
15  self.correspondences.append([])
16  entryno, cat, name = el.split(':')
17  entryno=int(entryno)-1
18  if len(self.correspondences[lineno]) == entryno:
19  self.correspondences[lineno].append((cat,name))
20  else:
21  self.correspondences[lineno][entryno]=(cat,name)
22  h.create_entry(cat,name)
23 
24  def add_data(self, h, lineno, colno, data):
25  """adds data point to hierarchy"""
26  cat,name = self.correspondences[lineno][colno]
27  if data.isdigit():
28  data = int(data)
29  else:
30  try:
31  data = float(data)
32  except ValueError:
33  pass
34  h.add_data(cat,name,data)
35 
36  def read_variables(self, statfile):
37  """reads a *_stats.txt file and returns variables present in it"""
38  h=History(statfile)
39  #read title and setup history
40  self.correspondences=[]
41  for line in open(statfile):
42  if line.startswith('*'):
43  continue
44  tokens=line.split()
45  if not tokens[0][1].isdigit():
46  continue
47  lineno = int(tokens[0][1:])-1
48  if line.startswith('#'):
49  for el in tokens[1:]:
50  self.create_entry(h, lineno, el)
51  continue
52  break
53  return self.correspondences
54 
55  def read_AMBER_variables(self, statfile):
56  """reads an AMBER mden file and returns variables present in it"""
57  h=History(statfile)
58  #read title and setup history
59  self.correspondences=[]
60  oldnum=-1
61  for line in open(statfile):
62  tokens=line.split()
63  lineno = int(tokens[0][1:])
64  if lineno < oldnum:
65  break
66  oldnum = lineno
67  for i,el in enumerate(tokens[1:]):
68  self.create_entry(h, lineno, '%d:global:%s' % (i+1,el))
69  return self.correspondences
70 
71  def read_AMBER_stats(self, statfile):
72  """reads an AMBER mden file and returns a History instance"""
73  h=History(statfile)
74  #read title and setup history
75  read_title=True
76  oldnum=-1
77  self.correspondences=[]
78  for line in open(statfile):
79  tokens=line.split()
80  lineno = int(tokens[0][1:])
81  if lineno < oldnum and read_title:
82  read_title=False
83  oldnum = lineno
84  if read_title:
85  for i,el in enumerate(tokens[1:]):
86  self.create_entry(h, lineno, '%d:global:%s' % (i+1,el))
87  continue
88  #from here on, the line contains data
89  for i, el in enumerate(tokens[1:]):
90  self.add_data(h, lineno, i, el)
91  #h.sanity_check()
92  return h
93 
94  def read_stats(self, statfile):
95  """reads a *_stats.txt file and returns a History instance"""
96  h=History(statfile)
97  #read title and setup history
98  read_title=True
99  self.correspondences=[]
100  for line in open(statfile):
101  if line.startswith('*'):
102  continue
103  tokens=line.split()
104  if not tokens[0][1].isdigit():
105  continue
106  lineno = int(tokens[0][1:])-1
107  if line.startswith('#'):
108  if read_title:
109  for el in tokens[1:]:
110  self.create_entry(h, lineno, el)
111  continue
112  elif read_title:
113  read_title = False
114  #from here on, the line starts with 'L'
115  for i, el in enumerate(tokens[1:]):
116  self.add_data(h, lineno, i, el)
117  #h.sanity_check()
118  return h
119 
120  def plot(self, h, *datums, **kwargs):
121  """plots datum (cat,name) from hierarchy h, optionnally specifying a
122  range. To plot multiple data at the same time, add them sequentially.
123  Takes x axis from the 'step' entry of the first datum. TODO.
124  """
125  data=[array(h.get_data(cat,name), dtype=float) \
126  for (cat, name) in datums]
127  x = h.get_data(datums[0][0],'step')
128  toplot = []
129  for i in range(len(data)):
130  toplot.extend([x,data[i]])
131  matplotlib.pyplot.plot(*data, **kwargs)
132  matplotlib.pyplot.grid(True)
133  matplotlib.pyplot.legend()
134  matplotlib.pyplot.show()
135 
136  def histogram(self, h, *datums, **kwargs):
137  """plots histogram of datum (cat,name) from hierarchy h, optionnally
138  specifying a range. To plot multiple data at the same time, add them
139  sequentially.
140  """
141  data=[array(h.get_data(*dat), dtype=float) \
142  for dat in datums]
143  matplotlib.pyplot.hist(*data, **kwargs)
144  matplotlib.pyplot.grid(True)
145  matplotlib.pyplot.legend()
146  matplotlib.pyplot.show()
147 
148  def dump(self, h, dest, *args):
149  """"dump float data from history h to file dest.
150  args can be either strings corresponding to categories, or tuples
151  corresponding to entries of a certain category. Only one counter will be
152  output for the whole dump, it corresponds to the counter of the first
153  entry's category. You can always specify additional counters if needed.
154  """
155  #parse args
156  cats=[]
157  names=[]
158  for arg in args:
159  if type(arg) == str:
160  #get rid of counter
161  ent=h.get_entries(arg)[1:]
162  names.extend(ent)
163  cats.extend([arg]*len(ent))
164  else:
165  #argument should be (cat, entry)
166  names.append(arg[1])
167  cats.append(arg[0])
168  #write data
169  steps=h.get_data(cats[0],'step')
170  fl=open(dest,'w')
171  fl.write("# %s:step\t" % cats[0])
172  fl.write('\t'.join(['%s:%s' % (i,j) for (i,j) in zip(cats,names)]))
173  fl.write('\n')
174  data=[h.get_data(i,j) for (i,j) in zip(cats,names)]
175  for i,st in enumerate(steps):
176  fl.write("%10d\t" % st)
177  for j in data:
178  fl.write('%10f\t' % j[i])
179  fl.write('\n')
180  fl.close()
181 
182 
183 
184 
185 
186 if __name__ == '__main__':
187 
188  import sys
189  a=Analysis()
190  h=a.read_stats(sys.argv[1])
191  h.toc()
192  matplotlib.pyplot.ion() #interactive