scp_info.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import struct, sys
  2. import matplotlib.pyplot as plt
  3. NO_DAT = 0
  4. PRINT_DAT = 1
  5. PLOT_DAT = 2
  6. def dump_track(dat, trk_offs, trknr, show_dat):
  7. print("Track %u:" % trknr)
  8. trk_off = trk_offs[trknr]
  9. if trk_off == 0:
  10. print("Empty")
  11. return
  12. # Parse the SCP track header and extract the flux data.
  13. thdr = dat[trk_off:trk_off+4+12*nr_revs]
  14. sig, tnr, _, _, s_off = struct.unpack("<3sB3I", thdr[:16])
  15. assert sig == b"TRK"
  16. assert tnr == trknr
  17. p_idx, tot = [], 0.0
  18. for i in range(nr_revs):
  19. t,n,_ = struct.unpack("<3I", thdr[4+i*12:4+(i+1)*12])
  20. print("Rev %u: time=%uus flux=%u" % (i, t//40, n))
  21. tot += t/40
  22. p_idx.append(tot)
  23. if not show_dat:
  24. return
  25. _, e_nr, e_off = struct.unpack("<3I", thdr[-12:])
  26. tdat = dat[trk_off+s_off:trk_off+e_off+e_nr*2]
  27. fluxl = []
  28. while tdat:
  29. flux, = struct.unpack(">H", tdat[:2])
  30. tdat = tdat[2:]
  31. fluxl.append(flux / 40)
  32. tot = 0.0
  33. i = 0
  34. px, py = [], []
  35. for x in fluxl:
  36. if show_dat == PRINT_DAT:
  37. bad = ""
  38. if (x < 3.6) or ((x > 4.4) and (x < 5.4)) \
  39. or ((x > 6.6) and (x < 7.2)) or (x > 8.8):
  40. bad = "BAD"
  41. print("%d: %f %s" % (i, x, bad))
  42. else:
  43. px.append(tot/1000)
  44. py.append(x)
  45. i += 1
  46. tot += x
  47. print("Total: %uus (%uus per rev)" % (int(tot), tot//nr_revs))
  48. if show_dat == PLOT_DAT:
  49. plt.xlabel("Time (ms)")
  50. plt.ylabel("Flux (us)")
  51. plt.gcf().set_size_inches(12, 8)
  52. plt.axvline(x=0, ymin=0.95, color='r')
  53. for t in p_idx:
  54. plt.axvline(x=t/1000, ymin=0.95, color='r')
  55. plt.scatter(px, py, s=1)
  56. plt.show()
  57. argv = sys.argv
  58. plot = (argv[1] == '--plot')
  59. if plot:
  60. argv = argv[1:]
  61. with open(argv[1], "rb") as f:
  62. dat = f.read()
  63. header = struct.unpack("<3s9BI", dat[0:16])
  64. (sig, _, _, nr_revs, s_trk, e_trk, flags, _, ss, _, _) = header
  65. assert sig == b"SCP"
  66. nr_sides = 1 if ss else 2
  67. trk_offs = struct.unpack("<168I", dat[16:0x2b0])
  68. print("Revolutions: %u" % nr_revs)
  69. if len(argv) == 3:
  70. dump_track(dat, trk_offs, int(argv[2]), PLOT_DAT if plot else PRINT_DAT)
  71. else:
  72. for i in range(s_trk, e_trk+1):
  73. dump_track(dat, trk_offs, i, NO_DAT)