mcell_checkpoint.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. ###################################################################################
  2. # #
  3. # Copyright (C) 2006-2013 by #
  4. # The Salk Institute for Biological Studies and #
  5. # Pittsburgh Supercomputing Center, Carnegie Mellon University #
  6. # #
  7. # This program is free software; you can redistribute it and/or #
  8. # modify it under the terms of the GNU General Public License #
  9. # as published by the Free Software Foundation; either version 2 #
  10. # of the License, or (at your option) any later version. #
  11. # #
  12. # This program is distributed in the hope that it will be useful, #
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of #
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  15. # GNU General Public License for more details. #
  16. # #
  17. # You should have received a copy of the GNU General Public License #
  18. # along with this program; if not, write to the Free Software #
  19. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
  20. # #
  21. ###################################################################################
  22. import struct
  23. class UnmarshalBuffer(object):
  24. def __init__(self, data):
  25. self.__data = data
  26. self.__offset = 0
  27. self.__endian = '<'
  28. def get_offset(self):
  29. return self.__offset
  30. offset = property(get_offset)
  31. def at_end(self):
  32. return self.__offset >= len(self.__data)
  33. def set_big_endian(self, e):
  34. if e:
  35. self.__endian = '>'
  36. else:
  37. self.__endian = '<'
  38. def next_byte(self):
  39. b = ord(self.__data[self.__offset])
  40. self.__offset += 1
  41. return b
  42. def next_vint(self):
  43. b = self.next_byte()
  44. accum = b & 0x7f
  45. while (b & 0x80) != 0:
  46. b = self.next_byte()
  47. accum <<= 7
  48. accum |= (b & 0x7f)
  49. return accum
  50. def next_svint(self):
  51. val = self.next_vint()
  52. if val & 1:
  53. return -(val >> 1)
  54. else:
  55. return (val >> 1)
  56. return accum
  57. def next_string(self):
  58. l = self.next_vint()
  59. return self.next_cstring(l)
  60. def next_cstring(self, l):
  61. return self.next_struct('%ds' % l)[0]
  62. def next_struct(self, tmpl):
  63. vals = struct.unpack_from(self.__endian + tmpl, self.__data, self.__offset)
  64. self.__offset += struct.calcsize(tmpl)
  65. return vals
  66. CMD_CURRENT_TIME = 1
  67. CMD_CURRENT_ITERATION = 2
  68. CMD_CHKPT_SEQ_NUM = 3
  69. CMD_RNG_STATE = 4
  70. CMD_MCELL_VERSION = 5
  71. CMD_SPECIES_TABLE = 6
  72. CMD_SCHEDULER_STATE = 7
  73. CMD_BYTE_ORDER = 8
  74. def read_current_time(ub):
  75. time, = ub.next_struct('d')
  76. return {'cur_time': time}
  77. def read_current_iteration(ub):
  78. start_time, real_time = ub.next_struct('qd')
  79. return {'start_time': start_time, 'real_time': real_time}
  80. def read_chkpt_sequence(ub):
  81. seq, = ub.next_struct('I')
  82. return {'chkpt_seq': seq}
  83. def read_rng_state(ub):
  84. seed = ub.next_vint()
  85. rngtype, = ub.next_struct('c')
  86. if rngtype == 'I':
  87. randcnt = ub.next_vint()
  88. aa, bb, cc = ub.next_struct('QQQ')
  89. randrsl = ub.next_struct('256Q')
  90. mm = ub.next_struct('256Q')
  91. return {'rng_seed': seed,
  92. 'rng_type': 'ISAAC64',
  93. 'rng_aa': aa,
  94. 'rng_bb': bb,
  95. 'rng_cc': cc,
  96. 'rng_rsl': randrsl,
  97. 'rng_mm': mm}
  98. elif rngtype == 'M':
  99. a, b, c, d = ub.next_struct('IIII')
  100. return {'rng_seed': seed,
  101. 'rng_type': 'SimpleRNG',
  102. 'rng_a': a,
  103. 'rng_b': b,
  104. 'rng_c': c,
  105. 'rng_d': d }
  106. else:
  107. raise Exception('Sorry -- this file seems to be malformed.')
  108. def read_byte_order(ub):
  109. bo, = ub.next_struct('I')
  110. if bo == 17:
  111. ub.set_big_endian(False)
  112. return {'endian': 'little'}
  113. elif bo == 0x10000000:
  114. ub.set_big_endian(True)
  115. return {'endian': 'big'}
  116. else:
  117. raise Exception('Unknown byte order %d' % bo)
  118. def read_mcell_version(ub):
  119. ver_len, = ub.next_struct('I')
  120. ver = ub.next_cstring(ver_len)
  121. return {'mcell_version': ver}
  122. def read_species(ub):
  123. nsp = ub.next_vint()
  124. species = {}
  125. for i in range(nsp):
  126. species_name = ub.next_string()
  127. species_id = ub.next_vint()
  128. species[species_id] = species_name
  129. return {'species': species}
  130. def read_scheduler(ub, spec):
  131. num_molecules = ub.next_vint()
  132. molecules = []
  133. for i in range(num_molecules):
  134. species = ub.next_vint()
  135. newbie = ub.next_byte()
  136. t, t2, bday, x, y, z = ub.next_struct('dddddd')
  137. orient = ub.next_svint()
  138. cmplx = ub.next_vint()
  139. m = {'species': spec[species],
  140. 'newbie': newbie != 0,
  141. 't': t,
  142. 't2': t2,
  143. 'birthday': bday,
  144. 'pos': (x, y, z),
  145. 'orient': orient}
  146. if cmplx != 0:
  147. suidx = ub.next_vint()
  148. m['cx_idx'] = cmplx
  149. m['cx_sub'] = suidx
  150. if suidx != 0:
  151. nunits = ub.next_vint()
  152. m['cx_cnt'] = nunits
  153. molecules.append(m)
  154. return {'molecules': molecules}
  155. def read_file(fname):
  156. ub = UnmarshalBuffer(open(fname, 'rb').read())
  157. data = {}
  158. while not ub.at_end():
  159. cmd = ub.next_byte()
  160. if cmd == CMD_CURRENT_TIME:
  161. d = read_current_time(ub)
  162. elif cmd == CMD_CURRENT_ITERATION:
  163. d = read_current_iteration(ub)
  164. elif cmd == CMD_CHKPT_SEQ_NUM:
  165. d = read_chkpt_sequence(ub)
  166. elif cmd == CMD_RNG_STATE:
  167. d = read_rng_state(ub)
  168. elif cmd == CMD_MCELL_VERSION:
  169. d = read_mcell_version(ub)
  170. elif cmd == CMD_SPECIES_TABLE:
  171. d = read_species(ub)
  172. elif cmd == CMD_SCHEDULER_STATE:
  173. d = read_scheduler(ub, data['species'])
  174. elif cmd == CMD_BYTE_ORDER:
  175. d = read_byte_order(ub)
  176. else:
  177. raise Exception('Unknown command %02x in file. Perhaps the file is malformed.' % cmd)
  178. data.update(d)
  179. return data
  180. def dump_data(data):
  181. ORIENTS = ['-', '_', '+']
  182. print ' MCell version: %s' % data['mcell_version']
  183. print ' File endianness: %s' % data['endian']
  184. print ' Cur time: %.15g' % data['cur_time']
  185. print ' Start iteration: %ld' % data['start_time']
  186. print ' Real time: %.15g' % data['real_time']
  187. print ' Sequence: %d' % data['chkpt_seq']
  188. rng_keys = [k for k in data.keys() if k.startswith('rng_')]
  189. rng_keys.sort()
  190. for d in rng_keys:
  191. print ' %s: %*s %s' % (d, 8-len(d), '', str(data[d]))
  192. print ' Species:'
  193. species_table = data['species']
  194. species_keys = species_table.keys()
  195. species_keys.sort()
  196. for d in species_keys:
  197. name = species_table[d]
  198. print ' %3d: %s' % (d, name)
  199. for m in data['molecules']:
  200. if m['species'] != name:
  201. continue
  202. print (' %c %18.15g %18.15g %18.15g (%18.15g, %18.15g, %18.15g) %c' %
  203. ('N' if m['newbie'] else '_',
  204. m['t'],
  205. m['t2'],
  206. m['birthday'],
  207. m['pos'][0],
  208. m['pos'][1],
  209. m['pos'][2],
  210. ORIENTS[m['orient'] + 1])),
  211. if m.has_key('cx_idx'):
  212. if m.has_key('cx_cnt'):
  213. print ' %5d[%d/%d]' % (m['cx_idx'], m['cx_sub'], m['cx_cnt'])
  214. else:
  215. print ' %5d[MASTER]' % (m['cx_idx'])
  216. else:
  217. print ''
  218. if __name__ == '__main__':
  219. try:
  220. import psyco
  221. psyco.full()
  222. except ImportError:
  223. pass
  224. import sys
  225. for i in sys.argv[1:]:
  226. print '%s:' % i
  227. data = read_file(i)
  228. dump_data(data)