Newer
Older
TB_Chris / TbIO / src / .svn / text-base / TbRawStream.cpp.svn-base
  1. #include "TbRawStream.h"
  2. #include <cmath>
  3.  
  4. DECLARE_TOOL_FACTORY(TbRawStream)
  5.  
  6. const int64_t TbRawStream::m_tenSeconds = 256 * std::pow(10, 11);
  7. const int64_t TbRawStream::m_maxTimeDifference = pow(2, 40);
  8.  
  9. //=============================================================================
  10. // Standard constructor
  11. //=============================================================================
  12. TbRawStream::TbRawStream(const std::string& type, const std::string& name,
  13. const IInterface* parent)
  14. : GaudiTool(type, name, parent),
  15. m_hitCache(), m_trgCache() {
  16. declareInterface<TbRawStream>(this);
  17. }
  18.  
  19. bool TbRawStream::setMSB(uint64_t msb) {
  20. uint64_t currentTime = (m_lsb + (msb << 32)) << 12;
  21. const int64_t timeDifference = currentTime - m_timer;
  22. if (timeDifference > m_tenSeconds) {
  23. // Detected jump of greater than 10s
  24. // warning() << "Jump detected - this is okay, probably means "
  25. // << "a bit has been updated between LSB and MSB" << endmsg;
  26. if (msb > 0) msb -= 1;
  27. currentTime = (m_lsb + (msb << 32)) << 12;
  28. }
  29. if (timeDifference > m_maxTimeDifference ||
  30. timeDifference < -m_maxTimeDifference) {
  31. // warning << "Current global time = " <<
  32. // m_timer*25*pow(10,-6)/4096 << " clock is trying to update to " <<
  33. // currentTime*25*pow(10,-6)/4096 << endmsg;
  34. return false;
  35. }
  36. m_timer = currentTime;
  37. // info() << "Current global time: " <<
  38. // currentTime*25/(4096*pow(10,9)) << " s" <<endmsg;
  39. return true;
  40. }
  41.  
  42. void TbRawStream::fastForward(const uint64_t timeToSkipTo) {
  43. // Go one second before we need to
  44. const double coarse_time = timeToSkipTo * 25 / (4096 * pow(10, 9));
  45. coarseFastForward(coarse_time);
  46. fineFastForward(timeToSkipTo);
  47. }
  48.  
  49. //=============================================================================
  50. // Binary search of the stream to find a particular time
  51. //=============================================================================
  52. void TbRawStream::coarseFastForward(const double timeToSkipTo) {
  53.  
  54. info() << "Skipping forward to time = " << timeToSkipTo << endmsg;
  55. // Need to work out which file to read first
  56. if (m_files.size() > 1) {
  57. for (auto it = m_files.begin(), end = m_files.end(); it != end; ++it) {
  58. m_currentFile = it;
  59. (*it)->initialise();
  60. const double timeInSeconds = getCurrentTime() * 25 / pow(10, 9);
  61. if (timeInSeconds > timeToSkipTo) {
  62. (*it)->reset();
  63. m_currentFile--;
  64. break;
  65. }
  66. (*it)->reset();
  67. }
  68. }
  69.  
  70. (*m_currentFile)->initialise();
  71. uint64_t dt = (*m_currentFile)->nPackets() / 2;
  72. uint64_t pos = dt;
  73. uint64_t timer = 0;
  74. double timeInSeconds = 0;
  75. while (!eos() && fabs(timeToSkipTo - timeInSeconds) > 0.6 && dt > 1) {
  76. // Scroll to the new position
  77. (*m_currentFile)->setOffset(pos);
  78. dt /= 2;
  79. timer = getCurrentTime();
  80. timeInSeconds = timer * 25 / pow(10, 9);
  81. pos = timeToSkipTo > timeInSeconds ? (pos + dt) : (pos - dt);
  82. }
  83. if (dt <= 1) info() << "Binary search has failed!" << endmsg;
  84. m_timer = timer << 12;
  85. }
  86.  
  87. void TbRawStream::fineFastForward(const uint64_t timeToSkipTo) {
  88. uint64_t currentTime(0);
  89. while (!eos() && currentTime < timeToSkipTo) {
  90. const uint64_t data_packet = getNext();
  91. const unsigned int header = data_packet >> 60;
  92. if (header == 0xA || header == 0xB) {
  93. uint64_t global_time = timer();
  94. uint64_t packet_time = (0xFFFF & data_packet) << 26;
  95. const int diff =
  96. (0x3 & (global_time >> 40)) - (0x3 & (packet_time >> 40));
  97. constexpr uint64_t one = (uint64_t)(1) << 40;
  98. if (diff == 1 || diff == -3)
  99. global_time = global_time - one;
  100. else if (diff == -1 || diff == 3)
  101. global_time = global_time + one;
  102. } else if (header == 0x4) {
  103. addTimingPacket(data_packet);
  104. currentTime = m_timer;
  105. }
  106. }
  107. }
  108.  
  109. uint64_t TbRawStream::getCurrentTime() {
  110. m_lsb = 0;
  111. uint64_t currentTime = 0;
  112. bool gotTime = false;
  113. while (!eos() && !gotTime) {
  114. // measures the current time in the stream//
  115. const uint64_t data_packet = getNext();
  116. const unsigned int header = data_packet >> 60;
  117. if (header == 0x4 && (0xF & (data_packet >> 54)) != 0xF) {
  118. const unsigned int subheader = 0xF & (data_packet >> 56);
  119. if (subheader == 0x4) {
  120. m_lsb = 0xFFFFFFFF & (data_packet >> 16);
  121. } else if (subheader == 0x5 && m_lsb != 0) {
  122. const uint64_t msb = 0xFFFFFFFF & (data_packet >> 16);
  123. currentTime = (m_lsb + (msb << 32));
  124. gotTime = true;
  125. }
  126. }
  127. }
  128. return currentTime;
  129. }
  130.  
  131. int TbRawStream::addTimingPacket(const uint64_t data_packet) {
  132. const unsigned int subheader = 0xF & (data_packet >> 56);
  133. int state = 1;
  134. if (subheader == 0x5) {
  135. // info() << "Current msb = Setting msb of clock: 0x" <<
  136. // std::hex << data_packet << std::dec <<endmsg;
  137. if (setMSB(0xFFFFFFFF & (data_packet >> 16)) == 0) state = 2;
  138. } else if (subheader == 0x4) {
  139. // info() << "Setting lsb of stream: 0x" << std::hex <<
  140. // data_packet << ", current = " << m_lsb << std::dec << endmsg;
  141. setLSB(0xFFFFFFFF & (data_packet >> 16));
  142. } else {
  143. state = 0;
  144. }
  145. return state;
  146. }
  147.  
  148. void TbRawStream::prepare() {
  149. m_currentFile = m_files.begin();
  150. (*m_currentFile)->initialise();
  151. m_size = 0;
  152. for (const auto& raw_file : m_files) m_size = m_size + raw_file->nPackets();
  153. //info() << "Stream = " << m_size << " 8-byte packets" << endmsg;
  154. unsigned int header(0);
  155. // Find the first pixel hit
  156. unsigned int prep_packets(0);
  157. while (!eos() && !(header == 0xA || header == 0xB)) {
  158. uint64_t packet = getNext();
  159. // info() << std::hex << packet << endmsg;
  160. header = 0xF & (packet >> 60);
  161. ++prep_packets;
  162. }
  163. // for (unsigned int i = 0; i < 100; ++i) {
  164. // info() << std::hex << "0x" << getNext() << std::dec << endmsg;
  165. // }
  166. // info() << "Number of prep packets skipped = " << prep_packets << endmsg;
  167. m_size = m_size - prep_packets + 1;
  168. getPrevious();
  169. }
  170.  
  171. template <>
  172. std::vector<LHCb::TbHit*>* TbRawStream::cache() {
  173. return &m_hitCache;
  174. }
  175. template <>
  176. std::vector<LHCb::TbTrigger*>* TbRawStream::cache() {
  177. return &m_trgCache;
  178. }
  179.  
  180. void TbRawStream::insert(LHCb::TbHit* packet) { m_hitCache.push_back(packet); }
  181.  
  182. void TbRawStream::insert(LHCb::TbTrigger* packet) {
  183. m_trgCache.push_back(packet);
  184. }