scp_info.py 2.4 KB

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