io.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import os
  2. import math
  3. import logging
  4. import numpy as np
  5. from heb import DataSet, BUNCHES_PER_TURN, HEADER_SIZE_BYTES
  6. def is_data_consistent(dataset):
  7. bunch_numbers = dataset.array[:, -1]
  8. expected = np.tile(np.arange(0, BUNCHES_PER_TURN), bunch_numbers.shape[0] / BUNCHES_PER_TURN)
  9. wrong_indices = np.argwhere(bunch_numbers != expected)
  10. if wrong_indices.shape[0] > 0:
  11. first_error = bunch_numbers.shape[0] - wrong_indices.shape[0]
  12. logging.info('Data inconsistent at offset %i'%first_error)
  13. np.savetxt('wrongdump', dataset.array[first_error - 3: first_error + 3])
  14. filling = bunch_numbers[wrong_indices[0][0]:]
  15. expected_filling = np.tile([222, 223], filling.shape[0] / 2)
  16. wrong_filling_indices = np.argwhere(filling != expected_filling)
  17. if wrong_filling_indices.shape[0] > 2: # Some times filling does not start immediately... Why? I have NO IDEA!
  18. return False
  19. else:
  20. return True
  21. else:
  22. return True
  23. def _cached_exist(filename):
  24. return os.path.exists(os.path.abspath('{}.npy'.format(filename)))
  25. def decode_data(data):
  26. data = data[np.where(data != 0x01234567)]
  27. # Make sure we read multiple of fours
  28. data = data[:4 * (math.floor(data.size / 4))]
  29. bunch_low = data & 0xfff
  30. bunch_high = np.right_shift(data, 12) & 0xfff
  31. bunch_number = np.right_shift(data, 24) & 0xfff
  32. bunch_low = bunch_low.reshape(-1, 4)
  33. bunch_high = bunch_high.reshape(-1, 4)
  34. result = np.empty((bunch_low.shape[0] + bunch_high.shape[0], 5), dtype=np.float)
  35. result[0::2,:4] = bunch_low
  36. result[1::2,:4] = bunch_high
  37. result[0::2, 4] = bunch_number[::4]
  38. result[1::2, 4] = bunch_number[::4] + 1
  39. result = result[:184 * (math.floor(result.shape[0] / 184)), :]
  40. return result
  41. def read_from_file(filename, force=False, header=False, cache=False):
  42. if _cached_exist(filename) and not force:
  43. cached_filename = '{}.npy'.format(filename)
  44. logging.info("Read pre-computed data from {}".format(cached_filename))
  45. return DataSet(np.load(cached_filename), filename)
  46. with open(filename, 'rb') as f:
  47. logging.info("Read data from {}".format(filename))
  48. data = np.fromfile(f, dtype=np.uint32)
  49. #If header is sent with the data, truncate it
  50. if header:
  51. # We read words of 4 bytes each
  52. splice_words = HEADER_SIZE_BYTES / 4
  53. data = data[splice_words:]
  54. result = decode_data(data)
  55. dataset = DataSet(result, filename)
  56. if cache:
  57. logging.info('Saving pre-computed data')
  58. np.save('{}.npy'.format(filename), result)
  59. return dataset
  60. def read_from_string(raw_data, force=False, header=False, cache=False, cache_filename="_heb_data_cache"):
  61. if _cached_exist(cache_filename) and not force:
  62. cache_file = '{}.npy'.format(cache_filename)
  63. logging.info("Read pre-computed data from {}".format(cache_file))
  64. return DataSet(np.load(cache_file), cache_filename)
  65. logging.info("Read data directly from device.")
  66. logging.info("Read %i bytes of data" % len(raw_data))
  67. data = np.fromstring(raw_data, dtype=np.uint32)
  68. #If header is sent with the data, truncate it
  69. if header:
  70. # We read words of 4 bytes each
  71. splice_words = HEADER_SIZE_BYTES / 4
  72. data = data[splice_words:]
  73. result = decode_data(data)
  74. dataset = DataSet(result, "HEB Live Data")
  75. if cache:
  76. logging.info('Saving pre-computed data')
  77. np.save('{}.npy'.format(cache_filename), result)
  78. return dataset