scp_info.py 2.6 KB

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