diff --git a/Event/LumiEvent/CMakeLists.txt b/Event/LumiEvent/CMakeLists.txt index d2259cdd377351c0e84a948ffd28b1e50c4bd87f..c2317d50099f747473e34b4b5a69073b85257953 100644 --- a/Event/LumiEvent/CMakeLists.txt +++ b/Event/LumiEvent/CMakeLists.txt @@ -18,15 +18,6 @@ gaudi_add_header_only_library(LumiEventLib Gaudi::GaudiKernel ) -gaudi_add_module(LumiEvent - SOURCES - src/HltLumiSummaryDecoder.cpp - LINK - LHCb::LHCbAlgsLib - LHCb::DAQEventLib - LHCb::LumiEventLib -) - gaudi_add_dictionary(LumiEventDict HEADERFILES dict/dictionary.h SELECTION dict/selection.xml diff --git a/Event/LumiEvent/include/Event/HltLumiSummary.h b/Event/LumiEvent/include/Event/HltLumiSummary.h index c7832c410e99123bd218285ded8184b383955667..4e60776eea45fbf92cce868e79d30fe4d69cf568 100644 --- a/Event/LumiEvent/include/Event/HltLumiSummary.h +++ b/Event/LumiEvent/include/Event/HltLumiSummary.h @@ -18,7 +18,7 @@ namespace LHCb { // Forward declarations // Class ID definition - static const CLID CLID_HltLumiSummary = 7520; + static const CLID CLID_HltLumiSummary = 7540; // Namespace for locations in TDS namespace HltLumiSummaryLocation { @@ -36,7 +36,7 @@ namespace LHCb { class HltLumiSummary final : public DataObject { public: /// User information - typedef GaudiUtils::VectorMap<int, int> ExtraInfo; + typedef GaudiUtils::VectorMap<std::string, int> ExtraInfo; /// Default Constructor HltLumiSummary() = default; @@ -55,21 +55,21 @@ namespace LHCb { const ExtraInfo& extraInfo() const { return m_extraInfo; } /// has information for specified key - bool hasInfo( int key ) const { return m_extraInfo.end() != m_extraInfo.find( key ); } + bool hasInfo( std::string const& key ) const { return m_extraInfo.end() != m_extraInfo.find( key ); } /// Add new information associated with the specified key. This method cannot be used to modify information for a /// pre-existing key. - bool addInfo( int key, int info ) { return m_extraInfo.insert( key, info ).second; } + bool addInfo( std::string const& key, int info ) { return m_extraInfo.insert( key, info ).second; } /// extract the information associated with the given key. If there is no such infomration the default value will be /// returned. - int info( const int key, const int def ) const { + int info( const std::string& key, const int def ) const { auto i = m_extraInfo.find( key ); return m_extraInfo.end() == i ? def : i->second; } /// erase the information associated with the given key - unsigned long eraseInfo( int key ) { return m_extraInfo.erase( key ); } + unsigned long eraseInfo( std::string const& key ) { return m_extraInfo.erase( key ); } /// Update Some addtional user information. Don't use directly. Use *Info() methods. HltLumiSummary& setExtraInfo( ExtraInfo value ) { diff --git a/Event/LumiEvent/include/Event/LumiCounters.h b/Event/LumiEvent/include/Event/LumiCounters.h deleted file mode 100644 index fc775ae0880145de71e123792a1130f101a0c559..0000000000000000000000000000000000000000 --- a/Event/LumiEvent/include/Event/LumiCounters.h +++ /dev/null @@ -1,217 +0,0 @@ -/*****************************************************************************\ -* (c) Copyright 2000-2019 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the GNU General Public * -* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * -* * -* In applying this licence, 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. * -\*****************************************************************************/ -#pragma once -#include "GaudiKernel/DataObject.h" -#include "GaudiKernel/VectorMap.h" -#include <algorithm> -#include <ostream> - -namespace LHCb { - - // Forward declarations - - // Class ID definition - static const CLID CLID_LumiCounters = 13500; - - /** @class LumiCounters LumiCounters.h - * - * Enum class for Lumi counters - * - * @author Jaap Panman - * - */ - - class LumiCounters final { - public: - /// lookup table for counter keys - enum counterKey { - PUMult = 0, // number of PU hits - RZVelo = 1, // number of Velo tracks - RZVeloBW = 2, // number of backward RZVelo tracks - Velo = 3, // number of Velo tracks pointing to IR - Muon = 4, // number of muon tracks - BKMuon = 5, // number of muon tracks NOT pointing to PV - SPDMult = 6, // number of SPD hits - CaloEt = 7, // Calo Et - TTIP = 8, // number of TT tracks from the IP - TTMIB = 9, // number of TT tracks parallel with beam - PV2D = 10, // number of 2D vertices - PV3D = 11, // number of 3D vertices - PU = 13, // number of PU vertices - Vertex = 14, // number of vertices accepted in IR - Method = 20, // method: 0 or missing is random method - Random = 21, // random method: 0 or missing is L0 method - PoissonPUMult = 50, // number of times PU hits over threshold - PoissonRZVelo = 51, // number of times Velo tracks over threshold - PoissonRZVeloBW = 52, // number of times backward RZVelo tracks over threshold - PoissonVelo = 53, // number of times Velo tracks pointing to IR over threshold - PoissonMuon = 54, // number of times muon tracks over threshold - PoissonBKMuon = 55, // number of times muon tracks NOT pointing to PV over threshold - PoissonSPDMult = 56, // number of times SPD hits over threshold - PoissonCaloEt = 57, // number of times Calo Et over threshold - PoissonTTIP = 58, // number of timesTT tracks from the IP over threshold - PoissonTTMIB = 59, // number of timesTT tracks parallel with beam over threshold - PoissonPV2D = 60, // number of times2D vertices over threshold - PoissonPV3D = 61, // number of times 3D vertices over threshold - PoissonPU = 63, // number of times PU vertices over threshold - PoissonVertex = 64, // number of times vertices in IR range over threshold - PoissonMethod = 70, // method: 0 or missing is random method - PoissonRandom = 71, // random method: 0 or missing is L0 method - Unknown = 98, // unknown value - LastGlobal = 99 // User variables should use flags greater than this value - }; - - LumiCounters() = delete; // class contains no data, so no use to instantiate it... - - /// conversion of string to enum for type counterKey - static LHCb::LumiCounters::counterKey counterKeyToType( const std::string& aName ); - - /// conversion to string for enum type counterKey - static const std::string& counterKeyToString( int aEnum ); - - private: - static const GaudiUtils::VectorMap<std::string, counterKey>& s_counterKeyTypMap(); - - }; // class LumiCounters - - inline std::ostream& operator<<( std::ostream& s, LHCb::LumiCounters::counterKey e ) { - switch ( e ) { - case LHCb::LumiCounters::PUMult: - return s << "PUMult"; - case LHCb::LumiCounters::RZVelo: - return s << "RZVelo"; - case LHCb::LumiCounters::RZVeloBW: - return s << "RZVeloBW"; - case LHCb::LumiCounters::Velo: - return s << "Velo"; - case LHCb::LumiCounters::Muon: - return s << "Muon"; - case LHCb::LumiCounters::BKMuon: - return s << "BKMuon"; - case LHCb::LumiCounters::SPDMult: - return s << "SPDMult"; - case LHCb::LumiCounters::CaloEt: - return s << "CaloEt"; - case LHCb::LumiCounters::TTIP: - return s << "TTIP"; - case LHCb::LumiCounters::TTMIB: - return s << "TTMIB"; - case LHCb::LumiCounters::PV2D: - return s << "PV2D"; - case LHCb::LumiCounters::PV3D: - return s << "PV3D"; - case LHCb::LumiCounters::PU: - return s << "PU"; - case LHCb::LumiCounters::Vertex: - return s << "Vertex"; - case LHCb::LumiCounters::Method: - return s << "Method"; - case LHCb::LumiCounters::Random: - return s << "Random"; - case LHCb::LumiCounters::PoissonPUMult: - return s << "PoissonPUMult"; - case LHCb::LumiCounters::PoissonRZVelo: - return s << "PoissonRZVelo"; - case LHCb::LumiCounters::PoissonRZVeloBW: - return s << "PoissonRZVeloBW"; - case LHCb::LumiCounters::PoissonVelo: - return s << "PoissonVelo"; - case LHCb::LumiCounters::PoissonMuon: - return s << "PoissonMuon"; - case LHCb::LumiCounters::PoissonBKMuon: - return s << "PoissonBKMuon"; - case LHCb::LumiCounters::PoissonSPDMult: - return s << "PoissonSPDMult"; - case LHCb::LumiCounters::PoissonCaloEt: - return s << "PoissonCaloEt"; - case LHCb::LumiCounters::PoissonTTIP: - return s << "PoissonTTIP"; - case LHCb::LumiCounters::PoissonTTMIB: - return s << "PoissonTTMIB"; - case LHCb::LumiCounters::PoissonPV2D: - return s << "PoissonPV2D"; - case LHCb::LumiCounters::PoissonPV3D: - return s << "PoissonPV3D"; - case LHCb::LumiCounters::PoissonPU: - return s << "PoissonPU"; - case LHCb::LumiCounters::PoissonVertex: - return s << "PoissonVertex"; - case LHCb::LumiCounters::PoissonMethod: - return s << "PoissonMethod"; - case LHCb::LumiCounters::PoissonRandom: - return s << "PoissonRandom"; - case LHCb::LumiCounters::Unknown: - return s << "Unknown"; - case LHCb::LumiCounters::LastGlobal: - return s << "LastGlobal"; - default: - return s << "ERROR wrong value " << int( e ) << " for enum LHCb::LumiCounters::counterKey"; - } - } - -} // namespace LHCb - -// ----------------------------------------------------------------------------- -// end of class -// ----------------------------------------------------------------------------- - -// Including forward declarations - -inline const GaudiUtils::VectorMap<std::string, LHCb::LumiCounters::counterKey>& -LHCb::LumiCounters::s_counterKeyTypMap() { - static const GaudiUtils::VectorMap<std::string, counterKey> m = {{"PUMult", PUMult}, - {"RZVelo", RZVelo}, - {"RZVeloBW", RZVeloBW}, - {"Velo", Velo}, - {"Muon", Muon}, - {"BKMuon", BKMuon}, - {"SPDMult", SPDMult}, - {"CaloEt", CaloEt}, - {"TTIP", TTIP}, - {"TTMIB", TTMIB}, - {"PV2D", PV2D}, - {"PV3D", PV3D}, - {"PU", PU}, - {"Vertex", Vertex}, - {"Method", Method}, - {"Random", Random}, - {"PoissonPUMult", PoissonPUMult}, - {"PoissonRZVelo", PoissonRZVelo}, - {"PoissonRZVeloBW", PoissonRZVeloBW}, - {"PoissonVelo", PoissonVelo}, - {"PoissonMuon", PoissonMuon}, - {"PoissonBKMuon", PoissonBKMuon}, - {"PoissonSPDMult", PoissonSPDMult}, - {"PoissonCaloEt", PoissonCaloEt}, - {"PoissonTTIP", PoissonTTIP}, - {"PoissonTTMIB", PoissonTTMIB}, - {"PoissonPV2D", PoissonPV2D}, - {"PoissonPV3D", PoissonPV3D}, - {"PoissonPU", PoissonPU}, - {"PoissonVertex", PoissonVertex}, - {"PoissonMethod", PoissonMethod}, - {"PoissonRandom", PoissonRandom}, - {"Unknown", Unknown}, - {"LastGlobal", LastGlobal}}; - return m; -} - -inline LHCb::LumiCounters::counterKey LHCb::LumiCounters::counterKeyToType( const std::string& aName ) { - auto iter = s_counterKeyTypMap().find( aName ); - return iter != s_counterKeyTypMap().end() ? iter->second : Unknown; -} - -inline const std::string& LHCb::LumiCounters::counterKeyToString( int aEnum ) { - static const std::string s_Unknown = "Unknown"; - auto iter = std::find_if( s_counterKeyTypMap().begin(), s_counterKeyTypMap().end(), - [&]( const std::pair<const std::string, counterKey>& i ) { return i.second == aEnum; } ); - return iter != s_counterKeyTypMap().end() ? iter->first : s_Unknown; -} diff --git a/Event/LumiEvent/src/HltLumiSummaryDecoder.cpp b/Event/LumiEvent/src/HltLumiSummaryDecoder.cpp deleted file mode 100644 index ba2f8355a07242abfc0feff765795d5f83ee0d47..0000000000000000000000000000000000000000 --- a/Event/LumiEvent/src/HltLumiSummaryDecoder.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/*****************************************************************************\ -* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * -* * -* This software is distributed under the terms of the GNU General Public * -* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * -* * -* In applying this licence, 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 "Event/HltLumiSummary.h" -#include "Event/RawBank.h" -#include "Event/RawEvent.h" - -#include "LHCbAlgs/Transformer.h" - -#include "Gaudi/Accumulators.h" - -#include <algorithm> -#include <string> - -namespace LHCb { - - /** - * Decodes the LumiSummary. - * - * @author Jaap Panman - * HenryIII Changed to use Transform Algorithm - * - * @date 2008-08-01 - */ - - class HltLumiSummaryDecoder : public Algorithm::Transformer<HltLumiSummary( const RawEvent& )> { - public: - /// Standard constructor - HltLumiSummaryDecoder( const std::string& name, ISvcLocator* pSvcLocator ) - : Transformer( name, pSvcLocator, - KeyValue{"RawEventLocations", Gaudi::Functional::concat_alternatives( - RawEventLocation::Trigger, RawEventLocation::Default )}, - KeyValue{"OutputContainerName", HltLumiSummaryLocation::Default} ) {} - - HltLumiSummary operator()( const RawEvent& event ) const override { - - HltLumiSummary hltLumiSummary; - - // Get the buffers associated with the HltLumiSummary - // Now copy the information from all banks (normally there should only be one) - auto size_buffer = m_totDataSize.buffer(); - for ( const auto& ibank : event.banks( RawBank::HltLumiSummary ) ) { - // get the raw data - for ( const unsigned w : ibank->range<unsigned int>() ) { - // decode the info - int iKey = ( w >> 16 ); - int iVal = ( w & 0xFFFF ); - if ( msgLevel( MSG::VERBOSE ) ) { verbose() << format( " %8x %11d %11d %11d ", w, w, iKey, iVal ) << endmsg; } - // add this counter - hltLumiSummary.addInfo( iKey, iVal ); - } - - // keep statistics - int totDataSize = ibank->size() / sizeof( unsigned int ); - size_buffer += totDataSize; - - if ( msgLevel( MSG::DEBUG ) ) { - debug() << "Bank size: " << format( "%4d ", ibank->size() ) << "Total Data bank size " << totDataSize - << endmsg; - } - } - - return hltLumiSummary; - } - - private: - // Statistics, mutable to allow statistics to be kept - mutable Gaudi::Accumulators::AveragingCounter<> m_totDataSize{this, "Average event size / 32-bit words"}; - }; - -} // namespace LHCb - -DECLARE_COMPONENT_WITH_ID( LHCb::HltLumiSummaryDecoder, "HltLumiSummaryDecoder" ) diff --git a/Event/RecEvent/dict/selection.xml b/Event/RecEvent/dict/selection.xml index ced07a942d889d7a0eaaeb4001d852ddc18df7ee..f0054e51cebeafb0d24d05b27f93921d6973b800 100755 --- a/Event/RecEvent/dict/selection.xml +++ b/Event/RecEvent/dict/selection.xml @@ -40,6 +40,7 @@ <class name="LHCb::ProtoParticle" id="00000323-0000-0000-0000-000000000000"/> <class name="LHCb::RecHeader" id="00000069-0000-0000-0000-000000000000"/> <class name="LHCb::RecSummary" id="0000006a-0000-0000-0000-000000000000"/> + <class name="LHCb::RecSummary::SummaryData"/> <class name="LHCb::RecVertex" id="0000272e-0000-0000-0000-000000000000"/> <class name="LHCb::RichPID" id="00003072-0000-0000-0000-000000000000"/> <class name="LHCb::RichSummaryPhoton"/> diff --git a/Hlt/HltDAQ/CMakeLists.txt b/Hlt/HltDAQ/CMakeLists.txt index 77195f96a7b02dc14255b453e4f8fc6e06be29e5..f00be24abdd14e0b5a9a6780abceb8df961b7e07 100644 --- a/Hlt/HltDAQ/CMakeLists.txt +++ b/Hlt/HltDAQ/CMakeLists.txt @@ -20,10 +20,12 @@ gaudi_add_module(HltDAQ src/component/HltDecoderUtils.cpp src/component/HltDecReportsWriter.cpp src/component/HltDiffHltDecReports.cpp + src/component/HltLumiSummaryDecoder.cpp + src/component/HltLumiSummaryMonitor.cpp src/component/HltLumiWriter.cpp src/component/HltPackedBufferWriter.cpp - src/component/HltPackedBufferDecoder.cpp - src/component/HltPackedBufferChecker.cpp + src/component/HltPackedBufferDecoder.cpp + src/component/HltPackedBufferChecker.cpp src/component/HltRawDataMonitor.cpp src/component/HltRoutingBitsFilter.cpp src/component/HltSelReportsDecoder.cpp diff --git a/Hlt/HltDAQ/src/component/HltLumiSummaryDecoder.cpp b/Hlt/HltDAQ/src/component/HltLumiSummaryDecoder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..80eba740d14e88e995021c76a6bebd617057fc3f --- /dev/null +++ b/Hlt/HltDAQ/src/component/HltLumiSummaryDecoder.cpp @@ -0,0 +1,254 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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 "Event/HltLumiSummary.h" +#include "Event/LumiSummaryOffsets_V1.h" +#include "Event/LumiSummaryOffsets_V2.h" +#include "Event/RawBank.h" +#include "Event/RawEvent.h" +#include "Kernel/IIndexedLumiSchemaSvc.h" + +#include "LHCbAlgs/Transformer.h" + +#include "Gaudi/Accumulators.h" + +#include <algorithm> +#include <string> + +namespace LHCb { + + /** + * Decodes the LumiSummary. + * + * @author Jaap Panman + * HenryIII Changed to use Transform Algorithm + * + * @date 2008-08-01 + */ + + class HltLumiSummaryDecoder : public Algorithm::Transformer<HltLumiSummary( const RawEvent& )> { + public: + /// Standard constructor + HltLumiSummaryDecoder( const std::string& name, ISvcLocator* pSvcLocator ) + : Transformer( name, pSvcLocator, + KeyValue{"RawEventLocations", Gaudi::Functional::concat_alternatives( + RawEventLocation::Trigger, RawEventLocation::Default )}, + KeyValue{"OutputContainerName", HltLumiSummaryLocation::Default} ) {} + + unsigned getField( unsigned offset, unsigned size, const unsigned* target ) const { + // Separate offset into a word part and bit part + unsigned word = offset / ( 8 * sizeof( unsigned ) ); + unsigned bitoffset = offset % ( 8 * sizeof( unsigned ) ); + + // Check size and offset line up with word boundaries + if ( bitoffset + size > ( 8 * sizeof( unsigned ) ) ) { return 0; } + + unsigned mask = ( ( 1ul << size ) - 1 ); + return ( ( target[word] >> bitoffset ) & mask ); + } + + HltLumiSummary operator()( const RawEvent& event ) const override { + + HltLumiSummary hltLumiSummary; + + // Get the buffers associated with the HltLumiSummary + // Now copy the information from all banks (normally there should only be one) + auto size_buffer = m_totDataSize.buffer(); + auto lumiSummaryBanks = event.banks( RawBank::HltLumiSummary ); + if ( lumiSummaryBanks.empty() ) { + throw GaudiException( "No LumiSummary RawBank in RawEvent. Did you filter on decision or routing bit?", name(), + StatusCode::FAILURE ); + } + for ( const auto& ibank : lumiSummaryBanks ) { + if ( ibank->version() == 0 ) { + // legacy Run 1+2 LumiSummary structure + warning() << "Unsupported HltLumiSummary version: " << format( "%4d", ibank->version() ) << endmsg; + } else if ( ibank->version() == 1 ) { + // initial Run 3 version + if ( ibank->size() != LHCb::LumiSummaryOffsets::V1::TotalSize / 8 ) { + warning() << "Bank size incorrect for HltLumiSummary V1: expected " + << format( "%4d", LHCb::LumiSummaryOffsets::V1::TotalSize ) << ", found " + << format( "%4d", ibank->size() ) << endmsg; + } else { + hltLumiSummary.addInfo( "T0Low", getField( LHCb::LumiSummaryOffsets::V1::t0LowOffset, + LHCb::LumiSummaryOffsets::V1::t0LowSize, ibank->data() ) ); + hltLumiSummary.addInfo( "T0High", getField( LHCb::LumiSummaryOffsets::V1::t0HighOffset, + LHCb::LumiSummaryOffsets::V1::t0HighSize, ibank->data() ) ); + hltLumiSummary.addInfo( "BCIDLow", getField( LHCb::LumiSummaryOffsets::V1::bcidLowOffset, + LHCb::LumiSummaryOffsets::V1::bcidLowSize, ibank->data() ) ); + hltLumiSummary.addInfo( "BCIDHigh", getField( LHCb::LumiSummaryOffsets::V1::bcidHighOffset, + LHCb::LumiSummaryOffsets::V1::bcidHighSize, ibank->data() ) ); + hltLumiSummary.addInfo( "BXType", getField( LHCb::LumiSummaryOffsets::V1::bxTypeOffset, + LHCb::LumiSummaryOffsets::V1::bxTypeSize, ibank->data() ) ); + hltLumiSummary.addInfo( "GEC", getField( LHCb::LumiSummaryOffsets::V1::GecOffset, + LHCb::LumiSummaryOffsets::V1::GecSize, ibank->data() ) ); + hltLumiSummary.addInfo( "VeloTracks", + getField( LHCb::LumiSummaryOffsets::V1::VeloTracksOffset, + LHCb::LumiSummaryOffsets::V1::VeloTracksSize, ibank->data() ) ); + hltLumiSummary.addInfo( "VeloVertices", + getField( LHCb::LumiSummaryOffsets::V1::VeloVerticesOffset, + LHCb::LumiSummaryOffsets::V1::VeloVerticesSize, ibank->data() ) ); + hltLumiSummary.addInfo( "SciFiClusters", + getField( LHCb::LumiSummaryOffsets::V1::SciFiClustersOffset, + LHCb::LumiSummaryOffsets::V1::SciFiClustersSize, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM2R2", getField( LHCb::LumiSummaryOffsets::V1::M2R2Offset, + LHCb::LumiSummaryOffsets::V1::M2R2Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM2R3", getField( LHCb::LumiSummaryOffsets::V1::M2R3Offset, + LHCb::LumiSummaryOffsets::V1::M2R3Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM3R2", getField( LHCb::LumiSummaryOffsets::V1::M3R2Offset, + LHCb::LumiSummaryOffsets::V1::M3R2Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM3R3", getField( LHCb::LumiSummaryOffsets::V1::M3R3Offset, + LHCb::LumiSummaryOffsets::V1::M3R3Size, ibank->data() ) ); + } + } else if ( ibank->version() == 2 ) { + auto encodingKey = getField( LHCb::LumiSummaryOffsets::V2::encodingKeyOffset, + LHCb::LumiSummaryOffsets::V2::encodingKeySize, ibank->data() ); + if ( msgLevel( MSG::VERBOSE ) ) { verbose() << "encodingKey :" << encodingKey << endmsg; } + if ( encodingKey != 0x61967914 ) { // This encoding key is the hash of the JSON representation of the initial + // fixed V2 schema + auto lumi_schema = m_svc->lumiCounters( encodingKey, 0 ); + if ( static_cast<unsigned>( ibank->size() ) != lumi_schema.size ) { + warning() << "Bank size incorrect for HltLumiSummary V2: expected " << format( "%4d", lumi_schema.size ) + << " for encoding key " << format( "%8x", encodingKey ) << ", found " + << format( "%4d", ibank->size() ) << endmsg; + } else { + for ( auto cntr : lumi_schema.counters ) { + hltLumiSummary.addInfo( cntr.name, getField( cntr.offset, cntr.size, ibank->data() ) ); + if ( msgLevel( MSG::VERBOSE ) ) { + verbose() << cntr.name << " (" << cntr.offset << "," << cntr.size + << ") :" << getField( cntr.offset, cntr.size, ibank->data() ) << endmsg; + } + } + } + } else { + if ( ibank->size() != LHCb::LumiSummaryOffsets::V2::TotalSize / 8 ) { + warning() << "Bank size incorrect for HltLumiSummary V2: expected " + << format( "%4d", LHCb::LumiSummaryOffsets::V2::TotalSize ) << ", found " + << format( "%4d", ibank->size() ) << endmsg; + } else { + hltLumiSummary.addInfo( "encodingKey", + getField( LHCb::LumiSummaryOffsets::V2::encodingKeyOffset, + LHCb::LumiSummaryOffsets::V2::encodingKeySize, ibank->data() ) ); + hltLumiSummary.addInfo( "T0Low", getField( LHCb::LumiSummaryOffsets::V2::T0LowOffset, + LHCb::LumiSummaryOffsets::V2::T0LowSize, ibank->data() ) ); + hltLumiSummary.addInfo( "T0High", getField( LHCb::LumiSummaryOffsets::V2::T0HighOffset, + LHCb::LumiSummaryOffsets::V2::T0HighSize, ibank->data() ) ); + hltLumiSummary.addInfo( "BCIDLow", getField( LHCb::LumiSummaryOffsets::V2::BCIDLowOffset, + LHCb::LumiSummaryOffsets::V2::BCIDLowSize, ibank->data() ) ); + hltLumiSummary.addInfo( "BCIDHigh", + getField( LHCb::LumiSummaryOffsets::V2::BCIDHighOffset, + LHCb::LumiSummaryOffsets::V2::BCIDHighSize, ibank->data() ) ); + hltLumiSummary.addInfo( "BXType", getField( LHCb::LumiSummaryOffsets::V2::BXTypeOffset, + LHCb::LumiSummaryOffsets::V2::BXTypeSize, ibank->data() ) ); + hltLumiSummary.addInfo( "GEC", getField( LHCb::LumiSummaryOffsets::V2::GECOffset, + LHCb::LumiSummaryOffsets::V2::GECSize, ibank->data() ) ); + hltLumiSummary.addInfo( "VeloTracks", + getField( LHCb::LumiSummaryOffsets::V2::VeloTracksOffset, + LHCb::LumiSummaryOffsets::V2::VeloTracksSize, ibank->data() ) ); + hltLumiSummary.addInfo( "VeloVertices", + getField( LHCb::LumiSummaryOffsets::V2::VeloVerticesOffset, + LHCb::LumiSummaryOffsets::V2::VeloVerticesSize, ibank->data() ) ); + hltLumiSummary.addInfo( "SciFiClusters", + getField( LHCb::LumiSummaryOffsets::V2::SciFiClustersOffset, + LHCb::LumiSummaryOffsets::V2::SciFiClustersSize, ibank->data() ) ); + hltLumiSummary.addInfo( "SciFiClustersS1M45", + getField( LHCb::LumiSummaryOffsets::V2::SciFiClustersS1M45Offset, + LHCb::LumiSummaryOffsets::V2::SciFiClustersS1M45Size, ibank->data() ) ); + hltLumiSummary.addInfo( "SciFiClustersS2M45", + getField( LHCb::LumiSummaryOffsets::V2::SciFiClustersS2M45Offset, + LHCb::LumiSummaryOffsets::V2::SciFiClustersS2M45Size, ibank->data() ) ); + hltLumiSummary.addInfo( "SciFiClustersS3M45", + getField( LHCb::LumiSummaryOffsets::V2::SciFiClustersS3M45Offset, + LHCb::LumiSummaryOffsets::V2::SciFiClustersS3M45Size, ibank->data() ) ); + hltLumiSummary.addInfo( "SciFiClustersS2M123", + getField( LHCb::LumiSummaryOffsets::V2::SciFiClustersS2M123Offset, + LHCb::LumiSummaryOffsets::V2::SciFiClustersS2M123Size, + ibank->data() ) ); + hltLumiSummary.addInfo( "SciFiClustersS3M123", + getField( LHCb::LumiSummaryOffsets::V2::SciFiClustersS3M123Offset, + LHCb::LumiSummaryOffsets::V2::SciFiClustersS3M123Size, + ibank->data() ) ); + hltLumiSummary.addInfo( "ECalET", getField( LHCb::LumiSummaryOffsets::V2::ECalETOffset, + LHCb::LumiSummaryOffsets::V2::ECalETSize, ibank->data() ) ); + hltLumiSummary.addInfo( "ECalEInnerTop", + getField( LHCb::LumiSummaryOffsets::V2::ECalEInnerTopOffset, + LHCb::LumiSummaryOffsets::V2::ECalEInnerTopSize, ibank->data() ) ); + hltLumiSummary.addInfo( "ECalEInnerBottom", + getField( LHCb::LumiSummaryOffsets::V2::ECalEInnerBottomOffset, + LHCb::LumiSummaryOffsets::V2::ECalEInnerBottomSize, ibank->data() ) ); + hltLumiSummary.addInfo( "ECalEMiddleTop", + getField( LHCb::LumiSummaryOffsets::V2::ECalEMiddleTopOffset, + LHCb::LumiSummaryOffsets::V2::ECalEMiddleTopSize, ibank->data() ) ); + hltLumiSummary.addInfo( "ECalEMiddleBottom", + getField( LHCb::LumiSummaryOffsets::V2::ECalEMiddleBottomOffset, + LHCb::LumiSummaryOffsets::V2::ECalEMiddleBottomSize, ibank->data() ) ); + hltLumiSummary.addInfo( "ECalEOuterTop", + getField( LHCb::LumiSummaryOffsets::V2::ECalEOuterTopOffset, + LHCb::LumiSummaryOffsets::V2::ECalEOuterTopSize, ibank->data() ) ); + hltLumiSummary.addInfo( "ECalEOuterBottom", + getField( LHCb::LumiSummaryOffsets::V2::ECalEOuterBottomOffset, + LHCb::LumiSummaryOffsets::V2::ECalEOuterBottomSize, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM2R1", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM2R1Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM2R1Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM2R2", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM2R2Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM2R2Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM2R3", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM2R3Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM2R3Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM2R4", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM2R4Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM2R4Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM3R1", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM3R1Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM3R1Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM3R2", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM3R2Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM3R2Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM3R3", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM3R3Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM3R3Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM3R4", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM3R4Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM3R4Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM4R1", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM4R1Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM4R1Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM4R2", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM4R2Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM4R2Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM4R3", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM4R3Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM4R3Size, ibank->data() ) ); + hltLumiSummary.addInfo( "MuonHitsM4R4", + getField( LHCb::LumiSummaryOffsets::V2::MuonHitsM4R4Offset, + LHCb::LumiSummaryOffsets::V2::MuonHitsM4R4Size, ibank->data() ) ); + } + } + } else { + warning() << "Unknown HltLumiSummary version: " << format( "%4d", ibank->version() ) << endmsg; + } + } + + return hltLumiSummary; + } + + private: + ServiceHandle<IIndexedLumiSchemaSvc> m_svc{this, "DecoderMapping", "HltANNSvc"}; + + // Statistics, mutable to allow statistics to be kept + mutable Gaudi::Accumulators::AveragingCounter<> m_totDataSize{this, "Average event size / 32-bit words"}; + }; + +} // namespace LHCb + +DECLARE_COMPONENT_WITH_ID( LHCb::HltLumiSummaryDecoder, "HltLumiSummaryDecoder" ) diff --git a/Hlt/HltDAQ/src/component/HltLumiSummaryMonitor.cpp b/Hlt/HltDAQ/src/component/HltLumiSummaryMonitor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..69766c1c30be0bd3ea83bbf33fa1fe926c41da2d --- /dev/null +++ b/Hlt/HltDAQ/src/component/HltLumiSummaryMonitor.cpp @@ -0,0 +1,92 @@ +/*****************************************************************************\ +* (c) Copyright 2019 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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 "Event/HltLumiSummary.h" +#include "Event/ODIN.h" +#include "LHCbAlgs/Consumer.h" + +#include "Gaudi/Accumulators/Histogram.h" +#include "GaudiKernel/EventContext.h" +#include "GaudiKernel/StatusCode.h" +#include "Kernel/EventContextExt.h" +#include "Kernel/IANNSvc.h" +#include <string> +#include <type_traits> +#include <vector> + +using BXTypes = LHCb::ODIN::BXTypes; + +namespace { + template <typename T, typename K, typename OWNER> + void map_emplace( T& t, K&& key, OWNER* owner, std::string const& name, std::string const& title, + Gaudi::Accumulators::Axis<typename T::mapped_type::AxisArithmeticType> axis1 ) { + t.emplace( std::piecewise_construct, std::forward_as_tuple( key ), + std::forward_as_tuple( owner, name, title, axis1 ) ); + } + + template <typename T> + std::string to_string( const T& streamable ) { + std::ostringstream oss; + oss << streamable; + return oss.str(); + } + + const auto AxisBCID = Gaudi::Accumulators::Axis<double>( 3565, -0.5, 3564.5 ); + const auto AxisTime = Gaudi::Accumulators::Axis<double>( 3600, 0, 3600 ); +} // namespace + +class HltLumiSummaryMonitor final + : public LHCb::Algorithm::Consumer<void( const LHCb::HltLumiSummary&, const LHCb::ODIN& )> { +public: + HltLumiSummaryMonitor( const std::string& name, ISvcLocator* pSvcLocator ) + : Consumer{name, pSvcLocator, {KeyValue{"Input", ""}, KeyValue{"ODIN", ""}}} {} + void operator()( const LHCb::HltLumiSummary&, const LHCb::ODIN& ) const override; + +private: + mutable std::map<std::pair<BXTypes, std::string>, Gaudi::Accumulators::Histogram<1>> m_value; + mutable std::map<std::pair<BXTypes, std::string>, Gaudi::Accumulators::ProfileHistogram<1>> m_time_mean; + mutable std::map<std::pair<BXTypes, std::string>, Gaudi::Accumulators::ProfileHistogram<1>> m_time_pnz; + + mutable std::mutex m_lock; +}; + +DECLARE_COMPONENT( HltLumiSummaryMonitor ) + +void HltLumiSummaryMonitor::operator()( const LHCb::HltLumiSummary& summary, const LHCb::ODIN& odin ) const { + auto lock = std::scoped_lock{m_lock}; + + if ( m_value.empty() ) { + for ( auto bx : {BXTypes::NoBeam, BXTypes::Beam1, BXTypes::Beam2, BXTypes::BeamCrossing} ) { + for ( const auto& info : summary.extraInfo() ) { + const auto& counter = info.first; + map_emplace( m_value, std::make_pair( bx, counter ), this, "value_" + to_string( bx ) + "_" + counter, + "Counter value for " + counter + "/" + to_string( bx ), + Gaudi::Accumulators::Axis<double>( 1024, 0, 1024 ) ); + map_emplace( m_time_mean, std::make_pair( bx, counter ), this, "mean_" + to_string( bx ) + "_" + counter, + "Mean value per second for " + counter + "/" + to_string( bx ), AxisTime ); + map_emplace( m_time_pnz, std::make_pair( bx, counter ), this, "pnz_" + to_string( bx ) + "_" + counter, + "P(>0) per second for " + counter + "/" + to_string( bx ), AxisTime ); + } + } + } + + const auto time = ( odin.gpsTime() / 1000000 ) % 3600; + for ( const auto& [counter, value] : summary.extraInfo() ) { + const auto key = std::make_pair( odin.bunchCrossingType(), counter ); + ++m_value.at( key )[value]; + m_time_mean.at( key )[time] += value; + m_time_pnz.at( key )[time] += ( value > 0 ); + } + if ( msgLevel( MSG::VERBOSE ) ) { + verbose() << "Counters: {"; + for ( const auto& [counter, value] : summary.extraInfo() ) { verbose() << counter << ':' << value << ", "; } + verbose() << '}' << endmsg; + } +} diff --git a/Hlt/HltDAQ/src/component/HltLumiWriter.cpp b/Hlt/HltDAQ/src/component/HltLumiWriter.cpp index 94575e875dd99fb8c5d5822a80155bf0b7a8f316..747074a13e0464ad0285f834a872c37027c506f5 100644 --- a/Hlt/HltDAQ/src/component/HltLumiWriter.cpp +++ b/Hlt/HltDAQ/src/component/HltLumiWriter.cpp @@ -1,5 +1,5 @@ /*****************************************************************************\ -* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* (c) Copyright 2000-2022 CERN for the benefit of the LHCb Collaboration * * * * This software is distributed under the terms of the GNU General Public * * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * @@ -9,8 +9,8 @@ * or submit itself to any jurisdiction. * \*****************************************************************************/ #include "Event/HltLumiSummary.h" -#include "Event/LumiCounters.h" #include "Event/RawEvent.h" +#include "Kernel/IIndexedLumiSchemaSvc.h" #include "Kernel/STLExtensions.h" #include "LHCbAlgs/Transformer.h" @@ -34,17 +34,23 @@ public: //============================================================================= // Main execution - // Fill the data bank, structure: Key (upper 16 bits) + value + // Fill the data bank, structure depends on encoding key //============================================================================= LHCb::RawBank::View operator()( const LHCb::HltLumiSummary& summary ) const override { + if ( summary.extraInfo().find( "encodingKey" ) == summary.extraInfo().end() ) { + throw std::runtime_error( "HltLumiSummary does not contain an encoding key" ); + } + auto encodingKey = summary.extraInfo().at( "encodingKey" ); + auto lumi_schema = m_svc->lumiCounters( encodingKey, 0 ); std::vector<unsigned int> bank; - bank.reserve( 20 ); - for ( const auto& info : summary.extraInfo() ) { - bank.push_back( ( std::min( info.first, 0xFFFF ) << 16 ) | ( std::min( info.second, 0xFFFF ) & 0xFFFF ) ); - if ( msgLevel( MSG::VERBOSE ) ) { - auto word = bank.back(); - verbose() << format( " %8x %11d %11d %11d ", word, word, word >> 16, word & 0xFFFF ) << endmsg; + bank.resize( lumi_schema.size / 4 ); + for ( auto cntr : lumi_schema.counters ) { + if ( summary.extraInfo().find( cntr.name ) != summary.extraInfo().end() ) { + auto val = summary.extraInfo().at( cntr.name ); + writeCounter( cntr.offset, cntr.size, &bank.front(), val ); + } else { + warning() << "Field " << cntr.name << " ignored by lumiSummary schema " << encodingKey << endmsg; } } @@ -54,7 +60,7 @@ public: } // set source, type, version - rawEvent->addBank( 0, LHCb::RawBank::HltLumiSummary, 0, bank ); + rawEvent->addBank( 0, LHCb::RawBank::HltLumiSummary, 2, bank ); m_totDataSize += bank.size(); @@ -73,6 +79,25 @@ public: return rawEvent->banks( LHCb::RawBank::HltLumiSummary ); } + + void writeCounter( unsigned offset, unsigned size, unsigned* target, unsigned value ) const { + // Check value fits within size bits + if ( size < ( 8 * sizeof( unsigned ) ) && value >= ( 1u << size ) ) { return; } + + // Separate offset into a word part and bit part + unsigned word = offset / ( 8 * sizeof( unsigned ) ); + unsigned bitoffset = offset % ( 8 * sizeof( unsigned ) ); + + // Check size and offset line up with word boundaries + if ( bitoffset + size > ( 8 * sizeof( unsigned ) ) ) { return; } + + // Apply the value to the matching bits + unsigned mask = ( ( 1ul << size ) - 1 ) << bitoffset; + target[word] = ( target[word] & ~mask ) | ( ( value << bitoffset ) & mask ); + } + +private: + ServiceHandle<IIndexedLumiSchemaSvc> m_svc{this, "DecoderMapping", "HltANNSvc"}; }; DECLARE_COMPONENT( HltLumiWriter ) diff --git a/Hlt/HltDAQ/src/component/HltRoutingBitsFilter.cpp b/Hlt/HltDAQ/src/component/HltRoutingBitsFilter.cpp index 1d3cd56abbfa4687d53e4a84102b1dcdbeec4860..2fbdeb9ef4879adf60dd9c9909c8be6674df39ee 100644 --- a/Hlt/HltDAQ/src/component/HltRoutingBitsFilter.cpp +++ b/Hlt/HltDAQ/src/component/HltRoutingBitsFilter.cpp @@ -60,7 +60,9 @@ bool HltRoutingBitsFilter::operator()( const LHCb::RawEvent& rawEvent ) const { ++m_unexpectedRawbanks; return m_passOnError; } - if ( banks[0]->size() != 3 * sizeof( unsigned int ) ) { + if ( banks[0]->size() != 3 * sizeof( unsigned int ) && + banks[0]->size() != 4 * sizeof( unsigned int ) // FIXME: should we ever write the 4th word into HltRoutingBits? + ) { ++m_unexpectedRawbanksSize; return m_passOnError; } diff --git a/Hlt/HltDAQ/tests/options/lumi_decoding.py b/Hlt/HltDAQ/tests/options/lumi_decoding.py new file mode 100644 index 0000000000000000000000000000000000000000..61e58fde70cb1fa5b66d255f39bba325ab8bad7f --- /dev/null +++ b/Hlt/HltDAQ/tests/options/lumi_decoding.py @@ -0,0 +1,55 @@ +############################################################################### +# (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, 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. # +############################################################################### +import logging +from Gaudi.Configuration import VERBOSE, DEBUG +from PRConfig.TestFileDB import test_file_db + +from PyConf.application import ( + default_raw_event, + configure_input, + configure, + make_odin, + CompositeNode, +) +from PyConf.Algorithms import ( + HltRoutingBitsFilter, + HltLumiSummaryDecoder, + HltLumiSummaryMonitor, + PrintHeader, +) + +options = test_file_db["hltlumisummary-raw-data-v1"].make_lbexec_options( + simulation=True, + dddb_tag="dddb-20210617", + conddb_tag="sim-20210617-vc-md100", + python_logging_level=logging.WARNING, + evt_max=5000, + histo_file='lumi_decoding_histo.root', +) + +configure_input(options) # must call this before calling default_raw_event +odin = make_odin() + +rb_filter = HltRoutingBitsFilter( + RawEventLocations=default_raw_event(["HltRoutingBits"]), + RequireMask=(1 << 1, 0, 0), + PassOnError=False) +summary = HltLumiSummaryDecoder( + RawEventLocations=default_raw_event( + ["HltLumiSummary"]), ).OutputContainerName +monitor = HltLumiSummaryMonitor(Input=summary, ODIN=odin, OutputLevel=VERBOSE) +print_event = PrintHeader(ODINLocation=odin) + +top_node = CompositeNode("Top", [rb_filter, print_event, monitor]) +configure(options, top_node) + +from Configurables import LHCb__DetDesc__ReserveDetDescForEvent as reserveIOV +reserveIOV("reserveIOV").PreloadGeometry = False diff --git a/Hlt/HltDAQ/tests/qmtest/hltdaq.qms/lumi_decoding.qmt b/Hlt/HltDAQ/tests/qmtest/hltdaq.qms/lumi_decoding.qmt new file mode 100644 index 0000000000000000000000000000000000000000..ec072b4b43cf162b24981c74635e0d73c0d44b42 --- /dev/null +++ b/Hlt/HltDAQ/tests/qmtest/hltdaq.qms/lumi_decoding.qmt @@ -0,0 +1,29 @@ +<?xml version="1.0" ?><!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> +<!-- + (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration + + This software is distributed under the terms of the GNU General Public + Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". + + In applying this licence, 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. +--> +<!-- +Check that the HltLumiSummary decoding works. +--> +<extension class="GaudiTest.GaudiExeTest" kind="test"> + <argument name="program"><text>gaudirun.py</text></argument> + <argument name="args"><set> + <text>../options/lumi_decoding.py</text> + </set></argument> + <argument name="use_temp_dir"><enumeral>true</enumeral></argument> + <argument name="reference"><text>../refs/lumi_decoding.ref</text></argument> + <argument name="validator"><text> + +from GaudiConf.QMTest.LHCbExclusions import preprocessor +validateWithReference(preproc=preprocessor) + +</text></argument> +</extension> + diff --git a/Hlt/HltDAQ/tests/refs/lumi_decoding.ref b/Hlt/HltDAQ/tests/refs/lumi_decoding.ref new file mode 100644 index 0000000000000000000000000000000000000000..b67e9d4a8134ae69e9f32afc1c20c1f791f1e8d6 --- /dev/null +++ b/Hlt/HltDAQ/tests/refs/lumi_decoding.ref @@ -0,0 +1,84 @@ +ApplicationMgr SUCCESS +==================================================================================================================================== +==================================================================================================================================== +ApplicationMgr INFO Application Manager Configured successfully +DetectorPersistencySvc INFO Added successfully Conversion service:XmlCnvSvc +DetectorDataSvc SUCCESS Detector description database: git:/lhcb.xml +HLTControlFlowMgr INFO Start initialization +RootHistSvc INFO Writing ROOT histograms to: lumi_decoding_histo.root +HistogramPersistencySvc INFO Added successfully Conversion service:RootHistSvc +HltLumiSummaryMonitor VERBOSE ServiceLocatorHelper::service: found service EventDataSvc +HltLumiSummaryMonitor VERBOSE ServiceLocatorHelper::service: found service TimelineSvc +HltLumiSummaryMonitor VERBOSE ServiceLocatorHelper::service: found service EventDataSvc +HltLumiSummaryMonitor DEBUG input handles: 2 +HltLumiSummaryMonitor DEBUG output handles: 0 +HltLumiSummaryMonitor DEBUG Data Deps for HltLumiSummaryMonitor + + INPUT '/Event/HltLumiSummaryDecoder/OutputContainerName' + + INPUT '/Event/createODIN/ODIN' +HLTControlFlowMgr INFO Concurrency level information: +HLTControlFlowMgr INFO o Number of events slots: 1 +HLTControlFlowMgr INFO o TBB thread pool size: 'ThreadPoolSize':1 +ApplicationMgr INFO Application Manager Initialized successfully +ApplicationMgr INFO Application Manager Started successfully +EventSelector INFO Stream:EventSelector.DataStreamTool_1 Def:DATAFILE='mdf:root://eoslhcb.cern.ch//eos/lhcb/user/e/edallocc/lumi/raw_data/Run_0000249421_20221015-160520-203_HCEB04_0224.mdf' SVC='LHCb::MDFSelector' OPT='READ' IgnoreChecksum='YES' +HLTControlFlowMgr INFO Will measure time between events 500 and 4500 (stop might be some events later) +HLTControlFlowMgr INFO Starting loop on events +EventSelector.DataStreamTool_1 INFO Compression:0 Checksum:0 +EventSelector SUCCESS Reading Event record 1. Record number within stream 1: 1 +EventPersistencySvc INFO Added successfully Conversion service:RootCnvSvc +EventPersistencySvc INFO Added successfully Conversion service:LHCb::RawDataCnvSvc +PrintHeader INFO Run 249421, Event 729764180 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:7, MuonHitsM2R3:3, MuonHitsM3R2:5, MuonHitsM3R3:0, SciFiClusters:338, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729792534 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:19, MuonHitsM2R3:12, MuonHitsM3R2:2, MuonHitsM3R3:0, SciFiClusters:796, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729793455 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:0, GEC:1, MuonHitsM2R2:2, MuonHitsM2R3:1, MuonHitsM3R2:4, MuonHitsM3R3:0, SciFiClusters:256, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729794524 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:2, GEC:1, MuonHitsM2R2:7, MuonHitsM2R3:1, MuonHitsM3R2:3, MuonHitsM3R3:0, SciFiClusters:241, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729796040 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:21, MuonHitsM2R3:5, MuonHitsM3R2:1, MuonHitsM3R3:0, SciFiClusters:449, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729768913 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:1, GEC:1, MuonHitsM2R2:2, MuonHitsM2R3:4, MuonHitsM3R2:2, MuonHitsM3R3:0, SciFiClusters:239, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729770819 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:11, MuonHitsM2R3:1, MuonHitsM3R2:5, MuonHitsM3R3:2, SciFiClusters:387, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729801532 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:15, MuonHitsM2R3:6, MuonHitsM3R2:2, MuonHitsM3R3:0, SciFiClusters:250, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729801796 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:8, MuonHitsM2R3:3, MuonHitsM3R2:3, MuonHitsM3R3:2, SciFiClusters:1221, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729772288 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:8, MuonHitsM2R3:2, MuonHitsM3R2:4, MuonHitsM3R3:2, SciFiClusters:737, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729772392 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:2, GEC:1, MuonHitsM2R2:5, MuonHitsM2R3:1, MuonHitsM3R2:0, MuonHitsM3R3:0, SciFiClusters:233, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729803627 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:6, MuonHitsM2R3:7, MuonHitsM3R2:5, MuonHitsM3R3:0, SciFiClusters:288, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729774219 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:13, MuonHitsM2R3:7, MuonHitsM3R2:18, MuonHitsM3R3:6, SciFiClusters:1625, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 729805808 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:0, GEC:1, MuonHitsM2R2:3, MuonHitsM2R3:2, MuonHitsM3R2:1, MuonHitsM3R3:2, SciFiClusters:236, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 736231706 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:40, MuonHitsM2R3:12, MuonHitsM3R2:8, MuonHitsM3R3:7, SciFiClusters:1619, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 736203567 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:57, MuonHitsM2R3:14, MuonHitsM3R2:1, MuonHitsM3R3:10, SciFiClusters:2446, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 736204556 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:13, MuonHitsM2R3:4, MuonHitsM3R2:3, MuonHitsM3R3:0, SciFiClusters:353, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 736204768 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:1, GEC:1, MuonHitsM2R2:16, MuonHitsM2R3:2, MuonHitsM3R2:2, MuonHitsM3R3:3, SciFiClusters:276, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +PrintHeader INFO Run 249421, Event 736206167 +HltLumiSummaryMonitor VERBOSE Counters: {BCIDHigh:0, BCIDLow:0, BXType:3, GEC:1, MuonHitsM2R2:12, MuonHitsM2R3:7, MuonHitsM3R2:8, MuonHitsM3R3:0, SciFiClusters:1192, T0High:0, T0Low:0, VeloTracks:0, VeloVertices:0, } +ApplicationMgr INFO Application Manager Stopped successfully +HLTControlFlowMgr INFO +HLTControlFlowMgr INFO StateTree: CFNode #executed #passed +LAZY_AND: Top #=5000 Sum=19 Eff=|(0.3800000 +- 0.0870122)%| + HltRoutingBitsFilter/HltRoutingBitsFilter #=5000 Sum=19 Eff=|(0.3800000 +- 0.0870122)%| + PrintHeader/PrintHeader #=19 Sum=19 Eff=|( 100.0000 +- 0.00000 )%| + HltLumiSummaryMonitor/HltLumiSummaryMonitor #=19 Sum=19 Eff=|( 100.0000 +- 0.00000 )%| +HLTControlFlowMgr INFO Histograms converted successfully according to request. +ToolSvc INFO Removing all tools created by ToolSvc +ApplicationMgr INFO Application Manager Finalized successfully +ApplicationMgr INFO Application Manager Terminated successfully +HltRoutingBitsFilter INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + |*"#accept" | 5000 | 19 |(0.3800000 +- 0.08701218)% | +PrintHeader INFO Number of counters : 1 + | Counter | # | sum | mean/eff^* | rms/err^* | min | max | + | "EventCount" | 19 | diff --git a/Hlt/HltServices/src/ANNSvcBase.h b/Hlt/HltServices/src/ANNSvcBase.h index cdff5287b1c9d5b15bcad4ea5ff6559c4ffb2ffe..7d336e988bc6491a58a7a664ade424acc501f427 100644 --- a/Hlt/HltServices/src/ANNSvcBase.h +++ b/Hlt/HltServices/src/ANNSvcBase.h @@ -11,6 +11,7 @@ #pragma once #include "GaudiKernel/Service.h" #include "Kernel/IIndexedANNSvc.h" +#include "Kernel/IIndexedLumiSchemaSvc.h" #include "Kernel/SynchronizedValue.h" #include <map> #include <string> @@ -36,7 +37,7 @@ namespace ANNSvcBase_details { } // namespace ANNSvcBase_details -class ANNSvcBase : public extends<Service, IIndexedANNSvc> { +class ANNSvcBase : public extends<Service, IIndexedANNSvc, IIndexedLumiSchemaSvc> { public: using extends::extends; @@ -67,14 +68,28 @@ public: return *ptr; } + lumi_schema_t const& lumiCounters( unsigned key, unsigned version ) const override final { + auto ptr = m_lumi.with_lock( [&]( std::map<std::pair<unsigned, unsigned>, lumi_schema_t>& lumi ) { + auto j = lumi.find( {key, version} ); + if ( j != lumi.end() ) return &j->second; + auto [k, ok] = lumi.emplace( std::pair{key, version}, fetch_lumi( key, version ) ); + return ok ? &k->second : nullptr; + } ); + if ( !ptr ) throw GaudiException{"Failed to add to lumi schema map", __PRETTY_FUNCTION__, StatusCode::FAILURE}; + return *ptr; + } + private: Gaudi::Property<bool> m_allow_zero_as_key{this, "AllowZeroAsKey", false}; - virtual map_t fetch( unsigned int tck, const Gaudi::StringKey& major ) const = 0; + virtual map_t fetch( unsigned int tck, const Gaudi::StringKey& major ) const = 0; + virtual lumi_schema_t fetch_lumi( unsigned int key, unsigned int version ) const = 0; mutable std::array<LHCb::cxx::SynchronizedValue<std::map<unsigned int, map_t>>, ANNSvcBase_details::s_majors.size()> m_maps; mutable std::array<LHCb::cxx::SynchronizedValue<std::map<unsigned int, inv_map_t>>, ANNSvcBase_details::s_majors.size()> m_inv_maps; + + mutable LHCb::cxx::SynchronizedValue<std::map<std::pair<unsigned, unsigned>, lumi_schema_t>> m_lumi; }; diff --git a/Hlt/HltServices/src/GitANNSvc.cpp b/Hlt/HltServices/src/GitANNSvc.cpp index c84853e5689b0d69df65395ea78a93361989d1e2..ab06e384d1b4fe4e690dd197524f24f3c466618b 100644 --- a/Hlt/HltServices/src/GitANNSvc.cpp +++ b/Hlt/HltServices/src/GitANNSvc.cpp @@ -96,30 +96,29 @@ class GitANNSvc : public ANNSvcBase { Gaudi::Property<std::string> m_fmt{this, "RefFormatter", "{0}:ann/json/{1:.2}/{1}.json"}; // 0=tag, 1=key, 2=label Gaudi::Property<std::string> m_altfmt{this, "AltRefFormatter", "key-{1}:ann/json/{1:.2}/{1}.json"}; + Gaudi::Property<std::map<unsigned int, std::string>> m_lumi_key2JSON{this, "LumiOverrule", {}}; + Gaudi::Property<std::string> m_lumi_fmt{this, "LumiRefFormatter", + "{0}:luminosity_counters/json/{1:.2}/{1}.json"}; // 0=tag, 1=key, 2=version + std::optional<std::string> fetch_from_repo( std::string const& repo, std::string const& name ) const { if ( repo.empty() ) error() << "no repo specified..." << endmsg; auto g = git{repo}; if ( !g ) throw GaudiException( "unable to open git repo: " + repo, __PRETTY_FUNCTION__, StatusCode::FAILURE ); if ( msgLevel( MSG::DEBUG ) ) { - debug() << "fetch_from_repos: trying to get " << name << " from " << repo << endmsg; + debug() << "fetch_from_repo: trying to get " << name << " from " << repo << endmsg; } return g.read( name ); } - std::optional<std::string> fetch_from_repos( std::string_view fmt, std::string_view key, - std::string_view major ) const { + template <typename F> + std::optional<std::string> fetch_from_repos( F&& fmt ) const { for ( const auto& [repo, tag] : m_repo.value() ) { - if ( auto s = fetch_from_repo( repo, fmt::format( fmt, tag, key, major ) ); s ) return s; + if ( auto s = fetch_from_repo( repo, fmt( tag ) ); s ) return s; } return std::nullopt; } - std::optional<std::string> fetch_from_repos( std::string_view key, std::string_view major ) const { - auto s = fetch_from_repos( m_fmt, key, major ); - return s ? s : fetch_from_repos( m_altfmt, key, major ); - } - - std::optional<nlohmann::json> fetch_json( unsigned int key, const Gaudi::StringKey& major ) const { + std::optional<nlohmann::json> fetch_ann_json( unsigned int key, const Gaudi::StringKey& major ) const { if ( auto io = m_key2JSON.find( key ); io != m_key2JSON.end() ) { warning() << "key " << fmt::format( "0x{:08x}", key ) << " has an explicitly configured overrule -- using that..." << endmsg; @@ -132,10 +131,11 @@ class GitANNSvc : public ANNSvcBase { auto id = ( i != m_key2commit.end() ? i->second : fmt::format( "{:08x}", key ) ); if ( msgLevel( MSG::DEBUG ) ) - debug() << "fetch_json( " << key << " -> " << id << " ) from repo " << m_repo.value() << endmsg; - - auto s = fetch_from_repos( id, major.str() ); + debug() << "fetch_ann_json( " << key << " -> " << id << " ) from repo " << m_repo.value() << endmsg; + auto s = fetch_from_repos( [&]( auto const& tag ) { return fmt::format( m_fmt.value(), tag, id, major.str() ); } ); + if ( !s ) + s = fetch_from_repos( [&]( auto const& tag ) { return fmt::format( m_altfmt.value(), tag, id, major.str() ); } ); if ( !s ) return std::nullopt; auto json = nlohmann::json::parse( *s, nullptr, false ); if ( json.is_discarded() ) return std::nullopt; @@ -144,7 +144,7 @@ class GitANNSvc : public ANNSvcBase { template <typename Inserter> void fetch_( unsigned int key, const Gaudi::StringKey& major, Inserter inserter ) const { - auto json = fetch_json( key, major ); + auto json = fetch_ann_json( key, major ); if ( !json ) throw GaudiException( fmt::format( "unable to obtain json for key {:08x} from repositories {}", key, Gaudi::Utils::toString( m_repo.value() ) ), @@ -162,6 +162,57 @@ class GitANNSvc : public ANNSvcBase { return m; } + std::optional<nlohmann::json> fetch_lumi_json( unsigned int key ) const { + if ( auto io = m_lumi_key2JSON.find( key ); io != m_lumi_key2JSON.end() ) { + warning() << "lumi key " << fmt::format( "0x{:08x}", key ) + << " has an explicitly configured overrule -- using that..." << endmsg; + auto json = nlohmann::json::parse( io->second, nullptr, false ); + if ( json.is_discarded() ) return std::nullopt; + return json; + } + + auto id = fmt::format( "{:08x}", key ); + + if ( msgLevel( MSG::DEBUG ) ) + debug() << "fetch_lumi_json( " << key << " -> " << id << " ) from repo " << m_repo.value() << endmsg; + + auto s = fetch_from_repos( [&]( auto const& tag ) { return fmt::format( m_lumi_fmt.value(), tag, id ); } ); + if ( !s ) return std::nullopt; + auto json = nlohmann::json::parse( *s, nullptr, false ); + if ( json.is_discarded() ) return std::nullopt; + return json; + } + + lumi_schema_t fetch_lumi( unsigned int key, unsigned int version ) const override { + if ( msgLevel( MSG::DEBUG ) ) debug() << "fetch lumi(" << key << "," << version << ")" << endmsg; + auto json = fetch_lumi_json( key ); + if ( !json ) + throw GaudiException( fmt::format( "unable to obtain json for key {:08x} from repositories {}", key, + Gaudi::Utils::toString( m_repo.value() ) ), + "GitANNSvc::fetch_lumi", StatusCode::FAILURE ); + auto vs = json->find( "version" ); + if ( vs == json->end() || vs->template get<unsigned>() != version ) { + // must have correct version!!!) + error() << "wrong version" << endmsg; + return {}; + } + auto sz = json->find( "size" ); + if ( sz == json->end() ) { + error() << "no size" << endmsg; + return {}; + } + auto j = json->find( "counters" ); + if ( j == json->end() ) { + error() << "no counters" << endmsg; + return {}; + } + lumi_schema_t m; + m.size = sz->template get<unsigned>(); + std::transform( j->begin(), j->end(), std::back_inserter( m.counters ), + []( const nlohmann::json& k ) { return IIndexedLumiSchemaSvc::from_json( k ); } ); + return m; + } + public: using ANNSvcBase::ANNSvcBase; }; diff --git a/Hlt/HltServices/src/TCKANNSvc.cpp b/Hlt/HltServices/src/TCKANNSvc.cpp index 1ebdc229d5c057b8fd4d5d0dfae13e7af675097a..40b1037851d0e3e39523969bc1a1a44f785bc8af 100644 --- a/Hlt/HltServices/src/TCKANNSvc.cpp +++ b/Hlt/HltServices/src/TCKANNSvc.cpp @@ -54,6 +54,11 @@ namespace std { class TCKANNSvc : public ANNSvcBase { + lumi_schema_t fetch_lumi( unsigned int, unsigned int ) const override { + throw GaudiException( "fetch_lumi not supported -- please use different service implementation", + __PRETTY_FUNCTION__, StatusCode::FAILURE ); + return {}; + } map_t fetch( unsigned int tck, const Gaudi::StringKey& major ) const override { TCK _tck( tck ); _tck.normalize(); diff --git a/Kernel/HltInterfaces/include/Kernel/IIndexedLumiSchemaSvc.h b/Kernel/HltInterfaces/include/Kernel/IIndexedLumiSchemaSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..36df796eef1fd972d6b6271b66387dd4080dcbda --- /dev/null +++ b/Kernel/HltInterfaces/include/Kernel/IIndexedLumiSchemaSvc.h @@ -0,0 +1,48 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ +#pragma once + +// Include files +#include "GaudiKernel/INamedInterface.h" + +/** @class ITCKANNSvc ITCKANNSvc.h + * + * return the layout of a lumi bank given a key + * + * @author Gerhard Raven + * @date 2014-05-29 + */ + +struct IIndexedLumiSchemaSvc : extend_interfaces<INamedInterface> { +public: + /// Return the interface ID + DeclareInterfaceID( IIndexedLumiSchemaSvc, 1, 0 ); + + struct CounterDefinition { + std::string name; + unsigned size; + unsigned offset; + }; + + template <typename JSON> + static CounterDefinition from_json( const JSON& json ) { + return CounterDefinition{json["name"].template get<std::string>(), json["size"].template get<unsigned>(), + json["offset"].template get<unsigned>()}; + } + + struct lumi_schema_t { + unsigned size; + std::vector<CounterDefinition> counters; + }; + + // given a bank of version `version`, and a key `key`, return which counters can be found where + virtual lumi_schema_t const& lumiCounters( unsigned key, unsigned version ) const = 0; +};