mcell_checkpoint.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import struct
  2. class UnmarshalBuffer(object):
  3. def __init__(self, data):
  4. self.__data = data
  5. self.__offset = 0
  6. self.__endian = '<'
  7. def get_offset(self):
  8. return self.__offset
  9. offset = property(get_offset)
  10. def at_end(self):
  11. return self.__offset >= len(self.__data)
  12. def set_big_endian(self, e):
  13. if e:
  14. self.__endian = '>'
  15. else:
  16. self.__endian = '<'
  17. def next_byte(self):
  18. b = ord(self.__data[self.__offset])
  19. self.__offset += 1
  20. return b
  21. def next_vint(self):
  22. b = self.next_byte()
  23. accum = b & 0x7f
  24. while (b & 0x80) != 0:
  25. b = self.next_byte()
  26. accum <<= 7
  27. accum |= (b & 0x7f)
  28. return accum
  29. def next_svint(self):
  30. val = self.next_vint()
  31. if val & 1:
  32. return -(val >> 1)
  33. else:
  34. return (val >> 1)
  35. return accum
  36. def next_string(self):
  37. l = self.next_vint()
  38. return self.next_cstring(l)
  39. def next_cstring(self, l):
  40. return self.next_struct('%ds' % l)[0]
  41. def next_struct(self, tmpl):
  42. vals = struct.unpack_from(self.__endian + tmpl, self.__data, self.__offset)
  43. self.__offset += struct.calcsize(tmpl)
  44. return vals
  45. CMD_CURRENT_TIME = 1
  46. CMD_CURRENT_ITERATION = 2
  47. CMD_CHKPT_SEQ_NUM = 3
  48. CMD_RNG_STATE = 4
  49. CMD_MCELL_VERSION = 5
  50. CMD_SPECIES_TABLE = 6
  51. CMD_SCHEDULER_STATE = 7
  52. CMD_BYTE_ORDER = 8
  53. def read_current_time(ub):
  54. time, = ub.next_struct('d')
  55. return {'cur_time': time}
  56. def read_current_iteration(ub):
  57. start_time, real_time = ub.next_struct('qd')
  58. return {'start_time': start_time, 'real_time': real_time}
  59. def read_chkpt_sequence(ub):
  60. seq, = ub.next_struct('I')
  61. return {'chkpt_seq': seq}
  62. def read_rng_state(ub):
  63. seed = ub.next_vint()
  64. rngtype, = ub.next_struct('c')
  65. if rngtype == 'I':
  66. randcnt = ub.next_vint()
  67. aa, bb, cc = ub.next_struct('QQQ')
  68. randrsl = ub.next_struct('256Q')
  69. mm = ub.next_struct('256Q')
  70. return {'rng_seed': seed,
  71. 'rng_type': 'ISAAC64',
  72. 'rng_aa': aa,
  73. 'rng_bb': bb,
  74. 'rng_cc': cc,
  75. 'rng_rsl': randrsl,
  76. 'rng_mm': mm}
  77. elif rngtype == 'M':
  78. a, b, c, d = ub.next_struct('IIII')
  79. return {'rng_seed': seed,
  80. 'rng_type': 'SimpleRNG',
  81. 'rng_a': a,
  82. 'rng_b': b,
  83. 'rng_c': c,
  84. 'rng_d': d }
  85. else:
  86. raise Exception('Sorry -- this file seems to be malformed.')
  87. def read_byte_order(ub):
  88. bo, = ub.next_struct('I')
  89. if bo == 17:
  90. ub.set_big_endian(False)
  91. return {'endian': 'little'}
  92. elif bo == 0x10000000:
  93. ub.set_big_endian(True)
  94. return {'endian': 'big'}
  95. else:
  96. raise Exception('Unknown byte order %d' % bo)
  97. def read_mcell_version(ub):
  98. ver_len, = ub.next_struct('I')
  99. ver = ub.next_cstring(ver_len)
  100. return {'mcell_version': ver}
  101. def read_species(ub):
  102. nsp = ub.next_vint()
  103. species = {}
  104. for i in range(nsp):
  105. species_name = ub.next_string()
  106. species_id = ub.next_vint()
  107. species[species_id] = species_name
  108. return {'species': species}
  109. def read_scheduler(ub, spec):
  110. num_molecules = ub.next_vint()
  111. molecules = []
  112. for i in range(num_molecules):
  113. species = ub.next_vint()
  114. newbie = ub.next_byte()
  115. t, t2, bday, x, y, z = ub.next_struct('dddddd')
  116. orient = ub.next_svint()
  117. cmplx = ub.next_vint()
  118. m = {'species': spec[species],
  119. 'newbie': newbie != 0,
  120. 't': t,
  121. 't2': t2,
  122. 'birthday': bday,
  123. 'pos': (x, y, z),
  124. 'orient': orient}
  125. if cmplx != 0:
  126. suidx = ub.next_vint()
  127. m['cx_idx'] = cmplx
  128. m['cx_sub'] = suidx
  129. if suidx != 0:
  130. nunits = ub.next_vint()
  131. m['cx_cnt'] = nunits
  132. molecules.append(m)
  133. return {'molecules': molecules}
  134. def read_file(fname):
  135. ub = UnmarshalBuffer(open(fname, 'rb').read())
  136. data = {}
  137. while not ub.at_end():
  138. cmd = ub.next_byte()
  139. if cmd == CMD_CURRENT_TIME:
  140. d = read_current_time(ub)
  141. elif cmd == CMD_CURRENT_ITERATION:
  142. d = read_current_iteration(ub)
  143. elif cmd == CMD_CHKPT_SEQ_NUM:
  144. d = read_chkpt_sequence(ub)
  145. elif cmd == CMD_RNG_STATE:
  146. d = read_rng_state(ub)
  147. elif cmd == CMD_MCELL_VERSION:
  148. d = read_mcell_version(ub)
  149. elif cmd == CMD_SPECIES_TABLE:
  150. d = read_species(ub)
  151. elif cmd == CMD_SCHEDULER_STATE:
  152. d = read_scheduler(ub, data['species'])
  153. elif cmd == CMD_BYTE_ORDER:
  154. d = read_byte_order(ub)
  155. else:
  156. raise Exception('Unknown command %02x in file. Perhaps the file is malformed.' % cmd)
  157. data.update(d)
  158. return data
  159. def dump_data(data):
  160. ORIENTS = ['-', '_', '+']
  161. print ' MCell version: %s' % data['mcell_version']
  162. print ' File endianness: %s' % data['endian']
  163. print ' Cur time: %.15g' % data['cur_time']
  164. print ' Start iteration: %ld' % data['start_time']
  165. print ' Real time: %.15g' % data['real_time']
  166. print ' Sequence: %d' % data['chkpt_seq']
  167. rng_keys = [k for k in data.keys() if k.startswith('rng_')]
  168. rng_keys.sort()
  169. for d in rng_keys:
  170. print ' %s: %*s %s' % (d, 8-len(d), '', str(data[d]))
  171. print ' Species:'
  172. species_table = data['species']
  173. species_keys = species_table.keys()
  174. species_keys.sort()
  175. for d in species_keys:
  176. name = species_table[d]
  177. print ' %3d: %s' % (d, name)
  178. for m in data['molecules']:
  179. if m['species'] != name:
  180. continue
  181. print (' %c %18.15g %18.15g %18.15g (%18.15g, %18.15g, %18.15g) %c' %
  182. ('N' if m['newbie'] else '_',
  183. m['t'],
  184. m['t2'],
  185. m['birthday'],
  186. m['pos'][0],
  187. m['pos'][1],
  188. m['pos'][2],
  189. ORIENTS[m['orient'] + 1])),
  190. if m.has_key('cx_idx'):
  191. if m.has_key('cx_cnt'):
  192. print ' %5d[%d/%d]' % (m['cx_idx'], m['cx_sub'], m['cx_cnt'])
  193. else:
  194. print ' %5d[MASTER]' % (m['cx_idx'])
  195. else:
  196. print ''
  197. if __name__ == '__main__':
  198. try:
  199. import psyco
  200. psyco.full()
  201. except ImportError:
  202. pass
  203. import sys
  204. for i in sys.argv[1:]:
  205. print '%s:' % i
  206. data = read_file(i)
  207. dump_data(data)