diff --git a/Detectors/MUON/MCH/Raw/Common/CMakeLists.txt b/Detectors/MUON/MCH/Raw/Common/CMakeLists.txt index 1913c19504934..7addc49f1ebc2 100644 --- a/Detectors/MUON/MCH/Raw/Common/CMakeLists.txt +++ b/Detectors/MUON/MCH/Raw/Common/CMakeLists.txt @@ -9,11 +9,10 @@ # submit itself to any jurisdiction. o2_add_library(MCHRawCommon - SOURCES src/RDHManip.cxx src/SampaHeader.cxx src/SampaCluster.cxx - PUBLIC_LINK_LIBRARIES fmt::fmt ms_gsl::ms_gsl Boost::boost - O2::Headers - PRIVATE_LINK_LIBRARIES O2::MCHRawImplHelpers) + SOURCES src/RDHManip.cxx src/SampaHeader.cxx src/SampaCluster.cxx src/RDHFieldsV4.cxx + PUBLIC_LINK_LIBRARIES fmt::fmt ms_gsl::ms_gsl Boost::boost O2::Headers O2::CommonConstants + PRIVATE_LINK_LIBRARIES O2::MCHRawImplHelpers) if(BUILD_TESTING) - add_subdirectory(test) + add_subdirectory(test) endif() diff --git a/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/RDHFields.h b/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/RDHFields.h new file mode 100644 index 0000000000000..44b1c7b727a09 --- /dev/null +++ b/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/RDHFields.h @@ -0,0 +1,101 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_MCH_RAW_RDH_FIELDS_H +#define O2_MCH_RAW_RDH_FIELDS_H + +#include + +namespace o2 +{ +namespace mch +{ +namespace raw +{ +template +uint16_t rdhPayloadSize(const RDH& rdh); + +template +uint16_t rdhCruId(const RDH& rdh); + +template +void rdhCruId(RDH& rdh, uint16_t cruId); + +template +uint8_t rdhLinkId(const RDH& rdh); + +template +void rdhLinkId(RDH& rdh, uint8_t linkId); + +template +uint32_t rdhOrbit(const RDH& rdh); + +template +void rdhOrbit(RDH& rdh, uint32_t orbit); + +template +uint16_t rdhBunchCrossing(const RDH& rdh); + +template +void rdhBunchCrossing(RDH& rdh, uint16_t bc); + +template +uint16_t rdhFeeId(const RDH& rdh); + +template +void rdhFeeId(RDH& rdh, uint16_t feeId); + +template +uint16_t rdhPageCounter(const RDH& rdh); + +template +void rdhPageCounter(RDH& rdh, uint16_t pageCnt); + +template +uint8_t rdhPacketCounter(const RDH& rhd); + +template +void rdhPacketCounter(RDH& rdh, uint8_t count); + +template +uint16_t rdhOffsetToNext(const RDH& rdh); + +template +void rdhOffsetToNext(RDH& rdh, uint16_t offset); + +template +uint16_t rdhMemorySize(const RDH& rdh); + +template +void rdhMemorySize(RDH& rdh, uint16_t memorySize); + +template +void rdhStop(RDH& rdh, uint8_t stop); + +template +uint8_t rdhStop(const RDH& rdh); + +template +uint32_t rdhTriggerType(const RDH& rdh); + +template +void rdhTriggerType(RDH& rdh, uint32_t triggerType); + +template +uint8_t rdhEndpoint(const RDH& rdh); + +template +void rdhEndpoint(RDH& rdh, uint8_t endpoint); + +} // namespace raw +} // namespace mch +} // namespace o2 + +#endif diff --git a/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/RDHManip.h b/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/RDHManip.h index 2eb140a244587..1da3443acb9e7 100644 --- a/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/RDHManip.h +++ b/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/RDHManip.h @@ -12,74 +12,51 @@ #define O2_MCH_RAW_RDH_MANIP_H #include -#include -#include +#include #include +#include +#include #include -#include +#include +#include "MCHRawCommon/RDHFields.h" +#include -namespace o2 -{ -namespace mch -{ -namespace raw +namespace o2::mch::raw { template void assertRDH(const RDH& rdh); template -void appendRDH(std::vector& buffer, const RDH& rdh); - -template -void appendRDH(std::vector& buffer, const RDH& rdh); - -template -RDH createRDH(gsl::span buffer); +void appendRDH(std::vector& buffer, const RDH& rdh); template -RDH createRDH(gsl::span buffer); +RDH createRDH(gsl::span buffer); template -RDH createRDH(uint16_t cruId, uint8_t linkId, uint16_t solarId, uint32_t orbit, uint16_t bunchCrossing, uint16_t payloadSize); +RDH createRDH(uint16_t cruId, uint8_t endpoint, uint8_t linkId, uint16_t feeId, uint32_t orbit, uint16_t bunchCrossing, uint16_t payloadSize); template bool isValid(const RDH& rdh); template -size_t rdhPayloadSize(const RDH& rdh); - -template -uint8_t rdhLinkId(const RDH& rdh); - -template -uint32_t rdhOrbit(const RDH& rdh); - -template -uint16_t rdhBunchCrossing(const RDH& rdh); - -template -int countRDHs(gsl::span buffer); - -template -int showRDHs(gsl::span buffer); +int countRDHs(gsl::span buffer); template -int showRDHs(gsl::span buffer); +int showRDHs(gsl::span buffer); -void dumpRDHBuffer(gsl::span buffer, std::string_view indent); +std::string triggerTypeAsString(uint32_t triggerType); template -int forEachRDH(gsl::span buffer, std::function f); +int forEachRDH(gsl::span buffer, std::function f); template -int countRDHs(gsl::span buffer); +int forEachRDH(gsl::span buffer, std::function::size_type offset)> f); +// beware : this version might modify the RDH, hence the buffer template -int countRDHs(gsl::span buffer); +int forEachRDH(gsl::span buffer, std::function::size_type offset)> f); -} // namespace raw -} // namespace mch -} // namespace o2 +} // namespace o2::mch::raw #endif diff --git a/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/SampaCluster.h b/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/SampaCluster.h index 4bfb4beb44105..795c307d2f4ac 100644 --- a/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/SampaCluster.h +++ b/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/SampaCluster.h @@ -85,6 +85,9 @@ void assertNotMixingClusters(const std::vector& data) } std::ostream& operator<<(std::ostream& os, const SampaCluster& sc); + +std::string asString(const SampaCluster& sc); + } // namespace raw } // namespace mch } // namespace o2 diff --git a/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/SampaHeader.h b/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/SampaHeader.h index 7bf17d91da157..33240dc71cce4 100755 --- a/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/SampaHeader.h +++ b/Detectors/MUON/MCH/Raw/Common/include/MCHRawCommon/SampaHeader.h @@ -111,7 +111,7 @@ class SampaHeader ///@} /// return the header as a 64-bits integer - uint64_t uint64() const { return mValue; } + constexpr uint64_t uint64() const { return mValue; } /// sets the value from a 64-bits integer. /// if the value does not fit within 50 bits an exception is thrown. @@ -128,6 +128,9 @@ constexpr uint64_t sampaSyncWord{0x1555540f00113}; /// The 50-bits Sampa SYNC word. SampaHeader sampaSync(); +/// Return channel number (0..63) +uint8_t channelNumber64(const SampaHeader& sh); + /// packetTypeName returns a string representation of the given packet type. std::string packetTypeName(SampaPacketType pkt); @@ -152,6 +155,8 @@ int computeHeaderParity2(uint64_t value); int computeHeaderParity3(uint64_t value); int computeHeaderParity4(uint64_t value); +std::string asString(const SampaHeader& sh); + std::ostream& operator<<(std::ostream& os, const SampaHeader& sh); diff --git a/Detectors/MUON/MCH/Raw/Common/src/RDHFieldsV4.cxx b/Detectors/MUON/MCH/Raw/Common/src/RDHFieldsV4.cxx new file mode 100644 index 0000000000000..ce65a3c0372bc --- /dev/null +++ b/Detectors/MUON/MCH/Raw/Common/src/RDHFieldsV4.cxx @@ -0,0 +1,171 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Headers/RAWDataHeader.h" +#include "MCHRawCommon/RDHFields.h" +#include "Assertions.h" + +namespace o2::mch::raw +{ + +template <> +uint32_t rdhOrbit(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.heartbeatOrbit; +} + +template <> +void rdhOrbit(o2::header::RAWDataHeaderV4& rdh, uint32_t orbit) +{ + rdh.heartbeatOrbit = orbit; +} + +template <> +uint16_t rdhPayloadSize(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.memorySize - sizeof(rdh); +} + +template <> +uint8_t rdhLinkId(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.linkID; +} + +template <> +void rdhLinkId(o2::header::RAWDataHeaderV4& rdh, uint8_t linkId) +{ + if (linkId < 0 || (linkId > 11 && linkId != 15)) { + throw std::invalid_argument(fmt::format("linkId should be between 0 and 11 or = 15 but is {}", linkId)); + } + rdh.linkID = linkId; +} + +template <> +uint16_t rdhCruId(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.cruID; +} + +template <> +void rdhCruId(o2::header::RAWDataHeaderV4& rdh, uint16_t cruId) +{ + rdh.cruID = cruId; +} + +template <> +uint16_t rdhBunchCrossing(const o2::header::RAWDataHeaderV4& rdh) +{ + return static_cast(rdh.heartbeatBC & 0xFFF); +} + +template <> +void rdhBunchCrossing(o2::header::RAWDataHeaderV4& rdh, uint16_t bc) +{ + rdh.heartbeatBC = bc; +} + +template <> +uint8_t rdhPacketCounter(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.packetCounter; +} + +template <> +void rdhPacketCounter(o2::header::RAWDataHeaderV4& rdh, uint8_t count) +{ + rdh.packetCounter = count; +} + +template <> +uint16_t rdhFeeId(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.feeId; +} + +template <> +void rdhFeeId(o2::header::RAWDataHeaderV4& rdh, uint16_t feeId) +{ + rdh.feeId = feeId; +} + +template <> +uint16_t rdhPageCounter(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.pageCnt; +} + +template <> +void rdhPageCounter(o2::header::RAWDataHeaderV4& rdh, uint16_t pageCnt) +{ + rdh.pageCnt = pageCnt; +} + +template <> +uint16_t rdhOffsetToNext(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.offsetToNext; +} + +template <> +void rdhOffsetToNext(o2::header::RAWDataHeaderV4& rdh, uint16_t offset) +{ + rdh.offsetToNext = offset; +} + +template <> +uint16_t rdhMemorySize(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.memorySize; +} + +template <> +void rdhMemorySize(o2::header::RAWDataHeaderV4& rdh, uint16_t memorySize) +{ + rdh.memorySize = memorySize; +} + +template <> +void rdhStop(o2::header::RAWDataHeaderV4& rdh, uint8_t stop) +{ + rdh.stop = stop; +} + +template <> +uint8_t rdhStop(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.stop; +} + +template <> +uint32_t rdhTriggerType(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.triggerType; +} + +template <> +void rdhTriggerType(o2::header::RAWDataHeaderV4& rdh, uint32_t triggerType) +{ + rdh.triggerType = triggerType; +} + +template <> +uint8_t rdhEndpoint(const o2::header::RAWDataHeaderV4& rdh) +{ + return rdh.endPointID; +} + +template <> +void rdhEndpoint(o2::header::RAWDataHeaderV4& rdh, uint8_t endpoint) +{ + impl::assertIsInRange("endpoint", endpoint, 0, 1); + rdh.endPointID = endpoint; +} +} // namespace o2::mch::raw diff --git a/Detectors/MUON/MCH/Raw/Common/src/RDHManip.cxx b/Detectors/MUON/MCH/Raw/Common/src/RDHManip.cxx index 86e32ec024cf9..77a728ebdf17f 100644 --- a/Detectors/MUON/MCH/Raw/Common/src/RDHManip.cxx +++ b/Detectors/MUON/MCH/Raw/Common/src/RDHManip.cxx @@ -8,42 +8,102 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +#include "CommonConstants/Triggers.h" +#include "Headers/RAWDataHeader.h" #include "MCHRawCommon/RDHManip.h" +#include #include -#include "Headers/RAWDataHeader.h" #include -#include +#include +#include "CommonConstants/Triggers.h" -using namespace o2::header; - -std::ostream& operator<<(std::ostream& os, const RAWDataHeaderV4& rdh) +namespace o2::header { - os << fmt::format("version {:03d} headerSize {:03d} \n", +std::ostream& operator<<(std::ostream& os, const o2::header::RAWDataHeaderV4& rdh) +{ + os << fmt::format("version {:03d} headerSize {:03d} triggerType {:08x} {:s}\n", rdh.version, - rdh.headerSize); - - os << fmt::format("cruId {:03d} dpwId {:02d} linkId {:03d}\n", rdh.cruID, rdh.endPointID, rdh.linkID); + rdh.headerSize, + rdh.triggerType, + o2::mch::raw::triggerTypeAsString(rdh.triggerType)); - os << fmt::format("offsetToNext {:05d} memorySize {:05d} blockLength {:05d}\n", rdh.offsetToNext, rdh.memorySize, rdh.blockLength); + os << fmt::format("cruId {:03d} dpwId {:02d} linkId {:03d}\n", rdh.cruID, rdh.endPointID, rdh.linkID); - os << fmt::format("triggerOrbit {:010d} HB orbit {:010d}\n", - rdh.triggerOrbit, rdh.heartbeatOrbit); + os << fmt::format("offsetToNext {:05d} memorySize {:05d} blockLength {:05d} {:s}\n", rdh.offsetToNext, rdh.memorySize, rdh.blockLength, + rdh.memorySize == sizeof(rdh) ? "EMPTY" : ""); - os << fmt::format("triggerBC {:04d} heartbeatBC {:04d}\n", - rdh.triggerBC, rdh.heartbeatBC); + os << fmt::format("heartbeatOrbit{:010d} heartbeatBC {:04d} feeId {:6d}\n", + rdh.heartbeatOrbit, rdh.heartbeatBC, rdh.feeId); - os << fmt::format("stopBit {:1d} pagesCounter {:03d} packetCounter {:03d} \n", - rdh.stop, rdh.pageCnt, rdh.packetCounter); + os << fmt::format("stopBit {:1d} pagesCounter {:03d} packetCounter {:03d} {:s}\n", + rdh.stop, rdh.pageCnt, rdh.packetCounter, + rdh.stop ? "STOP" : ""); return os; } -namespace o2 -{ -namespace mch +} // namespace o2::header + +using namespace o2::header; + +namespace o2::mch::raw { -namespace raw + +std::string triggerTypeAsString(uint32_t triggerType) { + std::string s; + + if (triggerType == 0) { + s = "UNKNOWN"; + } + + if (triggerType & o2::trigger::ORBIT) { + s += "ORBIT "; + } + if (triggerType & o2::trigger::HB) { + s += "HB "; + } + if (triggerType & o2::trigger::HBr) { + s += "HBr "; + } + if (triggerType & o2::trigger::HC) { + s += "HC "; + } + if (triggerType & o2::trigger::PhT) { + s += "PhT "; + } + if (triggerType & o2::trigger::PP) { + s += "PP "; + } + if (triggerType & o2::trigger::Cal) { + s += "Cal "; + } + if (triggerType & o2::trigger::SOT) { + s += "SOT "; + } + if (triggerType & o2::trigger::EOT) { + s += "EOT "; + } + if (triggerType & o2::trigger::SOC) { + s += "SOC "; + } + if (triggerType & o2::trigger::EOC) { + s += "EOC "; + } + if (triggerType & o2::trigger::TF) { + s += "TF "; + } + if (triggerType & o2::trigger::TPC) { + s += "TPC "; + } + if (triggerType & o2::trigger::TPCrst) { + s += "TPCrst "; + } + if (triggerType & o2::trigger::TOF) { + s += "TOF "; + } + return s; +} template <> bool isValid(const RAWDataHeaderV4& rdh) @@ -70,33 +130,20 @@ void append(std::vector& buffer, uint64_t w) buffer.emplace_back(static_cast((w & UINT64_C(0xFFFFFFFF00000000)) >> 32)); } -template <> -void appendRDH(std::vector& buffer, const RAWDataHeaderV4& rdh) -{ - append(buffer, rdh.word0); - append(buffer, rdh.word1); - append(buffer, rdh.word2); - append(buffer, rdh.word3); - append(buffer, rdh.word4); - append(buffer, rdh.word5); - append(buffer, rdh.word6); - append(buffer, rdh.word7); -} - -void append(std::vector& buffer, uint64_t w) +void append(std::vector& buffer, uint64_t w) { - buffer.emplace_back(static_cast((w & UINT64_C(0x00000000000000FF)))); - buffer.emplace_back(static_cast((w & UINT64_C(0x000000000000FF00)) >> 8)); - buffer.emplace_back(static_cast((w & UINT64_C(0x0000000000FF0000)) >> 16)); - buffer.emplace_back(static_cast((w & UINT64_C(0x00000000FF000000)) >> 24)); - buffer.emplace_back(static_cast((w & UINT64_C(0x000000FF00000000)) >> 32)); - buffer.emplace_back(static_cast((w & UINT64_C(0x0000FF0000000000)) >> 40)); - buffer.emplace_back(static_cast((w & UINT64_C(0x00FF000000000000)) >> 48)); - buffer.emplace_back(static_cast((w & UINT64_C(0xFF00000000000000)) >> 56)); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x00000000000000FF)) >> 0)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x000000000000FF00)) >> 8)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x0000000000FF0000)) >> 16)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x00000000FF000000)) >> 24)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x000000FF00000000)) >> 32)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x0000FF0000000000)) >> 40)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x00FF000000000000)) >> 48)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0xFF00000000000000)) >> 56)}); } template <> -void appendRDH(std::vector& buffer, const RAWDataHeaderV4& rdh) +void appendRDH(std::vector& buffer, const RAWDataHeaderV4& rdh) { append(buffer, rdh.word0); append(buffer, rdh.word1); @@ -108,7 +155,7 @@ void appendRDH(std::vector& buffer, const RAWDataHeaderV4& rdh) append(buffer, rdh.word7); } -uint64_t eightBytes(gsl::span buffer) +uint64_t eightBytes(gsl::span buffer) { return (static_cast(buffer[0])) | (static_cast(buffer[1]) << 8) | @@ -121,7 +168,7 @@ uint64_t eightBytes(gsl::span buffer) } template <> -RAWDataHeaderV4 createRDH(gsl::span buffer) +RAWDataHeaderV4 createRDH(gsl::span buffer) { if (buffer.size() < 64) { throw std::invalid_argument("buffer should be at least 64 bytes"); @@ -138,32 +185,8 @@ RAWDataHeaderV4 createRDH(gsl::span buffer) return rdh; } -uint64_t from32(gsl::span buffer) -{ - return static_cast(buffer[0]) | - (static_cast(buffer[1]) << 32); -} - -template <> -RAWDataHeaderV4 createRDH(gsl::span buffer) -{ - if (buffer.size() < 16) { - throw std::invalid_argument("buffer should be at least 16 words"); - } - RAWDataHeaderV4 rdh; - rdh.word0 = from32(buffer.subspan(0, 2)); - rdh.word1 = from32(buffer.subspan(2, 2)); - rdh.word2 = from32(buffer.subspan(4, 2)); - rdh.word3 = from32(buffer.subspan(6, 2)); - rdh.word4 = from32(buffer.subspan(8, 2)); - rdh.word5 = from32(buffer.subspan(10, 2)); - rdh.word6 = from32(buffer.subspan(12, 2)); - rdh.word7 = from32(buffer.subspan(14, 2)); - return rdh; -} - template <> -RAWDataHeaderV4 createRDH(uint16_t cruId, uint8_t linkId, uint16_t solarId, uint32_t orbit, uint16_t bunchCrossing, +RAWDataHeaderV4 createRDH(uint16_t cruId, uint8_t endpoint, uint8_t linkId, uint16_t feeId, uint32_t orbit, uint16_t bunchCrossing, uint16_t payloadSize) { RAWDataHeaderV4 rdh; @@ -175,151 +198,119 @@ RAWDataHeaderV4 createRDH(uint16_t cruId, uint8_t linkId, uint16_t solarId, uint uint16_t memorySize = payloadSize + sizeof(rdh); rdh.cruID = cruId; - rdh.linkID = linkId; - // (need cru mappper : from (cruid,linkid)->(solarid) ? and then we pass cruId,linkId to this function - // and deduce solarId instead ?) - rdh.endPointID = 0; // FIXME: fill this ? - rdh.feeId = solarId; //FIXME: what is this field supposed to contain ? unclear to me. + rdhLinkId(rdh, linkId); + rdhEndpoint(rdh, endpoint); + rdh.feeId = feeId; rdh.priority = 0; rdh.blockLength = memorySize - sizeof(rdh); // FIXME: the blockLength disappears in RDHv5 ? rdh.memorySize = memorySize; rdh.offsetToNext = memorySize; - rdh.packetCounter = 0; // FIXME: fill this ? - rdh.triggerType = 0; // FIXME: fill this ? + rdh.packetCounter = 0; + rdh.triggerType = 0; rdh.detectorField = 0; // FIXME: fill this ? rdh.par = 0; // FIXME: fill this ? rdh.stop = 0; - rdh.pageCnt = 1; - rdh.triggerOrbit = orbit; - rdh.heartbeatOrbit = orbit; // FIXME: RDHv5 has only triggerOrbit ? - rdh.triggerBC = bunchCrossing; - rdh.heartbeatBC = bunchCrossing; // FIXME: RDHv5 has only triggerBC ? + rdh.pageCnt = 0; + rdh.heartbeatOrbit = orbit; + rdh.heartbeatBC = bunchCrossing; return rdh; } -template <> -uint32_t rdhOrbit(const RAWDataHeaderV4& rdh) -{ - return rdh.triggerOrbit; // or is it heartbeatOrbit ? -} - -template <> -size_t rdhPayloadSize(const RAWDataHeaderV4& rdh) -{ - return rdh.memorySize - sizeof(rdh); -} - -template <> -uint8_t rdhLinkId(const RAWDataHeaderV4& rdh) -{ - return rdh.linkID + 12 * rdh.endPointID; -} - -template <> -uint16_t rdhBunchCrossing(const RAWDataHeaderV4& rdh) +template +int showRDHs(gsl::span buffer) { - return static_cast(rdh.triggerBC & 0xFFF); + assert(buffer.size() % 4 == 0); + return forEachRDH(buffer, [](const RDH& rdh) { + std::cout << rdh << "\n"; + }); } -void dumpRDHBuffer(gsl::span buffer, std::string_view indent) +template +int countRDHs(gsl::span buffer) { - auto const rdh = createRDH(buffer); - std::cout << fmt::format("{:016X} {:016X}", - rdh.word1, rdh.word0); - std::cout << fmt::format(" version {:d} headerSize {:d} blockLength {:d} \n", - rdh.version, rdh.headerSize, rdh.blockLength); - std::cout << fmt::format("{:44s} feeId {} priority {}\n", " ", rdh.feeId, rdh.priority); - std::cout << fmt::format("{:44s} offsetnext {} memsize {}\n", " ", rdh.offsetToNext, rdh.memorySize); - std::cout << fmt::format("{:44s} linkId {} packetCount {} cruId {} dpwId {}\n", " ", rdh.linkID, rdh.packetCounter, rdh.cruID, rdh.endPointID); - - std::cout << indent << fmt::format("{:016X} {:016X}", rdh.word3, rdh.word2); - std::cout << fmt::format(" triggerOrbit {:d} \n", rdh.triggerOrbit); - std::cout << fmt::format("{:44s} heartbeatOrbit {}\n", " ", rdh.heartbeatOrbit); - std::cout << fmt::format("{:44s} zero\n", " "); - std::cout << fmt::format("{:44s} zero\n", " "); - - std::cout << indent << fmt::format("{:016X} {:016X}", rdh.word5, rdh.word4); - std::cout << fmt::format(" triggerBC {} heartbeatBC {}\n", rdh.triggerBC, - rdh.heartbeatBC); - std::cout << fmt::format("{:44s} triggerType {}\n", " ", rdh.triggerType); - std::cout << fmt::format("{:44s} zero\n", " "); - std::cout << fmt::format("{:44s} zero\n", " "); - - std::cout << indent << fmt::format("{:016X} {:016X}", rdh.word7, rdh.word6); - std::cout << fmt::format(" detectorField {} par {}\n", rdh.detectorField, - rdh.par); - std::cout << fmt::format("{:44s} stopBit {} pagesCounter {}\n", " ", - rdh.stop, rdh.pageCnt); - std::cout << fmt::format("{:44s} zero\n", " "); - std::cout << fmt::format("{:44s} zero\n", " "); + return forEachRDH(buffer, static_cast>(nullptr)); } template -int forEachRDH(gsl::span buffer, std::function f) +int forEachRDH(gsl::span buffer, std::function::size_type offset)> f) { - RDH rdh; int index{0}; int nrdh{0}; while (index < buffer.size()) { - memcpy(&rdh, &buffer[0] + index, sizeof(rdh)); + RDH* rdhPtr = reinterpret_cast(&buffer[index]); + RDH& rdh = *rdhPtr; if (!isValid(rdh)) { break; } nrdh++; if (f) { - f(rdh); + f(rdh, index); } if (rdh.offsetToNext == 0) { return -1; } - index += rdh.offsetToNext / 4; + index += rdh.offsetToNext; } return nrdh; } template -int showRDHs(gsl::span buffer) -{ - return forEachRDH(buffer, [](RDH& rdh) { - std::cout << rdh << "\n"; - }); -} - -template -int showRDHs(gsl::span buffer) +int forEachRDH(gsl::span buffer, std::function f) { assert(buffer.size() % 4 == 0); - gsl::span buf32{reinterpret_cast(&buffer[0]), - buffer.size() / 4}; - return showRDHs(buf32); -} - -template -int countRDHs(gsl::span buffer) -{ - return forEachRDH(buffer, nullptr); + RDH rdh; + int index{0}; + int nrdh{0}; + while (index < buffer.size()) { + memcpy(&rdh, &buffer[index], sizeof(rdh)); + if (!isValid(rdh)) { + break; + } + nrdh++; + if (f) { + f(rdh); + } + if (rdh.offsetToNext == 0) { + return -1; + } + index += rdh.offsetToNext; + } + return nrdh; } template -int countRDHs(gsl::span buffer) +int forEachRDH(gsl::span buffer, std::function::size_type)> f) { assert(buffer.size() % 4 == 0); - gsl::span buf32{reinterpret_cast(&buffer[0]), - buffer.size() / 4}; - return countRDHs(buf32); + RDH rdh; + int index{0}; + int nrdh{0}; + while (index < buffer.size()) { + memcpy(&rdh, &buffer[index], sizeof(rdh)); + if (!isValid(rdh)) { + break; + } + nrdh++; + if (f) { + f(rdh, index); + } + if (rdh.offsetToNext == 0) { + return -1; + } + index += rdh.offsetToNext; + } + return nrdh; } // force instanciation of (only) the templates we need // RDH v4 versions -template int showRDHs(gsl::span buffer); -template int showRDHs(gsl::span buffer); -template int countRDHs(gsl::span buffer); -template int countRDHs(gsl::span buffer); -template int forEachRDH(gsl::span buffer, std::function f); +template int showRDHs(gsl::span buffer); +template int countRDHs(gsl::span buffer); +template int forEachRDH(gsl::span buffer, std::function f); +template int forEachRDH(gsl::span buffer, std::function::size_type)> f); +template int forEachRDH(gsl::span buffer, std::function::size_type)> f); -} // namespace raw -} // namespace mch -} // namespace o2 +} // namespace o2::mch::raw diff --git a/Detectors/MUON/MCH/Raw/Common/src/SampaCluster.cxx b/Detectors/MUON/MCH/Raw/Common/src/SampaCluster.cxx index b54c027f9474f..a51b68b22b447 100644 --- a/Detectors/MUON/MCH/Raw/Common/src/SampaCluster.cxx +++ b/Detectors/MUON/MCH/Raw/Common/src/SampaCluster.cxx @@ -12,6 +12,7 @@ #include "MCHRawCommon/DataFormats.h" #include "Assertions.h" #include +#include namespace o2 { @@ -37,7 +38,7 @@ SampaCluster::SampaCluster(uint16_t timestamp, const std::vector& samp throw std::invalid_argument("cannot add data with no sample"); } for (auto i = 0; i < samples.size(); i++) { - impl::assertIsInRange(fmt::format("samples[{}]", i), samples[i], 0, 0x3FF); + impl::assertIsInRange("sample", samples[i], 0, 0x3FF); } } @@ -82,6 +83,13 @@ std::ostream& operator<<(std::ostream& os, const SampaCluster& sc) return os; } +std::string asString(const SampaCluster& sc) +{ + std::stringstream s; + s << sc; + return s.str(); +} + } // namespace raw } // namespace mch } // namespace o2 diff --git a/Detectors/MUON/MCH/Raw/Common/src/SampaHeader.cxx b/Detectors/MUON/MCH/Raw/Common/src/SampaHeader.cxx index fc021e459484c..3a1fca07a8d18 100644 --- a/Detectors/MUON/MCH/Raw/Common/src/SampaHeader.cxx +++ b/Detectors/MUON/MCH/Raw/Common/src/SampaHeader.cxx @@ -18,6 +18,7 @@ #include #include "NofBits.h" #include +#include namespace { @@ -373,8 +374,10 @@ SampaHeader sampaSync() 0); } -std::ostream& operator<<(std::ostream& os, const SampaHeader& sh) +std::string asString(const SampaHeader& sh) { + std::stringstream os; + uint64_t one = 1; std::vector sep = {5, 6, 9, 19, 23, 28, 48}; for (int i = 0; i < 50; i++) { @@ -397,7 +400,12 @@ std::ostream& operator<<(std::ostream& os, const SampaHeader& sh) packetTypeName(sh.packetType()), sh.hasError() ? "ERROR" : "") << "\n"; - return os; + return os.str(); +} + +std::ostream& operator<<(std::ostream& os, const SampaHeader& sh) +{ + return os << asString(sh); } // conv array convert a bit position in the hamming sense @@ -611,6 +619,11 @@ int computeHeaderParity4(uint64_t no) no &= ~(one << 6); // reset bit 6 return computeParity(no); } + +uint8_t channelNumber64(const SampaHeader& sh) +{ + return sh.channelAddress() + (sh.chipAddress() % 2) * 32; +} } // namespace raw } // namespace mch } // namespace o2 diff --git a/Detectors/MUON/MCH/Raw/Common/test/CMakeLists.txt b/Detectors/MUON/MCH/Raw/Common/test/CMakeLists.txt index 6dbb6e77c8133..834eddf4cf569 100644 --- a/Detectors/MUON/MCH/Raw/Common/test/CMakeLists.txt +++ b/Detectors/MUON/MCH/Raw/Common/test/CMakeLists.txt @@ -10,20 +10,20 @@ o2_add_test(rdh-manip SOURCES testRDHManip.cxx - COMPONENT_NAME mch - LABELS "mch;raw" + COMPONENT_NAME mchraw + LABELS "muon;mch;raw" PUBLIC_LINK_LIBRARIES O2::MCHRawCommon Boost::boost) o2_add_test(sampa-header SOURCES testSampaHeader.cxx - COMPONENT_NAME mch - LABELS "mch;raw" + COMPONENT_NAME mchraw + LABELS "muon;mch;raw" PUBLIC_LINK_LIBRARIES O2::MCHRawCommon Boost::boost) o2_add_test(sampa-cluster SOURCES testSampaCluster.cxx - COMPONENT_NAME mch - LABELS "mch;raw" + COMPONENT_NAME mchraw + LABELS "muon;mch;raw" PUBLIC_LINK_LIBRARIES O2::MCHRawCommon Boost::boost) if(benchmark_FOUND) diff --git a/Detectors/MUON/MCH/Raw/Common/test/testRDHManip.cxx b/Detectors/MUON/MCH/Raw/Common/test/testRDHManip.cxx index 2e3929d8e8cf7..ea2263ada4eb0 100644 --- a/Detectors/MUON/MCH/Raw/Common/test/testRDHManip.cxx +++ b/Detectors/MUON/MCH/Raw/Common/test/testRDHManip.cxx @@ -29,11 +29,11 @@ std::vector testBuffer32() return buffer; } -std::vector testBuffer8() +std::vector testBufferByte() { - std::vector buffer(64); - for (int i = 0; i < 64; i++) { - buffer[i] = i; + std::vector buffer(64); + for (uint8_t i = 0; i < 64; i++) { + buffer[i] = std::byte{i}; } return buffer; } @@ -57,43 +57,19 @@ o2::header::RAWDataHeaderV4 getTestRDH() return rdh; } -BOOST_AUTO_TEST_CASE(AppendRDH32) -{ - auto rdh = getTestRDH(); - std::vector buffer; - appendRDH(buffer, rdh); - auto tb = testBuffer32(); - BOOST_CHECK_EQUAL(buffer.size(), tb.size()); - BOOST_CHECK(std::equal(begin(buffer), end(buffer), begin(tb))); -} - BOOST_AUTO_TEST_CASE(AppendRDH8) { auto rdh = getTestRDH(); - std::vector buffer; + std::vector buffer; appendRDH(buffer, rdh); - auto tb = testBuffer8(); + auto tb = testBufferByte(); BOOST_CHECK_EQUAL(buffer.size(), tb.size()); BOOST_CHECK(std::equal(begin(buffer), end(buffer), begin(tb))); } -BOOST_AUTO_TEST_CASE(CreateRDHFromBuffer32) -{ - auto buffer = testBuffer32(); - auto rdh = createRDH(buffer); - BOOST_CHECK_EQUAL(rdh.word0, 0x0706050403020100); - BOOST_CHECK_EQUAL(rdh.word1, 0x0F0E0D0C0B0A0908); - BOOST_CHECK_EQUAL(rdh.word2, 0x1716151413121110); - BOOST_CHECK_EQUAL(rdh.word3, 0x1F1E1D1C1B1A1918); - BOOST_CHECK_EQUAL(rdh.word4, 0x2726252423222120); - BOOST_CHECK_EQUAL(rdh.word5, 0x2F2E2D2C2B2A2928); - BOOST_CHECK_EQUAL(rdh.word6, 0x3736353433323130); - BOOST_CHECK_EQUAL(rdh.word7, 0x3F3E3D3C3B3A3938); -} - BOOST_AUTO_TEST_CASE(CreateRDHFromBuffer8) { - auto buffer = testBuffer8(); + auto buffer = testBufferByte(); auto rdh = createRDH(buffer); BOOST_CHECK_EQUAL(rdh.word0, 0x0706050403020100); BOOST_CHECK_EQUAL(rdh.word1, 0x0F0E0D0C0B0A0908); diff --git a/Detectors/MUON/MCH/Raw/Decoder/CMakeLists.txt b/Detectors/MUON/MCH/Raw/Decoder/CMakeLists.txt index 61cc33b135795..738a63de188ea 100644 --- a/Detectors/MUON/MCH/Raw/Decoder/CMakeLists.txt +++ b/Detectors/MUON/MCH/Raw/Decoder/CMakeLists.txt @@ -9,27 +9,28 @@ # submit itself to any jurisdiction. o2_add_library(MCHRawDecoder - SOURCES src/Decoder.cxx - PUBLIC_LINK_LIBRARIES O2::MCHRawCommon O2::MCHRawElecMap - PRIVATE_LINK_LIBRARIES O2::MCHRawImplHelpers) + SOURCES src/PageDecoder.cxx src/DecoderLogic.cxx + PUBLIC_LINK_LIBRARIES O2::MCHRawCommon O2::MCHRawElecMap + PRIVATE_LINK_LIBRARIES O2::MCHRawImplHelpers) if(BUILD_TESTING) - o2_add_test(decoder - SOURCES src/testDecoder.cxx - COMPONENT_NAME mch - LABELS "mch;raw" - PUBLIC_LINK_LIBRARIES O2::MCHRawDecoder O2::MCHTestRawRefBuffers) + o2_add_test(page-decoder + SOURCES src/testPageDecoder.cxx + COMPONENT_NAME mchraw + LABELS "muon;mch;raw" + PUBLIC_LINK_LIBRARIES O2::MCHRawDecoder O2::MCHTestRawRefBuffers + O2::DPLUtils) - o2_add_test(bare-elink-decoder - SOURCES src/testBareElinkDecoder.cxx - COMPONENT_NAME mch - LABELS "mch;raw" - PUBLIC_LINK_LIBRARIES O2::MCHRawDecoder O2::MCHRawImplHelpers) + o2_add_test(bare-elink-decoder + SOURCES src/testBareElinkDecoder.cxx + COMPONENT_NAME mchraw + LABELS "muon;mch;raw" + PUBLIC_LINK_LIBRARIES O2::MCHRawDecoder O2::MCHRawImplHelpers) - o2_add_test(userlogic-elink-decoder - SOURCES src/testUserLogicElinkDecoder.cxx - COMPONENT_NAME mch - LABELS "mch;raw" - PUBLIC_LINK_LIBRARIES O2::MCHRawDecoder O2::MCHRawImplHelpers) + o2_add_test(userlogic-endpoint-decoder + SOURCES src/testUserLogicEndpointDecoder.cxx + COMPONENT_NAME mchraw + LABELS "muon;mch;raw" + PUBLIC_LINK_LIBRARIES O2::MCHRawDecoder O2::MCHRawImplHelpers) endif() diff --git a/Detectors/MUON/MCH/Raw/Decoder/README.md b/Detectors/MUON/MCH/Raw/Decoder/README.md index 0a14c6a75551d..9809e143403b6 100644 --- a/Detectors/MUON/MCH/Raw/Decoder/README.md +++ b/Detectors/MUON/MCH/Raw/Decoder/README.md @@ -11,13 +11,30 @@ sampa electronics does the charge integration) or in sample mode (the sampa electronics transmit all the charge samples). All formats are composed of {RawDataHeader,Payload} pairs. -Note that the cluster sum mode has to be properly selected, as there is -unfortunately no way to infer it from the data itself... +The work of the MCH Raw Data decoder is to decode one single such pair, also +called a (CRU) page. How the loop on the raw pages is done is *not* the decoder business. -## createDecoder<FORMAT,CHARGESUM,RDH> +## createPageDecoder -On the reading/consumer/decoding end, the choice of the decoder to use is made -through a templatized function, `createDecoder`. +On the reading/consumer/decoding end, the choice of the internal decoder to use is made +using the data itself. You must give (at least) a part of a raw data buffer that contains + a (valid) RawDataHeader. That RDH is used to deduce which implementation is picked. + + gsl::span rawbuffer = ... ; + auto pageDecoder = o2::mch::raw::createPageDecoder(rawbuffer,channelHandler); + +The `pageDecoder` that is returned is a function that you have to call on each +data page that you want to decode : + + while(some_data_is_available) { + // get some memory buffer from somewhere ... + buffer = ... + + // decode that buffer + pageDecode(buffer); + } + +Internally the implementation is using templatized implementation, `PageDecoderImpl`. Currently the following template parameters combinations have been tested : | FORMAT | CHARGESUM | RDH | @@ -29,46 +46,14 @@ Currently the following template parameters combinations have been tested : RDH V5 is not yet supported, but is planned. -As an example, to get a decoder for BareFormat in ChargeSum mode, using -RawDataHeaderV4 : - -```.cpp -#include "MCHRawDecoder/Decoder.h" - -RawDataHeaderHandler rh; -SampaChannelHandler ch; - -auto decoder = o2::mch::raw::createDecoder(rh, ch); - -// get some memory buffer from somewhere ... -buffer = ... - -// decode that buffer -decode(buffer); -``` - -The `createDecoder` function requires two parameters : a `RawDataHeaderHandler` +The `createPageDecoder` function requires two parameters : a raw memory buffer +(in the form of a `gsl::span` (note that the span is on constant bytes, +i.e. the input buffer is read-only) and a `SampaChannelHandler`. -Both parameters can be defined as lambdas, regular free functions, or member -functions of some class. - -## RawDataHeaderHandler - -The `RawDataHeaderHandler` is a function that takes a RawDataHeader and -(optionally) returns a RawDataHeader, i.e. : - -```.cpp -using RawDataHeaderHandler = std::function(const RDH& rdh)>; -``` - -If no RDH is returned (i.e. `std::nullopt` is returned) then that part of the -raw data is *not* decoded at all. -The returned RDH can be a modified version of the argument, e.g. to change some -of the values (like `feeId` according to some mapping). ## SampaChannelHandler -The `SampaChannelHandler` is also a function, that takes a dual sampa +The `SampaChannelHandler` is a function, that takes a dual sampa identifier (in electronics realm, aka solar,group,index tuple), a channel identifier within that dual sampa, a `SampaCluster` and returns nothing, i.e. : @@ -93,6 +78,7 @@ SampaChannelHandler handlePacket(DsElecId dsId, uint8_t channel, SampaCluster sc // (note that this particular function only correctly handles the SampaCluster in ChargeSum Mode) ``` -## TODO +## Example of decoding raw data -Add a description of the two data formats here ? +A (not particularly clean) example of how to decode raw data can be found in the source of the `o2-mchraw-dump` + executable [rawdump](../Tools/rawdump.cxx) diff --git a/Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/Decoder.h b/Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/Decoder.h deleted file mode 100644 index aa1690528bc17..0000000000000 --- a/Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/Decoder.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef O2_MCH_RAW_DECODER_H -#define O2_MCH_RAW_DECODER_H - -#include -#include -#include "MCHRawDecoder/SampaChannelHandler.h" -#include "MCHRawDecoder/RawDataHeaderHandler.h" -#include - -namespace o2 -{ -namespace mch -{ -/// Classes and functions to deal with MCH Raw Data Formats. -namespace raw -{ - -struct DecoderStat { - uint64_t nofOrbitJumps{0}; - uint64_t nofOrbitSeen{0}; - uint64_t nofBytesUsed{0}; -}; - -std::ostream& operator<<(std::ostream& out, const DecoderStat& decStat); - -using Decoder = std::function buffer)>; - -template -Decoder createDecoder(RawDataHeaderHandler rdhHandler, - SampaChannelHandler channelHandler); - -} // namespace raw -} // namespace mch -} // namespace o2 -#endif diff --git a/Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/PageDecoder.h b/Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/PageDecoder.h new file mode 100644 index 0000000000000..55fd4da10cec8 --- /dev/null +++ b/Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/PageDecoder.h @@ -0,0 +1,52 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_MCH_RAW_DECODER_PAGE_DECODER_H +#define O2_MCH_RAW_DECODER_PAGE_DECODER_H + +#include +#include +#include +#include "MCHRawDecoder/SampaChannelHandler.h" + +namespace o2::mch::raw +{ + +// A (CRU) Page is a raw memory buffer containing a pair (RDH,payload) +using Page = gsl::span; + +// A PageDecoder decodes a single (CRU) Page +using PageDecoder = std::function; + +using RawBuffer = gsl::span; + +// Create a PageDecoder depending on the first rdh found in the buffer. +// +// @param rdhBuffer a raw memory buffer containing (at least) one RDH +// which information is used to decide which PageDecoder implementation to choose +// @param channelHandler (optional) a callable object that will be called for each +// decoded SampaCluster +// +// Note that while the channelHandler parameter is optional, unless for testing purposes +// it does not really make sense to not provide it. +// +PageDecoder createPageDecoder(RawBuffer rdhBuffer, + SampaChannelHandler channelHandler = nullptr); + +// A PageParser loops over the given buffer and apply the given page decoder +// to each page. +using PageParser = std::function; + +// Create a PageParser depending on the first rdh found in the buffer. +PageParser createPageParser(RawBuffer rdhBuffer); + +} // namespace o2::mch::raw + +#endif diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/BareElinkDecoder.h b/Detectors/MUON/MCH/Raw/Decoder/src/BareElinkDecoder.h index 6df54981989b0..1dde99b1dda18 100644 --- a/Detectors/MUON/MCH/Raw/Decoder/src/BareElinkDecoder.h +++ b/Detectors/MUON/MCH/Raw/Decoder/src/BareElinkDecoder.h @@ -151,7 +151,6 @@ std::string bitBufferString(const std::bitset<50>& bs, int imax) } } // namespace -//FIXME: probably needs the GBT id as well here ? template BareElinkDecoder::BareElinkDecoder(DsElecId dsId, SampaChannelHandler sampaChannelHandler) @@ -418,17 +417,12 @@ std::ostream& operator<<(std::ostream& os, const o2::mch::raw::BareElinkDecoder< return os; } -uint8_t channelNumber(const SampaHeader& sh) -{ - return sh.channelAddress() + (sh.chipAddress() % 2) * 32; -} - template <> void BareElinkDecoder::sendCluster() { if (mSampaChannelHandler) { mSampaChannelHandler(mDsId, - channelNumber(mSampaHeader), + channelNumber64(mSampaHeader), SampaCluster(mTimestamp, mClusterSum)); } } @@ -438,7 +432,7 @@ void BareElinkDecoder::sendCluster() { if (mSampaChannelHandler) { mSampaChannelHandler(mDsId, - channelNumber(mSampaHeader), + channelNumber64(mSampaHeader), SampaCluster(mTimestamp, mSamples)); } mSamples.clear(); diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/BareGBTDecoder.h b/Detectors/MUON/MCH/Raw/Decoder/src/BareGBTDecoder.h index 25cdf091105f0..2699e7b2b0d4f 100644 --- a/Detectors/MUON/MCH/Raw/Decoder/src/BareGBTDecoder.h +++ b/Detectors/MUON/MCH/Raw/Decoder/src/BareGBTDecoder.h @@ -21,6 +21,7 @@ #include "Assertions.h" #include #include +#include "PayloadDecoder.h" namespace o2 { @@ -34,11 +35,9 @@ namespace raw /// It's one GBT = one Solar. template -class BareGBTDecoder +class BareGBTDecoder : public PayloadDecoder> { public: - static constexpr uint8_t baseSize{128}; - /// Constructor. /// \param solarId /// \param sampaChannelHandler the callable that will handle each SampaCluster @@ -56,7 +55,7 @@ class BareGBTDecoder * * @return the number of bytes that have been used from bytes span */ - size_t append(gsl::span bytes); + size_t append(Payload bytes); ///@} /** @name Methods for testing @@ -75,6 +74,7 @@ class BareGBTDecoder int mSolarId; std::array, 40> mElinks; int mNofGbtWordsSeens; + uint32_t mOrbit; }; using namespace boost::multiprecision; @@ -82,14 +82,15 @@ using namespace boost::multiprecision; template BareGBTDecoder::BareGBTDecoder(uint16_t solarId, SampaChannelHandler sampaChannelHandler) - : mSolarId{solarId}, + : PayloadDecoder>(sampaChannelHandler), + mSolarId{solarId}, mElinks{impl::makeArray<40>([=](uint8_t i) { return BareElinkDecoder(DsElecId{solarId, static_cast(i / 5), static_cast(i % 5)}, sampaChannelHandler); })}, mNofGbtWordsSeens{0} { } template -size_t BareGBTDecoder::append(gsl::span bytes) +size_t BareGBTDecoder::append(Payload bytes) { if (bytes.size() % 16 != 0) { throw std::invalid_argument("can only bytes by group of 16 (i.e. 128 bits)"); @@ -99,10 +100,11 @@ size_t BareGBTDecoder::append(gsl::span bytes) ++mNofGbtWordsSeens; int elinkIndex = 0; for (auto b : bytes.subspan(j, 10)) { - mElinks[elinkIndex++].append(b & 2, b & 1); - mElinks[elinkIndex++].append(b & 8, b & 4); - mElinks[elinkIndex++].append(b & 32, b & 16); - mElinks[elinkIndex++].append(b & 128, b & 64); + const uint8_t b8 = std::to_integer(b); + mElinks[elinkIndex++].append(b8 & 2, b8 & 1); + mElinks[elinkIndex++].append(b8 & 8, b8 & 4); + mElinks[elinkIndex++].append(b8 & 32, b8 & 16); + mElinks[elinkIndex++].append(b8 & 128, b8 & 64); } n += 10; } diff --git a/Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/RawDataHeaderHandler.h b/Detectors/MUON/MCH/Raw/Decoder/src/Debug.h similarity index 55% rename from Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/RawDataHeaderHandler.h rename to Detectors/MUON/MCH/Raw/Decoder/src/Debug.h index 1044f1a892a98..a7f2940dc2d30 100644 --- a/Detectors/MUON/MCH/Raw/Decoder/include/MCHRawDecoder/RawDataHeaderHandler.h +++ b/Detectors/MUON/MCH/Raw/Decoder/src/Debug.h @@ -8,24 +8,4 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef O2_MCH_RAW_RAWDATAHEADER_HANDLER_H -#define O2_MCH_RAW_RAWDATAHEADER_HANDLER_H - -#include -#include "MCHRawCommon/RDHManip.h" -#include - -namespace o2 -{ -namespace mch -{ -namespace raw -{ -template -using RawDataHeaderHandler = std::function(const RDH& rdh)>; - -} // namespace raw -} // namespace mch -} // namespace o2 - -#endif +//#define ULDEBUG diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/Decoder.cxx b/Detectors/MUON/MCH/Raw/Decoder/src/Decoder.cxx deleted file mode 100644 index 1b4a34bf02944..0000000000000 --- a/Detectors/MUON/MCH/Raw/Decoder/src/Decoder.cxx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "PageParser.h" -#include "BareGBTDecoder.h" -#include "UserLogicGBTDecoder.h" -#include "Headers/RAWDataHeader.h" -#include "MCHRawCommon/DataFormats.h" - -namespace o2::mch::raw -{ - -template -struct GBTDecoderTrait { - using type = void; -}; - -template -struct GBTDecoderTrait { - using type = BareGBTDecoder; -}; - -template -struct GBTDecoderTrait { - using type = UserLogicGBTDecoder; -}; - -template -Decoder createDecoder(RawDataHeaderHandler rdhHandler, SampaChannelHandler channelHandler) -{ - using GBTDecoder = typename GBTDecoderTrait::type; - using PAYLOADDECODER = PayloadDecoder; - return [rdhHandler, channelHandler](gsl::span buffer) -> DecoderStat { - static PageParser mPageParser(rdhHandler, PAYLOADDECODER(channelHandler)); - return mPageParser.parse(buffer); - }; -} - -std::ostream& operator<<(std::ostream& out, const DecoderStat& decStat) -{ - out << fmt::format("Nof orbits seen {} - Nof orbits jumps {}", - decStat.nofOrbitSeen, - decStat.nofOrbitJumps); - return out; -} - -// define only the specialization we use - -using RDHv4 = o2::header::RAWDataHeaderV4; - -template Decoder createDecoder(RawDataHeaderHandler, SampaChannelHandler); -template Decoder createDecoder(RawDataHeaderHandler, SampaChannelHandler); -template Decoder createDecoder(RawDataHeaderHandler, SampaChannelHandler); -template Decoder createDecoder(RawDataHeaderHandler, SampaChannelHandler); -} // namespace o2::mch::raw diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/DecoderLogic.cxx b/Detectors/MUON/MCH/Raw/Decoder/src/DecoderLogic.cxx new file mode 100644 index 0000000000000..afb50dc9d6cea --- /dev/null +++ b/Detectors/MUON/MCH/Raw/Decoder/src/DecoderLogic.cxx @@ -0,0 +1,236 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "DecoderLogic.h" +#include +#include "Debug.h" +#include "MCHRawCommon/DataFormats.h" + +namespace o2::mch::raw +{ + +DecoderLogic::DecoderLogic(DsElecId dsId, SampaChannelHandler sampaChannelHandler) + : mDsId{dsId}, mSampaChannelHandler{sampaChannelHandler} +{ +} + +DsElecId DecoderLogic::dsId() const +{ + return mDsId; +} + +std::ostream& DecoderLogic::debugHeader() const +{ + std::cout << fmt::format("--ULDEBUG--{:s}-----------", asString(mDsId)); + return std::cout; +} + +bool DecoderLogic::hasError() const +{ + return mErrorMessage.has_value(); +} + +std::string DecoderLogic::errorMessage() const +{ + return hasError() ? mErrorMessage.value() : ""; +} + +void DecoderLogic::decrementClusterSize() +{ + --mClusterSize; +} + +void DecoderLogic::setClusterSize(uint16_t value) +{ + mClusterSize = value; + int checkSize = mClusterSize + 2 - mSampaHeader.nof10BitWords(); + mErrorMessage = std::nullopt; + if (mClusterSize == 0) { + mErrorMessage = "cluster size is zero"; + } + if (checkSize > 0) { + mErrorMessage = "cluster size bigger than nof10BitWords"; + } +#ifdef ULDEBUG + debugHeader() << " -> size=" << mClusterSize << " maskIndex=" << mMaskIndex + << " nof10BitWords=" << mSampaHeader.nof10BitWords() + << " " << (hasError() ? "ERROR:" : "") << errorMessage() << "\n"; +#endif +} // namespace o2::mch::raw + +void DecoderLogic::setClusterTime(uint16_t value) +{ + mClusterTime = value; +#ifdef ULDEBUG + debugHeader() << " -> time=" << mClusterTime << " maskIndex=" << mMaskIndex << "\n"; +#endif +} + +void DecoderLogic::reset() +{ +#ifdef ULDEBUG + debugHeader() << " -> reset\n"; +#endif + mMaskIndex = mMasks.size(); + mHeaderParts.clear(); + mClusterSize = 0; + mNof10BitWords = 0; + mErrorMessage = std::nullopt; +} + +void DecoderLogic::setData(uint64_t data) +{ + mData = data; + mMaskIndex = 0; +#ifdef ULDEBUG + debugHeader() << fmt::format(">>>>> setData {:08X} maskIndex {} 10bits=", mData, mMaskIndex); + for (int i = 0; i < mMasks.size(); i++) { + std::cout << fmt::format("{:2d} ", data10(mData, i)); + } + std::cout << "\n"; +#endif +} + +uint16_t DecoderLogic::data10(uint64_t value, size_t index) const +{ + uint64_t m = mMasks.at(index); + return static_cast((value & m) >> (index * 10) & 0x3FF); +} + +uint16_t DecoderLogic::pop10() +{ + auto rv = data10(mData, mMaskIndex); + mNof10BitWords = std::max(0, mNof10BitWords - 1); + mMaskIndex = std::min(mMasks.size(), mMaskIndex + 1); + return rv; +} + +void DecoderLogic::sendCluster(const SampaCluster& sc) const +{ +#ifdef ULDEBUG + std::stringstream s; + s << sc; + debugHeader() << fmt::format(" calling channelHandler for {} ch {} = {}\n", + asString(mDsId), channelNumber64(mSampaHeader), s.str()); + debugHeader() << (*this) << "\n"; +#endif + mSampaChannelHandler(mDsId, channelNumber64(mSampaHeader), sc); +} + +template <> +void DecoderLogic::addSample(uint16_t sample) +{ +#ifdef ULDEBUG + debugHeader() << "sample = " << sample << "\n"; +#endif + mSamples.emplace_back(sample); + + if (mClusterSize == 0) { + SampaCluster sc(mClusterTime, mSamples); + sendCluster(sc); + mSamples.clear(); + } +} + +template <> +void DecoderLogic::addSample(uint16_t sample) +{ +#ifdef ULDEBUG + debugHeader() << "charge sum part = " << sample << "\n"; +#endif + mSamples.emplace_back(sample); + + if (mClusterSize == 0) { + if (mSamples.size() != 2) { + throw std::invalid_argument(fmt::format("expected sample size to be 2 but it is {}", mSamples.size())); + } + uint32_t q = (((static_cast(mSamples[1]) & 0x3FF) << 10) | (static_cast(mSamples[0]) & 0x3FF)); + SampaCluster sc(mClusterTime, q); + sendCluster(sc); + mSamples.clear(); + } +} + +void DecoderLogic::completeHeader() +{ + uint64_t header{0}; + for (auto i = 0; i < mHeaderParts.size(); i++) { + header += (static_cast(mHeaderParts[i]) << (10 * i)); + } + + mSampaHeader = SampaHeader(header); + mNof10BitWords = mSampaHeader.nof10BitWords(); + +#ifdef ULDEBUG + debugHeader() + << fmt::format(">>>>> completeHeader {:013X}\n", header) + << "\n" + << mSampaHeader << "\n"; +#endif + + mHeaderParts.clear(); +} + +void DecoderLogic::addHeaderPart(uint16_t a) +{ + mHeaderParts.emplace_back(a); +#ifdef ULDEBUG + debugHeader() + << fmt::format(">>>>> readHeader {:08X}", a); + for (auto h : mHeaderParts) { + std::cout << fmt::format("{:4d} ", h); + } + std::cout << "\n"; +#endif +} + +bool DecoderLogic::moreDataAvailable() const +{ + return mMaskIndex < mMasks.size(); +} + +bool DecoderLogic::moreSampleToRead() const +{ + return mClusterSize > 0; +} + +bool DecoderLogic::headerIsComplete() const +{ + return mHeaderParts.size() == 5; +} + +bool DecoderLogic::moreWordsToRead() const +{ + return mNof10BitWords > 0; +} + +std::ostream& operator<<(std::ostream& os, const DecoderLogic& ds) +{ + os << &ds << fmt::format(" DecoderLogic {} data=0X{:08X} n10={:4d} csize={:4d} ctime={:4d} maskIndex={:4d} ", asString(ds.dsId()), ds.mData, ds.mNof10BitWords, ds.mClusterSize, ds.mClusterTime, ds.mMaskIndex); + os << fmt::format("header({})= ", ds.mHeaderParts.size()); + for (auto h : ds.mHeaderParts) { + os << fmt::format("{:4d} ", h); + } + os << fmt::format("samples({})= ", ds.mSamples.size()); + for (auto s : ds.mSamples) { + os << fmt::format("{:4d} ", s); + } + os << " handler=" << (ds.mSampaChannelHandler ? "valid" : "empty") << " "; + + os << fmt::format("moreWordsToRead: {} moreSampleToRead: {} moreDataAvailable: {}", + ds.moreWordsToRead(), ds.moreSampleToRead(), ds.moreDataAvailable()); + + if (ds.hasError()) { + os << " ERROR:" << ds.errorMessage(); + } + return os; +} + +} // namespace o2::mch::raw diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/DecoderLogic.h b/Detectors/MUON/MCH/Raw/Decoder/src/DecoderLogic.h new file mode 100644 index 0000000000000..432b1af86a885 --- /dev/null +++ b/Detectors/MUON/MCH/Raw/Decoder/src/DecoderLogic.h @@ -0,0 +1,76 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_MCH_RAW_DECODER_DECODER_LOGIC_H +#define O2_MCH_RAW_DECODER_DECODER_LOGIC_H + +#include +#include +#include "MCHRawDecoder/SampaChannelHandler.h" +#include "MCHRawCommon/SampaHeader.h" +#include "MCHRawElecMap/DsElecId.h" +#include +#include +#include + +namespace o2::mch::raw +{ +class DecoderLogic +{ + public: + DecoderLogic() = delete; + DecoderLogic(DsElecId dsId, SampaChannelHandler sampaChannelHandler); + + bool headerIsComplete() const; + bool moreDataAvailable() const; + bool moreSampleToRead() const; + bool moreWordsToRead() const; + uint16_t data10(uint64_t value, size_t index) const; + uint16_t pop10(); + void addHeaderPart(uint16_t a); + template + void addSample(uint16_t sample); + void completeHeader(); + void decrementClusterSize(); + void reset(); + void setClusterSize(uint16_t value); + void setClusterTime(uint16_t value); + void setData(uint64_t data); + + bool hasError() const; + std::string errorMessage() const; + + DsElecId dsId() const; + + friend std::ostream& operator<<(std::ostream&, const DecoderLogic&); + + private: + std::ostream& debugHeader() const; + void sendCluster(const SampaCluster& sc) const; + + private: + // mMasks used to access groups of 10 bits in a 50 bits range + static constexpr std::array mMasks = {0x3FF, 0xFFC00, 0x3FF00000, 0xFFC0000000, 0x3FF0000000000}; + DsElecId mDsId{0, 0, 0}; + uint16_t mNof10BitWords{0}; + uint16_t mClusterSize{0}; + uint16_t mClusterTime{0}; + uint64_t mData{0}; + size_t mMaskIndex{mMasks.size()}; + std::vector mSamples; + std::vector mHeaderParts; + SampaChannelHandler mSampaChannelHandler; + SampaHeader mSampaHeader; + std::optional mErrorMessage{std::nullopt}; +}; + +} // namespace o2::mch::raw + +#endif diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/PageDecoder.cxx b/Detectors/MUON/MCH/Raw/Decoder/src/PageDecoder.cxx new file mode 100644 index 0000000000000..a741348bd0433 --- /dev/null +++ b/Detectors/MUON/MCH/Raw/Decoder/src/PageDecoder.cxx @@ -0,0 +1,158 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "BareGBTDecoder.h" +#include "Headers/RAWDataHeader.h" +#include "MCHRawCommon/DataFormats.h" +#include "MCHRawCommon/RDHManip.h" +#include "MCHRawDecoder/PageDecoder.h" +#include "UserLogicEndpointDecoder.h" +#include "MCHRawElecMap/Mapper.h" + +#include + +namespace o2::header +{ +extern std::ostream& operator<<(std::ostream&, const o2::header::RAWDataHeaderV4&); +} + +namespace o2::mch::raw +{ + +namespace impl +{ +uint16_t CRUID_MASK = 0xFF; +uint16_t CHARGESUM_MASK = 0x100; + +template +struct PayloadDecoderImpl { + + using type = struct { + void process(uint32_t, gsl::span); + }; + + type operator()(const FeeLinkId& feeLinkId, SampaChannelHandler sampaChannelHandler); +}; + +template +struct PayloadDecoderImpl { + using type = UserLogicEndpointDecoder; + + type operator()(const FeeLinkId& feeLinkId, SampaChannelHandler sampaChannelHandler) + { + auto fee2solar = createFeeLink2SolarMapper(); + return std::move(UserLogicEndpointDecoder(feeLinkId.feeId(), fee2solar, sampaChannelHandler)); + } +}; + +template +struct PayloadDecoderImpl { + using type = BareGBTDecoder; + + type operator()(const FeeLinkId& feeLinkId, SampaChannelHandler sampaChannelHandler) + { + auto fee2solar = createFeeLink2SolarMapper(); + auto solarId = fee2solar(feeLinkId); + if (!solarId.has_value()) { + throw std::logic_error(fmt::format("{} could not get solarId from feelinkid={}\n", __PRETTY_FUNCTION__, feeLinkId)); + } + return std::move(BareGBTDecoder(solarId.value(), sampaChannelHandler)); + } +}; + +template +void print(const RDH& rdh); + +template +class PageDecoderImpl +{ + public: + PageDecoderImpl(SampaChannelHandler sampaChannelHandler) : mSampaChannelHandler{sampaChannelHandler} + { + } + + void operator()(Page page) + { + auto rdh = createRDH(page); + FeeLinkId feeLinkId(rdhFeeId(rdh) & CRUID_MASK, rdhLinkId(rdh)); + + auto p = mPayloadDecoders.find(feeLinkId); + + if (p == mPayloadDecoders.end()) { + mPayloadDecoders.emplace(feeLinkId, PayloadDecoderImpl()(feeLinkId, mSampaChannelHandler)); + p = mPayloadDecoders.find(feeLinkId); + } + + uint32_t orbit = rdhOrbit(rdh); + p->second.process(orbit, page.subspan(sizeof(rdh), rdhPayloadSize(rdh))); + } + + private: + SampaChannelHandler mSampaChannelHandler; + std::map::type> mPayloadDecoders; +}; + +template +class PageParser +{ + public: + void operator()(RawBuffer buffer, PageDecoder pageDecoder) + { + size_t pos{0}; + while (pos < buffer.size_bytes() - sizeof(RDH)) { + auto rdh = createRDH(buffer.subspan(pos, sizeof(RDH))); + auto payloadSize = rdhPayloadSize(rdh); + pageDecoder(buffer.subspan(pos, sizeof(RDH) + payloadSize)); + pos += rdhOffsetToNext(rdh); + } + } +}; + +} // namespace impl +using V4 = o2::header::RAWDataHeaderV4; +//using V5 = o2::header::RAWDataHeaderV5; + +template <> +void impl::print(const V4& rdh) +{ + std::cout << rdhOrbit(rdh) << " " << rdhBunchCrossing(rdh) << " " << rdhFeeId(rdh) << "\n"; +} + +PageDecoder createPageDecoder(RawBuffer rdhBuffer, SampaChannelHandler channelHandler) +{ + auto rdh = createRDH(rdhBuffer); + if (isValid(rdh)) { + if (rdhLinkId(rdh) == 15) { + if (rdhFeeId(rdh) & impl::CHARGESUM_MASK) { + return impl::PageDecoderImpl(channelHandler); + } else { + return impl::PageDecoderImpl(channelHandler); + } + } else { + if (rdhFeeId(rdh) & impl::CHARGESUM_MASK) { + return impl::PageDecoderImpl(channelHandler); + } else { + return impl::PageDecoderImpl(channelHandler); + } + } + } + throw std::invalid_argument("do not know how to create a page decoder for this RDH type\n"); +} + +PageParser createPageParser(RawBuffer buffer) +{ + auto rdh = createRDH(buffer); + if (isValid(rdh)) { + return impl::PageParser(); + } + throw std::invalid_argument("do not know how to create a page parser for this RDH type\n"); +} + +} // namespace o2::mch::raw diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/PageParser.h b/Detectors/MUON/MCH/Raw/Decoder/src/PageParser.h deleted file mode 100644 index 8bc5b58cf19ea..0000000000000 --- a/Detectors/MUON/MCH/Raw/Decoder/src/PageParser.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef O2_MCH_RAW_PAGEPARSER_H -#define O2_MCH_RAW_PAGEPARSER_H - -#include -#include "MCHRawDecoder/RawDataHeaderHandler.h" -#include "PayloadDecoder.h" - -namespace -{ -bool hasOrbitJump(uint32_t orb1, uint32_t orb2) -{ - return std::abs(static_cast(orb1 - orb2)) > 1; -} -} // namespace - -namespace o2::mch::raw -{ - -template -class PageParser -{ - public: - PageParser(RawDataHeaderHandler rdhHandler, PAYLOADDECODER decoder); - - DecoderStat parse(gsl::span buffer); - - private: - RawDataHeaderHandler mRdhHandler; - PAYLOADDECODER mDecoder; - uint32_t mOrbit{0}; - DecoderStat mStats; -}; - -template -PageParser::PageParser(RawDataHeaderHandler rdhHandler, PAYLOADDECODER decoder) - : mRdhHandler(rdhHandler), mDecoder(decoder), mStats{} -{ -} - -template -DecoderStat PageParser::parse(gsl::span buffer) -{ - RDH originalRDH; - const size_t nofRDHWords = sizeof(originalRDH); - size_t index{0}; - uint64_t nbytes{0}; - - while ((index + nofRDHWords) < buffer.size()) { - originalRDH = createRDH(buffer.subspan(index, nofRDHWords)); - if (!isValid(originalRDH)) { - std::cout << "Got an invalid RDH\n"; - impl::dumpBuffer(buffer.subspan(index, nofRDHWords)); - return mStats; - } - if (hasOrbitJump(rdhOrbit(originalRDH), mOrbit)) { - ++mStats.nofOrbitJumps; - mDecoder.reset(); - } else if (rdhOrbit(originalRDH) != mOrbit) { - ++mStats.nofOrbitSeen; - } - mOrbit = rdhOrbit(originalRDH); - auto rdhOpt = mRdhHandler(originalRDH); - if (!rdhOpt.has_value()) { - break; - } - auto rdh = rdhOpt.value(); - int payloadSize = rdhPayloadSize(rdh); - size_t n = static_cast(payloadSize); - if (n) { - size_t pos = static_cast(index + nofRDHWords); - mDecoder.process(rdh, buffer.subspan(pos, n)); - nbytes += n + nofRDHWords; - } - index += rdh.offsetToNext; - } - mStats.nofBytesUsed += nbytes; - return mStats; -} - -} // namespace o2::mch::raw - -#endif diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/PayloadDecoder.h b/Detectors/MUON/MCH/Raw/Decoder/src/PayloadDecoder.h index 6c39969ea93a2..1b5adddc542cb 100644 --- a/Detectors/MUON/MCH/Raw/Decoder/src/PayloadDecoder.h +++ b/Detectors/MUON/MCH/Raw/Decoder/src/PayloadDecoder.h @@ -11,17 +11,12 @@ #ifndef O2_MCH_RAW_PAYLOAD_DECODER_H #define O2_MCH_RAW_PAYLOAD_DECODER_H -#include "BareGBTDecoder.h" -#include "DumpBuffer.h" #include "Headers/RAWDataHeader.h" -#include "MCHRawDecoder/Decoder.h" -#include "MakeArray.h" -#include "PayloadDecoder.h" -#include "UserLogicGBTDecoder.h" +#include "MCHRawDecoder/SampaChannelHandler.h" +#include "MCHRawDecoder/PageDecoder.h" +#include #include -#include #include -#include namespace o2 { @@ -29,9 +24,16 @@ namespace mch { namespace raw { +bool hasOrbitJump(uint32_t orb1, uint32_t orb2) +{ + return std::abs(static_cast(orb1 - orb2)) > 1; +} + +using Payload = Page; + /// @brief Decoder for MCH Raw Data Format. -template +template class PayloadDecoder { public: @@ -40,41 +42,29 @@ class PayloadDecoder /// piece of sampa data (a SampaCluster, i.e. a part of a time window) PayloadDecoder(SampaChannelHandler channelHandler); - /// decode the buffer + /// decode the buffer (=payload only) /// \return the number of bytes used from the buffer - size_t process(const RDH& rdh, gsl::span buffer); - - void reset(); + size_t process(uint32_t orbit, Payload payload); private: - std::map mDecoders; //< helper decoders + uint32_t mOrbit; SampaChannelHandler mChannelHandler; }; -template -PayloadDecoder::PayloadDecoder(SampaChannelHandler channelHandler) +template +PayloadDecoder::PayloadDecoder(SampaChannelHandler channelHandler) : mChannelHandler(channelHandler) { } -template -size_t PayloadDecoder::process(const RDH& rdh, gsl::span buffer) -{ - auto solarId = rdh.feeId; - auto c = mDecoders.find(solarId); - if (c == mDecoders.end()) { - mDecoders.emplace(solarId, GBTDECODER(solarId, mChannelHandler)); - c = mDecoders.find(solarId); - } - return c->second.append(buffer); -} - -template -void PayloadDecoder::reset() +template +size_t PayloadDecoder::process(uint32_t orbit, Payload payload) { - for (auto& c : mDecoders) { - c.second.reset(); + if (hasOrbitJump(orbit, mOrbit)) { + static_cast(this)->reset(); } + mOrbit = orbit; + return static_cast(this)->append(payload); } } // namespace raw diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/UserLogicElinkDecoder.h b/Detectors/MUON/MCH/Raw/Decoder/src/UserLogicElinkDecoder.h index 63d0e103ef67a..fa2bfecf046da 100644 --- a/Detectors/MUON/MCH/Raw/Decoder/src/UserLogicElinkDecoder.h +++ b/Detectors/MUON/MCH/Raw/Decoder/src/UserLogicElinkDecoder.h @@ -11,350 +11,423 @@ #ifndef O2_MCH_RAW_USER_LOGIC_ELINK_DECODER_H #define O2_MCH_RAW_USER_LOGIC_ELINK_DECODER_H +#include "Debug.h" #include "MCHRawCommon/DataFormats.h" #include "MCHRawCommon/SampaHeader.h" -#include "MCHRawDecoder/Decoder.h" -#include -#include -#include -#include -#include -#include -#include +#include "MCHRawDecoder/SampaChannelHandler.h" #include "MCHRawElecMap/DsElecId.h" - -namespace msm = boost::msm; -namespace mpl = boost::mpl; -using namespace msm::front; -using namespace msm::front::euml; // for Not_ operator - -//#define ULDEBUG +#include +#include +#include +#include +#include +#include +#include +#include namespace o2::mch::raw { -constexpr uint64_t FIFTYBITSATONE = 0x3FFFFFFFFFFFF; - -struct NewData { - NewData(uint64_t d) : data{d & FIFTYBITSATONE} {} - uint64_t data; -}; - -struct Never { -}; +template +class UserLogicElinkDecoder +{ + public: + UserLogicElinkDecoder(DsElecId dsId, SampaChannelHandler sampaChannelHandler); -// States + /// Append 50 bits-worth of data + void append(uint64_t data50, uint8_t error); -struct NamedState : public msm::front::state<> { - NamedState(const char* name_) : name{name_} {} -#ifdef ULDEBUG - template - void on_entry(const Event&, const FSM&) - { - std::cout << "--> " << name << "\n"; - } - template - void on_exit(const Event&, const FSM&) - { - std::cout << name << "--> \n"; - } -#endif - std::string name; -}; + /// Reset our internal state + /// i.e. assume the sync has to be found again + void reset(); -struct WaitingSync : public NamedState { - WaitingSync() : NamedState("WaitingSync") {} -}; + private: + /// The possible states we can be in + enum class State : int { + WaitingSync, + WaitingHeader, + WaitingSize, + WaitingTime, + WaitingSample + }; + std::string asString(State state) const; + + using uint10_t = uint16_t; + + template + friend std::ostream& operator<<(std::ostream& os, const o2::mch::raw::UserLogicElinkDecoder& e); + + void clear(); + bool hasError() const; + bool isHeaderComplete() const { return mHeaderParts.size() == 5; } + bool moreSampleToRead() const { return mClusterSize > 0; } + bool moreWordsToRead() const { return mNof10BitWords > 0; } + std::ostream& debugHeader() const; + std::string errorMessage() const; + void append10(uint10_t data10); + void completeHeader(); + void oneLess10BitWord(); + void prepareAndSendCluster(); + void sendCluster(const SampaCluster& sc) const; + void setClusterSize(uint10_t value); + void setClusterTime(uint10_t value); + void setHeaderPart(uint10_t data10); + void setSample(uint10_t value); + void transition(State to); -struct WaitingHeader : public NamedState { - WaitingHeader() : NamedState("WaitingHeader") {} + private: + DsElecId mDsId; + SampaChannelHandler mSampaChannelHandler; + State mState; + std::vector mSamples{}; + std::vector mHeaderParts{}; + SampaHeader mSampaHeader{}; + uint10_t mNof10BitWords{}; + uint10_t mClusterSize{}; + uint10_t mClusterTime{}; + std::optional mErrorMessage{std::nullopt}; }; -struct WaitingSize : public NamedState { - WaitingSize() : NamedState("WaitingSize") {} +constexpr bool isSync(uint64_t data) +{ + constexpr uint64_t sampaSyncWord{0x1555540f00113}; + return data == sampaSyncWord; }; -struct WaitingTime : public NamedState { - WaitingTime() : NamedState("WaitingTime") {} -}; +constexpr bool isIncomplete(uint8_t error) +{ + return (error & 0x4) > 0; +} -struct WaitingSample : public NamedState { - WaitingSample() : NamedState("WaitingSample") {} -}; +template +UserLogicElinkDecoder::UserLogicElinkDecoder(DsElecId dsId, + SampaChannelHandler sampaChannelHandler) + : mDsId{dsId}, mSampaChannelHandler{sampaChannelHandler}, mState{State::WaitingSync} +{ +} -// Guards +template +void UserLogicElinkDecoder::append(uint64_t data50, uint8_t error) +{ +#ifdef ULDEBUG + debugHeader() << (*this) << fmt::format(" --> append50 {:013x} error {} data10={:d} {:d} {:d} {:d}\n", data50, error, static_cast(data50 & 0x3FF), static_cast((data50 & 0xFFC00) >> 10), static_cast((data50 & 0x3FF00000) >> 20), static_cast((data50 & 0xFFC0000000) >> 30), static_cast((data50 & 0x3FF0000000000) >> 40)); +#endif -struct isSync { - template - bool operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - return (evt.data == sampaSyncWord); + if (isSync(data50)) { + clear(); + transition(State::WaitingHeader); + return; } -}; -struct moreWordsToRead { - template - bool operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { + auto data = data50; + + for (auto i = 0; i < 5; i++) { + append10(static_cast(data & 0x3FF)); + data >>= 10; + if (hasError()) { #ifdef ULDEBUG - std::cout << fmt::format("moreWordsToRead {} n10 {}\n", (fsm.nof10BitWords > 0), fsm.nof10BitWords); + debugHeader() << (*this) << " reset due to hasError\n"; #endif - return fsm.nof10BitWords > 0; - } -}; - -struct moreDataAvailable { - template - bool operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - bool rv = (fsm.maskIndex < fsm.masks.size()); + reset(); + break; + } + if (mState == State::WaitingHeader && isIncomplete(error)) { #ifdef ULDEBUG - std::cout << fmt::format("moreDataAvailable {} maskIndex {}\n", rv, fsm.maskIndex); + debugHeader() << (*this) << " reset due to isIncomplete\n"; #endif - return rv; + reset(); + return; + } } +} // namespace o2::mch::raw + +template +struct DataFormatSizeFactor; + +template <> +struct DataFormatSizeFactor { + static constexpr uint8_t value = 1; +}; + +template <> +struct DataFormatSizeFactor { + static constexpr uint8_t value = 2; }; -struct moreSampleToRead { - template - bool operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - bool rv = (fsm.clusterSize > 0); +template +void UserLogicElinkDecoder::append10(uint10_t data10) +{ #ifdef ULDEBUG - std::cout << fmt::format("moreSampleToRead {} clustersize {}\n", rv, fsm.clusterSize); + debugHeader() << (*this) << fmt::format(" --> data10 {:d}\n", data10); #endif - return rv; - } -}; + switch (mState) { + case State::WaitingHeader: + setHeaderPart(data10); + if (isHeaderComplete()) { + completeHeader(); + if (isSync(mSampaHeader.uint64()) || + mSampaHeader.packetType() == SampaPacketType::HeartBeat || + mSampaHeader.nof10BitWords() == 0) { + reset(); + } else { + transition(State::WaitingSize); + } + } + break; + case State::WaitingSize: + if (moreWordsToRead()) { + auto factor = DataFormatSizeFactor::value; + auto value = factor * data10; + setClusterSize(value); + if (hasError()) { + return; + } + transition(State::WaitingTime); + } else { + mErrorMessage = "WaitingSize but no more words"; + return; + } + break; + case State::WaitingTime: + if (moreWordsToRead()) { + setClusterTime(data10); + transition(State::WaitingSample); + } else { + mErrorMessage = "WaitingTime but no more words"; + return; + } + break; + case State::WaitingSample: + if (moreSampleToRead()) { + setSample(data10); + } else if (moreWordsToRead()) { + transition(State::WaitingSize); + append10(data10); + } else { + transition(State::WaitingHeader); + append10(data10); + } + break; + default: + break; + }; +} -// Actions +template +std::string UserLogicElinkDecoder::asString(State s) const +{ + switch (s) { + case State::WaitingSync: + return "WaitingSync"; + break; + case State::WaitingHeader: + return "WaitingHeader"; + break; + case State::WaitingSize: + return "WaitingSize"; + break; + case State::WaitingTime: + return "WaitingTime"; + break; + case State::WaitingSample: + return "WaitingSample"; + break; + }; +} -struct foundSync { - template - void operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - fsm.nofSync++; - } -}; +template +void UserLogicElinkDecoder::clear() +{ + mSamples.clear(); + mHeaderParts.clear(); + mNof10BitWords = 0; + mClusterSize = 0; + mErrorMessage = std::nullopt; +} template -struct readSize { - template - void operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt); -}; +void UserLogicElinkDecoder::completeHeader() +{ + uint64_t header{0}; + for (auto i = 0; i < mHeaderParts.size(); i++) { + header += (static_cast(mHeaderParts[i]) << (10 * i)); + } + + mSampaHeader = SampaHeader(header); + mNof10BitWords = mSampaHeader.nof10BitWords(); -template <> -struct readSize { - template - void operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - fsm.clusterSize = fsm.pop10(); #ifdef ULDEBUG - std::cout << " -> size=" << fsm.clusterSize << " maskIndex=" << fsm.maskIndex << "\n"; -#endif + debugHeader() << (*this) << fmt::format(" --> completeHeader {:013X}\n", header); + debugHeader() << "\n"; + std::stringstream s(o2::mch::raw::asString(mSampaHeader)); + std::string part; + while (std::getline(s, part, '\n')) { + debugHeader() << (*this) << part << "\n"; } -}; + debugHeader() << "\n"; +#endif -template <> -struct readSize { - template - void operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - fsm.clusterSize = 2 * fsm.pop10(); + mHeaderParts.clear(); +} + +template +std::ostream& UserLogicElinkDecoder::debugHeader() const +{ + //std::cout << fmt::format("--ULDEBUG--{:p}-----------", reinterpret_cast(this)); + //return std::cout; + return std::cout << "---"; +} + +template +std::string UserLogicElinkDecoder::errorMessage() const +{ + return hasError() ? mErrorMessage.value() : ""; +} + +template +bool UserLogicElinkDecoder::hasError() const +{ + return mErrorMessage.has_value(); +} + +template +void UserLogicElinkDecoder::reset() +{ #ifdef ULDEBUG - std::cout << " -> size=" << fsm.clusterSize << " maskIndex=" << fsm.maskIndex << "\n"; + debugHeader() << (*this) << " ---> reset\n"; #endif - } -}; + clear(); + transition(State::WaitingSync); +} -struct readTime { - template - void operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - fsm.clusterTime = fsm.pop10(); +template +void UserLogicElinkDecoder::sendCluster(const SampaCluster& sc) const +{ #ifdef ULDEBUG - std::cout << " -> time=" << fsm.clusterTime << " maskIndex=" << fsm.maskIndex << "\n"; + debugHeader() << (*this) << " --> " + << fmt::format(" calling channelHandler for {} ch {} = {}\n", + o2::mch::raw::asString(mDsId), + channelNumber64(mSampaHeader), + o2::mch::raw::asString(sc)); #endif - } -}; + mSampaChannelHandler(mDsId, channelNumber64(mSampaHeader), sc); +} template -struct readSample { - template - void operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt); -}; +void UserLogicElinkDecoder::oneLess10BitWord() +{ + mNof10BitWords = std::max(0, mNof10BitWords - 1); +} -template <> -struct readSample { - template - void operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - fsm.clusterSize -= 2; - auto b = fsm.pop10(); - auto a = fsm.pop10(); - fsm.addChargeSum(b, a); +template +void UserLogicElinkDecoder::setClusterSize(uint10_t value) +{ + oneLess10BitWord(); + mClusterSize = value; + int checkSize = mClusterSize + 2 - mSampaHeader.nof10BitWords(); + mErrorMessage = std::nullopt; + if (mClusterSize == 0) { + mErrorMessage = "cluster size is zero"; } -}; - -template <> -struct readSample { - template - void operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - --fsm.clusterSize; - fsm.addSample(fsm.pop10()); + if (checkSize > 0) { + mErrorMessage = "cluster size bigger than nof10BitWords"; } -}; - -struct readHeader { - template - void operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - fsm.sampaHeader = SampaHeader(fsm.data); - fsm.nof10BitWords = fsm.sampaHeader.nof10BitWords(); #ifdef ULDEBUG - std::cout << fmt::format(">>>>> readHeader {:08X} maskIndex {}\n", fsm.data, fsm.maskIndex) - << fsm.sampaHeader << "\n"; + debugHeader() << (*this) << " --> size=" << mClusterSize << "\n"; #endif - fsm.maskIndex = fsm.masks.size(); - } -}; +} -struct setData { - template - void operator()(const EVT& evt, FSM& fsm, SourceState& src, TargetState& tgt) - { - fsm.data = evt.data; - fsm.maskIndex = 0; +template +void UserLogicElinkDecoder::setClusterTime(uint10_t value) +{ + oneLess10BitWord(); + mClusterTime = value; #ifdef ULDEBUG - std::cout << fmt::format(">>>>> setData {:08X} maskIndex {}\n", fsm.data, fsm.maskIndex); + debugHeader() << (*this) << " --> time=" << mClusterTime << "\n"; #endif - } -}; +} template -struct StateMachine_ : public msm::front::state_machine_def> { - - typedef WaitingSync initial_state; - - struct transition_table : mpl::vector< - // clang-format off - // Start Event Next Action Guard - Row< WaitingSync , NewData , WaitingHeader , foundSync , isSync >, - - Row< WaitingHeader , NewData , WaitingSize , ActionSequence_< - mpl::vector> , Not_ >, - Row< WaitingSize , NewData , WaitingSize , setData , And_> >, - Row< WaitingSize , none , WaitingTime , readSize , And_ >, - Row< WaitingTime , NewData , WaitingTime , setData , And_> >, - Row< WaitingTime , none , WaitingSample , readTime , And_ >, - - Row< WaitingSample , NewData , WaitingSample , setData , moreSampleToRead >, - Row< WaitingSample , none , WaitingHeader , none , Not_ >, - - Row< WaitingSample , none , WaitingSample , readSample , And_ >, - Row< WaitingSample , none , WaitingSize , none , And_>> - // clang-format on - > { - }; - uint16_t data10(uint64_t value, size_t index) const - { - if (index < 0 || index >= masks.size()) { - std::cout << fmt::format("index {} is out of range\n", index); - return 0; - } - uint64_t m = masks[index]; - return static_cast(((value & m) >> (masks.size() - 1 - index) * 10) & 0x3FF); - } - uint8_t channelNumber(const SampaHeader& sh) - { - return sh.channelAddress() + (sh.chipAddress() % 2) * 32; - } - uint16_t pop10() - { - auto rv = data10(data, maskIndex); - nof10BitWords = std::max(0, nof10BitWords - 1); - maskIndex = std::min(masks.size(), maskIndex + 1); - return rv; - } - void addSample(uint16_t sample) - { +void UserLogicElinkDecoder::setHeaderPart(uint10_t a) +{ + oneLess10BitWord(); + mHeaderParts.emplace_back(a); #ifdef ULDEBUG - std::cout << "sample = " << sample << "\n"; + debugHeader() << (*this) << fmt::format(" --> readHeader {:08X}\n", a); #endif - samples.emplace_back(sample); - if (clusterSize == 0) { - // a cluster is ready, send it - channelHandler(dsId, - channelNumber(sampaHeader), - SampaCluster(clusterTime, samples)); - samples.clear(); - } - } - void addChargeSum(uint16_t b, uint16_t a) - { - // a cluster is ready, send it - uint32_t q = (((static_cast(a) & 0x3FF) << 10) | (static_cast(b) & 0x3FF)); +} + +template +void UserLogicElinkDecoder::setSample(uint10_t sample) +{ #ifdef ULDEBUG - std::cout << "chargeSum = " << q << "\n"; + debugHeader() << (*this) << " --> sample = " << sample << "\n"; #endif - channelHandler(dsId, - channelNumber(sampaHeader), - SampaCluster(clusterTime, q)); - } + --mClusterSize; + oneLess10BitWord(); + mSamples.emplace_back(sample); - // Replaces the default no-transition response. - template - void no_transition(Event const& e, FSM&, int state) - { - std::cout << "no transition from state " << state - << " on event " << typeid(e).name() << std::endl; + if (mClusterSize == 0) { + prepareAndSendCluster(); } +} - // masks used to access groups of 10 bits in a 50 bits range - std::array - masks = {0x3FF0000000000, 0xFFC0000000, 0x3FF00000, 0xFFC00, 0x3FF}; - DsElecId dsId{0, 0, 0}; - uint16_t nof10BitWords{0}; - uint16_t clusterSize{0}; - uint16_t clusterTime{0}; - uint64_t data{0}; - size_t maskIndex{0}; - size_t nofSync{0}; - std::vector samples; - SampaHeader sampaHeader; - SampaChannelHandler channelHandler; -}; +template <> +void UserLogicElinkDecoder::prepareAndSendCluster() +{ + if (mSampaChannelHandler) { + SampaCluster sc(mClusterTime, mSamples); + sendCluster(sc); + } + mSamples.clear(); +} -template -class UserLogicElinkDecoder +template <> +void UserLogicElinkDecoder::prepareAndSendCluster() { - public: - UserLogicElinkDecoder(DsElecId dsId, SampaChannelHandler sampaChannelHandler) - : mFSM{} - { - mFSM.dsId = dsId; - mFSM.channelHandler = sampaChannelHandler; + if (mSamples.size() != 2) { + throw std::invalid_argument(fmt::format("expected sample size to be 2 but it is {}", mSamples.size())); } + uint32_t q = (((static_cast(mSamples[1]) & 0x3FF) << 10) | (static_cast(mSamples[0]) & 0x3FF)); + SampaCluster sc(mClusterTime, q); + sendCluster(sc); + mSamples.clear(); +} - void append(uint64_t data) - { +template +void UserLogicElinkDecoder::transition(State to) +{ #ifdef ULDEBUG - std::cout << fmt::format("******************************* append {:8X}\n", data); + debugHeader() << (*this) << " --> Transition from " << asString(mState) << " to " << asString(to) << "\n"; #endif - mFSM.process_event(NewData(data)); + mState = to; +} + +template +std::ostream& operator<<(std::ostream& os, const o2::mch::raw::UserLogicElinkDecoder& e) +{ + os << fmt::format("{} n10={:4d} size={:4d} t={:4d} ", asString(e.mDsId), e.mNof10BitWords, e.mClusterSize, e.mClusterTime); + os << fmt::format("h({:2d})= ", e.mHeaderParts.size()); + for (auto h : e.mHeaderParts) { + os << fmt::format("{:4d} ", h); + } + os << fmt::format("s({:2d})= ", e.mSamples.size()); + for (auto s : e.mSamples) { + os << fmt::format("{:4d} ", s); + } + if (!e.mSampaChannelHandler) { + os << " empty handler "; } - private: - msm::back::state_machine> mFSM; -}; + os << fmt::format("moreWords: {:5} moreSample: {:5} ", + e.moreWordsToRead(), e.moreSampleToRead()); + + if (e.hasError()) { + os << " ERROR:" << e.errorMessage(); + } + return os; +} } // namespace o2::mch::raw + #endif diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/UserLogicEndpointDecoder.h b/Detectors/MUON/MCH/Raw/Decoder/src/UserLogicEndpointDecoder.h new file mode 100644 index 0000000000000..da916e98a9b5e --- /dev/null +++ b/Detectors/MUON/MCH/Raw/Decoder/src/UserLogicEndpointDecoder.h @@ -0,0 +1,176 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef O2_MCH_RAW_USERLOGIC_ENDPOINT_DECODER_H +#define O2_MCH_RAW_USERLOGIC_ENDPOINT_DECODER_H + +#include +#include "UserLogicElinkDecoder.h" +#include "MCHRawDecoder/SampaChannelHandler.h" +#include +#include +#include +#include "MakeArray.h" +#include "Assertions.h" +#include +#include +#include "MCHRawElecMap/FeeLinkId.h" +#include "PayloadDecoder.h" +#include "Debug.h" + +namespace +{ +constexpr uint64_t FIFTYBITSATONE = (static_cast(1) << 50) - 1; +} + +namespace o2::mch::raw +{ + +/// +/// @brief A UserLogicEndpointDecoder groups 12 x (40 UserLogicElinkDecoder objects) +/// + +template +class UserLogicEndpointDecoder : public PayloadDecoder> +{ + public: + using ElinkDecoder = UserLogicElinkDecoder; + + /// Constructor. + /// \param linkId + /// \param sampaChannelHandler the callable that will handle each SampaCluster + UserLogicEndpointDecoder(uint16_t feeId, + std::function(FeeLinkId id)> fee2SolarMapper, + SampaChannelHandler sampaChannelHandler); + + /** @name Main interface + */ + ///@{ + + /** @brief Append the equivalent n 64-bits words + * bytes size (=n) must be a multiple of 8 + * + * @return the number of bytes used in the bytes span + */ + size_t append(Payload bytes); + ///@} + + /** @name Methods for testing + */ + + ///@{ + + /// Clear our internal Elinks + void reset(); + ///@} + + private: + uint16_t mFeeId; + std::function(FeeLinkId id)> mFee2SolarMapper; + SampaChannelHandler mChannelHandler; + std::map> mElinkDecoders; + int mNofGbtWordsSeens; +}; + +using namespace o2::mch::raw; +using namespace boost::multiprecision; + +template +UserLogicEndpointDecoder::UserLogicEndpointDecoder(uint16_t feeId, + std::function(FeeLinkId id)> fee2SolarMapper, + SampaChannelHandler sampaChannelHandler) + : PayloadDecoder>(sampaChannelHandler), + mFeeId{feeId}, + mFee2SolarMapper{fee2SolarMapper}, + mChannelHandler(sampaChannelHandler), + mNofGbtWordsSeens{0} +{ +} + +template +size_t UserLogicEndpointDecoder::append(Payload buffer) +{ + if (buffer.size() % 8) { + throw std::invalid_argument("buffer size should be a multiple of 8"); + } + size_t n{0}; + + for (size_t i = 0; i < buffer.size(); i += 8) { + uint64_t word = (static_cast(buffer[i + 0])) | + (static_cast(buffer[i + 1]) << 8) | + (static_cast(buffer[i + 2]) << 16) | + (static_cast(buffer[i + 3]) << 24) | + (static_cast(buffer[i + 4]) << 32) | + (static_cast(buffer[i + 5]) << 40) | + (static_cast(buffer[i + 6]) << 48) | + (static_cast(buffer[i + 7]) << 56); + + if (word == 0) { + continue; + } + if (word == 0xFEEDDEEDFEEDDEED) { + continue; + } + + // Get the GBT link associated to this word + int gbt = (word >> 59) & 0x1F; + if (gbt < 0 || gbt > 11) { + throw fmt::format("warning : out-of-range linkId {} word={:08X}\n", gbt, word); + } + if (gbt != 0) { + std::cout << "CAUTION : got gbt = " << gbt << "\n"; + } + + // Get the corresponding decoders array, or allocate it if does not exist yet + auto d = mElinkDecoders.find(gbt); + if (d == mElinkDecoders.end()) { + + // Compute the (feeId, linkId) pair... + FeeLinkId feeLinkId(mFeeId, gbt); + // ... and get the solar from it + auto solarId = mFee2SolarMapper(feeLinkId); + + if (!solarId.has_value()) { + throw std::logic_error(fmt::format("{} Could not get solarId from feeLinkId={}\n", __PRETTY_FUNCTION__, asString(feeLinkId))); + } + + mElinkDecoders.emplace(static_cast(gbt), + impl::makeArray<40>([=](size_t i) { + DsElecId dselec{solarId.value(), static_cast(i / 5), static_cast(i % 5)}; + return ElinkDecoder(dselec, mChannelHandler); + })); + d = mElinkDecoders.find(gbt); + } + + // in the 14 MSB(Most Significant Bits) 6 are used to specify the Dual Sampa index (0..39) + uint16_t dsid = (word >> 53) & 0x3F; + + // bits 50..52 are error bits + int8_t error = static_cast((word >> 50) & 0x7); + + // the remaining (LSB) 50 bits represents the actual data to passed to the ElinkDecoder + uint64_t data50 = word & FIFTYBITSATONE; + d->second.at(dsid).append(data50, error); + n += 8; + } + return n; +} + +template +void UserLogicEndpointDecoder::reset() +{ + for (auto& arrays : mElinkDecoders) { + for (auto& d : arrays.second) { + d.reset(); + } + } +} +} // namespace o2::mch::raw +#endif diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/UserLogicGBTDecoder.h b/Detectors/MUON/MCH/Raw/Decoder/src/UserLogicGBTDecoder.h deleted file mode 100644 index 3feb2aa7f5116..0000000000000 --- a/Detectors/MUON/MCH/Raw/Decoder/src/UserLogicGBTDecoder.h +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef O2_MCH_RAW_USERLOGIC_GBT_DECODER_H -#define O2_MCH_RAW_USERLOGIC_GBT_DECODER_H - -#include -#include "UserLogicElinkDecoder.h" -#include "MCHRawDecoder/SampaChannelHandler.h" -#include -#include "UserLogicGBTDecoder.h" -#include -#include -#include "MakeArray.h" -#include "Assertions.h" -#include -#include - -namespace o2::mch::raw -{ - -/// @brief A UserLogicGBTDecoder groups 40 UserLogicChannelDecoder objects. - -template -class UserLogicGBTDecoder -{ - public: - static constexpr uint8_t baseSize{64}; - /// Constructor. - /// \param solarId - /// \param sampaChannelHandler the callable that will handle each SampaCluster - UserLogicGBTDecoder(uint16_t solarId, SampaChannelHandler sampaChannelHandler); - - /** @name Main interface - */ - ///@{ - - /** @brief Append the equivalent n 64-bits words - * bytes size (=n) must be a multiple of 8 - * - * @return the number of bytes used in the bytes span - */ - size_t append(gsl::span bytes); - ///@} - - /** @name Methods for testing - */ - - ///@{ - - /// Clear our internal Elinks - void reset() {} - ///@} - - private: - int mSolarId; - std::array, 40> mElinkDecoders; - int mNofGbtWordsSeens; -}; - -using namespace o2::mch::raw; -using namespace boost::multiprecision; - -template -UserLogicGBTDecoder::UserLogicGBTDecoder(uint16_t solarId, - SampaChannelHandler sampaChannelHandler) - : mSolarId{solarId}, - mElinkDecoders{ - impl::makeArray<40>([=](size_t i) { - return UserLogicElinkDecoder(DsElecId{solarId, static_cast(i / 8), static_cast(i % 5)}, sampaChannelHandler); - })} // namespace o2::mch::raw - , - mNofGbtWordsSeens{0} -{ -} - -template -size_t UserLogicGBTDecoder::append(gsl::span buffer) -{ - if (buffer.size() % 8) { - throw std::invalid_argument("buffer size should be a multiple of 8"); - } - size_t n{0}; - - for (size_t i = 0; i < buffer.size(); i += 8) { - - uint64_t word = (static_cast(buffer[i + 0])) | - (static_cast(buffer[i + 1]) << 8) | - (static_cast(buffer[i + 2]) << 16) | - (static_cast(buffer[i + 3]) << 24) | - (static_cast(buffer[i + 4]) << 32) | - (static_cast(buffer[i + 5]) << 40) | - (static_cast(buffer[i + 6]) << 48) | - (static_cast(buffer[i + 7]) << 56); - - if (word == 0) { - continue; - } - if (word == 0xFEEDDEEDFEEDDEED) { - continue; - } - int gbt = (word >> 59) & 0x1F; - if (gbt != mSolarId) { - std::cout << fmt::format("warning : solarId {} != expected {} word={:08X}\n", gbt, mSolarId, word); - // throw std::invalid_argument(fmt::format("gbt {} != expected {} word={:X}\n", gbt, mGbtId, word)); - } - - uint16_t dsid = (word >> 53) & 0x3F; - impl::assertIsInRange("dsid", dsid, 0, 39); - - // the remaining 50 bits are passed to the ElinkDecoder - uint64_t data = word & UINT64_C(0x003FFFFFFFFFFFFF); - mElinkDecoders.at(dsid).append(data); - n += 8; - } - return n; -} - -} // namespace o2::mch::raw -#endif diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/testDecoder.cxx b/Detectors/MUON/MCH/Raw/Decoder/src/testPageDecoder.cxx similarity index 72% rename from Detectors/MUON/MCH/Raw/Decoder/src/testDecoder.cxx rename to Detectors/MUON/MCH/Raw/Decoder/src/testPageDecoder.cxx index 2bbb96e27d4c7..abab43615e9fe 100644 --- a/Detectors/MUON/MCH/Raw/Decoder/src/testDecoder.cxx +++ b/Detectors/MUON/MCH/Raw/Decoder/src/testPageDecoder.cxx @@ -18,23 +18,17 @@ #include #include "MCHRawCommon/RDHManip.h" #include "MCHRawCommon/DataFormats.h" -#include "MCHRawDecoder/Decoder.h" +#include "MCHRawDecoder/PageDecoder.h" #include "Headers/RAWDataHeader.h" #include "RefBuffers.h" #include "BareGBTDecoder.h" +#include using namespace o2::mch::raw; using o2::header::RAWDataHeaderV4; std::ostream& operator<<(std::ostream&, const RAWDataHeaderV4&); -std::optional handleRDH(const RAWDataHeaderV4& rdh) -{ - // std::cout << std::string(80, '-') << "\n"; - // std::cout << rdh << "\n"; - return rdh; -} - SampaChannelHandler handlePacketStoreAsVec(std::vector& result) { return [&result](DsElecId dsId, uint8_t channel, SampaCluster sc) { @@ -46,31 +40,29 @@ BOOST_AUTO_TEST_SUITE(o2_mch_raw) BOOST_AUTO_TEST_SUITE(decoder) -BOOST_AUTO_TEST_CASE(Test0) -{ - RawDataHeaderHandler rh; - SampaChannelHandler ch; - - auto d = createDecoder(rh, ch); - - createDecoder(handleRDH, ch); - createDecoder( - handleRDH, [](DsElecId dsId, uint8_t channel, SampaCluster sc) { - }); -} - BOOST_AUTO_TEST_CASE(Test1) { - std::vector buffer(1024); - std::generate(buffer.begin(), buffer.end(), std::rand); + std::vector buffer(1024); + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution dis(0, 0xFF); + std::generate(buffer.begin(), buffer.end(), [&] { return std::byte{dis(gen)}; }); + + uint16_t dummyCruId{0}; + uint8_t dummyEndpoint{0}; + uint8_t dummyLinkId{0}; + uint16_t dummyFeeId{0}; + uint32_t orbit{12}; + uint16_t bunchCrossing{34}; - auto rdh = createRDH(0, 0, 0, 12, 34, buffer.size()); + auto rdh = createRDH(dummyCruId, dummyEndpoint, dummyLinkId, dummyFeeId, + orbit, bunchCrossing, buffer.size()); - std::vector testBuffer; + std::vector testBuffer; // duplicate the (rdh+payload) to fake a 3 rdhs buffer int nrdhs{3}; - for (int i = 0; i < nrdhs; i++) { + for (auto i = 0; i < nrdhs; i++) { appendRDH(testBuffer, rdh); std::copy(begin(buffer), end(buffer), std::back_inserter(testBuffer)); } @@ -86,13 +78,9 @@ BOOST_AUTO_TEST_CASE(TestDecoding) { auto testBuffer = REF_BUFFER_CRU(); int n = countRDHs(testBuffer); - BOOST_CHECK_EQUAL(n, 4); + BOOST_CHECK_EQUAL(n, 28); std::vector result; std::vector expected{ - "S728-J1-DS2-ch-0-ts-0-q-10", - - "S728-J1-DS2-ch-0-ts-0-q-10", - "S728-J1-DS2-ch-1-ts-0-q-10", "S728-J1-DS0-ch-3-ts-0-q-13", "S728-J1-DS0-ch-13-ts-0-q-133", @@ -108,12 +96,13 @@ BOOST_AUTO_TEST_CASE(TestDecoding) "S448-J6-DS2-ch-24-ts-0-q-440", "S448-J6-DS2-ch-25-ts-0-q-450", "S448-J6-DS2-ch-26-ts-0-q-460", - "S448-J6-DS2-ch-12-ts-0-q-420" + "S448-J6-DS2-ch-12-ts-0-q-420"}; - }; + auto pageDecoder = createPageDecoder(testBuffer, handlePacketStoreAsVec(result)); + + auto parser = createPageParser(testBuffer); - auto decode = createDecoder(handleRDH, handlePacketStoreAsVec(result)); - decode(testBuffer); + parser(testBuffer, pageDecoder); BOOST_CHECK_EQUAL(result.size(), expected.size()); BOOST_CHECK(std::is_permutation(begin(result), end(result), begin(expected))); @@ -131,8 +120,8 @@ BOOST_AUTO_TEST_CASE(BareGBTDecoderFromBuffer) { std::vector result; BareGBTDecoder dec(0, handlePacketStoreAsVec(result)); - auto buf = REF_BUFFER_GBT(); - dec.append(buf); + auto testBuffer = REF_BUFFER_GBT(); + dec.append(testBuffer); std::vector expected{ "S0-J0-DS3-ch-63-ts-12-q-163", "S0-J0-DS3-ch-33-ts-12-q-133", diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/testUserLogicElinkDecoder.cxx b/Detectors/MUON/MCH/Raw/Decoder/src/testUserLogicElinkDecoder.cxx index 964667d530e26..2248bf350a819 100644 --- a/Detectors/MUON/MCH/Raw/Decoder/src/testUserLogicElinkDecoder.cxx +++ b/Detectors/MUON/MCH/Raw/Decoder/src/testUserLogicElinkDecoder.cxx @@ -132,9 +132,9 @@ std::vector createBuffer(const std::vector& clusters, template void decodeBuffer(UserLogicElinkDecoder& dec, const std::vector& b64) { - std::vector b8; + std::vector b8; impl::copyBuffer(b64, b8); - impl::dumpBuffer(b8); + impl::dumpBuffer(b8); for (auto b : b64) { dec.append(b); } diff --git a/Detectors/MUON/MCH/Raw/Decoder/src/testUserLogicEndpointDecoder.cxx b/Detectors/MUON/MCH/Raw/Decoder/src/testUserLogicEndpointDecoder.cxx new file mode 100644 index 0000000000000..861bc9257a7d1 --- /dev/null +++ b/Detectors/MUON/MCH/Raw/Decoder/src/testUserLogicEndpointDecoder.cxx @@ -0,0 +1,387 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// @author Laurent Aphecetche + +#define BOOST_TEST_MODULE Test MCHRaw UserLogicElinkDecoder +#define BOOST_TEST_MAIN +#define BOOST_TEST_DYN_LINK + +#include +#include +#include +#include +#include "UserLogicEndpointDecoder.h" +#include "MCHRawCommon/SampaHeader.h" +#include "Assertions.h" +#include "MoveBuffer.h" +#include "DumpBuffer.h" +#include "MCHRawCommon/DataFormats.h" +#include "MCHRawDecoder/SampaChannelHandler.h" +#include "MCHRawDecoder/PageDecoder.h" + +using namespace o2::mch::raw; +using o2::header::RAWDataHeaderV4; + +using uint10_t = uint16_t; +using uint50_t = uint64_t; + +SampaChannelHandler handlePacket(std::string& result) +{ + return [&result](DsElecId dsId, uint8_t channel, SampaCluster sc) { + result += fmt::format("{}-ch-{}-ts-{}-q", asString(dsId), channel, sc.timestamp); + if (sc.isClusterSum()) { + result += fmt::format("-{}", sc.chargeSum); + } else { + for (auto s : sc.samples) { + result += fmt::format("-{}", s); + } + } + result += "\n"; + }; +} + +SampaHeader createHeader(const std::vector& clusters) +{ + uint16_t n10{0}; + for (auto c : clusters) { + n10 += c.nof10BitWords(); + } + SampaHeader sh; + sh.nof10BitWords(n10); + sh.packetType(SampaPacketType::Data); + sh.hammingCode(computeHammingCode(sh.uint64())); + sh.headerParity(computeHeaderParity(sh.uint64())); + return sh; +} + +uint64_t build64(uint16_t a10, uint16_t b10 = 0, uint16_t c10 = 0, uint16_t d10 = 0, uint16_t e10 = 0) +{ + impl::assertIsInRange("a10", a10, 0, 1023); + impl::assertIsInRange("b10", a10, 0, 1023); + impl::assertIsInRange("c10", a10, 0, 1023); + impl::assertIsInRange("d10", a10, 0, 1023); + impl::assertIsInRange("e10", a10, 0, 1023); + return (static_cast(a10) << 40) | + (static_cast(b10) << 30) | + (static_cast(c10) << 20) | + (static_cast(d10) << 10) | + (static_cast(e10)); +} + +void dumpb10(const std::vector& b10) +{ + for (auto i = 0; i < b10.size(); i++) { + if (i % 5 == 0) { + std::cout << "\nB10"; + } + std::cout << fmt::format("{:4d} ", b10[i]); + } + std::cout << "\n"; +} + +std::vector b10to64(std::vector b10, uint16_t prefix14) +{ + uint64_t prefix = prefix14; + prefix <<= 50; + std::vector b64; + + while (b10.size() % 5) { + b10.emplace_back(0); + } + for (auto i = 0; i < b10.size(); i += 5) { + uint64_t v = build64(b10[i + 4], b10[i + 3], b10[i + 2], b10[i + 1], b10[i + 0]); + b64.emplace_back(v | prefix); + } + return b64; +} + +void bufferizeClusters(const std::vector& clusters, std::vector& b10) +{ + for (auto& c : clusters) { + std::cout << "c=" << c << "\n"; + b10.emplace_back(c.nofSamples()); + b10.emplace_back(c.timestamp); + if (c.isClusterSum()) { + b10.emplace_back(c.chargeSum & 0x3FF); + b10.emplace_back((c.chargeSum & 0xFFC00) >> 10); + } else { + for (auto& s : c.samples) { + b10.emplace_back(s); + } + } + } +} + +void append(std::vector& b10, uint50_t value) +{ + b10.emplace_back((value & 0x3FF)); + b10.emplace_back((value & 0xFFC00) >> 10); + b10.emplace_back((value & 0x3FF00000) >> 20); + b10.emplace_back((value & 0xFFC0000000) >> 30); + b10.emplace_back((value & 0x3FF0000000000) >> 40); +} + +std::vector createBuffer10(const std::vector& clusters, + uint8_t chip, + uint8_t ch, + bool sync) +{ + auto sh = createHeader(clusters); + sh.chipAddress(chip); + sh.channelAddress(ch); + std::vector b10; + if (sync) { + append(b10, sampaSyncWord); + } + append(b10, sh.uint64()); + bufferizeClusters(clusters, b10); + return b10; +} + +template +void decodeBuffer(typename UserLogicEndpointDecoder::ElinkDecoder& dec, const std::vector& b64) +{ + std::vector b8; + impl::copyBuffer(b64, b8); + impl::dumpBuffer(b8); + constexpr uint64_t FIFTYBITSATONE = (static_cast(1) << 50) - 1; + for (auto b : b64) { + uint64_t data50 = b & FIFTYBITSATONE; + dec.append(data50, 0); + } +} + +constexpr uint8_t CHIP = 5; +constexpr uint8_t CHANNEL = 31; +constexpr uint16_t PREFIX = 24; +// exact value not relevant as long as it is non-zero, +// and is not setting the error bits that are used (for the moment only bit 52) +// Idea being to populate bits 50-63 with some data to ensure +// the decoder is only using the lower 50 bits to get the sync and +// header values, for instance. + +std::vector createBuffer10(const std::vector& clustersFirstChannel, + const std::vector& clustersSecondChannel = {}) +{ + bool sync{true}; + auto b10 = createBuffer10(clustersFirstChannel, CHIP, CHANNEL, sync); + if (clustersSecondChannel.size()) { + auto chip2 = CHIP; + auto ch2 = CHANNEL / 2; + auto b10_2 = createBuffer10(clustersSecondChannel, chip2, ch2, !sync); + b10.insert(b10.end(), b10_2.begin(), b10_2.end()); + } + return b10; +} + +template +std::string testPayloadDecode(const std::vector& clustersFirstChannel, + const std::vector& clustersSecondChannel = {}, + std::optional insertSync = std::nullopt) +{ + auto b10 = createBuffer10(clustersFirstChannel, clustersSecondChannel); + auto b64 = b10to64(b10, PREFIX); + if (insertSync.has_value() && insertSync.value() < b64.size()) { + b64.insert(b64.begin() + insertSync.value(), (static_cast(PREFIX) << 50) | sampaSyncWord); + } + std::string results; + + uint16_t dummySolarId{0}; + uint8_t dummyGroup{0}; + uint8_t index = (CHIP - (CHANNEL > 32)) / 2; + DsElecId dsId{dummySolarId, dummyGroup, index}; + typename UserLogicEndpointDecoder::ElinkDecoder dec(dsId, handlePacket(results)); + decodeBuffer(dec, b64); + return results; +} + +template +void testDecode(const std::vector& clustersFirstChannel, + const std::vector& clustersSecondChannel = {}) +{ + auto b10 = createBuffer10(clustersFirstChannel, clustersSecondChannel); + auto b64 = b10to64(b10, PREFIX); + + std::vector b8; + impl::copyBuffer(b64, b8); + + std::vector buffer; + uint8_t linkIDforUL = 15; // must be 15 + uint16_t feeId = 18; + uint16_t cruId = feeId / 2; + uint8_t endpoint = 0; + auto rdh = createRDH(cruId, endpoint, linkIDforUL, feeId, 12, 34, b8.size()); + appendRDH(buffer, rdh); + buffer.insert(buffer.end(), b8.begin(), b8.end()); + const auto handlePacket = [](DsElecId dsId, uint8_t channel, SampaCluster sc) { + std::cout << fmt::format("testDecode:{}-{}\n", asString(dsId), asString(sc)); + }; + + impl::dumpBuffer(buffer); + + gsl::span page(reinterpret_cast(buffer.data()), buffer.size()); + auto decoder = createPageDecoder(page, handlePacket); + decoder(page); +} + +BOOST_AUTO_TEST_SUITE(o2_mch_raw) + +BOOST_AUTO_TEST_SUITE(userlogicdsdecoder) + +BOOST_AUTO_TEST_CASE(SampleModeSimplest) +{ + // only one channel with one very small cluster + // fitting within one 64-bits word + SampaCluster cl(345, {123, 456}); + auto r = testPayloadDecode({cl}); + BOOST_CHECK_EQUAL(r, "S0-J0-DS2-ch-63-ts-345-q-123-456\n"); +} + +BOOST_AUTO_TEST_CASE(SampleModeSimple) +{ + // only one channel with one cluster, but the cluster + // spans 2 64-bits words. + SampaCluster cl(345, {123, 456, 789, 901, 902}); + auto r = testPayloadDecode({cl}); + BOOST_CHECK_EQUAL(r, "S0-J0-DS2-ch-63-ts-345-q-123-456-789-901-902\n"); +} + +BOOST_AUTO_TEST_CASE(SampleModeTwoChannels) +{ + // 2 channels with one cluster + SampaCluster cl(345, {123, 456, 789, 901, 902}); + SampaCluster cl2(346, {1001, 1002, 1003, 1004, 1005, 1006, 1007}); + auto r = testPayloadDecode({cl}, {cl2}); + BOOST_CHECK_EQUAL(r, + "S0-J0-DS2-ch-63-ts-345-q-123-456-789-901-902\n" + "S0-J0-DS2-ch-47-ts-346-q-1001-1002-1003-1004-1005-1006-1007\n"); +} + +BOOST_AUTO_TEST_CASE(ChargeSumModeSimplest) +{ + // only one channel with one cluster + // (hence fitting within one 64 bits word) + SampaCluster cl(345, 123456); + auto r = testPayloadDecode({cl}); + BOOST_CHECK_EQUAL(r, "S0-J0-DS2-ch-63-ts-345-q-123456\n"); +} + +BOOST_AUTO_TEST_CASE(ChargeSumModeSimple) +{ + // only one channel with 2 clusters + // (hence spanning 2 64-bits words) + SampaCluster cl1(345, 123456); + SampaCluster cl2(346, 789012); + auto r = testPayloadDecode({cl1, cl2}); + BOOST_CHECK_EQUAL(r, + "S0-J0-DS2-ch-63-ts-345-q-123456\n" + "S0-J0-DS2-ch-63-ts-346-q-789012\n"); +} + +BOOST_AUTO_TEST_CASE(ChargeSumModeTwoChannels) +{ + // two channels with 2 clusters + SampaCluster cl1(345, 123456); + SampaCluster cl2(346, 789012); + SampaCluster cl3(347, 1357); + SampaCluster cl4(348, 791); + auto r = testPayloadDecode({cl1, cl2}, {cl3, cl4}); + BOOST_CHECK_EQUAL(r, + "S0-J0-DS2-ch-63-ts-345-q-123456\n" + "S0-J0-DS2-ch-63-ts-346-q-789012\n" + "S0-J0-DS2-ch-47-ts-347-q-1357\n" + "S0-J0-DS2-ch-47-ts-348-q-791\n"); +} + +BOOST_AUTO_TEST_CASE(DecodeSampleModeSimplest) +{ + // only one channel with one very small cluster + // fitting within one 64-bits word + SampaCluster cl(345, {123, 456}); + testDecode({cl}); + BOOST_CHECK(true); +} + +BOOST_AUTO_TEST_CASE(SyncInTheMiddleChargeSumModeTwoChannels) +{ + // Insert a sync word in the middle of + // the TwoChannels case and check the decoder is handling this fine + // (by just returning to wait for sync mode, i.e. dropping the 2nd part + // of the communication until a second sync) + SampaCluster cl1(345, 123456); + SampaCluster cl2(346, 789012); + SampaCluster cl3(347, 1357); + SampaCluster cl4(348, 791); + auto r = testPayloadDecode({cl1, cl2}, {cl3, cl4}, + 5); + BOOST_CHECK_EQUAL(r, + "S0-J0-DS2-ch-63-ts-345-q-123456\n" + "S0-J0-DS2-ch-63-ts-346-q-789012\n"); +} + +std::string asBinary(uint64_t value) +{ + std::string s; + uint64_t one = 1; + int space{0}; + for (auto i = 63; i >= 0; i--) { + if (value & (one << i)) { + s += "1"; + } else { + s += "0"; + } + if (i % 4 == 0 && i) { + s += " "; + } + } + return s; +} + +std::string binaryRule(bool top, std::vector stops) +{ + std::string s; + for (auto i = 63; i >= 0; i--) { + if (std::find(stops.begin(), stops.end(), i) != stops.end()) { + s += fmt::format("{}", (top ? i / 10 : i % 10)); + } else { + s += " "; + } + if (i % 4 == 0) { + s += " "; + } + } + return s; +} + +void dump(uint64_t value, std::vector stops = {63, 47, 31, 15, 0}) +{ + std::cout << asBinary(value) << "\n"; + std::cout << binaryRule(true, stops) << "\n"; + std::cout << binaryRule(false, stops) << "\n"; +} + +BOOST_AUTO_TEST_CASE(Prefix) +{ + std::vector b10; + append(b10, sampaSyncWord); + auto b64 = b10to64(b10, 24); + auto w = b64[0]; + BOOST_CHECK_EQUAL(asBinary(w), "0000 0000 0110 0001 0101 0101 0101 0101 0100 0000 1111 0000 0000 0001 0001 0011"); +} + +BOOST_AUTO_TEST_CASE(Binary) +{ + dump(static_cast(7) << 50, {50, 51, 52, 0}); +} + +BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() diff --git a/Detectors/MUON/MCH/Raw/ElecMap/CMakeLists.txt b/Detectors/MUON/MCH/Raw/ElecMap/CMakeLists.txt index 2d0cef8a3dfb1..c9486db9cb739 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/CMakeLists.txt +++ b/Detectors/MUON/MCH/Raw/ElecMap/CMakeLists.txt @@ -17,8 +17,9 @@ o2_add_library(MCHRawElecMap src/CH6R.cxx src/CH7L.cxx src/CH7R.cxx - src/CruLinkId.cxx + src/CH8L.cxx src/DsDetId.cxx + src/FeeLinkId.cxx src/ElectronicMapperDummy.cxx src/ElectronicMapperGenerated.cxx src/dslist.cxx @@ -26,19 +27,19 @@ o2_add_library(MCHRawElecMap PUBLIC_LINK_LIBRARIES O2::MCHRawImplHelpers ms_gsl::ms_gsl) if(BUILD_TESTING) - o2_add_test(elecmap-dummy + o2_add_test(elecmap SOURCES src/testElectronicMapper.cxx - COMPONENT_NAME mch + COMPONENT_NAME mchraw LABELS "muon;mch;raw" PUBLIC_LINK_LIBRARIES O2::MCHRawElecMap) o2_add_test(dselecid SOURCES src/testDsElecId.cxx - COMPONENT_NAME mch + COMPONENT_NAME mchraw LABELS "muon;mch;raw" PUBLIC_LINK_LIBRARIES O2::MCHRawElecMap) - o2_add_test(crulinkid - SOURCES src/testCruLinkId.cxx - COMPONENT_NAME mch + o2_add_test(feelinkid + SOURCES src/testFeeLinkId.cxx + COMPONENT_NAME mchraw LABELS "muon;mch;raw" PUBLIC_LINK_LIBRARIES O2::MCHRawElecMap) endif() diff --git a/Detectors/MUON/MCH/Raw/ElecMap/README.md b/Detectors/MUON/MCH/Raw/ElecMap/README.md index 79b460842dfa3..7391c0613f1e8 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/README.md +++ b/Detectors/MUON/MCH/Raw/ElecMap/README.md @@ -14,12 +14,17 @@ detection elements. The solar board based id is represented by the class [DsElecId](include/MCHRawElecMap/DsElecId.h) while the detection element based one is represented by the class [DsDetId](include/MCHRawElecMap/DsDetId.h) -In addition, one must know to which CRU a given solar board is connected. +In addition, one must know to which CRU a given solar board is connected. This +is currently handled with the help of the +[FeeLinkId](include/MCHRawElecMap/FeeLinkId.h) class which store a pair +`(FeeId,LinkId)`, where the `FeeId` is basically `cruId * 2 + endpoint` +(remember here that each CRU has two endpoints, each handling 12 links out of +the 24 of a CRU). As the time of this writing the electronic mapping is still a bit in flux, as : - the detector electronic is still being (re)installed -- the CRU to Solar part is still to be clarified +- the FeeId,LinkId to Solar part is still to be implemented at Pt2 so things might evolve... diff --git a/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/DsElecId.h b/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/DsElecId.h index 860fb8d2fce60..1e276c4968376 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/DsElecId.h +++ b/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/DsElecId.h @@ -68,12 +68,12 @@ class DsElecId uint8_t mElinkIndexInGroup; // 0..4 }; -uint16_t encode(const DsElecId& id); +uint32_t encode(const DsElecId& id); /// Creates (if possible) a DsElecId object from a code. /// If the code does not correspond to a valid DsElectId /// std::nullopt is returned -std::optional decodeDsElecId(uint16_t code); +std::optional decodeDsElecId(uint32_t code); /// Creates (if possible) a DsElecId object from a string representation /// If the string does not correspond to a valid DsElectId diff --git a/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/CruLinkId.h b/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/FeeLinkId.h similarity index 58% rename from Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/CruLinkId.h rename to Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/FeeLinkId.h index f6bb222bdbb74..b9358340ba489 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/CruLinkId.h +++ b/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/FeeLinkId.h @@ -8,34 +8,37 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#ifndef O2_MCH_RAW_ELECMAP_CRU_LINK_ID_H -#define O2_MCH_RAW_ELECMAP_CRU_LINK_ID_H +#ifndef O2_MCH_RAW_ELECMAP_FEE_LINK_ID_H +#define O2_MCH_RAW_ELECMAP_FEE_LINK_ID_H #include #include namespace o2::mch::raw { -class CruLinkId + +class FeeLinkId { public: - CruLinkId(uint16_t cruId, uint8_t linkId); - CruLinkId(uint16_t cruId, uint8_t linkId, uint16_t deId); + FeeLinkId(uint16_t feeId, uint8_t linkId); - uint16_t cruId() const { return mCruId; } - uint16_t deId() const { return mDeId; } + uint16_t feeId() const { return mFeeId; } uint8_t linkId() const { return mLinkId; } private: - uint16_t mCruId; + uint16_t mFeeId; uint8_t mLinkId; - uint16_t mDeId; }; -CruLinkId decodeCruLinkId(uint32_t code); -uint32_t encode(const CruLinkId& id); +FeeLinkId decodeFeeLinkId(uint32_t code); + +uint32_t encode(const FeeLinkId& id); -std::ostream& operator<<(std::ostream& os, const CruLinkId& id); +bool operator<(const FeeLinkId& f1, const FeeLinkId& f2); +std::ostream& operator<<(std::ostream& os, const FeeLinkId& id); + +std::string asString(const FeeLinkId& feeLinkId); } // namespace o2::mch::raw + #endif diff --git a/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/Mapper.h b/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/Mapper.h index f161592d5925a..7e3a6ace0d410 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/Mapper.h +++ b/Detectors/MUON/MCH/Raw/ElecMap/include/MCHRawElecMap/Mapper.h @@ -18,7 +18,7 @@ #include #include "MCHRawElecMap/DsDetId.h" #include "MCHRawElecMap/DsElecId.h" -#include "MCHRawElecMap/CruLinkId.h" +#include "MCHRawElecMap/FeeLinkId.h" #include #include #include @@ -31,7 +31,7 @@ extern std::array deIdsForAllMCH; /**@name Mapper templates. Those creator functions return functions that can do the mapping to/from - DsElecId to DsDetId and to/from CruLinkId to solarId. + DsElecId to DsDetId and to/from FeeLinkId to solarId. */ ///@{ @@ -39,27 +39,19 @@ extern std::array deIdsForAllMCH; /// timestamp is foreseen to specify a data taking period (not used for the moment) /// use 0 to get the latest mapping template -std::function(DsElecId)> createElec2DetMapper(gsl::span deIds, - uint64_t timestamp = 0); - -/// From (deId,dsId) to (solarId,groupId,index) for a given list of detection elements -template -std::function(DsDetId id)> createDet2ElecMapper(gsl::span deIds); +std::function(DsElecId)> createElec2DetMapper(uint64_t timestamp = 0); /// From (deId,dsId) to (solarId,groupId,index) for all detection elements template -std::function(DsDetId id)> createDet2ElecMapper() -{ - return createDet2ElecMapper(deIdsForAllMCH); -} +std::function(DsDetId id)> createDet2ElecMapper(); -/// From (cruId,linkId) to solarId +/// From (feeId,linkId) to solarId template -std::function(CruLinkId id)> createCruLink2SolarMapper(); +std::function(FeeLinkId id)> createFeeLink2SolarMapper(); -/// From solarId to (cruId,linkId) +/// From solarId to (feeId,linkId) template -std::function(uint16_t solarId)> createSolar2CruLinkMapper(); +std::function(uint16_t solarId)> createSolar2FeeLinkMapper(); ///@} /**@name Actual mapper types. diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/CH.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/CH.cxx index b55b9f63effa2..cb956d08d4a0e 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/CH.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/CH.cxx @@ -12,7 +12,7 @@ #include #include "MCHRawElecMap/DsElecId.h" #include "MCHRawElecMap/DsDetId.h" -#include "MCHRawElecMap/CruLinkId.h" +#include "MCHRawElecMap/FeeLinkId.h" #include #include #include @@ -20,23 +20,36 @@ namespace { -void add(std::map& e2d, int deId, int dsId, +void add(std::map& e2d, int deId, int dsId, uint16_t solarId, uint8_t groupId, uint8_t index) { - e2d.emplace(encode(o2::mch::raw::DsElecId(solarId, groupId, index)), encode(o2::mch::raw::DsDetId(deId, dsId))); + o2::mch::raw::DsElecId dselec(solarId, groupId, index); + auto code = encode(dselec); + auto already = e2d.find(code); + + // ensure we don't try to use already used key in the map + if (already != e2d.end()) { + auto previous = o2::mch::raw::decodeDsDetId(already->second); + throw std::logic_error(fmt::format("FATAL_ERROR: dselec={} (deId,dsId={},{}) is already in the map for (deId,dsId={})", + o2::mch::raw::asString(dselec), deId, dsId, o2::mch::raw::asString(previous))); + } + + // // ensure we don't have duplicated codes in the map + // if (std::find_if(begin(e2d), end(e2d), [code](const auto& v) { return v.second == code; }) != end(e2d)) { + // throw std::logic_error(fmt::format("FATAL_ERROR dselec={} (de,ds={},{}) is already referenced in the map !", + // o2::mch::raw::asString(dselec), deId, dsId)); + // } + e2d.emplace(code, encode(o2::mch::raw::DsDetId(deId, dsId))); } -void add_cru(std::map& s2c, int cruId, int linkId, uint16_t solarId, uint16_t deId) + +void add_cru(std::map& s2f, int feeId, int linkId, uint16_t solarId) { - auto code = encode(o2::mch::raw::CruLinkId(cruId, linkId, deId)); + auto code = encode(o2::mch::raw::FeeLinkId(feeId, linkId)); // ensure we don't have duplicated codes in the map - - // std::cout << fmt::format("CRU {:4d} LINK {:2d} SOLAR {:4d} DE {:4d} CODE {:8d}\n", - // cruId, linkId, solarId, deId, code); - - if (std::find_if(begin(s2c), end(s2c), [code](const auto& v) { return v.second == code; }) != end(s2c)) { - throw std::logic_error(fmt::format("Seems cru,link,deId=({},{},{}) is already referenced in the map !", - cruId, linkId, deId)); + if (std::find_if(begin(s2f), end(s2f), [code](const auto& v) { return v.second == code; }) != end(s2f)) { + throw std::logic_error(fmt::format("FATAL_ERROR feeid,link=({},{}) (solarId={}) is already referenced in the map !", + feeId, linkId, solarId)); } - s2c.emplace(solarId, code); + s2f.emplace(solarId, code); } } // namespace diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/CH5L.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/CH5L.cxx index 4f8ecef201925..e1b3be52ccc3c 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/CH5L.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/CH5L.cxx @@ -13,7 +13,7 @@ /// #include "CH.cxx" -void fillElec2DetCH5L(std::map& e2d) +void fillElec2DetCH5L(std::map& e2d) { add(e2d, 505, 16, 144, 0, 0); add(e2d, 505, 15, 144, 0, 1); @@ -620,32 +620,32 @@ void fillElec2DetCH5L(std::map& e2d) add(e2d, 513, 1131, 338, 7, 2); add(e2d, 513, 1130, 338, 7, 3); } -void fillSolar2CruLinkCH5L(std::map& s2c) +void fillSolar2FeeLinkCH5L(std::map& s2f) { - add_cru(s2c, 0, 6, 144, 505); - add_cru(s2c, 0, 7, 145, 506); - add_cru(s2c, 0, 8, 146, 506); - add_cru(s2c, 0, 9, 147, 507); - add_cru(s2c, 0, 10, 148, 507); - add_cru(s2c, 0, 0, 80, 507); - add_cru(s2c, 0, 1, 81, 507); - add_cru(s2c, 0, 2, 82, 508); - add_cru(s2c, 0, 3, 83, 508); - add_cru(s2c, 0, 4, 84, 508); - add_cru(s2c, 0, 5, 85, 508); - add_cru(s2c, 0, 12, 424, 509); - add_cru(s2c, 0, 13, 425, 509); - add_cru(s2c, 0, 14, 426, 509); - add_cru(s2c, 0, 15, 427, 509); - add_cru(s2c, 0, 16, 428, 510); - add_cru(s2c, 0, 17, 429, 510); - add_cru(s2c, 1, 0, 440, 510); - add_cru(s2c, 1, 1, 441, 510); - add_cru(s2c, 1, 2, 442, 511); - add_cru(s2c, 1, 3, 443, 511); - add_cru(s2c, 1, 4, 444, 511); - add_cru(s2c, 1, 5, 445, 511); - add_cru(s2c, 0, 18, 336, 512); - add_cru(s2c, 0, 19, 337, 512); - add_cru(s2c, 0, 20, 338, 513); + add_cru(s2f, 18, 6, 144); + add_cru(s2f, 18, 7, 145); + add_cru(s2f, 18, 8, 146); + add_cru(s2f, 18, 9, 147); + add_cru(s2f, 18, 10, 148); + add_cru(s2f, 18, 0, 80); + add_cru(s2f, 18, 1, 81); + add_cru(s2f, 18, 2, 82); + add_cru(s2f, 18, 3, 83); + add_cru(s2f, 18, 4, 84); + add_cru(s2f, 18, 5, 85); + add_cru(s2f, 19, 0, 424); + add_cru(s2f, 19, 1, 425); + add_cru(s2f, 19, 2, 426); + add_cru(s2f, 19, 3, 427); + add_cru(s2f, 19, 4, 428); + add_cru(s2f, 19, 5, 429); + add_cru(s2f, 20, 0, 440); + add_cru(s2f, 20, 1, 441); + add_cru(s2f, 20, 2, 442); + add_cru(s2f, 20, 3, 443); + add_cru(s2f, 20, 4, 444); + add_cru(s2f, 20, 5, 445); + add_cru(s2f, 19, 6, 336); + add_cru(s2f, 19, 7, 337); + add_cru(s2f, 19, 8, 338); } \ No newline at end of file diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/CH5R.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/CH5R.cxx index 2b304f1badb4c..332c585cdb801 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/CH5R.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/CH5R.cxx @@ -13,7 +13,7 @@ /// #include "CH.cxx" -void fillElec2DetCH5R(std::map& e2d) +void fillElec2DetCH5R(std::map& e2d) { add(e2d, 504, 16, 72, 0, 0); add(e2d, 504, 15, 72, 0, 1); @@ -420,15 +420,15 @@ void fillElec2DetCH5R(std::map& e2d) add(e2d, 517, 225, 400, 1, 2); add(e2d, 517, 224, 400, 1, 3); add(e2d, 517, 223, 400, 1, 4); - add(e2d, 517, 215, 400, 3, 0); - add(e2d, 517, 214, 400, 3, 1); - add(e2d, 517, 213, 400, 3, 2); - add(e2d, 517, 212, 400, 3, 3); - add(e2d, 517, 211, 400, 3, 4); + add(e2d, 517, 214, 400, 3, 0); + add(e2d, 517, 213, 400, 3, 1); + add(e2d, 517, 212, 400, 3, 2); + add(e2d, 517, 211, 400, 3, 3); add(e2d, 517, 207, 400, 5, 0); add(e2d, 517, 206, 400, 5, 1); add(e2d, 517, 205, 400, 5, 2); add(e2d, 517, 204, 400, 5, 3); + add(e2d, 517, 215, 400, 5, 4); add(e2d, 517, 1329, 401, 0, 0); add(e2d, 517, 1328, 401, 0, 1); add(e2d, 517, 1327, 401, 0, 2); @@ -620,32 +620,32 @@ void fillElec2DetCH5R(std::map& e2d) add(e2d, 514, 1131, 370, 7, 2); add(e2d, 514, 1130, 370, 7, 3); } -void fillSolar2CruLinkCH5R(std::map& s2c) +void fillSolar2FeeLinkCH5R(std::map& s2f) { - add_cru(s2c, 1, 18, 72, 504); - add_cru(s2c, 1, 19, 73, 503); - add_cru(s2c, 1, 20, 74, 503); - add_cru(s2c, 1, 21, 75, 502); - add_cru(s2c, 1, 22, 76, 502); - add_cru(s2c, 1, 12, 184, 502); - add_cru(s2c, 1, 13, 185, 502); - add_cru(s2c, 1, 14, 186, 501); - add_cru(s2c, 1, 15, 187, 501); - add_cru(s2c, 1, 16, 188, 501); - add_cru(s2c, 1, 17, 189, 501); - add_cru(s2c, 2, 0, 456, 500); - add_cru(s2c, 2, 1, 457, 500); - add_cru(s2c, 2, 2, 458, 500); - add_cru(s2c, 2, 3, 459, 500); - add_cru(s2c, 2, 4, 460, 517); - add_cru(s2c, 2, 5, 461, 517); - add_cru(s2c, 2, 12, 400, 517); - add_cru(s2c, 2, 13, 401, 517); - add_cru(s2c, 2, 14, 402, 516); - add_cru(s2c, 2, 15, 403, 516); - add_cru(s2c, 2, 16, 404, 516); - add_cru(s2c, 2, 17, 405, 516); - add_cru(s2c, 2, 6, 368, 515); - add_cru(s2c, 2, 7, 369, 515); - add_cru(s2c, 2, 8, 370, 514); + add_cru(s2f, 21, 6, 72); + add_cru(s2f, 21, 7, 73); + add_cru(s2f, 21, 8, 74); + add_cru(s2f, 21, 9, 75); + add_cru(s2f, 21, 10, 76); + add_cru(s2f, 21, 0, 184); + add_cru(s2f, 21, 1, 185); + add_cru(s2f, 21, 2, 186); + add_cru(s2f, 21, 3, 187); + add_cru(s2f, 21, 4, 188); + add_cru(s2f, 21, 5, 189); + add_cru(s2f, 22, 0, 456); + add_cru(s2f, 22, 1, 457); + add_cru(s2f, 22, 2, 458); + add_cru(s2f, 22, 3, 459); + add_cru(s2f, 22, 4, 460); + add_cru(s2f, 22, 5, 461); + add_cru(s2f, 23, 0, 400); + add_cru(s2f, 23, 1, 401); + add_cru(s2f, 23, 2, 402); + add_cru(s2f, 23, 3, 403); + add_cru(s2f, 23, 4, 404); + add_cru(s2f, 23, 5, 405); + add_cru(s2f, 22, 6, 368); + add_cru(s2f, 22, 7, 369); + add_cru(s2f, 22, 8, 370); } \ No newline at end of file diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/CH6L.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/CH6L.cxx index 2341103554c41..d5883b888d440 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/CH6L.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/CH6L.cxx @@ -18,7 +18,7 @@ #include "MCHRawElecMap/DsDetId.h" using namespace o2::mch::raw; -void fillElec2DetCH6L(std::map& e2d) +void fillElec2DetCH6L(std::map& e2d) { } -void fillSolar2CruLinkCH6L(std::map& s2c) {} +void fillSolar2FeeLinkCH6L(std::map& s2c) {} diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/CH6R.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/CH6R.cxx index cac8f435359bf..88a32de96f0dc 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/CH6R.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/CH6R.cxx @@ -13,7 +13,7 @@ /// #include "CH.cxx" -void fillElec2DetCH6R(std::map& e2d) +void fillElec2DetCH6R(std::map& e2d) { add(e2d, 604, 16, 448, 0, 0); add(e2d, 604, 15, 448, 0, 1); @@ -630,32 +630,32 @@ void fillElec2DetCH6R(std::map& e2d) add(e2d, 614, 1131, 412, 7, 2); add(e2d, 614, 1130, 412, 7, 3); } -void fillSolar2CruLinkCH6R(std::map& s2c) +void fillSolar2FeeLinkCH6R(std::map& s2f) { - add_cru(s2c, 0, 12, 448, 604); - add_cru(s2c, 0, 13, 449, 603); - add_cru(s2c, 0, 14, 450, 603); - add_cru(s2c, 0, 18, 360, 602); - add_cru(s2c, 0, 19, 361, 602); - add_cru(s2c, 0, 20, 362, 602); - add_cru(s2c, 0, 21, 363, 602); - add_cru(s2c, 0, 22, 364, 601); - add_cru(s2c, 0, 23, 365, 601); - add_cru(s2c, 1, 12, 216, 601); - add_cru(s2c, 1, 13, 217, 601); - add_cru(s2c, 1, 14, 218, 600); - add_cru(s2c, 1, 15, 219, 600); - add_cru(s2c, 1, 16, 220, 600); - add_cru(s2c, 1, 17, 221, 600); - add_cru(s2c, 1, 0, 432, 617); - add_cru(s2c, 1, 1, 433, 617); - add_cru(s2c, 1, 2, 434, 617); - add_cru(s2c, 1, 3, 435, 617); - add_cru(s2c, 1, 4, 436, 616); - add_cru(s2c, 1, 5, 437, 616); - add_cru(s2c, 1, 6, 408, 616); - add_cru(s2c, 1, 7, 409, 616); - add_cru(s2c, 1, 8, 410, 615); - add_cru(s2c, 1, 9, 411, 615); - add_cru(s2c, 1, 10, 412, 614); + add_cru(s2f, 27, 0, 448); + add_cru(s2f, 27, 1, 449); + add_cru(s2f, 27, 2, 450); + add_cru(s2f, 27, 6, 360); + add_cru(s2f, 27, 7, 361); + add_cru(s2f, 27, 8, 362); + add_cru(s2f, 27, 9, 363); + add_cru(s2f, 27, 10, 364); + add_cru(s2f, 27, 11, 365); + add_cru(s2f, 29, 0, 216); + add_cru(s2f, 29, 1, 217); + add_cru(s2f, 29, 2, 218); + add_cru(s2f, 29, 3, 219); + add_cru(s2f, 29, 4, 220); + add_cru(s2f, 29, 5, 221); + add_cru(s2f, 28, 0, 432); + add_cru(s2f, 28, 1, 433); + add_cru(s2f, 28, 2, 434); + add_cru(s2f, 28, 3, 435); + add_cru(s2f, 28, 4, 436); + add_cru(s2f, 28, 5, 437); + add_cru(s2f, 28, 6, 408); + add_cru(s2f, 28, 7, 409); + add_cru(s2f, 28, 8, 410); + add_cru(s2f, 28, 9, 411); + add_cru(s2f, 28, 10, 412); } \ No newline at end of file diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/CH7L.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/CH7L.cxx index 7f74faaa783cc..42cf0de2d8c6f 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/CH7L.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/CH7L.cxx @@ -13,7 +13,7 @@ /// #include "CH.cxx" -void fillElec2DetCH7L(std::map& e2d) +void fillElec2DetCH7L(std::map& e2d) { add(e2d, 707, 8, 728, 0, 0); add(e2d, 707, 7, 728, 0, 1); @@ -879,44 +879,44 @@ void fillElec2DetCH7L(std::map& e2d) add(e2d, 719, 1129, 860, 6, 0); add(e2d, 719, 1128, 860, 6, 1); } -void fillSolar2CruLinkCH7L(std::map& s2c) +void fillSolar2FeeLinkCH7L(std::map& s2f) { - add_cru(s2c, 0, 0, 728, 707); - add_cru(s2c, 0, 1, 729, 708); - add_cru(s2c, 0, 2, 730, 708); - add_cru(s2c, 0, 3, 731, 709); - add_cru(s2c, 0, 4, 732, 709); - add_cru(s2c, 0, 5, 736, 710); - add_cru(s2c, 0, 6, 737, 710); - add_cru(s2c, 0, 7, 738, 710); - add_cru(s2c, 0, 8, 739, 710); - add_cru(s2c, 0, 9, 740, 711); - add_cru(s2c, 0, 10, 741, 711); - add_cru(s2c, 0, 11, 776, 711); - add_cru(s2c, 0, 12, 777, 711); - add_cru(s2c, 0, 13, 778, 712); - add_cru(s2c, 0, 14, 779, 712); - add_cru(s2c, 0, 15, 780, 712); - add_cru(s2c, 0, 16, 781, 712); - add_cru(s2c, 0, 17, 864, 713); - add_cru(s2c, 0, 18, 865, 713); - add_cru(s2c, 0, 19, 866, 713); - add_cru(s2c, 0, 20, 867, 713); - add_cru(s2c, 0, 21, 352, 714); - add_cru(s2c, 0, 22, 353, 714); - add_cru(s2c, 0, 23, 354, 714); - add_cru(s2c, 0, 0, 355, 714); - add_cru(s2c, 1, 1, 356, 715); - add_cru(s2c, 1, 2, 357, 715); - add_cru(s2c, 1, 3, 304, 715); - add_cru(s2c, 1, 4, 305, 715); - add_cru(s2c, 1, 5, 306, 716); - add_cru(s2c, 1, 6, 307, 716); - add_cru(s2c, 1, 7, 308, 716); - add_cru(s2c, 1, 8, 309, 716); - add_cru(s2c, 1, 9, 856, 717); - add_cru(s2c, 1, 10, 857, 717); - add_cru(s2c, 1, 11, 858, 718); - add_cru(s2c, 1, 12, 859, 718); - add_cru(s2c, 1, 13, 860, 719); + add_cru(s2f, 30, 0, 728); + add_cru(s2f, 30, 1, 729); + add_cru(s2f, 30, 2, 730); + add_cru(s2f, 30, 3, 731); + add_cru(s2f, 30, 4, 732); + add_cru(s2f, 30, 5, 736); + add_cru(s2f, 30, 6, 737); + add_cru(s2f, 30, 7, 738); + add_cru(s2f, 30, 8, 739); + add_cru(s2f, 30, 9, 740); + add_cru(s2f, 30, 10, 741); + add_cru(s2f, 30, 11, 776); + add_cru(s2f, 31, 0, 777); + add_cru(s2f, 31, 1, 778); + add_cru(s2f, 31, 2, 779); + add_cru(s2f, 31, 3, 780); + add_cru(s2f, 31, 4, 781); + add_cru(s2f, 31, 5, 864); + add_cru(s2f, 31, 6, 865); + add_cru(s2f, 31, 7, 866); + add_cru(s2f, 31, 8, 867); + add_cru(s2f, 31, 9, 352); + add_cru(s2f, 31, 10, 353); + add_cru(s2f, 31, 11, 354); + add_cru(s2f, 32, 0, 355); + add_cru(s2f, 32, 1, 356); + add_cru(s2f, 32, 2, 357); + add_cru(s2f, 32, 3, 304); + add_cru(s2f, 32, 4, 305); + add_cru(s2f, 32, 5, 306); + add_cru(s2f, 32, 6, 307); + add_cru(s2f, 32, 7, 308); + add_cru(s2f, 32, 8, 309); + add_cru(s2f, 32, 9, 856); + add_cru(s2f, 32, 10, 857); + add_cru(s2f, 32, 11, 858); + add_cru(s2f, 33, 0, 859); + add_cru(s2f, 33, 1, 860); } \ No newline at end of file diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/CH7R.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/CH7R.cxx index 7dffbd1e3db37..71cb44f105ecd 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/CH7R.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/CH7R.cxx @@ -13,7 +13,7 @@ /// #include "CH.cxx" -void fillElec2DetCH7R(std::map& e2d) +void fillElec2DetCH7R(std::map& e2d) { add(e2d, 706, 8, 840, 0, 0); add(e2d, 706, 7, 840, 0, 1); @@ -879,44 +879,44 @@ void fillElec2DetCH7R(std::map& e2d) add(e2d, 720, 1129, 588, 6, 0); add(e2d, 720, 1128, 588, 6, 1); } -void fillSolar2CruLinkCH7R(std::map& s2c) +void fillSolar2FeeLinkCH7R(std::map& s2f) { - add_cru(s2c, 1, 14, 840, 706); - add_cru(s2c, 1, 15, 841, 705); - add_cru(s2c, 1, 16, 842, 705); - add_cru(s2c, 1, 17, 843, 704); - add_cru(s2c, 1, 18, 844, 704); - add_cru(s2c, 1, 19, 800, 703); - add_cru(s2c, 1, 20, 801, 703); - add_cru(s2c, 1, 21, 802, 703); - add_cru(s2c, 1, 22, 803, 703); - add_cru(s2c, 1, 23, 804, 702); - add_cru(s2c, 1, 0, 805, 702); - add_cru(s2c, 2, 1, 816, 702); - add_cru(s2c, 2, 2, 817, 702); - add_cru(s2c, 2, 3, 818, 701); - add_cru(s2c, 2, 4, 819, 701); - add_cru(s2c, 2, 5, 820, 701); - add_cru(s2c, 2, 7, 821, 701); - add_cru(s2c, 2, 7, 624, 700); - add_cru(s2c, 2, 8, 625, 700); - add_cru(s2c, 2, 9, 626, 700); - add_cru(s2c, 2, 10, 627, 700); - add_cru(s2c, 2, 11, 528, 725); - add_cru(s2c, 2, 12, 529, 725); - add_cru(s2c, 2, 13, 530, 725); - add_cru(s2c, 2, 14, 531, 725); - add_cru(s2c, 2, 15, 532, 724); - add_cru(s2c, 2, 16, 533, 724); - add_cru(s2c, 2, 17, 512, 724); - add_cru(s2c, 2, 18, 513, 724); - add_cru(s2c, 2, 19, 514, 723); - add_cru(s2c, 2, 20, 515, 723); - add_cru(s2c, 2, 21, 516, 723); - add_cru(s2c, 2, 22, 517, 723); - add_cru(s2c, 2, 23, 584, 722); - add_cru(s2c, 2, 0, 585, 722); - add_cru(s2c, 3, 1, 586, 721); - add_cru(s2c, 3, 2, 587, 721); - add_cru(s2c, 3, 3, 588, 720); + add_cru(s2f, 33, 2, 840); + add_cru(s2f, 33, 3, 841); + add_cru(s2f, 33, 4, 842); + add_cru(s2f, 33, 5, 843); + add_cru(s2f, 33, 6, 844); + add_cru(s2f, 33, 7, 800); + add_cru(s2f, 33, 8, 801); + add_cru(s2f, 33, 9, 802); + add_cru(s2f, 33, 10, 803); + add_cru(s2f, 33, 11, 804); + add_cru(s2f, 34, 0, 805); + add_cru(s2f, 34, 1, 816); + add_cru(s2f, 34, 2, 817); + add_cru(s2f, 34, 3, 818); + add_cru(s2f, 34, 4, 819); + add_cru(s2f, 34, 5, 820); + add_cru(s2f, 34, 6, 821); + add_cru(s2f, 34, 7, 624); + add_cru(s2f, 34, 8, 625); + add_cru(s2f, 34, 9, 626); + add_cru(s2f, 34, 10, 627); + add_cru(s2f, 34, 11, 528); + add_cru(s2f, 35, 0, 529); + add_cru(s2f, 35, 1, 530); + add_cru(s2f, 35, 2, 531); + add_cru(s2f, 35, 3, 532); + add_cru(s2f, 35, 4, 533); + add_cru(s2f, 35, 5, 512); + add_cru(s2f, 35, 6, 513); + add_cru(s2f, 35, 7, 514); + add_cru(s2f, 35, 8, 515); + add_cru(s2f, 35, 9, 516); + add_cru(s2f, 35, 10, 517); + add_cru(s2f, 35, 11, 584); + add_cru(s2f, 36, 0, 585); + add_cru(s2f, 36, 1, 586); + add_cru(s2f, 36, 2, 587); + add_cru(s2f, 36, 3, 588); } \ No newline at end of file diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/CH8L.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/CH8L.cxx new file mode 100644 index 0000000000000..64e133ffe8d6b --- /dev/null +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/CH8L.cxx @@ -0,0 +1,923 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// GENERATED CODE ! DO NOT EDIT ! +/// + +#include "CH.cxx" +void fillElec2DetCH8L(std::map& e2d) +{ + add(e2d, 807, 8, 968, 0, 0); + add(e2d, 807, 7, 968, 0, 1); + add(e2d, 807, 4, 968, 2, 0); + add(e2d, 807, 3, 968, 2, 1); + add(e2d, 807, 1029, 968, 4, 0); + add(e2d, 807, 1030, 968, 4, 1); + add(e2d, 807, 1025, 968, 6, 0); + add(e2d, 807, 1026, 968, 6, 1); + add(e2d, 807, 106, 968, 1, 0); + add(e2d, 807, 107, 968, 1, 1); + add(e2d, 807, 108, 968, 1, 2); + add(e2d, 807, 101, 968, 3, 0); + add(e2d, 807, 102, 968, 3, 1); + add(e2d, 807, 103, 968, 3, 2); + add(e2d, 807, 1134, 968, 5, 0); + add(e2d, 807, 1133, 968, 5, 1); + add(e2d, 807, 1129, 968, 7, 0); + add(e2d, 807, 1128, 968, 7, 1); + add(e2d, 808, 111, 969, 1, 0); + add(e2d, 808, 112, 969, 1, 1); + add(e2d, 808, 113, 969, 1, 2); + add(e2d, 808, 106, 969, 3, 0); + add(e2d, 808, 107, 969, 3, 1); + add(e2d, 808, 108, 969, 3, 2); + add(e2d, 808, 101, 969, 5, 0); + add(e2d, 808, 102, 969, 5, 1); + add(e2d, 808, 103, 969, 5, 2); + add(e2d, 808, 1138, 969, 0, 0); + add(e2d, 808, 1139, 969, 0, 1); + add(e2d, 808, 1133, 969, 2, 0); + add(e2d, 808, 1134, 969, 2, 1); + add(e2d, 808, 1128, 969, 4, 0); + add(e2d, 808, 1129, 969, 4, 1); + add(e2d, 808, 12, 970, 1, 0); + add(e2d, 808, 11, 970, 1, 1); + add(e2d, 808, 8, 970, 3, 0); + add(e2d, 808, 7, 970, 3, 1); + add(e2d, 808, 4, 970, 5, 0); + add(e2d, 808, 3, 970, 5, 1); + add(e2d, 808, 1033, 970, 0, 0); + add(e2d, 808, 1034, 970, 0, 1); + add(e2d, 808, 1029, 970, 2, 0); + add(e2d, 808, 1030, 970, 2, 1); + add(e2d, 808, 1025, 970, 4, 0); + add(e2d, 808, 1026, 970, 4, 1); + add(e2d, 809, 1, 971, 1, 0); + add(e2d, 809, 2, 971, 1, 1); + add(e2d, 809, 3, 971, 1, 2); + add(e2d, 809, 4, 971, 1, 3); + add(e2d, 809, 5, 971, 1, 4); + add(e2d, 809, 116, 971, 3, 0); + add(e2d, 809, 115, 971, 3, 1); + add(e2d, 809, 114, 971, 3, 2); + add(e2d, 809, 113, 971, 3, 3); + add(e2d, 809, 112, 971, 3, 4); + add(e2d, 809, 108, 971, 5, 0); + add(e2d, 809, 107, 971, 5, 1); + add(e2d, 809, 104, 971, 7, 0); + add(e2d, 809, 103, 971, 7, 1); + add(e2d, 809, 1033, 971, 0, 0); + add(e2d, 809, 1032, 971, 0, 1); + add(e2d, 809, 1031, 971, 0, 2); + add(e2d, 809, 1030, 971, 0, 3); + add(e2d, 809, 1133, 971, 2, 0); + add(e2d, 809, 1134, 971, 2, 1); + add(e2d, 809, 1135, 971, 2, 2); + add(e2d, 809, 1129, 971, 4, 0); + add(e2d, 809, 1130, 971, 4, 1); + add(e2d, 809, 1125, 971, 6, 0); + add(e2d, 809, 1126, 971, 6, 1); + add(e2d, 809, 308, 972, 1, 0); + add(e2d, 809, 307, 972, 1, 1); + add(e2d, 809, 306, 972, 1, 2); + add(e2d, 809, 305, 972, 1, 3); + add(e2d, 809, 304, 972, 1, 4); + add(e2d, 809, 211, 972, 3, 0); + add(e2d, 809, 212, 972, 3, 1); + add(e2d, 809, 213, 972, 3, 2); + add(e2d, 809, 214, 972, 3, 3); + add(e2d, 809, 215, 972, 3, 4); + add(e2d, 809, 206, 972, 5, 0); + add(e2d, 809, 207, 972, 5, 1); + add(e2d, 809, 208, 972, 5, 2); + add(e2d, 809, 201, 972, 7, 0); + add(e2d, 809, 202, 972, 7, 1); + add(e2d, 809, 203, 972, 7, 2); + add(e2d, 809, 1325, 972, 0, 0); + add(e2d, 809, 1326, 972, 0, 1); + add(e2d, 809, 1327, 972, 0, 2); + add(e2d, 809, 1243, 972, 2, 0); + add(e2d, 809, 1242, 972, 2, 1); + add(e2d, 809, 1241, 972, 2, 2); + add(e2d, 809, 1240, 972, 2, 3); + add(e2d, 809, 1234, 972, 4, 0); + add(e2d, 809, 1233, 972, 4, 1); + add(e2d, 809, 1229, 972, 6, 0); + add(e2d, 809, 1228, 972, 6, 1); + add(e2d, 810, 308, 976, 1, 0); + add(e2d, 810, 307, 976, 1, 1); + add(e2d, 810, 306, 976, 1, 2); + add(e2d, 810, 305, 976, 1, 3); + add(e2d, 810, 304, 976, 1, 4); + add(e2d, 810, 316, 976, 3, 0); + add(e2d, 810, 315, 976, 3, 1); + add(e2d, 810, 314, 976, 3, 2); + add(e2d, 810, 313, 976, 3, 3); + add(e2d, 810, 312, 976, 3, 4); + add(e2d, 810, 211, 976, 5, 0); + add(e2d, 810, 212, 976, 5, 1); + add(e2d, 810, 213, 976, 5, 2); + add(e2d, 810, 214, 976, 5, 3); + add(e2d, 810, 215, 976, 5, 4); + add(e2d, 810, 206, 976, 0, 0); + add(e2d, 810, 207, 976, 0, 1); + add(e2d, 810, 208, 976, 0, 2); + add(e2d, 810, 201, 976, 2, 0); + add(e2d, 810, 202, 976, 2, 1); + add(e2d, 810, 203, 976, 2, 2); + add(e2d, 810, 1325, 977, 0, 0); + add(e2d, 810, 1326, 977, 0, 1); + add(e2d, 810, 1327, 977, 0, 2); + add(e2d, 810, 1333, 977, 2, 0); + add(e2d, 810, 1334, 977, 2, 1); + add(e2d, 810, 1335, 977, 2, 2); + add(e2d, 810, 1243, 977, 4, 0); + add(e2d, 810, 1242, 977, 4, 1); + add(e2d, 810, 1241, 977, 4, 2); + add(e2d, 810, 1240, 977, 4, 3); + add(e2d, 810, 1234, 977, 1, 0); + add(e2d, 810, 1233, 977, 1, 1); + add(e2d, 810, 1229, 977, 3, 0); + add(e2d, 810, 1228, 977, 3, 1); + add(e2d, 810, 1, 978, 1, 0); + add(e2d, 810, 2, 978, 1, 1); + add(e2d, 810, 3, 978, 1, 2); + add(e2d, 810, 4, 978, 1, 3); + add(e2d, 810, 5, 978, 1, 4); + add(e2d, 810, 10, 978, 3, 0); + add(e2d, 810, 11, 978, 3, 1); + add(e2d, 810, 12, 978, 3, 2); + add(e2d, 810, 13, 978, 3, 3); + add(e2d, 810, 14, 978, 3, 4); + add(e2d, 810, 116, 978, 5, 0); + add(e2d, 810, 115, 978, 5, 1); + add(e2d, 810, 114, 978, 5, 2); + add(e2d, 810, 113, 978, 5, 3); + add(e2d, 810, 112, 978, 5, 4); + add(e2d, 810, 108, 978, 0, 0); + add(e2d, 810, 107, 978, 0, 1); + add(e2d, 810, 104, 978, 2, 0); + add(e2d, 810, 103, 978, 2, 1); + add(e2d, 810, 1033, 979, 0, 0); + add(e2d, 810, 1032, 979, 0, 1); + add(e2d, 810, 1031, 979, 0, 2); + add(e2d, 810, 1030, 979, 0, 3); + add(e2d, 810, 1042, 979, 2, 0); + add(e2d, 810, 1041, 979, 2, 1); + add(e2d, 810, 1040, 979, 2, 2); + add(e2d, 810, 1039, 979, 2, 3); + add(e2d, 810, 1133, 979, 4, 0); + add(e2d, 810, 1134, 979, 4, 1); + add(e2d, 810, 1135, 979, 4, 2); + add(e2d, 810, 1129, 979, 1, 0); + add(e2d, 810, 1130, 979, 1, 1); + add(e2d, 810, 1125, 979, 3, 0); + add(e2d, 810, 1126, 979, 3, 1); + add(e2d, 811, 5, 980, 1, 0); + add(e2d, 811, 4, 980, 1, 1); + add(e2d, 811, 3, 980, 1, 2); + add(e2d, 811, 2, 980, 1, 3); + add(e2d, 811, 1, 980, 1, 4); + add(e2d, 811, 10, 980, 3, 0); + add(e2d, 811, 9, 980, 3, 1); + add(e2d, 811, 8, 980, 3, 2); + add(e2d, 811, 7, 980, 3, 3); + add(e2d, 811, 6, 980, 3, 4); + add(e2d, 811, 22, 980, 5, 0); + add(e2d, 811, 21, 980, 5, 1); + add(e2d, 811, 20, 980, 5, 2); + add(e2d, 811, 19, 980, 5, 3); + add(e2d, 811, 18, 980, 5, 4); + add(e2d, 811, 27, 980, 7, 0); + add(e2d, 811, 26, 980, 7, 1); + add(e2d, 811, 25, 980, 7, 2); + add(e2d, 811, 24, 980, 7, 3); + add(e2d, 811, 23, 980, 7, 4); + add(e2d, 811, 120, 980, 0, 0); + add(e2d, 811, 119, 980, 0, 1); + add(e2d, 811, 118, 980, 0, 2); + add(e2d, 811, 117, 980, 0, 3); + add(e2d, 811, 116, 980, 0, 4); + add(e2d, 811, 112, 980, 2, 0); + add(e2d, 811, 111, 980, 2, 1); + add(e2d, 811, 110, 980, 2, 2); + add(e2d, 811, 109, 980, 2, 3); + add(e2d, 811, 108, 980, 2, 4); + add(e2d, 811, 104, 980, 4, 0); + add(e2d, 811, 103, 980, 4, 1); + add(e2d, 811, 1039, 981, 0, 0); + add(e2d, 811, 1040, 981, 0, 1); + add(e2d, 811, 1041, 981, 0, 2); + add(e2d, 811, 1035, 981, 2, 0); + add(e2d, 811, 1036, 981, 2, 1); + add(e2d, 811, 1037, 981, 2, 2); + add(e2d, 811, 1038, 981, 2, 3); + add(e2d, 811, 1056, 981, 4, 0); + add(e2d, 811, 1057, 981, 4, 1); + add(e2d, 811, 1058, 981, 4, 2); + add(e2d, 811, 1052, 981, 6, 0); + add(e2d, 811, 1053, 981, 6, 1); + add(e2d, 811, 1054, 981, 6, 2); + add(e2d, 811, 1055, 981, 6, 3); + add(e2d, 811, 1137, 981, 1, 0); + add(e2d, 811, 1138, 981, 1, 1); + add(e2d, 811, 1139, 981, 1, 2); + add(e2d, 811, 1129, 981, 3, 0); + add(e2d, 811, 1130, 981, 3, 1); + add(e2d, 811, 1131, 981, 3, 2); + add(e2d, 811, 1125, 981, 5, 0); + add(e2d, 811, 1126, 981, 5, 1); + add(e2d, 811, 1127, 981, 5, 2); + add(e2d, 811, 313, 984, 1, 0); + add(e2d, 811, 314, 984, 1, 1); + add(e2d, 811, 315, 984, 1, 2); + add(e2d, 811, 316, 984, 1, 3); + add(e2d, 811, 317, 984, 1, 4); + add(e2d, 811, 308, 984, 3, 0); + add(e2d, 811, 309, 984, 3, 1); + add(e2d, 811, 310, 984, 3, 2); + add(e2d, 811, 311, 984, 3, 3); + add(e2d, 811, 312, 984, 3, 4); + add(e2d, 811, 330, 984, 5, 0); + add(e2d, 811, 331, 984, 5, 1); + add(e2d, 811, 332, 984, 5, 2); + add(e2d, 811, 333, 984, 5, 3); + add(e2d, 811, 334, 984, 5, 4); + add(e2d, 811, 325, 984, 7, 0); + add(e2d, 811, 326, 984, 7, 1); + add(e2d, 811, 327, 984, 7, 2); + add(e2d, 811, 328, 984, 7, 3); + add(e2d, 811, 329, 984, 7, 4); + add(e2d, 811, 215, 984, 0, 0); + add(e2d, 811, 216, 984, 0, 1); + add(e2d, 811, 217, 984, 0, 2); + add(e2d, 811, 218, 984, 0, 3); + add(e2d, 811, 219, 984, 0, 4); + add(e2d, 811, 206, 984, 2, 0); + add(e2d, 811, 207, 984, 2, 1); + add(e2d, 811, 208, 984, 2, 2); + add(e2d, 811, 209, 984, 2, 3); + add(e2d, 811, 210, 984, 2, 4); + add(e2d, 811, 201, 984, 4, 0); + add(e2d, 811, 202, 984, 4, 1); + add(e2d, 811, 203, 984, 4, 2); + add(e2d, 811, 1327, 985, 0, 0); + add(e2d, 811, 1326, 985, 0, 1); + add(e2d, 811, 1325, 985, 0, 2); + add(e2d, 811, 1331, 985, 2, 0); + add(e2d, 811, 1330, 985, 2, 1); + add(e2d, 811, 1329, 985, 2, 2); + add(e2d, 811, 1328, 985, 2, 3); + add(e2d, 811, 1344, 985, 4, 0); + add(e2d, 811, 1343, 985, 4, 1); + add(e2d, 811, 1342, 985, 4, 2); + add(e2d, 811, 1348, 985, 6, 0); + add(e2d, 811, 1347, 985, 6, 1); + add(e2d, 811, 1346, 985, 6, 2); + add(e2d, 811, 1345, 985, 6, 3); + add(e2d, 811, 1247, 985, 1, 0); + add(e2d, 811, 1246, 985, 1, 1); + add(e2d, 811, 1245, 985, 1, 2); + add(e2d, 811, 1244, 985, 1, 3); + add(e2d, 811, 1238, 985, 3, 0); + add(e2d, 811, 1237, 985, 3, 1); + add(e2d, 811, 1236, 985, 3, 2); + add(e2d, 811, 1235, 985, 3, 3); + add(e2d, 811, 1229, 985, 5, 0); + add(e2d, 811, 1228, 985, 5, 1); + add(e2d, 812, 403, 986, 1, 0); + add(e2d, 812, 402, 986, 1, 1); + add(e2d, 812, 401, 986, 1, 2); + add(e2d, 812, 408, 986, 3, 0); + add(e2d, 812, 407, 986, 3, 1); + add(e2d, 812, 406, 986, 3, 2); + add(e2d, 812, 405, 986, 3, 3); + add(e2d, 812, 404, 986, 3, 4); + add(e2d, 812, 413, 986, 5, 0); + add(e2d, 812, 412, 986, 5, 1); + add(e2d, 812, 411, 986, 5, 2); + add(e2d, 812, 410, 986, 5, 3); + add(e2d, 812, 409, 986, 5, 4); + add(e2d, 812, 315, 986, 7, 0); + add(e2d, 812, 314, 986, 7, 1); + add(e2d, 812, 313, 986, 7, 2); + add(e2d, 812, 312, 986, 7, 3); + add(e2d, 812, 311, 986, 7, 4); + add(e2d, 812, 320, 986, 0, 0); + add(e2d, 812, 319, 986, 0, 1); + add(e2d, 812, 318, 986, 0, 2); + add(e2d, 812, 317, 986, 0, 3); + add(e2d, 812, 316, 986, 0, 4); + add(e2d, 812, 328, 986, 2, 0); + add(e2d, 812, 329, 986, 2, 1); + add(e2d, 812, 330, 986, 2, 2); + add(e2d, 812, 331, 986, 2, 3); + add(e2d, 812, 332, 986, 2, 4); + add(e2d, 812, 216, 986, 4, 0); + add(e2d, 812, 215, 986, 4, 1); + add(e2d, 812, 214, 986, 4, 2); + add(e2d, 812, 213, 986, 4, 3); + add(e2d, 812, 212, 986, 4, 4); + add(e2d, 812, 208, 986, 6, 0); + add(e2d, 812, 207, 986, 6, 1); + add(e2d, 812, 1330, 987, 0, 0); + add(e2d, 812, 1331, 987, 0, 1); + add(e2d, 812, 1332, 987, 0, 2); + add(e2d, 812, 1333, 987, 0, 3); + add(e2d, 812, 1334, 987, 0, 4); + add(e2d, 812, 1325, 987, 2, 0); + add(e2d, 812, 1326, 987, 2, 1); + add(e2d, 812, 1327, 987, 2, 2); + add(e2d, 812, 1328, 987, 2, 3); + add(e2d, 812, 1329, 987, 2, 4); + add(e2d, 812, 1349, 987, 4, 0); + add(e2d, 812, 1350, 987, 4, 1); + add(e2d, 812, 1351, 987, 4, 2); + add(e2d, 812, 1345, 987, 6, 0); + add(e2d, 812, 1346, 987, 6, 1); + add(e2d, 812, 1347, 987, 6, 2); + add(e2d, 812, 1348, 987, 6, 3); + add(e2d, 812, 1360, 987, 1, 0); + add(e2d, 812, 1359, 987, 1, 1); + add(e2d, 812, 1358, 987, 1, 2); + add(e2d, 812, 1357, 987, 1, 3); + add(e2d, 812, 1233, 987, 3, 0); + add(e2d, 812, 1234, 987, 3, 1); + add(e2d, 812, 1235, 987, 3, 2); + add(e2d, 812, 1229, 987, 5, 0); + add(e2d, 812, 1230, 987, 5, 1); + add(e2d, 812, 1225, 987, 7, 0); + add(e2d, 812, 1226, 987, 7, 1); + add(e2d, 812, 204, 988, 1, 0); + add(e2d, 812, 203, 988, 1, 1); + add(e2d, 812, 1, 988, 3, 0); + add(e2d, 812, 0, 988, 3, 1); + add(e2d, 812, 14, 988, 5, 0); + add(e2d, 812, 15, 988, 5, 1); + add(e2d, 812, 16, 988, 5, 2); + add(e2d, 812, 17, 988, 5, 3); + add(e2d, 812, 18, 988, 5, 4); + add(e2d, 812, 9, 988, 7, 0); + add(e2d, 812, 10, 988, 7, 1); + add(e2d, 812, 11, 988, 7, 2); + add(e2d, 812, 12, 988, 7, 3); + add(e2d, 812, 13, 988, 7, 4); + add(e2d, 812, 26, 988, 0, 0); + add(e2d, 812, 25, 988, 0, 1); + add(e2d, 812, 24, 988, 0, 2); + add(e2d, 812, 23, 988, 0, 3); + add(e2d, 812, 22, 988, 0, 4); + add(e2d, 812, 111, 988, 2, 0); + add(e2d, 812, 112, 988, 2, 1); + add(e2d, 812, 113, 988, 2, 2); + add(e2d, 812, 114, 988, 2, 3); + add(e2d, 812, 115, 988, 2, 4); + add(e2d, 812, 106, 988, 4, 0); + add(e2d, 812, 107, 988, 4, 1); + add(e2d, 812, 108, 988, 4, 2); + add(e2d, 812, 101, 988, 6, 0); + add(e2d, 812, 102, 988, 6, 1); + add(e2d, 812, 103, 988, 6, 2); + add(e2d, 812, 1028, 989, 0, 0); + add(e2d, 812, 1027, 989, 0, 1); + add(e2d, 812, 1026, 989, 0, 2); + add(e2d, 812, 1032, 989, 2, 0); + add(e2d, 812, 1031, 989, 2, 1); + add(e2d, 812, 1030, 989, 2, 2); + add(e2d, 812, 1029, 989, 2, 3); + add(e2d, 812, 1043, 989, 4, 0); + add(e2d, 812, 1044, 989, 4, 1); + add(e2d, 812, 1045, 989, 4, 2); + add(e2d, 812, 1143, 989, 1, 0); + add(e2d, 812, 1142, 989, 1, 1); + add(e2d, 812, 1141, 989, 1, 2); + add(e2d, 812, 1140, 989, 1, 3); + add(e2d, 812, 1134, 989, 3, 0); + add(e2d, 812, 1133, 989, 3, 1); + add(e2d, 812, 1129, 989, 5, 0); + add(e2d, 812, 1128, 989, 5, 1); + add(e2d, 813, 5, 992, 1, 0); + add(e2d, 813, 4, 992, 1, 1); + add(e2d, 813, 3, 992, 1, 2); + add(e2d, 813, 2, 992, 1, 3); + add(e2d, 813, 1, 992, 1, 4); + add(e2d, 813, 10, 992, 3, 0); + add(e2d, 813, 9, 992, 3, 1); + add(e2d, 813, 8, 992, 3, 2); + add(e2d, 813, 7, 992, 3, 3); + add(e2d, 813, 6, 992, 3, 4); + add(e2d, 813, 18, 992, 5, 0); + add(e2d, 813, 19, 992, 5, 1); + add(e2d, 813, 20, 992, 5, 2); + add(e2d, 813, 21, 992, 5, 3); + add(e2d, 813, 22, 992, 5, 4); + add(e2d, 813, 116, 992, 0, 0); + add(e2d, 813, 115, 992, 0, 1); + add(e2d, 813, 114, 992, 0, 2); + add(e2d, 813, 113, 992, 0, 3); + add(e2d, 813, 112, 992, 0, 4); + add(e2d, 813, 108, 992, 2, 0); + add(e2d, 813, 107, 992, 2, 1); + add(e2d, 813, 104, 992, 4, 0); + add(e2d, 813, 103, 992, 4, 1); + add(e2d, 813, 1039, 993, 0, 0); + add(e2d, 813, 1040, 993, 0, 1); + add(e2d, 813, 1041, 993, 0, 2); + add(e2d, 813, 1035, 993, 2, 0); + add(e2d, 813, 1036, 993, 2, 1); + add(e2d, 813, 1037, 993, 2, 2); + add(e2d, 813, 1038, 993, 2, 3); + add(e2d, 813, 1050, 993, 4, 0); + add(e2d, 813, 1049, 993, 4, 1); + add(e2d, 813, 1048, 993, 4, 2); + add(e2d, 813, 1047, 993, 4, 3); + add(e2d, 813, 1133, 993, 1, 0); + add(e2d, 813, 1134, 993, 1, 1); + add(e2d, 813, 1135, 993, 1, 2); + add(e2d, 813, 1129, 993, 3, 0); + add(e2d, 813, 1130, 993, 3, 1); + add(e2d, 813, 1125, 993, 5, 0); + add(e2d, 813, 1126, 993, 5, 1); + add(e2d, 813, 313, 994, 1, 0); + add(e2d, 813, 314, 994, 1, 1); + add(e2d, 813, 315, 994, 1, 2); + add(e2d, 813, 316, 994, 1, 3); + add(e2d, 813, 317, 994, 1, 4); + add(e2d, 813, 308, 994, 3, 0); + add(e2d, 813, 309, 994, 3, 1); + add(e2d, 813, 310, 994, 3, 2); + add(e2d, 813, 311, 994, 3, 3); + add(e2d, 813, 312, 994, 3, 4); + add(e2d, 813, 325, 994, 5, 0); + add(e2d, 813, 324, 994, 5, 1); + add(e2d, 813, 323, 994, 5, 2); + add(e2d, 813, 322, 994, 5, 3); + add(e2d, 813, 321, 994, 5, 4); + add(e2d, 813, 211, 994, 0, 0); + add(e2d, 813, 212, 994, 0, 1); + add(e2d, 813, 213, 994, 0, 2); + add(e2d, 813, 214, 994, 0, 3); + add(e2d, 813, 215, 994, 0, 4); + add(e2d, 813, 206, 994, 2, 0); + add(e2d, 813, 207, 994, 2, 1); + add(e2d, 813, 208, 994, 2, 2); + add(e2d, 813, 201, 994, 4, 0); + add(e2d, 813, 202, 994, 4, 1); + add(e2d, 813, 203, 994, 4, 2); + add(e2d, 813, 1327, 995, 0, 0); + add(e2d, 813, 1326, 995, 0, 1); + add(e2d, 813, 1325, 995, 0, 2); + add(e2d, 813, 1331, 995, 2, 0); + add(e2d, 813, 1330, 995, 2, 1); + add(e2d, 813, 1329, 995, 2, 2); + add(e2d, 813, 1328, 995, 2, 3); + add(e2d, 813, 1342, 995, 4, 0); + add(e2d, 813, 1343, 995, 4, 1); + add(e2d, 813, 1344, 995, 4, 2); + add(e2d, 813, 1243, 995, 1, 0); + add(e2d, 813, 1242, 995, 1, 1); + add(e2d, 813, 1241, 995, 1, 2); + add(e2d, 813, 1240, 995, 1, 3); + add(e2d, 813, 1234, 995, 3, 0); + add(e2d, 813, 1233, 995, 3, 1); + add(e2d, 813, 1229, 995, 5, 0); + add(e2d, 813, 1228, 995, 5, 1); + add(e2d, 814, 1, 1000, 1, 0); + add(e2d, 814, 0, 1000, 1, 1); + add(e2d, 814, 204, 1000, 3, 0); + add(e2d, 814, 203, 1000, 3, 1); + add(e2d, 814, 14, 1000, 5, 0); + add(e2d, 814, 15, 1000, 5, 1); + add(e2d, 814, 16, 1000, 5, 2); + add(e2d, 814, 17, 1000, 5, 3); + add(e2d, 814, 18, 1000, 5, 4); + add(e2d, 814, 9, 1000, 7, 0); + add(e2d, 814, 10, 1000, 7, 1); + add(e2d, 814, 11, 1000, 7, 2); + add(e2d, 814, 12, 1000, 7, 3); + add(e2d, 814, 13, 1000, 7, 4); + add(e2d, 814, 26, 1000, 0, 0); + add(e2d, 814, 25, 1000, 0, 1); + add(e2d, 814, 24, 1000, 0, 2); + add(e2d, 814, 23, 1000, 0, 3); + add(e2d, 814, 22, 1000, 0, 4); + add(e2d, 814, 111, 1000, 2, 0); + add(e2d, 814, 112, 1000, 2, 1); + add(e2d, 814, 113, 1000, 2, 2); + add(e2d, 814, 114, 1000, 2, 3); + add(e2d, 814, 115, 1000, 2, 4); + add(e2d, 814, 106, 1000, 4, 0); + add(e2d, 814, 107, 1000, 4, 1); + add(e2d, 814, 108, 1000, 4, 2); + add(e2d, 814, 101, 1000, 6, 0); + add(e2d, 814, 102, 1000, 6, 1); + add(e2d, 814, 103, 1000, 6, 2); + add(e2d, 814, 1028, 1001, 0, 0); + add(e2d, 814, 1027, 1001, 0, 1); + add(e2d, 814, 1026, 1001, 0, 2); + add(e2d, 814, 1032, 1001, 2, 0); + add(e2d, 814, 1031, 1001, 2, 1); + add(e2d, 814, 1030, 1001, 2, 2); + add(e2d, 814, 1029, 1001, 2, 3); + add(e2d, 814, 1043, 1001, 4, 0); + add(e2d, 814, 1044, 1001, 4, 1); + add(e2d, 814, 1045, 1001, 4, 2); + add(e2d, 814, 1143, 1001, 1, 0); + add(e2d, 814, 1142, 1001, 1, 1); + add(e2d, 814, 1141, 1001, 1, 2); + add(e2d, 814, 1140, 1001, 1, 3); + add(e2d, 814, 1134, 1001, 3, 0); + add(e2d, 814, 1133, 1001, 3, 1); + add(e2d, 814, 1129, 1001, 5, 0); + add(e2d, 814, 1128, 1001, 5, 1); + add(e2d, 814, 403, 1002, 1, 0); + add(e2d, 814, 402, 1002, 1, 1); + add(e2d, 814, 401, 1002, 1, 2); + add(e2d, 814, 408, 1002, 3, 0); + add(e2d, 814, 407, 1002, 3, 1); + add(e2d, 814, 406, 1002, 3, 2); + add(e2d, 814, 405, 1002, 3, 3); + add(e2d, 814, 404, 1002, 3, 4); + add(e2d, 814, 413, 1002, 5, 0); + add(e2d, 814, 412, 1002, 5, 1); + add(e2d, 814, 411, 1002, 5, 2); + add(e2d, 814, 410, 1002, 5, 3); + add(e2d, 814, 409, 1002, 5, 4); + add(e2d, 814, 315, 1002, 7, 0); + add(e2d, 814, 314, 1002, 7, 1); + add(e2d, 814, 313, 1002, 7, 2); + add(e2d, 814, 312, 1002, 7, 3); + add(e2d, 814, 311, 1002, 7, 4); + add(e2d, 814, 320, 1002, 0, 0); + add(e2d, 814, 319, 1002, 0, 1); + add(e2d, 814, 318, 1002, 0, 2); + add(e2d, 814, 317, 1002, 0, 3); + add(e2d, 814, 316, 1002, 0, 4); + add(e2d, 814, 328, 1002, 2, 0); + add(e2d, 814, 329, 1002, 2, 1); + add(e2d, 814, 330, 1002, 2, 2); + add(e2d, 814, 331, 1002, 2, 3); + add(e2d, 814, 332, 1002, 2, 4); + add(e2d, 814, 216, 1002, 4, 0); + add(e2d, 814, 215, 1002, 4, 1); + add(e2d, 814, 214, 1002, 4, 2); + add(e2d, 814, 213, 1002, 4, 3); + add(e2d, 814, 212, 1002, 4, 4); + add(e2d, 814, 208, 1002, 6, 0); + add(e2d, 814, 207, 1002, 6, 1); + add(e2d, 814, 1330, 1003, 0, 0); + add(e2d, 814, 1331, 1003, 0, 1); + add(e2d, 814, 1332, 1003, 0, 2); + add(e2d, 814, 1333, 1003, 0, 3); + add(e2d, 814, 1334, 1003, 0, 4); + add(e2d, 814, 1325, 1003, 2, 0); + add(e2d, 814, 1326, 1003, 2, 1); + add(e2d, 814, 1327, 1003, 2, 2); + add(e2d, 814, 1328, 1003, 2, 3); + add(e2d, 814, 1329, 1003, 2, 4); + add(e2d, 814, 1349, 1003, 4, 0); + add(e2d, 814, 1350, 1003, 4, 1); + add(e2d, 814, 1351, 1003, 4, 2); + add(e2d, 814, 1345, 1003, 6, 0); + add(e2d, 814, 1346, 1003, 6, 1); + add(e2d, 814, 1347, 1003, 6, 2); + add(e2d, 814, 1348, 1003, 6, 3); + add(e2d, 814, 1360, 1003, 1, 0); + add(e2d, 814, 1359, 1003, 1, 1); + add(e2d, 814, 1358, 1003, 1, 2); + add(e2d, 814, 1357, 1003, 1, 3); + add(e2d, 814, 1233, 1003, 3, 0); + add(e2d, 814, 1234, 1003, 3, 1); + add(e2d, 814, 1235, 1003, 3, 2); + add(e2d, 814, 1229, 1003, 5, 0); + add(e2d, 814, 1230, 1003, 5, 1); + add(e2d, 814, 1225, 1003, 7, 0); + add(e2d, 814, 1226, 1003, 7, 1); + add(e2d, 815, 5, 1004, 1, 0); + add(e2d, 815, 4, 1004, 1, 1); + add(e2d, 815, 3, 1004, 1, 2); + add(e2d, 815, 2, 1004, 1, 3); + add(e2d, 815, 1, 1004, 1, 4); + add(e2d, 815, 10, 1004, 3, 0); + add(e2d, 815, 9, 1004, 3, 1); + add(e2d, 815, 8, 1004, 3, 2); + add(e2d, 815, 7, 1004, 3, 3); + add(e2d, 815, 6, 1004, 3, 4); + add(e2d, 815, 22, 1004, 5, 0); + add(e2d, 815, 21, 1004, 5, 1); + add(e2d, 815, 20, 1004, 5, 2); + add(e2d, 815, 19, 1004, 5, 3); + add(e2d, 815, 18, 1004, 5, 4); + add(e2d, 815, 27, 1004, 7, 0); + add(e2d, 815, 26, 1004, 7, 1); + add(e2d, 815, 25, 1004, 7, 2); + add(e2d, 815, 24, 1004, 7, 3); + add(e2d, 815, 23, 1004, 7, 4); + add(e2d, 815, 120, 1004, 0, 0); + add(e2d, 815, 119, 1004, 0, 1); + add(e2d, 815, 118, 1004, 0, 2); + add(e2d, 815, 117, 1004, 0, 3); + add(e2d, 815, 116, 1004, 0, 4); + add(e2d, 815, 112, 1004, 2, 0); + add(e2d, 815, 111, 1004, 2, 1); + add(e2d, 815, 110, 1004, 2, 2); + add(e2d, 815, 109, 1004, 2, 3); + add(e2d, 815, 108, 1004, 2, 4); + add(e2d, 815, 104, 1004, 4, 0); + add(e2d, 815, 103, 1004, 4, 1); + add(e2d, 815, 1039, 1005, 0, 0); + add(e2d, 815, 1040, 1005, 0, 1); + add(e2d, 815, 1041, 1005, 0, 2); + add(e2d, 815, 1035, 1005, 2, 0); + add(e2d, 815, 1036, 1005, 2, 1); + add(e2d, 815, 1037, 1005, 2, 2); + add(e2d, 815, 1038, 1005, 2, 3); + add(e2d, 815, 1056, 1005, 4, 0); + add(e2d, 815, 1057, 1005, 4, 1); + add(e2d, 815, 1058, 1005, 4, 2); + add(e2d, 815, 1052, 1005, 6, 0); + add(e2d, 815, 1053, 1005, 6, 1); + add(e2d, 815, 1054, 1005, 6, 2); + add(e2d, 815, 1055, 1005, 6, 3); + add(e2d, 815, 1137, 1005, 1, 0); + add(e2d, 815, 1138, 1005, 1, 1); + add(e2d, 815, 1139, 1005, 1, 2); + add(e2d, 815, 1129, 1005, 3, 0); + add(e2d, 815, 1130, 1005, 3, 1); + add(e2d, 815, 1131, 1005, 3, 2); + add(e2d, 815, 1125, 1005, 5, 0); + add(e2d, 815, 1126, 1005, 5, 1); + add(e2d, 815, 1127, 1005, 5, 2); + add(e2d, 815, 313, 1008, 1, 0); + add(e2d, 815, 314, 1008, 1, 1); + add(e2d, 815, 315, 1008, 1, 2); + add(e2d, 815, 316, 1008, 1, 3); + add(e2d, 815, 317, 1008, 1, 4); + add(e2d, 815, 308, 1008, 3, 0); + add(e2d, 815, 309, 1008, 3, 1); + add(e2d, 815, 310, 1008, 3, 2); + add(e2d, 815, 311, 1008, 3, 3); + add(e2d, 815, 312, 1008, 3, 4); + add(e2d, 815, 330, 1008, 5, 0); + add(e2d, 815, 331, 1008, 5, 1); + add(e2d, 815, 332, 1008, 5, 2); + add(e2d, 815, 333, 1008, 5, 3); + add(e2d, 815, 334, 1008, 5, 4); + add(e2d, 815, 325, 1008, 7, 0); + add(e2d, 815, 326, 1008, 7, 1); + add(e2d, 815, 327, 1008, 7, 2); + add(e2d, 815, 328, 1008, 7, 3); + add(e2d, 815, 329, 1008, 7, 4); + add(e2d, 815, 215, 1008, 0, 0); + add(e2d, 815, 216, 1008, 0, 1); + add(e2d, 815, 217, 1008, 0, 2); + add(e2d, 815, 218, 1008, 0, 3); + add(e2d, 815, 219, 1008, 0, 4); + add(e2d, 815, 206, 1008, 2, 0); + add(e2d, 815, 207, 1008, 2, 1); + add(e2d, 815, 208, 1008, 2, 2); + add(e2d, 815, 209, 1008, 2, 3); + add(e2d, 815, 210, 1008, 2, 4); + add(e2d, 815, 201, 1008, 4, 0); + add(e2d, 815, 202, 1008, 4, 1); + add(e2d, 815, 203, 1008, 4, 2); + add(e2d, 815, 1327, 1009, 0, 0); + add(e2d, 815, 1326, 1009, 0, 1); + add(e2d, 815, 1325, 1009, 0, 2); + add(e2d, 815, 1331, 1009, 2, 0); + add(e2d, 815, 1330, 1009, 2, 1); + add(e2d, 815, 1329, 1009, 2, 2); + add(e2d, 815, 1328, 1009, 2, 3); + add(e2d, 815, 1344, 1009, 4, 0); + add(e2d, 815, 1343, 1009, 4, 1); + add(e2d, 815, 1342, 1009, 4, 2); + add(e2d, 815, 1348, 1009, 6, 0); + add(e2d, 815, 1347, 1009, 6, 1); + add(e2d, 815, 1346, 1009, 6, 2); + add(e2d, 815, 1345, 1009, 6, 3); + add(e2d, 815, 1247, 1009, 1, 0); + add(e2d, 815, 1246, 1009, 1, 1); + add(e2d, 815, 1245, 1009, 1, 2); + add(e2d, 815, 1244, 1009, 1, 3); + add(e2d, 815, 1238, 1009, 3, 0); + add(e2d, 815, 1237, 1009, 3, 1); + add(e2d, 815, 1236, 1009, 3, 2); + add(e2d, 815, 1235, 1009, 3, 3); + add(e2d, 815, 1229, 1009, 5, 0); + add(e2d, 815, 1228, 1009, 5, 1); + add(e2d, 816, 308, 1010, 1, 0); + add(e2d, 816, 307, 1010, 1, 1); + add(e2d, 816, 306, 1010, 1, 2); + add(e2d, 816, 305, 1010, 1, 3); + add(e2d, 816, 304, 1010, 1, 4); + add(e2d, 816, 316, 1010, 3, 0); + add(e2d, 816, 315, 1010, 3, 1); + add(e2d, 816, 314, 1010, 3, 2); + add(e2d, 816, 313, 1010, 3, 3); + add(e2d, 816, 312, 1010, 3, 4); + add(e2d, 816, 211, 1010, 5, 0); + add(e2d, 816, 212, 1010, 5, 1); + add(e2d, 816, 213, 1010, 5, 2); + add(e2d, 816, 214, 1010, 5, 3); + add(e2d, 816, 215, 1010, 5, 4); + add(e2d, 816, 206, 1010, 0, 0); + add(e2d, 816, 207, 1010, 0, 1); + add(e2d, 816, 208, 1010, 0, 2); + add(e2d, 816, 201, 1010, 2, 0); + add(e2d, 816, 202, 1010, 2, 1); + add(e2d, 816, 203, 1010, 2, 2); + add(e2d, 816, 1325, 1011, 0, 0); + add(e2d, 816, 1326, 1011, 0, 1); + add(e2d, 816, 1327, 1011, 0, 2); + add(e2d, 816, 1333, 1011, 2, 0); + add(e2d, 816, 1334, 1011, 2, 1); + add(e2d, 816, 1335, 1011, 2, 2); + add(e2d, 816, 1243, 1011, 4, 0); + add(e2d, 816, 1242, 1011, 4, 1); + add(e2d, 816, 1241, 1011, 4, 2); + add(e2d, 816, 1240, 1011, 4, 3); + add(e2d, 816, 1234, 1011, 1, 0); + add(e2d, 816, 1233, 1011, 1, 1); + add(e2d, 816, 1229, 1011, 3, 0); + add(e2d, 816, 1228, 1011, 3, 1); + add(e2d, 816, 1, 1012, 1, 0); + add(e2d, 816, 2, 1012, 1, 1); + add(e2d, 816, 3, 1012, 1, 2); + add(e2d, 816, 4, 1012, 1, 3); + add(e2d, 816, 5, 1012, 1, 4); + add(e2d, 816, 10, 1012, 3, 0); + add(e2d, 816, 11, 1012, 3, 1); + add(e2d, 816, 12, 1012, 3, 2); + add(e2d, 816, 13, 1012, 3, 3); + add(e2d, 816, 14, 1012, 3, 4); + add(e2d, 816, 116, 1012, 5, 0); + add(e2d, 816, 115, 1012, 5, 1); + add(e2d, 816, 114, 1012, 5, 2); + add(e2d, 816, 113, 1012, 5, 3); + add(e2d, 816, 112, 1012, 5, 4); + add(e2d, 816, 108, 1012, 0, 0); + add(e2d, 816, 107, 1012, 0, 1); + add(e2d, 816, 104, 1012, 2, 0); + add(e2d, 816, 103, 1012, 2, 1); + add(e2d, 816, 1033, 1013, 0, 0); + add(e2d, 816, 1032, 1013, 0, 1); + add(e2d, 816, 1031, 1013, 0, 2); + add(e2d, 816, 1030, 1013, 0, 3); + add(e2d, 816, 1042, 1013, 2, 0); + add(e2d, 816, 1041, 1013, 2, 1); + add(e2d, 816, 1040, 1013, 2, 2); + add(e2d, 816, 1039, 1013, 2, 3); + add(e2d, 816, 1133, 1013, 4, 0); + add(e2d, 816, 1134, 1013, 4, 1); + add(e2d, 816, 1135, 1013, 4, 2); + add(e2d, 816, 1129, 1013, 1, 0); + add(e2d, 816, 1130, 1013, 1, 1); + add(e2d, 816, 1125, 1013, 3, 0); + add(e2d, 816, 1126, 1013, 3, 1); + add(e2d, 817, 1, 1016, 1, 0); + add(e2d, 817, 2, 1016, 1, 1); + add(e2d, 817, 3, 1016, 1, 2); + add(e2d, 817, 4, 1016, 1, 3); + add(e2d, 817, 5, 1016, 1, 4); + add(e2d, 817, 116, 1016, 3, 0); + add(e2d, 817, 115, 1016, 3, 1); + add(e2d, 817, 114, 1016, 3, 2); + add(e2d, 817, 113, 1016, 3, 3); + add(e2d, 817, 112, 1016, 3, 4); + add(e2d, 817, 108, 1016, 5, 0); + add(e2d, 817, 107, 1016, 5, 1); + add(e2d, 817, 104, 1016, 7, 0); + add(e2d, 817, 103, 1016, 7, 1); + add(e2d, 817, 1033, 1016, 0, 0); + add(e2d, 817, 1032, 1016, 0, 1); + add(e2d, 817, 1031, 1016, 0, 2); + add(e2d, 817, 1030, 1016, 0, 3); + add(e2d, 817, 1133, 1016, 2, 0); + add(e2d, 817, 1134, 1016, 2, 1); + add(e2d, 817, 1135, 1016, 2, 2); + add(e2d, 817, 1129, 1016, 4, 0); + add(e2d, 817, 1130, 1016, 4, 1); + add(e2d, 817, 1125, 1016, 6, 0); + add(e2d, 817, 1126, 1016, 6, 1); + add(e2d, 817, 308, 1017, 1, 0); + add(e2d, 817, 307, 1017, 1, 1); + add(e2d, 817, 306, 1017, 1, 2); + add(e2d, 817, 305, 1017, 1, 3); + add(e2d, 817, 304, 1017, 1, 4); + add(e2d, 817, 211, 1017, 3, 0); + add(e2d, 817, 212, 1017, 3, 1); + add(e2d, 817, 213, 1017, 3, 2); + add(e2d, 817, 214, 1017, 3, 3); + add(e2d, 817, 215, 1017, 3, 4); + add(e2d, 817, 206, 1017, 5, 0); + add(e2d, 817, 207, 1017, 5, 1); + add(e2d, 817, 208, 1017, 5, 2); + add(e2d, 817, 201, 1017, 7, 0); + add(e2d, 817, 202, 1017, 7, 1); + add(e2d, 817, 203, 1017, 7, 2); + add(e2d, 817, 1325, 1017, 0, 0); + add(e2d, 817, 1326, 1017, 0, 1); + add(e2d, 817, 1327, 1017, 0, 2); + add(e2d, 817, 1243, 1017, 2, 0); + add(e2d, 817, 1242, 1017, 2, 1); + add(e2d, 817, 1241, 1017, 2, 2); + add(e2d, 817, 1240, 1017, 2, 3); + add(e2d, 817, 1234, 1017, 4, 0); + add(e2d, 817, 1233, 1017, 4, 1); + add(e2d, 817, 1229, 1017, 6, 0); + add(e2d, 817, 1228, 1017, 6, 1); + add(e2d, 818, 111, 1018, 1, 0); + add(e2d, 818, 112, 1018, 1, 1); + add(e2d, 818, 113, 1018, 1, 2); + add(e2d, 818, 106, 1018, 3, 0); + add(e2d, 818, 107, 1018, 3, 1); + add(e2d, 818, 108, 1018, 3, 2); + add(e2d, 818, 101, 1018, 5, 0); + add(e2d, 818, 102, 1018, 5, 1); + add(e2d, 818, 103, 1018, 5, 2); + add(e2d, 818, 1138, 1018, 0, 0); + add(e2d, 818, 1139, 1018, 0, 1); + add(e2d, 818, 1133, 1018, 2, 0); + add(e2d, 818, 1134, 1018, 2, 1); + add(e2d, 818, 1128, 1018, 4, 0); + add(e2d, 818, 1129, 1018, 4, 1); + add(e2d, 818, 12, 1019, 1, 0); + add(e2d, 818, 11, 1019, 1, 1); + add(e2d, 818, 8, 1019, 3, 0); + add(e2d, 818, 7, 1019, 3, 1); + add(e2d, 818, 4, 1019, 5, 0); + add(e2d, 818, 3, 1019, 5, 1); + add(e2d, 818, 1033, 1019, 0, 0); + add(e2d, 818, 1034, 1019, 0, 1); + add(e2d, 818, 1029, 1019, 2, 0); + add(e2d, 818, 1030, 1019, 2, 1); + add(e2d, 818, 1025, 1019, 4, 0); + add(e2d, 818, 1026, 1019, 4, 1); + add(e2d, 819, 8, 1020, 1, 0); + add(e2d, 819, 7, 1020, 1, 1); + add(e2d, 819, 4, 1020, 3, 0); + add(e2d, 819, 3, 1020, 3, 1); + add(e2d, 819, 1029, 1020, 5, 0); + add(e2d, 819, 1030, 1020, 5, 1); + add(e2d, 819, 1025, 1020, 7, 0); + add(e2d, 819, 1026, 1020, 7, 1); + add(e2d, 819, 106, 1020, 0, 0); + add(e2d, 819, 107, 1020, 0, 1); + add(e2d, 819, 108, 1020, 0, 2); + add(e2d, 819, 101, 1020, 2, 0); + add(e2d, 819, 102, 1020, 2, 1); + add(e2d, 819, 103, 1020, 2, 2); + add(e2d, 819, 1134, 1020, 4, 0); + add(e2d, 819, 1133, 1020, 4, 1); + add(e2d, 819, 1129, 1020, 6, 0); + add(e2d, 819, 1128, 1020, 6, 1); +} +void fillSolar2FeeLinkCH8L(std::map& s2f) +{ + add_cru(s2f, 37, 4, 968); + add_cru(s2f, 37, 5, 969); + add_cru(s2f, 37, 6, 970); + add_cru(s2f, 37, 7, 971); + add_cru(s2f, 37, 8, 972); + add_cru(s2f, 37, 9, 976); + add_cru(s2f, 37, 10, 977); + add_cru(s2f, 37, 11, 978); + add_cru(s2f, 39, 0, 979); + add_cru(s2f, 39, 1, 980); + add_cru(s2f, 38, 2, 981); + add_cru(s2f, 38, 3, 984); + add_cru(s2f, 38, 4, 985); + add_cru(s2f, 38, 5, 986); + add_cru(s2f, 38, 6, 987); + add_cru(s2f, 38, 7, 988); + add_cru(s2f, 38, 8, 989); + add_cru(s2f, 38, 9, 992); + add_cru(s2f, 38, 10, 993); + add_cru(s2f, 38, 11, 994); + add_cru(s2f, 40, 0, 995); + add_cru(s2f, 40, 1, 1000); + add_cru(s2f, 41, 2, 1001); + add_cru(s2f, 41, 3, 1002); + add_cru(s2f, 41, 4, 1003); + add_cru(s2f, 41, 5, 1004); + add_cru(s2f, 41, 6, 1005); + add_cru(s2f, 41, 7, 1008); + add_cru(s2f, 41, 8, 1009); + add_cru(s2f, 41, 9, 1010); + add_cru(s2f, 41, 10, 1011); + add_cru(s2f, 41, 11, 1012); + add_cru(s2f, 43, 0, 1013); + add_cru(s2f, 43, 1, 1016); + add_cru(s2f, 42, 2, 1017); + add_cru(s2f, 42, 3, 1018); + add_cru(s2f, 42, 4, 1019); + add_cru(s2f, 44, 0, 1020); +} \ No newline at end of file diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/CruLinkId.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/CruLinkId.cxx deleted file mode 100644 index de72957b37a30..0000000000000 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/CruLinkId.cxx +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright CERN and copyright holders of ALICE O2. This software is -// distributed under the terms of the GNU General Public License v3 (GPL -// Version 3), copied verbatim in the file "COPYING". -// -// See http://alice-o2.web.cern.ch/license for full licensing information. -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#include "MCHRawElecMap/CruLinkId.h" -#include "Assertions.h" -#include -#include - -namespace o2::mch::raw -{ - -CruLinkId::CruLinkId(uint16_t cruId, uint8_t linkId) - : mCruId(cruId), mLinkId(linkId) -{ - impl::assertIsInRange("linkId", mLinkId, 0, 23); -} - -CruLinkId::CruLinkId(uint16_t cruId, uint8_t linkId, uint16_t deId) - : mCruId(cruId), mLinkId(linkId), mDeId(deId) -{ - impl::assertIsInRange("linkId", mLinkId, 0, 23); -} - -uint32_t encode(const CruLinkId& id) -{ - return (id.deId() << 17) | (id.cruId() << 5) | id.linkId(); -} - -CruLinkId decodeCruLinkId(uint32_t x) -{ - uint16_t cruId = static_cast((x & 0x3FFE0) >> 5); - uint16_t linkId = static_cast(x & 0x1F); - uint16_t deId = static_cast((x & 0xFFFC0000) >> 17); - return CruLinkId(cruId, linkId, deId); -} - -std::ostream& operator<<(std::ostream& os, const CruLinkId& id) -{ - os << fmt::format("CruLinkId(CRU={:4d},LINK={:1d},DE={:4d}) CODE={:8d}", id.cruId(), id.linkId(), id.deId(), encode(id)); - return os; -} - -} // namespace o2::mch::raw diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/DsElecId.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/DsElecId.cxx index 8507a1aab8ca3..6df4aac5b211d 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/DsElecId.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/DsElecId.cxx @@ -21,23 +21,25 @@ namespace o2::mch::raw DsElecId::DsElecId(uint16_t solarId, uint8_t elinkGroupId, uint8_t elinkIndex) : mSolarId{solarId}, mElinkGroupId{elinkGroupId}, mElinkIndexInGroup{elinkIndex} { + impl::assertIsInRange("solarId", solarId, 0, 1023); impl::assertIsInRange("elinkGroupId", mElinkGroupId, 0, 7); impl::assertIsInRange("elinkIndex", mElinkIndexInGroup, 0, 4); } -uint16_t encode(const DsElecId& id) +uint32_t encode(const DsElecId& id) { - return (id.solarId() & 0x3FF) | ((id.elinkGroupId() & 0x7) << 10) | - ((id.elinkIndexInGroup() & 0x7) << 13); + return ((id.solarId() & 0xFFFF) << 16) | + ((id.elinkGroupId() & 0xFF) << 8) | + ((id.elinkIndexInGroup() & 0xFF) << 0); } -std::optional decodeDsElecId(uint16_t code) +std::optional decodeDsElecId(uint32_t code) { - uint16_t solarId = code & 0x3FF; + uint16_t solarId = (code & 0xFFFF0000) >> 16; // 11 (LSB) bits used - uint8_t groupId = (code & 0x1C00) >> 10; + uint8_t groupId = (code & 0xFF00) >> 8; // 3 (LSB) bits used - uint8_t index = (code & 0xE000) >> 13; + uint8_t index = (code & 0xFF) >> 0; // 3 (LSB) bits used if (groupId > 7) { return std::nullopt; diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperDummy.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperDummy.cxx index a850b0c533665..bdb3943514523 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperDummy.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperDummy.cxx @@ -13,7 +13,7 @@ #include #include "MCHRawElecMap/DsElecId.h" #include "MCHRawElecMap/DsDetId.h" -#include "MCHRawElecMap/CruLinkId.h" +#include "MCHRawElecMap/FeeLinkId.h" #include "ElectronicMapperImplHelper.h" #include "dslist.h" @@ -21,10 +21,9 @@ namespace { // build the map to go from electronic ds id to detector ds id - -std::map buildDsElecId2DsDetIdMap(gsl::span deIds) +std::map buildDsElecId2DsDetIdMap() { - std::map e2d; + std::map e2d; auto dslist = createDualSampaMapper(); @@ -54,18 +53,15 @@ std::map buildDsElecId2DsDetIdMap(gsl::span deIds) } o2::mch::raw::DsElecId dsElecId(solarId, groupId, index); o2::mch::raw::DsDetId dsDetId(deId, dsId); - // only update the map if deId is one of the desired ones - if (std::find(deIds.begin(), deIds.end(), deId) != deIds.end()) { - e2d.emplace(o2::mch::raw::encode(dsElecId), - o2::mch::raw::encode(dsDetId)); - } + e2d.emplace(o2::mch::raw::encode(dsElecId), + o2::mch::raw::encode(dsDetId)); n++; }; }; return e2d; } -std::map buildCruLinkId2SolarIdMap() +std::map buildFeeLinkId2SolarIdMap() { std::map c2s; @@ -81,14 +77,14 @@ std::map buildCruLinkId2SolarIdMap() solarId++; auto cruId = solarId / 24; auto linkId = solarId - cruId * 24; - c2s[encode(o2::mch::raw::CruLinkId(cruId, linkId))] = solarId; + c2s[encode(o2::mch::raw::FeeLinkId(cruId, linkId))] = solarId; } n++; }; }; auto cruId = solarId / 24; auto linkId = solarId - cruId * 24; - c2s[encode(o2::mch::raw::CruLinkId(cruId, linkId))] = solarId; + c2s[encode(o2::mch::raw::FeeLinkId(cruId, linkId))] = solarId; return c2s; } } // namespace @@ -98,43 +94,33 @@ namespace o2::mch::raw template <> std::function(DsElecId)> - createElec2DetMapper(gsl::span deIds, uint64_t timestamp) + createElec2DetMapper(uint64_t timestamp) { - std::map dsElecId2DsDetId = buildDsElecId2DsDetIdMap(deIds); + static std::map dsElecId2DsDetId = buildDsElecId2DsDetIdMap(); return impl::mapperElec2Det(dsElecId2DsDetId); } template <> std::function(DsDetId)> - createDet2ElecMapper(gsl::span deIds) + createDet2ElecMapper() { - std::map dsElecId2DsDetId = buildDsElecId2DsDetIdMap(deIds); - std::map dsDetId2dsElecId; - - for (auto p : dsElecId2DsDetId) { - dsDetId2dsElecId.emplace(p.second, p.first); - } - + static std::map dsDetId2dsElecId = impl::inverseMap(buildDsElecId2DsDetIdMap()); return impl::mapperDet2Elec(dsDetId2dsElecId); } template <> -std::function(CruLinkId)> - createCruLink2SolarMapper() +std::function(FeeLinkId)> + createFeeLink2SolarMapper() { - auto c2s = buildCruLinkId2SolarIdMap(); - return impl::mapperCruLink2Solar(c2s); + static auto f2s = buildFeeLinkId2SolarIdMap(); + return impl::mapperFeeLink2Solar(f2s); } template <> -std::function(uint16_t)> - createSolar2CruLinkMapper() +std::function(uint16_t)> + createSolar2FeeLinkMapper() { - std::map s2c; - auto c2s = buildCruLinkId2SolarIdMap(); - for (auto p : c2s) { - s2c[p.second] = p.first; - } - return impl::mapperSolar2CruLink(s2c); + static auto s2f = impl::inverseMap(buildFeeLinkId2SolarIdMap()); + return impl::mapperSolar2FeeLink(s2f); } } // namespace o2::mch::raw diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperGenerated.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperGenerated.cxx index 8c666fbc48a6b..469007ee9b74d 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperGenerated.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperGenerated.cxx @@ -16,66 +16,56 @@ #include #include -extern void fillElec2DetCH5R(std::map& e2d); -extern void fillElec2DetCH5L(std::map& e2d); -extern void fillElec2DetCH6R(std::map& e2d); -extern void fillElec2DetCH6L(std::map& e2d); -extern void fillElec2DetCH7R(std::map& e2d); -extern void fillElec2DetCH7L(std::map& e2d); - -extern void fillSolar2CruLinkCH5R(std::map& s2c); -extern void fillSolar2CruLinkCH5L(std::map& s2c); -extern void fillSolar2CruLinkCH6R(std::map& s2c); -extern void fillSolar2CruLinkCH6L(std::map& s2c); -extern void fillSolar2CruLinkCH7R(std::map& s2c); -extern void fillSolar2CruLinkCH7L(std::map& s2c); +extern void fillElec2DetCH5R(std::map& e2d); +extern void fillElec2DetCH5L(std::map& e2d); +extern void fillElec2DetCH6R(std::map& e2d); +extern void fillElec2DetCH6L(std::map& e2d); +extern void fillElec2DetCH7R(std::map& e2d); +extern void fillElec2DetCH7L(std::map& e2d); +extern void fillElec2DetCH8L(std::map& e2d); + +extern void fillSolar2FeeLinkCH5R(std::map& s2c); +extern void fillSolar2FeeLinkCH5L(std::map& s2c); +extern void fillSolar2FeeLinkCH6R(std::map& s2c); +extern void fillSolar2FeeLinkCH6L(std::map& s2c); +extern void fillSolar2FeeLinkCH7R(std::map& s2c); +extern void fillSolar2FeeLinkCH7L(std::map& s2c); +extern void fillSolar2FeeLinkCH8L(std::map& s2c); namespace { -void dump(const std::map& e2d) +void dump(const std::map& e2d) { for (auto p : e2d) { std::cout << o2::mch::raw::decodeDsElecId(p.first).value() << " -> " << o2::mch::raw::decodeDsDetId(p.second) << "\n"; } } -// return a version of m where only the detection elements in deIds -// are present -std::map filter(const std::map& m, gsl::span deIds) -{ - std::map e2d; - for (auto p : m) { - o2::mch::raw::DsDetId id = o2::mch::raw::decodeDsDetId(p.second); - if (std::find(deIds.begin(), deIds.end(), id.deId()) != deIds.end()) { - e2d.emplace(p.first, p.second); - } - } - return e2d; -} - -std::map buildDsElecId2DsDetIdMap(gsl::span deIds) +std::map buildDsElecId2DsDetIdMap() { - std::map e2d; + std::map e2d; fillElec2DetCH5R(e2d); fillElec2DetCH5L(e2d); fillElec2DetCH6R(e2d); fillElec2DetCH6L(e2d); fillElec2DetCH7R(e2d); fillElec2DetCH7L(e2d); - return filter(e2d, deIds); + fillElec2DetCH8L(e2d); + return e2d; } -std::map buildSolarId2CruLinkIdMap() +std::map buildSolarId2FeeLinkIdMap() { - std::map s2c; - fillSolar2CruLinkCH5R(s2c); - fillSolar2CruLinkCH5L(s2c); - fillSolar2CruLinkCH6R(s2c); - fillSolar2CruLinkCH6L(s2c); - fillSolar2CruLinkCH7R(s2c); - fillSolar2CruLinkCH7L(s2c); - return s2c; + std::map s2f; + fillSolar2FeeLinkCH5R(s2f); + fillSolar2FeeLinkCH5L(s2f); + fillSolar2FeeLinkCH6R(s2f); + fillSolar2FeeLinkCH6L(s2f); + fillSolar2FeeLinkCH7R(s2f); + fillSolar2FeeLinkCH7L(s2f); + fillSolar2FeeLinkCH8L(s2f); + return s2f; } } // namespace @@ -85,43 +75,34 @@ namespace o2::mch::raw template <> std::function(DsElecId)> - createElec2DetMapper(gsl::span deIds, uint64_t timestamp) + createElec2DetMapper(uint64_t /*timestamp*/) { - std::map dsElecId2DsDetId = buildDsElecId2DsDetIdMap(deIds); + static std::map dsElecId2DsDetId = buildDsElecId2DsDetIdMap(); return impl::mapperElec2Det(dsElecId2DsDetId); } template <> std::function(DsDetId)> - createDet2ElecMapper(gsl::span deIds) + createDet2ElecMapper() { - std::map dsElecId2DsDetId = buildDsElecId2DsDetIdMap(deIds); - std::map dsDetId2dsElecId; - - for (auto p : dsElecId2DsDetId) { - dsDetId2dsElecId.emplace(p.second, p.first); - } + static std::map dsDetId2dsElecId = impl::inverseMap(buildDsElecId2DsDetIdMap()); return impl::mapperDet2Elec(dsDetId2dsElecId); } template <> -std::function(uint16_t)> - createSolar2CruLinkMapper() +std::function(uint16_t)> + createSolar2FeeLinkMapper() { - std::map solarId2CruLinkId = buildSolarId2CruLinkIdMap(); - return impl::mapperSolar2CruLink(solarId2CruLinkId); + static std::map solarId2FeeLinkId = buildSolarId2FeeLinkIdMap(); + return impl::mapperSolar2FeeLink(solarId2FeeLinkId); } template <> -std::function(CruLinkId)> - createCruLink2SolarMapper() +std::function(FeeLinkId)> + createFeeLink2SolarMapper() { - std::map solarId2CruLinkId = buildSolarId2CruLinkIdMap(); - std::map cruLinkId2SolarId; - for (auto p : solarId2CruLinkId) { - cruLinkId2SolarId[p.second] = p.first; - } - return impl::mapperCruLink2Solar(cruLinkId2SolarId); + static std::map feeLinkId2SolarId = impl::inverseMap(buildSolarId2FeeLinkIdMap()); + return impl::mapperFeeLink2Solar(feeLinkId2SolarId); } } // namespace o2::mch::raw diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperImplHelper.h b/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperImplHelper.h index abfe9d36b2afe..736ef82c00ab8 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperImplHelper.h +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/ElectronicMapperImplHelper.h @@ -13,7 +13,7 @@ #include "MCHRawElecMap/DsDetId.h" #include "MCHRawElecMap/DsElecId.h" -#include "MCHRawElecMap/CruLinkId.h" +#include "MCHRawElecMap/FeeLinkId.h" #include #include #include @@ -26,7 +26,7 @@ namespace o2::mch::raw::impl { template std::function(o2::mch::raw::DsElecId)> - mapperElec2Det(const std::map& elec2det) + mapperElec2Det(const std::map& elec2det) { return [elec2det](o2::mch::raw::DsElecId id) -> std::optional { auto it = elec2det.find(encode(id)); @@ -39,7 +39,7 @@ std::function(o2::mch::raw::DsElecId)> template std::function(o2::mch::raw::DsDetId)> - mapperDet2Elec(const std::map& det2elec) + mapperDet2Elec(const std::map& det2elec) { return [det2elec](o2::mch::raw::DsDetId id) -> std::optional { auto it = det2elec.find(encode(id)); @@ -51,23 +51,23 @@ std::function(o2::mch::raw::DsDetId)> } template -std::function(uint16_t)> - mapperSolar2CruLink(const std::map& solar2cruLink) +std::function(uint16_t)> + mapperSolar2FeeLink(const std::map& solar2cruLink) { - return [solar2cruLink](uint16_t solarId) -> std::optional { + return [solar2cruLink](uint16_t solarId) -> std::optional { auto it = solar2cruLink.find(solarId); if (it == solar2cruLink.end()) { return std::nullopt; } - return decodeCruLinkId(it->second); + return decodeFeeLinkId(it->second); }; } template -std::function(CruLinkId)> - mapperCruLink2Solar(const std::map& cruLink2solar) +std::function(FeeLinkId)> + mapperFeeLink2Solar(const std::map& cruLink2solar) { - return [cruLink2solar](o2::mch::raw::CruLinkId id) -> std::optional { + return [cruLink2solar](o2::mch::raw::FeeLinkId id) -> std::optional { auto it = cruLink2solar.find(encode(id)); if (it == cruLink2solar.end()) { return std::nullopt; @@ -76,6 +76,15 @@ std::function(CruLinkId)> }; } +template +std::map inverseMap(const std::map& src) +{ + std::map dest; + for (auto p : src) { + dest.emplace(p.second, p.first); + } + return dest; +} } // namespace o2::mch::raw::impl #endif diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/FeeLinkId.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/FeeLinkId.cxx new file mode 100644 index 0000000000000..94730272aa2f3 --- /dev/null +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/FeeLinkId.cxx @@ -0,0 +1,51 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "MCHRawElecMap/FeeLinkId.h" +#include +#include + +namespace o2::mch::raw +{ +FeeLinkId::FeeLinkId(uint16_t feeId, uint8_t linkId) : mFeeId{feeId}, + mLinkId{linkId} +{ + if (mLinkId < 0 || (mLinkId > 11 && mLinkId != 15)) { + throw std::invalid_argument(fmt::format("LinkId should be between 0 and 11 or = 15 but is {}", linkId)); + } +} +uint32_t encode(const FeeLinkId& id) +{ + return (id.feeId() << 16) | id.linkId(); +} + +FeeLinkId decodeFeeLinkId(uint32_t x) +{ + uint16_t feeId = static_cast((x & 0xFFFF0000) >> 16); + uint16_t linkId = static_cast(x & 0xF); + return FeeLinkId(feeId, linkId); +} + +std::ostream& operator<<(std::ostream& os, const FeeLinkId& id) +{ + os << fmt::format("FeeLinkId(FEE={:4d},LINK={:1d}) CODE={:8d}", id.feeId(), id.linkId(), encode(id)); + return os; +} + +std::string asString(const FeeLinkId& feeLinkId) +{ + return fmt::format("FEE{}-LINK{}", feeLinkId.feeId(), feeLinkId.linkId()); +} + +bool operator<(const FeeLinkId& f1, const FeeLinkId& f2) +{ + return encode(f1) < encode(f2); +} +} // namespace o2::mch::raw diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/elecmap.py b/Detectors/MUON/MCH/Raw/ElecMap/src/elecmap.py index 7f1349a1d505c..3f246c98c6cae 100755 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/elecmap.py +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/elecmap.py @@ -74,7 +74,7 @@ def gencode_do(df, df_cru, solar_map, chamber): ''') out.write( - "void fillElec2Det{}(std::map& e2d){{".format(chamber)) + "void fillElec2Det{}(std::map& e2d){{".format(chamber)) for row in df.itertuples(): gencode_insert_row_in_map(out, row) @@ -82,12 +82,12 @@ def gencode_do(df, df_cru, solar_map, chamber): out.write("}") out.write( - "void fillSolar2CruLink{}(std::map& s2c){{".format(chamber)) + "void fillSolar2FeeLink{}(std::map& s2f){{".format(chamber)) for row in df_cru.itertuples(): if len(row.solar_id) > 0: - out.write("add_cru(s2c,{},{},{},{});\n".format( - row.cru_id, row.link_id, row.solar_id, solar_map[int(row.solar_id)])) + out.write("add_cru(s2f,{},{},{});\n".format( + row.fee_id, row.link_id, row.solar_id)) out.write("}") gencode_close_generated(out) @@ -135,12 +135,13 @@ def gs_read_sheet_cru(credential_file, workbook, sheet_name): data = wks.get_all_values() -# LINK ID CRU ID CRU LINK DWP CRU ADDR DW ADDR +# LINK ID CRU ID CRU LINK DWP CRU ADDR DW ADDR FEE ID - cols = np.array([0, 1, 2, 3, 4, 5]) + cols = np.array([0, 1, 2, 3, 4, 5,6,7]) df = pd.DataFrame(np.asarray(data)[:, cols], - columns=["solar_id", "cru_id", "link_id", - "dwp", "cru_address_0", "cru_address_1"]) + columns=["solar_id", "cru_id", "link_id", "cru_sn", + "dwp", "cru_address_0", "cru_address_1", + "fee_id"]) return df.iloc[1:] diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/gen.sh b/Detectors/MUON/MCH/Raw/ElecMap/src/gen.sh index 5f95242ba4476..2b1adbfb034e2 100755 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/gen.sh +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/gen.sh @@ -1,6 +1,6 @@ #!/bin/sh -for chamber in CH5R CH5L CH6R CH7R CH7L; do +for chamber in CH5R CH5L CH6R CH7R CH7L CH8L; do # srcdir=/Users/laurent/ownCloud/archive/2019/MRRTF/raw-data-encdec # ./elecmap.py -i ${srcdir}/Mapping-${chamber}.xlsx -c ${chamber} echo "Generating ${chamber}" diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/testDsElecId.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/testDsElecId.cxx index 137d25cc84f7a..552977def8e51 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/testDsElecId.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/testDsElecId.cxx @@ -32,6 +32,12 @@ BOOST_AUTO_TEST_CASE(DsElecId) BOOST_CHECK_EQUAL(code, encode(x.value())); } +BOOST_AUTO_TEST_CASE(DsElecIdTooBigSolarIdShouldThrow) +{ + BOOST_CHECK_THROW(o2::mch::raw::DsElecId eid(1024, 0, 1), std::invalid_argument); + BOOST_CHECK_NO_THROW(o2::mch::raw::DsElecId eid(1023, 0, 1)); +} + BOOST_AUTO_TEST_CASE(DsElecIdValidString) { o2::mch::raw::DsElecId eid(448, 6, 2); diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/testElectronicMapper.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/testElectronicMapper.cxx index e1877e4aa93a6..2745693c4c113 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/testElectronicMapper.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/testElectronicMapper.cxx @@ -79,7 +79,7 @@ std::set nofDualSampasFromMapper(gsl::span deids) { std::set ds; - auto d2e = o2::mch::raw::createDet2ElecMapper(deids); + auto d2e = o2::mch::raw::createDet2ElecMapper(); for (auto deid : deids) { size_t nref = dslist(deid).size(); @@ -91,6 +91,8 @@ std::set nofDualSampasFromMapper(gsl::span deids) auto code = o2::mch::raw::encode(id); // encode to be sure we're counting unique pairs (deid,dsid) ds.insert(code); dsForOneDE.insert(code); + } else { + std::cout << "did not find matching dsel for id=" << id << "\n"; } }; if (dsForOneDE.size() != nref) { @@ -172,6 +174,20 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(MustContainAllSampaCH7L, T, testTypes) BOOST_CHECK(std::equal(expected.begin(), expected.end(), check.begin())); } +// BOOST_AUTO_TEST_CASE_TEMPLATE(MustContainAllSampaCH8R, T, testTypes) +// { +// auto check = nofDualSampasFromMapper(o2::mch::raw::deIdsOfCH8R); +// auto expected = nofDualSampas(o2::mch::raw::deIdsOfCH8R); +// BOOST_CHECK(std::equal(expected.begin(), expected.end(), check.begin())); +// } + +BOOST_AUTO_TEST_CASE_TEMPLATE(MustContainAllSampaCH8L, T, testTypes) +{ + auto check = nofDualSampasFromMapper(o2::mch::raw::deIdsOfCH8L); + auto expected = nofDualSampas(o2::mch::raw::deIdsOfCH8L); + BOOST_CHECK(std::equal(expected.begin(), expected.end(), check.begin())); +} + BOOST_AUTO_TEST_CASE_TEMPLATE(CheckNumberOfSolarsPerDetectionElement, T, realTypes) { // Chamber 1 @@ -288,19 +304,19 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(CheckNumberOfSolarsPerDetectionElement, T, realTyp BOOST_CHECK_EQUAL(getSolarUIDs(824).size(), 0); BOOST_CHECK_EQUAL(getSolarUIDs(825).size(), 0); // 8L = 8O - BOOST_CHECK_EQUAL(getSolarUIDs(807).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(808).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(809).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(810).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(811).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(812).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(813).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(814).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(815).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(816).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(817).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(818).size(), 0); - BOOST_CHECK_EQUAL(getSolarUIDs(819).size(), 0); + BOOST_CHECK_EQUAL(getSolarUIDs(807).size(), 1); + BOOST_CHECK_EQUAL(getSolarUIDs(808).size(), 2); + BOOST_CHECK_EQUAL(getSolarUIDs(809).size(), 2); + BOOST_CHECK_EQUAL(getSolarUIDs(810).size(), 4); + BOOST_CHECK_EQUAL(getSolarUIDs(811).size(), 4); + BOOST_CHECK_EQUAL(getSolarUIDs(812).size(), 4); + BOOST_CHECK_EQUAL(getSolarUIDs(813).size(), 4); + BOOST_CHECK_EQUAL(getSolarUIDs(814).size(), 4); + BOOST_CHECK_EQUAL(getSolarUIDs(815).size(), 4); + BOOST_CHECK_EQUAL(getSolarUIDs(816).size(), 4); + BOOST_CHECK_EQUAL(getSolarUIDs(817).size(), 2); + BOOST_CHECK_EQUAL(getSolarUIDs(818).size(), 2); + BOOST_CHECK_EQUAL(getSolarUIDs(819).size(), 1); // Chamber 9 // 9R = 9I @@ -363,24 +379,28 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(CheckNumberOfSolarsPerDetectionElement, T, realTyp BOOST_CHECK_EQUAL(getSolarUIDs(1019).size(), 0); } -BOOST_AUTO_TEST_CASE_TEMPLATE(AllSolarsMustGetACruLink, T, realTypes) +BOOST_AUTO_TEST_CASE_TEMPLATE(AllSolarsMustGetAFeeLink, T, realTypes) { std::set solarIds = getSolarUIDs(); - auto solar2cruLink = o2::mch::raw::createSolar2CruLinkMapper(); + auto solar2feeLink = o2::mch::raw::createSolar2FeeLinkMapper(); int nbad{0}; for (auto s : solarIds) { - auto p = solar2cruLink(s); + auto p = solar2feeLink(s); if (!p.has_value()) { ++nbad; + std::cout << "Got no feelinkId for solarId " << s << "\n"; } - // std::cout << fmt::format("SOLAR {:4d} ", s); - // if (p.has_value()) { - // std::cout << fmt::format("CRU {:4d} LINK {:1d}\n", p->cruId(), p->linkId()); - // } else { - // std::cout << " NO DATA\n"; - // } } BOOST_CHECK_EQUAL(nbad, 0); + BOOST_CHECK_EQUAL(solarIds.size(), 192); // must be updated when adding more chambers +} + +BOOST_AUTO_TEST_CASE(SpotCheck) +{ + o2::mch::raw::FeeLinkId id(44, 0); + auto f2s = o2::mch::raw::createFeeLink2SolarMapper(); + auto s = f2s(id); + BOOST_CHECK_EQUAL(s.has_value(), true); } BOOST_AUTO_TEST_SUITE_END() diff --git a/Detectors/MUON/MCH/Raw/ElecMap/src/testCruLinkId.cxx b/Detectors/MUON/MCH/Raw/ElecMap/src/testFeeLinkId.cxx similarity index 57% rename from Detectors/MUON/MCH/Raw/ElecMap/src/testCruLinkId.cxx rename to Detectors/MUON/MCH/Raw/ElecMap/src/testFeeLinkId.cxx index 51665d1890f07..21b01565be15b 100644 --- a/Detectors/MUON/MCH/Raw/ElecMap/src/testCruLinkId.cxx +++ b/Detectors/MUON/MCH/Raw/ElecMap/src/testFeeLinkId.cxx @@ -8,39 +8,37 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#define BOOST_TEST_MODULE Test MCHRaw CruLinkId +#define BOOST_TEST_MODULE Test MCHRaw FeeLinkId #define BOOST_TEST_MAIN #define BOOST_TEST_DYN_LINK #include -#include "MCHRawElecMap/CruLinkId.h" +#include "MCHRawElecMap/FeeLinkId.h" #include using namespace o2::mch::raw; BOOST_AUTO_TEST_SUITE(o2_mch_raw) -BOOST_AUTO_TEST_SUITE(crulinkid) +BOOST_AUTO_TEST_SUITE(feelinkid) -BOOST_AUTO_TEST_CASE(CruLinkIdEncodeDecode) +BOOST_AUTO_TEST_CASE(FeeLinkIdEncodeDecode) { - uint16_t cruId{0}; - uint8_t linkId{23}; - uint16_t deId{0}; - CruLinkId cl(cruId, linkId, deId); + uint16_t feeId{0}; + uint8_t linkId{11}; + FeeLinkId cl(feeId, linkId); auto code = encode(cl); - auto x = decodeCruLinkId(code); + auto x = decodeFeeLinkId(code); BOOST_CHECK_EQUAL(code, encode(x)); } -BOOST_AUTO_TEST_CASE(CruLinkIdCtorMustThrowIfLinkIdIsInvalid) +BOOST_AUTO_TEST_CASE(FeeLinkIdCtorMustThrowIfLinkIdIsInvalid) { - uint16_t cruId{0}; - uint16_t solarId{0}; - BOOST_CHECK_THROW(CruLinkId a(cruId, 24, solarId), std::logic_error); - BOOST_CHECK_NO_THROW(CruLinkId a(cruId, 0, solarId)); - BOOST_CHECK_NO_THROW(CruLinkId a(cruId, 23, solarId)); + uint16_t feeId{0}; + BOOST_CHECK_THROW(FeeLinkId a(feeId, 24), std::logic_error); + BOOST_CHECK_NO_THROW(FeeLinkId a(feeId, 0)); + BOOST_CHECK_NO_THROW(FeeLinkId a(feeId, 11)); } BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END() diff --git a/Detectors/MUON/MCH/Raw/ImplHelpers/CMakeLists.txt b/Detectors/MUON/MCH/Raw/ImplHelpers/CMakeLists.txt index e1a8540b1872e..ab39aef6cb6d9 100644 --- a/Detectors/MUON/MCH/Raw/ImplHelpers/CMakeLists.txt +++ b/Detectors/MUON/MCH/Raw/ImplHelpers/CMakeLists.txt @@ -16,5 +16,5 @@ o2_add_header_only_library( o2_add_test(movebuffer SOURCES testMoveBuffer.cxx PUBLIC_LINK_LIBRARIES O2::MCHRawImplHelpers - COMPONENT_NAME mch - LABELS "mch;raw") + COMPONENT_NAME mchraw + LABELS "muon;mch;raw") diff --git a/Detectors/MUON/MCH/Raw/ImplHelpers/DumpBuffer.h b/Detectors/MUON/MCH/Raw/ImplHelpers/DumpBuffer.h index b6d386400218a..5dbed97355d41 100644 --- a/Detectors/MUON/MCH/Raw/ImplHelpers/DumpBuffer.h +++ b/Detectors/MUON/MCH/Raw/ImplHelpers/DumpBuffer.h @@ -19,12 +19,13 @@ #include #include "MCHRawCommon/RDHManip.h" #include "Headers/RAWDataHeader.h" +#include "MCHRawCommon/DataFormats.h" namespace o2::mch::raw::impl { template ::value, int> = 1> -void dumpBuffer(gsl::span buffer) +void dumpByteBuffer(gsl::span buffer) { int i{0}; @@ -38,7 +39,7 @@ void dumpBuffer(gsl::span buffer) std::cout << "\n"; } -uint64_t b8to64(gsl::span buffer, size_t i) +uint64_t b8to64(gsl::span buffer, size_t i) { return (static_cast(buffer[i + 0])) | (static_cast(buffer[i + 1]) << 8) | @@ -50,19 +51,23 @@ uint64_t b8to64(gsl::span buffer, size_t i) (static_cast(buffer[i + 7]) << 56); } -void append(std::vector& buffer, uint64_t w) +void append(std::vector& buffer, uint64_t w) { - buffer.emplace_back(static_cast((w & UINT64_C(0x00000000000000FF)))); - buffer.emplace_back(static_cast((w & UINT64_C(0x000000000000FF00)) >> 8)); - buffer.emplace_back(static_cast((w & UINT64_C(0x0000000000FF0000)) >> 16)); - buffer.emplace_back(static_cast((w & UINT64_C(0x00000000FF000000)) >> 24)); - buffer.emplace_back(static_cast((w & UINT64_C(0x000000FF00000000)) >> 32)); - buffer.emplace_back(static_cast((w & UINT64_C(0x0000FF0000000000)) >> 40)); - buffer.emplace_back(static_cast((w & UINT64_C(0x00FF000000000000)) >> 48)); - buffer.emplace_back(static_cast((w & UINT64_C(0xFF00000000000000)) >> 56)); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x00000000000000FF)))}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x000000000000FF00)) >> 8)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x0000000000FF0000)) >> 16)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x00000000FF000000)) >> 24)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x000000FF00000000)) >> 32)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x0000FF0000000000)) >> 40)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0x00FF000000000000)) >> 48)}); + buffer.emplace_back(std::byte{static_cast((w & UINT64_C(0xFF00000000000000)) >> 56)}); } -void dumpBuffer(gsl::span buffer, std::ostream& out = std::cout, size_t maxbytes = std::numeric_limits::max()) +template +void dumpBuffer(gsl::span buffer, std::ostream& out = std::cout, size_t maxbytes = std::numeric_limits::max()); + +template <> +void dumpBuffer(gsl::span buffer, std::ostream& out, size_t maxbytes) { int i{0}; int inRDH{0}; @@ -98,9 +103,13 @@ void dumpBuffer(gsl::span buffer, std::ostream& out = std::cout, size_t out << "End RDH "; } } else { - SampaHeader h(w & 0x3FFFFFFFFFFFF); - if (h.packetType() == SampaPacketType::Sync) { - out << "SYNC"; + constexpr uint64_t FIFTYBITSATONE = (static_cast(1) << 50) - 1; + SampaHeader h(w & FIFTYBITSATONE); + std::cout << "14first=" << ((w & 0xFFFC000000000000) >> 50) << " "; + if (h == sampaSync()) { + out << "SYNC !!"; + } else if (h.packetType() == SampaPacketType::Sync) { + out << "SYNC " << std::boolalpha << (h == sampaSync()); } else if (h.packetType() == SampaPacketType::Data) { out << fmt::format(" n10 {:4d} chip {:2d} ch {:2d}", h.nof10BitWords(), h.chipAddress(), h.channelAddress()); @@ -110,13 +119,63 @@ void dumpBuffer(gsl::span buffer, std::ostream& out = std::cout, size_t } out << "\n"; } + +template <> +void dumpBuffer(gsl::span buffer, std::ostream& out, size_t maxbytes) +{ + int i{0}; + int inRDH{0}; + o2::header::RAWDataHeaderV4 rdh; + + if (buffer.size() < 8) { + std::cout << "Should at least get 8 bytes to be able to dump\n"; + return; + } + while ((i < buffer.size() - 7) && i < maxbytes) { + if (i % 8 == 0) { + out << fmt::format("\n{:8d} : ", i); + } + uint64_t w = b8to64(buffer, i); + out << fmt::format("{:016X} {:4d} {:4d} {:4d} {:4d} {:4d} ", + w, + (w & 0x3FF0000000000) >> 40, + (w & 0xFFC0000000) >> 30, + (w & 0x3FF00000) >> 20, + (w & 0xFFC00) >> 10, + (w & 0x3FF)); + if ((w & 0xFFFF) == 0x4004) { + inRDH = 8; + } + if (inRDH) { + --inRDH; + if (inRDH == 7) { + out << "Begin RDH "; + rdh = o2::mch::raw::createRDH(buffer.subspan(i, 64)); + std::cout << fmt::format("ORBIT {} BX {} PAYLOADSIZE {}", rdhOrbit(rdh), rdhBunchCrossing(rdh), rdhPayloadSize(rdh)); + } + if (inRDH == 0) { + out << "End RDH "; + } + } else { + constexpr uint64_t FIFTYBITSATONE = (static_cast(1) << 50) - 1; + SampaHeader h(w & FIFTYBITSATONE); + if (h == sampaSync()) { + out << "SYNC !!"; + } + } + i += 8; + } + out << "\n"; +} + +template void dumpBuffer(const std::vector& buffer, std::ostream& out = std::cout, size_t maxbytes = std::numeric_limits::max()) { - std::vector b8; + std::vector b8; for (auto w : buffer) { append(b8, w); } - dumpBuffer(b8, out, maxbytes); + dumpBuffer(b8, out, maxbytes); } } // namespace o2::mch::raw::impl diff --git a/Detectors/MUON/MCH/Raw/ImplHelpers/MoveBuffer.h b/Detectors/MUON/MCH/Raw/ImplHelpers/MoveBuffer.h index 3c846b9bcf88d..c2abe8abb4fc1 100644 --- a/Detectors/MUON/MCH/Raw/ImplHelpers/MoveBuffer.h +++ b/Detectors/MUON/MCH/Raw/ImplHelpers/MoveBuffer.h @@ -21,7 +21,7 @@ namespace o2::mch::raw::impl /// Copy the content of b64 to b8 /// Returns the number of bytes copied into b8. size_t copyBuffer(const std::vector& b64, - std::vector& b8, + std::vector& b8, uint64_t prefix = 0) { constexpr uint64_t m = 0xFF; @@ -31,7 +31,7 @@ size_t copyBuffer(const std::vector& b64, uint64_t g = b | prefix; for (uint64_t i = 0; i < 64; i += 8) { uint64_t w = m << i; - b8.emplace_back(static_cast((g & w) >> i)); + b8.emplace_back(std::byte{static_cast((g & w) >> i)}); } } return b8.size() - s8; @@ -40,7 +40,7 @@ size_t copyBuffer(const std::vector& b64, /// Move the content of b64 to b8 and clears b64. /// Returns the number of bytes moved into b8. size_t moveBuffer(std::vector& b64, - std::vector& b8, + std::vector& b8, uint64_t prefix = 0) { auto s = copyBuffer(b64, b8, prefix); diff --git a/Detectors/MUON/MCH/Raw/ImplHelpers/testMoveBuffer.cxx b/Detectors/MUON/MCH/Raw/ImplHelpers/testMoveBuffer.cxx index dc07f704760dc..dadf6ba283c2c 100644 --- a/Detectors/MUON/MCH/Raw/ImplHelpers/testMoveBuffer.cxx +++ b/Detectors/MUON/MCH/Raw/ImplHelpers/testMoveBuffer.cxx @@ -26,10 +26,12 @@ BOOST_AUTO_TEST_CASE(MoveBuffer) std::vector b64; b64.emplace_back(0x0706050403020100); b64.emplace_back(0x0F0E0D0C0B0A0908); - std::vector b8; + std::vector b8; impl::moveBuffer(b64, b8); - std::vector expected = {0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15}; + std::vector expected; + for (uint8_t i = 0; i < 16; i++) { + expected.emplace_back(std::byte{i}); + } BOOST_CHECK_EQUAL(b8.size(), expected.size()); BOOST_CHECK(b8 == expected); } diff --git a/Detectors/MUON/MCH/Raw/Tools/CMakeLists.txt b/Detectors/MUON/MCH/Raw/Tools/CMakeLists.txt index c5ef1ab9db2c5..c92bc33677886 100644 --- a/Detectors/MUON/MCH/Raw/Tools/CMakeLists.txt +++ b/Detectors/MUON/MCH/Raw/Tools/CMakeLists.txt @@ -9,9 +9,9 @@ # submit itself to any jurisdiction. o2_add_executable( - rawdump + dump SOURCES rawdump.cxx - COMPONENT_NAME mch + COMPONENT_NAME mchraw PUBLIC_LINK_LIBRARIES O2::MCHRawDecoder Boost::program_options O2::MCHRawImplHelpers RapidJSON::RapidJSON) diff --git a/Detectors/MUON/MCH/Raw/Tools/README.md b/Detectors/MUON/MCH/Raw/Tools/README.md index dc275d8097795..6e84cb2cbbc74 100644 --- a/Detectors/MUON/MCH/Raw/Tools/README.md +++ b/Detectors/MUON/MCH/Raw/Tools/README.md @@ -6,23 +6,25 @@ ## Raw Dump -The `o2-mch-rawdump` executable reads events from a raw data file and computes +The `o2-mchraw-dump` executable reads events from a raw data file and computes the mean and sigma of the data of each channel. +The data format (Bare or UserLogic) is deduced from the data itself. + +Until the data is completely self-consistent though (when we'll move to RDH v5 +or 6), you'll have to provide the CRU id with the `--cru` option. + ```bash -> o2-mch-rawdump -h +> o2-mchraw-dump -h Generic options: -h [ --help ] produce help message -i [ --input-file ] arg input file name -n [ --nrdhs ] arg number of RDHs to go through -s [ --showRDHs ] show RDHs - -u [ --userLogic ] user logic format - -c [ --chargeSum ] charge sum format -j [ --json ] output means and rms in json format - -d [ --de ] arg detection element id of the data to be decoded --cru arg force cruId -> o2-mch-rawdump -i $HOME/cernbox/o2muon/data-DE617.raw -j -n 10000 -cru 0 +> o2-mchraw-dump -i $HOME/cernbox/o2muon/data-DE617.raw -j -n 10000 -cru 0 ``` Note that options `-j` and `-s` are incompatible (as the rdh output is not in diff --git a/Detectors/MUON/MCH/Raw/Tools/rawdump.cxx b/Detectors/MUON/MCH/Raw/Tools/rawdump.cxx index ec76e3c26972c..723f3cb01f516 100644 --- a/Detectors/MUON/MCH/Raw/Tools/rawdump.cxx +++ b/Detectors/MUON/MCH/Raw/Tools/rawdump.cxx @@ -14,10 +14,9 @@ #include "DumpBuffer.h" #include "Headers/RAWDataHeader.h" #include "MCHRawCommon/DataFormats.h" -#include "MCHRawDecoder/Decoder.h" +#include "MCHRawDecoder/PageDecoder.h" #include "MCHRawElecMap/Mapper.h" #include "boost/program_options.hpp" -#include #include #include #include @@ -27,10 +26,15 @@ #include #include #include +#include +#include namespace po = boost::program_options; +namespace o2::header +{ extern std::ostream& operator<<(std::ostream&, const o2::header::RAWDataHeaderV4&); +} using namespace o2::mch::raw; using RDHv4 = o2::header::RAWDataHeaderV4; @@ -38,13 +42,9 @@ using RDHv4 = o2::header::RAWDataHeaderV4; class DumpOptions { public: - DumpOptions(unsigned int deId, unsigned int maxNofRDHs, bool showRDHs, bool jsonOutput) - : mDeId{deId}, mMaxNofRDHs{maxNofRDHs == 0 ? std::numeric_limits::max() : maxNofRDHs}, mShowRDHs{showRDHs}, mJSON{jsonOutput} {} + DumpOptions(unsigned int maxNofRDHs, bool showRDHs, bool jsonOutput) + : mMaxNofRDHs{maxNofRDHs == 0 ? std::numeric_limits::max() : maxNofRDHs}, mShowRDHs{showRDHs}, mJSON{jsonOutput} {} - unsigned int deId() const - { - return mDeId; - } unsigned int maxNofRDHs() const { return mMaxNofRDHs; @@ -68,18 +68,18 @@ class DumpOptions void cruId(uint16_t c) { mCruId = c; } private: - unsigned int mDeId; unsigned int mMaxNofRDHs; bool mShowRDHs; bool mJSON; std::optional mCruId{std::nullopt}; }; -struct Stat { +struct ChannelStat { double mean{0}; double rms{0}; double q{0}; int n{0}; + void incr(int v) { n++; @@ -90,13 +90,13 @@ struct Stat { } }; -std::ostream& operator<<(std::ostream& os, const Stat& s) +std::ostream& operator<<(std::ostream& os, const ChannelStat& s) { os << fmt::format("MEAN {:7.3f} RMS {:7.3f} NSAMPLES {:5d} ", s.mean, s.rms, s.n); return os; } -template -std::map rawdump(std::string input, DumpOptions opt) + +std::map rawdump(std::string input, DumpOptions opt) { std::ifstream in(input.c_str(), std::ios::binary); if (!in.good()) { @@ -105,75 +105,74 @@ std::map rawdump(std::string input, DumpOptions opt) } constexpr size_t pageSize = 8192; - std::array buffer; - gsl::span sbuffer(buffer); - - size_t ndigits{0}; - - std::map uniqueDS; - std::map uniqueChannel; - std::map statChannel; - - memset(&buffer[0], 0, buffer.size()); - auto channelHandler = [&ndigits, &uniqueDS, &uniqueChannel, &statChannel](DsElecId dsId, - uint8_t channel, o2::mch::raw::SampaCluster sc) { - auto s = asString(dsId); - uniqueDS[s]++; - auto ch = fmt::format("{}-CH{}", s, channel); - uniqueChannel[ch]++; - auto& stat = statChannel[ch]; - for (auto d = 0; d < sc.nofSamples(); d++) { - stat.incr(sc.samples[d]); - } - ++ndigits; - }; - - auto cruLink2solar = o2::mch::raw::createCruLink2SolarMapper(); + std::array buffer; + gsl::span page(buffer); size_t nrdhs{0}; - auto rdhHandler = [&](const RDH& rdh) -> std::optional { + const auto patchPage = [&](gsl::span rdhBuffer) { + auto rdhPtr = reinterpret_cast(&rdhBuffer[0]); + auto& rdh = *rdhPtr; nrdhs++; - if (opt.showRDHs()) { - std::cout << nrdhs << "--" << rdh << "\n"; - } - auto r = rdh; - auto cruId = r.cruID; + auto cruId = rdhCruId(rdh); if (opt.cruId().has_value()) { - // force cruId to externally given value cruId = opt.cruId().value(); + rdhLinkId(rdh, 0); } - auto linkId = rdhLinkId(r); - auto solar = cruLink2solar(o2::mch::raw::CruLinkId(cruId, linkId, opt.deId())); - if (!solar.has_value()) { - std::cout << fmt::format("ERROR - Could not get solarUID from CRU,LINK=({},{},{})\n", - cruId, linkId, opt.deId()); - return std::nullopt; + rdhFeeId(rdh, cruId * 2 + rdhEndpoint(rdh)); + if (opt.showRDHs()) { + std::cout << nrdhs << "--" << rdh << "\n"; } - r.feeId = solar.value(); - return r; }; - o2::mch::raw::Decoder decode = o2::mch::raw::createDecoder(rdhHandler, channelHandler); - - std::vector timers; + struct Counters { + std::map uniqueDS; + std::map uniqueChannel; + std::map statChannel; + int ndigits{0}; + } counters; + + const auto channelHandler = + [&](DsElecId dsId, uint8_t channel, o2::mch::raw::SampaCluster sc) { + auto s = asString(dsId); + counters.uniqueDS[s]++; + auto ch = fmt::format("{}-CH{}", s, channel); + counters.uniqueChannel[ch]++; + auto& chanstat = counters.statChannel[ch]; + if (sc.isClusterSum()) { + chanstat.incr(sc.chargeSum); + } else { + for (auto d = 0; d < sc.nofSamples(); d++) { + chanstat.incr(sc.samples[d]); + } + } + counters.ndigits++; + }; + + o2::mch::raw::PageDecoder decode = nullptr; size_t npages{0}; - DecoderStat decStat; + uint64_t bytesRead{0}; - while (npages < opt.maxNofRDHs() && in.read(reinterpret_cast(&buffer[0]), pageSize)) { + // warning : we currently assume fixed-size pages for reading the file... + while (npages < opt.maxNofRDHs() && in.read(reinterpret_cast(&buffer[0]), pageSize) && in.gcount() == pageSize) { npages++; - decStat = decode(sbuffer); + bytesRead += in.gcount(); + if (!decode) { + decode = createPageDecoder(page, channelHandler); + } + patchPage(buffer); + decode(page); } if (!opt.json()) { - std::cout << ndigits << " digits seen - " << nrdhs << " RDHs seen - " << npages << " npages read\n"; - std::cout << "#unique DS=" << uniqueDS.size() << " #unique Channel=" << uniqueChannel.size() << "\n"; - std::cout << decStat << "\n"; + std::cout << counters.ndigits << " digits seen - " << nrdhs << " RDHs seen - " << npages << " npages read\n"; + std::cout << "#unique DS=" << counters.uniqueDS.size() << " #unique Channel=" << counters.uniqueChannel.size() << "\n"; } - return statChannel; + + return counters.statChannel; } -void output(const std::map& channels) +void output(const std::map& channels) { rapidjson::StringBuffer buffer; rapidjson::Writer writer(buffer); @@ -206,7 +205,6 @@ int main(int argc, char* argv[]) po::variables_map vm; po::options_description generic("Generic options"); unsigned int nrdhs{0}; - unsigned int deId{0}; bool showRDHs{false}; bool userLogic{false}; // default format is bareformat... bool chargeSum{false}; //... in sample mode @@ -218,10 +216,8 @@ int main(int argc, char* argv[]) ("input-file,i", po::value(&inputFile)->required(), "input file name") ("nrdhs,n", po::value(&nrdhs), "number of RDHs to go through") ("showRDHs,s",po::bool_switch(&showRDHs),"show RDHs") - ("userLogic,u",po::bool_switch(&userLogic),"user logic format") ("chargeSum,c",po::bool_switch(&chargeSum),"charge sum format") ("json,j",po::bool_switch(&jsonOutput),"output means and rms in json format") - ("de,d",po::value(&deId)->required(),"detection element id of the data to be decoded") ("cru",po::value(),"force cruId") ; // clang-format on @@ -243,25 +239,13 @@ int main(int argc, char* argv[]) exit(1); } - DumpOptions opt(deId, nrdhs, showRDHs, jsonOutput); - std::map statChannel; + DumpOptions opt(nrdhs, showRDHs, jsonOutput); if (vm.count("cru")) { opt.cruId(vm["cru"].as()); } - if (userLogic) { - if (chargeSum) { - statChannel = rawdump(inputFile, opt); - } else { - statChannel = rawdump(inputFile, opt); - } - } else { - if (chargeSum) { - statChannel = rawdump(inputFile, opt); - } else { - statChannel = rawdump(inputFile, opt); - } - } + + auto statChannel = rawdump(inputFile, opt); if (jsonOutput) { output(statChannel); diff --git a/Detectors/MUON/MCH/Raw/testdata/RefBufferCRU.cxx b/Detectors/MUON/MCH/Raw/testdata/RefBufferCRU.cxx index beab0204c47b8..81cb6525fe814 100644 --- a/Detectors/MUON/MCH/Raw/testdata/RefBufferCRU.cxx +++ b/Detectors/MUON/MCH/Raw/testdata/RefBufferCRU.cxx @@ -12,21 +12,20 @@ #include #include "MCHRawCommon/DataFormats.h" -extern std::array REF_BUFFER_CRU_BARE_CHARGESUM; +extern std::array REF_BUFFER_CRU_BARE_CHARGESUM; template <> -std::vector REF_BUFFER_CRU() +gsl::span REF_BUFFER_CRU() { - return std::vector(REF_BUFFER_CRU_BARE_CHARGESUM.begin(), REF_BUFFER_CRU_BARE_CHARGESUM.end()); + return gsl::span(reinterpret_cast(&REF_BUFFER_CRU_BARE_CHARGESUM[0]), REF_BUFFER_CRU_BARE_CHARGESUM.size()); } - -std::array REF_BUFFER_CRU_BARE_CHARGESUM = { +std::array REF_BUFFER_CRU_BARE_CHARGESUM = { // clang-format off -0x04, 0x40, 0x60, 0x04, 0xD8, 0x02, 0x00, 0x00, 0xA0, 0x04, 0xA0, 0x04, -0x00, 0x00, 0x03, 0x00, 0x39, 0x30, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0xA6, 0x02, +0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, +0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -60,125 +59,33 @@ std::array REF_BUFFER_CRU_BARE_CHARGESUM = { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xBF, 0xFF, 0xFF, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x6A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7F, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0xD0, 0x0C, -0x69, 0x01, 0x00, 0x00, 0x10, 0x0D, 0x10, 0x0D, 0x00, 0x00, 0x0B, 0x00, -0x39, 0x30, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x8E, 0x03, 0x8E, 0x03, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, +0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA9, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -191,15 +98,19 @@ std::array REF_BUFFER_CRU_BARE_CHARGESUM = { 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -238,80 +149,96 @@ std::array REF_BUFFER_CRU_BARE_CHARGESUM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, +0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, +0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, +0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA9, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, @@ -350,67 +277,67 @@ std::array REF_BUFFER_CRU_BARE_CHARGESUM = { 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, +0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, +0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, +0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0xD0, 0x00, 0x07, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA9, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x70, 0x12, 0xC0, 0x01, 0x00, 0x00, -0xB0, 0x12, 0xB0, 0x12, 0x00, 0x00, 0x17, 0x00, 0x39, 0x30, 0x00, 0x00, -0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x8E, 0x03, 0x8E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA8, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -418,142 +345,242 @@ std::array REF_BUFFER_CRU_BARE_CHARGESUM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, +0x00, 0x02, 0x40, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, +0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, +0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -591,9 +618,13 @@ std::array REF_BUFFER_CRU_BARE_CHARGESUM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, @@ -604,68 +635,80 @@ std::array REF_BUFFER_CRU_BARE_CHARGESUM = { 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAB, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, +0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, @@ -703,61 +746,73 @@ std::array REF_BUFFER_CRU_BARE_CHARGESUM = { 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAB, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFD, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFC, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, @@ -770,15 +825,19 @@ std::array REF_BUFFER_CRU_BARE_CHARGESUM = { 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, +0x1B, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -798,198 +857,364 @@ std::array REF_BUFFER_CRU_BARE_CHARGESUM = { 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x04, 0x40, 0xC0, 0x08, 0xD8, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x09, -0x00, 0x00, 0x03, 0x00, 0x39, 0x30, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x03, 0x8E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, +0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0B, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x40, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x6A, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x6A, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, +0x1E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x26, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA6, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x33, 0xFF, 0xFF, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x3B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, +0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3B, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x62, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xE2, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x62, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xA6, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA6, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x26, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x33, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA6, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x40, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF3, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, -0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x73, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF3, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x33, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, +0x1E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x26, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xE2, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA6, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xEA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xFF, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAE, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xFF, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, +0x00, 0x02, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xA6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0xE2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xE2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, +0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xBF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0xA6, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, -0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0xA6, 0xAA, 0xAA, +0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0xA2, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, +0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x40, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x30, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // clang-format on - }; diff --git a/Detectors/MUON/MCH/Raw/testdata/RefBufferGBT.cxx b/Detectors/MUON/MCH/Raw/testdata/RefBufferGBT.cxx index f1412a6b1ad77..c1d9a0aec5c56 100644 --- a/Detectors/MUON/MCH/Raw/testdata/RefBufferGBT.cxx +++ b/Detectors/MUON/MCH/Raw/testdata/RefBufferGBT.cxx @@ -12,22 +12,22 @@ #include "MCHRawCommon/DataFormats.h" #include -extern std::array REF_BUFFER_GBT_BARE_CHARGESUM; -extern std::array REF_BUFFER_GBT_USER_LOGIC_CHARGESUM; +extern std::array REF_BUFFER_GBT_BARE_CHARGESUM; +extern std::array REF_BUFFER_GBT_USER_LOGIC_CHARGESUM; template <> -std::vector REF_BUFFER_GBT() +gsl::span REF_BUFFER_GBT() { - return {REF_BUFFER_GBT_BARE_CHARGESUM.begin(), REF_BUFFER_GBT_BARE_CHARGESUM.end()}; + return gsl::span(reinterpret_cast(&REF_BUFFER_GBT_BARE_CHARGESUM[0]), REF_BUFFER_GBT_BARE_CHARGESUM.size()); } template <> -std::vector REF_BUFFER_GBT() +gsl::span REF_BUFFER_GBT() { - return {REF_BUFFER_GBT_USER_LOGIC_CHARGESUM.begin(), REF_BUFFER_GBT_USER_LOGIC_CHARGESUM.end()}; + return {reinterpret_cast(&REF_BUFFER_GBT_USER_LOGIC_CHARGESUM[0]), REF_BUFFER_GBT_USER_LOGIC_CHARGESUM.size()}; } -std::array REF_BUFFER_GBT_BARE_CHARGESUM = +std::array REF_BUFFER_GBT_BARE_CHARGESUM = { // clang-format off 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, @@ -246,7 +246,7 @@ std::array REF_BUFFER_GBT_BARE_CHARGESUM = 0x00, 0x00, 0x00, 0x00 // clang-format on }; -std::array REF_BUFFER_GBT_USER_LOGIC_CHARGESUM = +std::array REF_BUFFER_GBT_USER_LOGIC_CHARGESUM = { // clang-format off 0x13, 0x01, 0xF0, 0x40, 0x55, 0x55, 0x01, 0xB8, 0x0C, 0x12, 0x00, 0x00, diff --git a/Detectors/MUON/MCH/Raw/testdata/RefBuffers.h b/Detectors/MUON/MCH/Raw/testdata/RefBuffers.h index ee5d6cd186dda..27d677767af87 100644 --- a/Detectors/MUON/MCH/Raw/testdata/RefBuffers.h +++ b/Detectors/MUON/MCH/Raw/testdata/RefBuffers.h @@ -11,13 +11,13 @@ #ifndef O2_MCH_RAW_TEST_REF_BUFFERS_H #define O2_MCH_RAW_TEST_REF_BUFFERS_H -#include -#include +#include +#include template -extern std::vector REF_BUFFER_GBT(); +extern gsl::span REF_BUFFER_GBT(); template -extern std::vector REF_BUFFER_CRU(); +extern gsl::span REF_BUFFER_CRU(); #endif diff --git a/Testing/Temporary/CTestCostData.txt b/Testing/Temporary/CTestCostData.txt deleted file mode 100644 index ed97d539c095c..0000000000000 --- a/Testing/Temporary/CTestCostData.txt +++ /dev/null @@ -1 +0,0 @@ ----