diff --git a/Event/DAQEvent/include/Event/ODIN.h b/Event/DAQEvent/include/Event/ODIN.h index 89506b123d12fe0a6080d605e91eb62079cec98b..8a23ce6c1543087c24e7c7679c4aad143f8cb08f 100644 --- a/Event/DAQEvent/include/Event/ODIN.h +++ b/Event/DAQEvent/include/Event/ODIN.h @@ -137,7 +137,10 @@ namespace LHCb { CalibrationTrigger = 7 }; - std::array<std::uint32_t, 10> data{0}; + static constexpr int BANK_VERSION = 7; + static constexpr int BANK_SIZE = 40; + + std::array<std::uint32_t, BANK_SIZE / sizeof(std::uint32_t)> data{ 0 }; ODIN() = default; ODIN( gsl::span<const std::uint32_t> buffer ) { @@ -145,11 +148,14 @@ namespace LHCb { std::memcpy( &data.front(), &buffer.front(), sizeof( data ) ); } + template <int VERSION = BANK_VERSION, typename = std::enable_if_t<VERSION == BANK_VERSION || VERSION == 6>> + static ODIN from_version( gsl::span<const std::uint32_t> buffer ); + // Retrieve pointer to class definition structure const CLID& clID() const override { return this->classID(); } static const CLID& classID() { return CLID_ODIN; } - static constexpr int version() { return 7; } + static constexpr int version() { return BANK_VERSION; } enum Fields { RunNumberSize = 32, diff --git a/Event/DAQEvent/src/ODIN.cpp b/Event/DAQEvent/src/ODIN.cpp index aa30410fa06cfc095a0d1abbe5246f2875c66a3c..c8263b7eda733070b87060a1f7df3482a4a5d84b 100644 --- a/Event/DAQEvent/src/ODIN.cpp +++ b/Event/DAQEvent/src/ODIN.cpp @@ -11,36 +11,42 @@ #include <Event/ODIN.h> namespace LHCb::ODINImplementation::v7 { + template <> + ODIN ODIN::from_version<7>( gsl::span<const std::uint32_t> buffer ) { + return buffer; + } + + template <> + ODIN ODIN::from_version<6>( gsl::span<const std::uint32_t> buffer ) { + using LHCb::ODINImplementation::details::get_bits; - ODIN ODIN::from_version( int version, gsl::span<const std::uint32_t> buffer ) { - if ( version == ODIN::version() ) { - // for the current version we just initialize from the buffer - return buffer; - } else if ( version == 6 ) { - using LHCb::ODINImplementation::details::get_bits; + // Check size of the input buffer + if ( UNLIKELY( buffer.size() != 10 ) ) { + throw GaudiException( "Invalid buffer size for ODIN bank version 6: got " + std::to_string( buffer.size() ) + + ", expected 10", + "LHCb::ODIN::from_version", StatusCode::FAILURE ); + } - ODIN odin; + ODIN odin; - // Map ODIN banck v6 layout to v7 - odin.data[0] = buffer[0]; // run number - odin.data[1] = buffer[1]; // event type + calibration step - odin.data[7] = buffer[2]; // orbit number - odin.data[9] = buffer[3]; // event number (hi) - odin.data[8] = buffer[4]; // event number (lo) - odin.data[3] = buffer[5]; // gps time (hi) - odin.data[2] = buffer[6]; // gps time (lo) - odin.data[4] = buffer[9]; // TCK - // error bits + detector status (dropped): buffer[7] - // misc fields (buffer[8], ignoring bits 15, 21, 24-31) - odin.setBunchId( get_bits<12, 8 * 32 + 0>( buffer ) ); - odin.setTimeAlignmentEventWindow( get_bits<3, 8 * 32 + 12>( buffer ) ); - odin.setTriggerType( get_bits<3, 8 * 32 + 16>( buffer ) ); - odin.setCalibrationType( get_bits<2, 8 * 32 + 19>( buffer ) ); - odin.setBunchCrossingType( static_cast<ODIN::BXTypes>( get_bits<2, 8 * 32 + 22>( buffer ) ) ); + // Map ODIN banck v6 layout to v7 + odin.data[0] = buffer[0]; // run number + odin.data[1] = buffer[1]; // event type + calibration step + odin.data[7] = buffer[2]; // orbit number + odin.data[9] = buffer[3]; // event number (hi) + odin.data[8] = buffer[4]; // event number (lo) + odin.data[3] = buffer[5]; // gps time (hi) + odin.data[2] = buffer[6]; // gps time (lo) + odin.data[4] = buffer[9]; // TCK + // error bits + detector status (dropped): buffer[7] + // misc fields (buffer[8], ignoring bits 15, 21, 24-31) + odin.setBunchId( get_bits<12, 8 * 32 + 0>( buffer ) ); + odin.setTimeAlignmentEventWindow( get_bits<3, 8 * 32 + 12>( buffer ) ); + odin.setTriggerType( get_bits<3, 8 * 32 + 16>( buffer ) ); + odin.setCalibrationType( get_bits<2, 8 * 32 + 19>( buffer ) ); + odin.setBunchCrossingType( static_cast<ODIN::BXTypes>( get_bits<2, 8 * 32 + 22>( buffer ) ) ); - return odin; - } - throw GaudiException( "unknown ODIN bank version " + std::to_string( version ), "ODIN", StatusCode::FAILURE ); + return odin; } std::ostream& operator<<( std::ostream& s, ODIN::CalibrationTypes e ) { diff --git a/Kernel/LHCbAlgs/src/ODINCodec.cpp b/Kernel/LHCbAlgs/src/ODINCodec.cpp index 905f77bdf487fe6385e7c3378478fc691d6666fc..937b1a3fb4b4416e92fbeddb30d39dfc77f9f873 100644 --- a/Kernel/LHCbAlgs/src/ODINCodec.cpp +++ b/Kernel/LHCbAlgs/src/ODINCodec.cpp @@ -50,7 +50,7 @@ ODIN LHCb::ODINCodec::decode( const RawBank& bank, const bool ignoreBankVersion DecoderAssert( bank.size() == expected_size, "Wrong ODIN bank size " + std::to_string( bank.size() ) + ", expected " + std::to_string( expected_size ) ); - return ODIN::from_version( version, bank.range<const unsigned int>() ); + return ODIN::from_version<6>( bank.range<const unsigned int>() ); } else { DecoderAssert( false, "Unknown ODIN bank version " + std::to_string( version ) + ", supported ones are: " + std::to_string( Bank::VERSION ) );