diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx index 65d96da865ea12493c6e6586438d14441f028dac..d40bf149f5a97c80fa51ba5156def855eeb90c03 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx +++ b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.cxx @@ -46,8 +46,8 @@ StatusCode CostData::cache() { return StatusCode::SUCCESS; } -void CostData::setRosToRobMap(const std::map<std::string, std::vector<uint32_t>>& rosToRobMap) { - m_rosToRob = &rosToRobMap; +void CostData::setCostROSData(const CostROSData& costROSData) { + m_costROSData = &costROSData; } void CostData::setLb(uint32_t lb) { @@ -84,8 +84,8 @@ const xAOD::TrigCompositeContainer& CostData::rosCollection() const { return *m_rosCollection; } -const std::map<std::string, std::vector<uint32_t>>& CostData::rosToRobMap() const { - return *m_rosToRob; +const CostROSData& CostData::costROSData() const { + return *m_costROSData; } const std::map<size_t, std::vector<size_t>>& CostData::algToRequestMap() const { diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h index 6df7dd102ae77c3c30540fd5f168f06f641cb599..dd91192c123282f4814eda0da50d13272a65aa47 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h +++ b/Trigger/TrigCost/TrigCostAnalysis/src/CostData.h @@ -10,6 +10,8 @@ #include "TrigConfData/HLTChain.h" #include "TrigCompositeUtils/AlgToChainTool.h" +#include "CostROSData.h" + #include <map> #include <vector> @@ -61,12 +63,12 @@ class CostData { /** * @brief Getter of the ROS to ROB map. */ - const std::map<std::string, std::vector<uint32_t>>& rosToRobMap() const; + const CostROSData& costROSData() const; /** * @brief Set ROS to ROB map */ - void setRosToRobMap(const std::map<std::string, std::vector<uint32_t>>& rosToRobMap); + void setCostROSData(const CostROSData& costROSData); /** * @brief Getter of the alg name to chains map. @@ -191,7 +193,7 @@ class CostData { bool m_liveTimeIsPerEvent; //!< If the livetime represents a single event or all of the current LB const std::unordered_map<uint32_t, std::string>* m_typeMapPtr; //!< Cached non-owning pointer mapping algorithm instance names to types std::map<size_t, std::vector<size_t>> m_algToRos; //!< Mapping of indexes from m_costCollection to corresponding ROS requests made by algorithm - const std::map<std::string, std::vector<uint32_t>>* m_rosToRob = nullptr; //!< Mapping of ROS corresponding to ROB requests + const CostROSData* m_costROSData = nullptr; //!< Helper class to store ROS to ROB mapping const std::map<std::string, std::set<size_t>>* m_chainToAlgIdx = nullptr; //!<Mapping of chain to algorithms idx const std::map<std::string, std::set<size_t>>* m_chainToUniqAlgIdx = nullptr; //!<Mapping of chain name to its unique algorithms const std::map<std::string, std::map<int16_t, std::set<size_t>>>* m_sequencers = nullptr; //!<Mapping of sequence to algorithms diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/CostROSData.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/CostROSData.cxx new file mode 100644 index 0000000000000000000000000000000000000000..eb76d7df6f932899cf3456fa8ad89b1414afdcb2 --- /dev/null +++ b/Trigger/TrigCost/TrigCostAnalysis/src/CostROSData.cxx @@ -0,0 +1,70 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +#include "CostROSData.h" + + +void CostROSData::initialize(const std::map<std::string, std::vector<uint32_t>>& rosToRobMap) { + + unsigned rosCounter = 0; + + for (const auto& rosRequest : rosToRobMap) { + for (uint32_t robId : rosRequest.second) { + m_robToRos[robId] = rosRequest.first; + } + m_rosIdToBin[rosRequest.first] = rosCounter; + ++rosCounter; + } + + m_rosToRob = rosToRobMap; + + m_msgStream.reset(new MsgStream(nullptr, "CostROSData")); +} + + +int CostROSData::getBinForROS(const std::string& rosName) const { + try { + return m_rosIdToBin.at(rosName); + } catch (const std::out_of_range& e) { + ATH_MSG_DEBUG("Bin for ROS " << rosName << " not found"); + return -1; + } +} + + +std::string CostROSData::getROSForROB(uint32_t robId) const { + try { + return m_robToRos.at(robId); + } catch (const std::out_of_range& e) { + ATH_MSG_DEBUG("ROS for ROB " << getROBName(robId) << " not found"); + return ""; + } +} + +std::vector<uint32_t> CostROSData::getROBForROS(const std::string& rosName) const { + try { + return m_rosToRob.at(rosName); + } catch (const std::out_of_range& e) { + ATH_MSG_DEBUG("ROBs for ROS " << rosName << " not found"); + return std::vector<uint32_t>(); + } +} + +std::string CostROSData::getROBName(uint32_t robId) const { + std::stringstream robName; + robName << "0x" << std::hex << robId; + return robName.str(); +} + +MsgStream& CostROSData::msg() const { + return *m_msgStream; +} + +MsgStream& CostROSData::msg(const MSG::Level lvl) const { + return *m_msgStream << lvl; +} + +bool CostROSData::msgLvl(const MSG::Level lvl) const { + return lvl >= m_msgStream->level(); +} \ No newline at end of file diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/CostROSData.h b/Trigger/TrigCost/TrigCostAnalysis/src/CostROSData.h new file mode 100644 index 0000000000000000000000000000000000000000..a49da140ce253429035588396149ba05b86b2659 --- /dev/null +++ b/Trigger/TrigCost/TrigCostAnalysis/src/CostROSData.h @@ -0,0 +1,106 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TRIGCOSTANALYSIS_COSTROSDATA_H +#define TRIGCOSTANALYSIS_COSTROSDATA_H 1 + +#include "AsgMessaging/MsgStream.h" +#include "AthenaBaseComps/AthMsgStreamMacros.h" + +#include <boost/thread/tss.hpp> + +#include <map> +#include <vector> + +/** + * @class CostROSData + * @brief Caches and propagates event data to be used by monitoring algorithms. + * + * The cache is created on passed rosToRob map + * +*/ + +class CostROSData{ + public: + + /** + * @brief Create object based on ROS to ROB mapping + */ + void initialize(const std::map<std::string, std::vector<uint32_t>>& rosToRobMap); + + /** + * @brief Return cached bin for given ROS name + * @param[in] rosName ROS name + * @return Bin number or -1 if not found + */ + int getBinForROS(const std::string& rosName) const; + + /** + * @brief Return ROS name for given ROB + * @param[in] robId ROB id + * @return ROS name + */ + std::string getROSForROB(uint32_t robId) const; + + /** + * @brief Return list of ROBs name for given ROS + * @param[in] rosName ROS name + * @return List of ROBs + */ + std::vector<uint32_t> getROBForROS(const std::string& rosName) const; + + /** + * @brief Create ROB name in hex string format + * @param[in] robId ROB id + * @return ROB id saved in hexadecimal representation + */ + std::string getROBName(uint32_t robId) const; + + /** + * @brief Return number of saved unique ROSes + * @return Number of ROSes + */ + unsigned getNROS() const {return m_rosIdToBin.size();} + + /** + * @brief Return ROS name to ROB ids map + * @return ROS name to ROB ids map + */ + const std::map<std::string, std::vector<uint32_t>>& getROStoROBMap() const {return m_rosToRob;} + + /** + * @brief Return ROB id to ROS name map + * @return ROB id to ROS name map + */ + const std::map<uint32_t, std::string>& getROBtoROSMap() const {return m_robToRos;} + + /** + * @brief Logging + * @return Message stream reference. + */ + MsgStream& msg() const; + + /** + * @brief Logging on a given level + * @param[in] lvl Verbosity level + * @return Message stream reference. + */ + MsgStream& msg(const MSG::Level lvl) const; + + /** + * @brief Returns if requested level is same or higher than logging level + * @param[in] lvl Verbosity level + * @return If requested level is same or higher than logging level + */ + bool msgLvl(const MSG::Level lvl) const; + + private: + std::map<std::string, std::vector<uint32_t>> m_rosToRob ; //!< Mapping of ROS corresponding to ROB requests + std::map<uint32_t, std::string> m_robToRos; //!< Mapping of ROB corresponding to ROS + std::map<std::string, int> m_rosIdToBin; //!< Cached mapping of ros id to bin in ROS histograms + + mutable boost::thread_specific_ptr<MsgStream> m_msgStream; +}; + +#endif // TRIGCOSTANALYSIS_COSTROSDATA_H \ No newline at end of file diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/CounterBase.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/CounterBase.cxx index 07ea9fcccfd74953bf1f523d1b45779a73213d6d..08dd97675bf42e1c44226dc198bfb8aed6e5d244 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/CounterBase.cxx +++ b/Trigger/TrigCost/TrigCostAnalysis/src/CounterBase.cxx @@ -7,6 +7,7 @@ #include "CounterBase.h" #include "TH1F.h" #include "TH2F.h" +#include "TProfile.h" CounterBase::CounterBase(const std::string& name, const MonitorBase* parent) : m_name(name), m_parent(parent) { @@ -64,6 +65,47 @@ void CounterBase::regHistogram(const std::string& name, // Histogram is now owned by THistSvc. A cache of the ptr is kept in the Variable } +void CounterBase::regTProfile(const std::string& name, + const std::string& title, + const VariableType type, + const LogType xaxis, + const float min, + const float max, + const size_t bins) +{ + std::string hisSvcName = getParent()->getParent()->getName() + "_" + getParent()->getName() + "_" + getName() + "_" + name; + std::unique_ptr<TProfile> hist; + + if (max <= min || bins == 0) { + throw std::runtime_error("CounterBase::regTProfile: Cannot have max <= min or bins == 0"); + } + + if (xaxis == kLinear) { + hist = std::make_unique<TProfile>(hisSvcName.c_str(), title.c_str(), bins, min, max); + } else if (xaxis == kLog) { + if (min <= 0) { + throw std::runtime_error("CounterBase::regTProfile: Cannot have min <= 0 with log binning"); + } + std::unique_ptr<double[]> xbins = std::make_unique<double[]>(bins+1); + const double xlogmin = log10(min); + const double xlogmax = log10(max); + const double dlogx = (xlogmax-xlogmin)/((double)bins); + for (size_t i = 0; i <= bins; ++i) { + const double xlog = xlogmin + i*dlogx; + xbins[i] = exp( log(10) * xlog ); + } + hist = std::make_unique<TProfile>(hisSvcName.c_str(), title.c_str(), bins, xbins.get()); + } else { + throw std::runtime_error("CounterBase::regTProfile: Unknown logarithm flag"); + } + + m_variables.emplace(std::piecewise_construct, + std::forward_as_tuple(name), + std::forward_as_tuple(name, bookGetPointer(hist.release()), type) + ); + // Histogram is now owned by THistSvc. A cache of the ptr is kept in the Variable +} + void CounterBase::regHistogram(const std::string& name, const std::string& title, const VariableType type, @@ -133,6 +175,10 @@ void CounterBase::regHistogram(const std::string& name, // Histogram is now owned by THistSvc. A cache of the ptr is kept in the Variable } +bool CounterBase::variableExists(const std::string& name) const { + return (m_variables.count(name) == 1); +} + Variable& CounterBase::getVariable(const std::string& name) { auto it = m_variables.find(name); if (it == m_variables.end()) { diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/CounterBase.h b/Trigger/TrigCost/TrigCostAnalysis/src/CounterBase.h index c02c3936519a5e005d91ae78d1889832e4fec31a..d74cf21a042fac2fdd27b0a1b0b144991a789f74 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/CounterBase.h +++ b/Trigger/TrigCost/TrigCostAnalysis/src/CounterBase.h @@ -63,6 +63,13 @@ class CounterBase { */ const MonitorBase* getParent() const; + /** + * @brief Check if a variable of a given name exists. + * @param[in] name Name of Variable. + * @return True if variable already exists. + */ + bool variableExists(const std::string& name) const; + /** * @brief Returns a mutable reference to a named Variable. Throws if no such Variable exists. * Used when more complicated logic is needed on a Variable than simply using the fill() method. @@ -134,6 +141,22 @@ class CounterBase { const float max = 1000000., const size_t bins = 70); + /** + * @brief Book a TProfile for this Counter, to be filled in per-event monitoring. + * @param[in] name The name of the histogram (and corresponding Variable) + * @param[in] title ROOT histogram title string in format "title;xaxis;yaxis" + * @param[in] xaxis Controls if the x-axis should use fixed-width or logarithmic bin boundaries. + * @param[in] min X-axis minimum bound. + * @param[in] max X-axis maximum bound. + * @param[in] bins Number of histogram bins. + */ + void regTProfile(const std::string& name, + const std::string& title, + const VariableType type = VariableType::kPerCall, + const LogType xaxis = kLog, + const float min = 0.1, + const float max = 1000000., + const size_t bins = 70); /** * @brief Book a 2D histogram for this Counter, to be filled in per-event monitoring. diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx index cd560a76f08ddd2803da36be080df973eaf80483..a8f9979f76fec488d51d4ed0fbc9f5d79dc54d36 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx +++ b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.cxx @@ -62,6 +62,8 @@ StatusCode TrigCostAnalysis::initialize() { TrigConf::HLTUtils::file2hashes(hashFile); } } + + m_costROSData.initialize(m_rosToRob); ATH_CHECK( m_histSvc->regTree("/COSTSTREAM/metadata", std::make_unique<TTree>("metadata", "metadata")) ); ATH_CHECK( m_histSvc->getTree("/COSTSTREAM/metadata", m_metadataTree) ); @@ -272,7 +274,7 @@ StatusCode TrigCostAnalysis::execute() { const uint32_t onlineSlot = getOnlineSlot( costDataHandle.get() ); CostData costData; ATH_CHECK( costData.set(costDataHandle.get(), rosDataHandle.get(), onlineSlot) ); - costData.setRosToRobMap(m_rosToRob); + costData.setCostROSData(m_costROSData); costData.setChainToAlgMap(chainToAlgIdx); costData.setChainToUniqAlgMap(chainToUniqAlgs); costData.setSequencersMap(seqToAlgIdx); diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h index a63b4706310668834f8664e4d59f97cde85a6c83..8363e592f4cbae1e581a84ad1dc6f386ac3d0b7f 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h +++ b/Trigger/TrigCost/TrigCostAnalysis/src/TrigCostAnalysis.h @@ -17,6 +17,7 @@ #include "GaudiKernel/ITHistSvc.h" #include "MonitoredRange.h" +#include "CostROSData.h" #include <unordered_map> #include <mutex> @@ -218,6 +219,7 @@ class TrigCostAnalysis: public ::AthAlgorithm { std::mutex m_addHostnameMutex; //!< Mutex to update set below mutable std::set<std::string> m_hostnames ATLAS_THREAD_SAFE; //!< Save unique hostnames for the run + CostROSData m_costROSData; //!< Cached CostROSData class with details needed for ROS monitoring }; #endif // TRIGCOSTANALYSIS_TRIGCOSTALYSIS_H diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/Variable.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/Variable.cxx index f4fa5ba45c1c1e259df1dcf314f65694d3b637a3..9a5fa301f9925291ca54b9ac36dab07f823af2c3 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/Variable.cxx +++ b/Trigger/TrigCost/TrigCostAnalysis/src/Variable.cxx @@ -7,6 +7,7 @@ #include "Variable.h" #include "TH1F.h" #include "TH2F.h" +#include "TProfile.h" Variable::Variable(const std::string& name, TH1* cacheHistoPtr, VariableType type) : m_name(name), @@ -67,9 +68,17 @@ StatusCode Variable::fill(float value, float weight) { StatusCode Variable::fill(float xvalue, float yvalue, float weight) { switch(m_variableType) { case kPerCall: + { ATH_CHECK(m_cacheHistoPtr != nullptr); - dynamic_cast<TH2F*>(m_cacheHistoPtr)->Fill(xvalue * m_oneOverDenominator, yvalue * m_oneOverDenominator, weight); + TH2F* th2f = dynamic_cast<TH2F*>(m_cacheHistoPtr); + if (th2f == nullptr){ + // Cast failed - should be TProfile + dynamic_cast<TProfile*>(m_cacheHistoPtr)->Fill(xvalue * m_oneOverDenominator, yvalue * m_oneOverDenominator, weight); + } else { + th2f->Fill(xvalue * m_oneOverDenominator, yvalue * m_oneOverDenominator, weight); + } break; + } case kPerEvent: ++m_calls; m_xaccumulator += xvalue; @@ -102,12 +111,24 @@ StatusCode Variable::setBinLabel(int bin, const std::string& label) { } +StatusCode Variable::setYBinLabel(int bin, const std::string& label) { + m_cacheHistoPtr->GetYaxis()->SetBinLabel(bin, label.c_str()); + return StatusCode::SUCCESS; +} + + StatusCode Variable::endEvent() { if (m_variableType == kPerEvent && m_calls > 0) { ATH_CHECK(m_cacheHistoPtr != nullptr); // 2D histogram if (m_yaccumulator > 0){ - dynamic_cast<TH2F*>(m_cacheHistoPtr)->Fill(m_xaccumulator * m_oneOverDenominator, m_yaccumulator, m_weight); + TH2F* th2f = dynamic_cast<TH2F*>(m_cacheHistoPtr); + if (th2f == nullptr){ + // Cast failed - should be TProfile + dynamic_cast<TProfile*>(m_cacheHistoPtr)->Fill(m_xaccumulator * m_oneOverDenominator, m_yaccumulator, m_weight); + } else { + th2f->Fill(m_xaccumulator * m_oneOverDenominator, m_yaccumulator, m_weight); + } } else { m_cacheHistoPtr->Fill(m_xaccumulator * m_oneOverDenominator, m_weight); } diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/Variable.h b/Trigger/TrigCost/TrigCostAnalysis/src/Variable.h index 5101aedafa650267bdd76883131a040cc6756d8c..db14619afe0b22d8d6da9c2912e0d09c5bd1122a 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/Variable.h +++ b/Trigger/TrigCost/TrigCostAnalysis/src/Variable.h @@ -118,7 +118,14 @@ class Variable { * @param[in] label Label to set */ StatusCode setBinLabel(int bin, const std::string& label); - + + /** + * @brief Set label on given bin in cached histogram on y axis + * @param[in] bin Bin number + * @param[in] label Label to set + */ + StatusCode setYBinLabel(int bin, const std::string& label); + /** * @brief Sets, until the end of the event, a denominator which will be used to normalise every Fill. * @pram[in] value The denominator to normalise Fill operations. diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx index 64a988cfb4788bdbf09b600931af95f30b4b547d..4b01b2140ee98bc47b18a79829a66320013fd04e 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx +++ b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.cxx @@ -9,7 +9,7 @@ CounterChain::CounterChain(const std::string& name, const MonitorBase* parent) - : CounterBase(name, parent) + : CounterBase(name, parent), m_isInitialized(false) { regHistogram("Group_perCall", "Chain group/Call;Group;Calls", VariableType::kPerCall, kLinear, -0.5, 9.5, 10); regHistogram("Chain_perEvent", "Chain calls/Event;Chain call;Events", VariableType::kPerEvent, kLinear, -0.5, 49.5); @@ -25,17 +25,37 @@ CounterChain::CounterChain(const std::string& name, const MonitorBase* parent) regHistogram("RequestTime_perEvent", "ROB Elapsed Time/Event;Elapsed Time [ms];Events", VariableType::kPerEvent); } +CounterChain::CounterChain(const std::string& name, unsigned nRos, const MonitorBase* parent) + : CounterChain(name, parent) +{ + regTProfile("ROSRequests_perEvent", "Number of ROS requests;ROS names;Numer of requests to ROS per event", VariableType::kPerCall, LogType::kLinear, 0, nRos, nRos); + regTProfile("ROBRequestsPerROS_perEvent", "Number of ROBs per ROS requests;ROS names;Numer of ROBs requested per request", VariableType::kPerCall, LogType::kLinear, 0, nRos, nRos); + regTProfile("ROBRequestsPerROSPerEvent_perEvent", "Number of ROBs per ROS requests per event;ROS names;Numer of ROBs requested by ROS per event", VariableType::kPerCall, LogType::kLinear, 0, nRos, nRos); +} + StatusCode CounterChain::newEvent(const CostData& data, size_t index, const float weight) { ATH_CHECK( increment("Chain_perEvent", weight) ); - // Fill the bins with groups and add the labels - int bin = 1; - for (const std::string& group : data.seededChains()[index].groups){ - ATH_CHECK( getVariable("Group_perCall").setBinLabel(bin, group) ); - ATH_CHECK( getVariable("Group_perCall").fill(group, weight) ); - ++bin; + if (!m_isInitialized && variableExists("ROSRequests_perEvent")) { + // Set histograms labels + for (const auto& rosToRobPair : data.costROSData().getROStoROBMap()) { + int binForROS = data.costROSData().getBinForROS(rosToRobPair.first) + 1; + ATH_CHECK( getVariable("ROSRequests_perEvent").setBinLabel(binForROS, rosToRobPair.first)); + ATH_CHECK( getVariable("ROBRequestsPerROS_perEvent").setBinLabel(binForROS, rosToRobPair.first)); + ATH_CHECK( getVariable("ROBRequestsPerROSPerEvent_perEvent").setBinLabel(binForROS, rosToRobPair.first)); + } + + // Fill the bins with groups and add the labels + int bin = 1; + for (const std::string& group : data.seededChains()[index].groups){ + ATH_CHECK( getVariable("Group_perCall").setBinLabel(bin, group) ); + ATH_CHECK( getVariable("Group_perCall").fill(group, weight) ); + ++bin; + } + + m_isInitialized = true; } if (data.seededChains()[index].isPassRaw){ @@ -45,6 +65,8 @@ StatusCode CounterChain::newEvent(const CostData& data, size_t index, const floa // Monitor algorithms associated with chain name if (!data.chainToAlgMap().count(getName())) return StatusCode::SUCCESS; + std::map<std::string, int> nRosPerEvent; // Accumulate how many times ROS was requested in a request per this event + std::map<std::string, int> nRobsPerRosPerEvent; // Accumulate how many ROBs ROS requested per this event for (const size_t algIndex : data.chainToAlgMap().at(getName())){ const xAOD::TrigComposite* alg = data.costCollection().at(algIndex); const uint32_t slot = alg->getDetail<uint32_t>("slot"); @@ -65,10 +87,14 @@ StatusCode CounterChain::newEvent(const CostData& data, size_t index, const floa for (size_t requestIdx : data.algToRequestMap().at(algIndex)) { const xAOD::TrigComposite* request = data.rosCollection().at(requestIdx); + const std::vector<uint32_t> robIdsPerRequest = request->getDetail<std::vector<uint32_t>>("robs_id"); const std::vector<unsigned> robs_history = request->getDetail<std::vector<unsigned>>("robs_history"); const std::vector<uint32_t> robs_size = request->getDetail<std::vector<uint32_t>>("robs_size"); + std::map<std::string, int> nRobsPerRosPerRequest; // Accumulate how many ROBs ROS requested per request + bool networkRequestIncremented = false; + std::set<std::string> requestedROSes; for (size_t i = 0; i < robs_size.size(); ++i) { // ROB request was fetched over the network if (robs_history[i] == robmonitor::RETRIEVED) { @@ -80,8 +106,28 @@ StatusCode CounterChain::newEvent(const CostData& data, size_t index, const floa else if (robs_history[i] == robmonitor::HLT_CACHED || robs_history[i] == robmonitor::DCM_CACHED) { ATH_CHECK( fill("CachedROBSize_perEvent", robs_size[i] / 500., weight) ); } + + uint32_t robId = robIdsPerRequest[i]; + if (variableExists("ROBRequestsPerROS_perEvent")){ + std::string rosForROB = data.costROSData().getROSForROB(robId); + if (!rosForROB.empty()){ + requestedROSes.insert(rosForROB); + nRobsPerRosPerRequest[rosForROB] += 1; + nRobsPerRosPerEvent[rosForROB] += 1; + } + } + } + + // Save number of ROBs per ROS per request + for (const auto& robPerRosPair : nRobsPerRosPerRequest) { + ATH_CHECK( fill("ROBRequestsPerROS_perEvent", data.costROSData().getBinForROS(robPerRosPair.first), robPerRosPair.second, weight) ); } + // Save the requested ROSes per request + for (const std::string& rosName : requestedROSes){ + nRosPerEvent[rosName] += 1; + } + ATH_CHECK( increment("Request_perEvent", weight) ); if (networkRequestIncremented) { @@ -93,6 +139,16 @@ StatusCode CounterChain::newEvent(const CostData& data, size_t index, const floa } } + // Save the requested ROSes per event + for (const auto& robPerRosPair : nRosPerEvent) { + ATH_CHECK( fill("ROSRequests_perEvent", data.costROSData().getBinForROS(robPerRosPair.first), robPerRosPair.second, weight) ); + } + + // Save the number of ROBs per ROS per event + for (const auto& robPerRosPair : nRobsPerRosPerEvent) { + ATH_CHECK( fill("ROBRequestsPerROSPerEvent_perEvent", data.costROSData().getBinForROS(robPerRosPair.first), robPerRosPair.second, weight) ); + } + // Monitor unique algorithms associated with chain name if (!data.chainToUniqAlgMap().count(getName())) return StatusCode::SUCCESS; diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.h b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.h index ebdeaddf2fb867490f4a927f36f73d7a1d14919d..32b604ac6d30290fd71f4c74f8ab518632fe6029 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.h +++ b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterChain.h @@ -25,6 +25,14 @@ class CounterChain : public CounterBase { */ CounterChain(const std::string& name, const MonitorBase* parent); + /** + * @brief Construct counter. + * @param[in] name Counter's name + * @param[in] nRos Number of possible ROSes + * @param[in] parent Counter's parent monitor, cached non-owning pointer. + */ + CounterChain(const std::string& name, unsigned nRos, const MonitorBase* parent); + /** * @brief Default destructor. */ @@ -47,6 +55,9 @@ class CounterChain : public CounterBase { * @param[in] weight Global event weight */ virtual StatusCode newEvent(const CostData& data, size_t index, const float weight = 1.) override; + + private: + bool m_isInitialized; }; #endif // TRIGCOSTANALYSIS_COUNTERALGORITHM_H diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterROS.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterROS.cxx index 540ba26d8f830246e8fa27a8fc641d45f6bba4b1..14716748d649b9151eff5050b3bf459a4721d915 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterROS.cxx +++ b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterROS.cxx @@ -22,6 +22,12 @@ CounterROS::CounterROS(const std::string& name, const MonitorBase* parent) regHistogram("ROBStatus_perCall", "ROB status/Call;Status;Events", VariableType::kPerCall, LogType::kLinear, 0, robmonitor::NUM_ROBHIST_CODES+1, robmonitor::NUM_ROBHIST_CODES+1); } +CounterROS::CounterROS(const std::string& name, unsigned nRobs, const MonitorBase* parent) + : CounterROS(name, parent) { + + regHistogram("ROBsPerRequest_perCall", "Number of ROB requests;ROBs names;Number of requests", VariableType::kPerCall, LogType::kLinear, 0, nRobs, nRobs); +} + StatusCode CounterROS::newEvent(const CostData& data, size_t index, const float weight) { // Monitor only ROB data for corresponding ROS @@ -31,23 +37,34 @@ StatusCode CounterROS::newEvent(const CostData& data, size_t index, const float const std::vector<unsigned> robs_history = tc->getDetail<std::vector<unsigned>>("robs_history"); const std::vector<unsigned short> robs_status = tc->getDetail<std::vector<unsigned short>>("robs_status"); - if (m_robIdsPerROS.size() == 0) { - m_robIdsPerROS = data.rosToRobMap().at(getName()); - } - // Set lables of status histogram - ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(1, "Unclassified")); - ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(2, "Retrieved")); - ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(3, "HLT Cached")); - ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(4, "DCM Cached")); - ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(5, "Ignored")); - ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(6, "Disabled")); - ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(7, "IsNotOK")); + if (m_robIdToBin.empty()) { + // Set lables of status histogram + ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(1, "Unclassified")); + ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(2, "Retrieved")); + ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(3, "HLT Cached")); + ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(4, "DCM Cached")); + ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(5, "Ignored")); + ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(6, "Disabled")); + ATH_CHECK( getVariable("ROBStatus_perCall").setBinLabel(7, "IsNotOK")); + + if (variableExists("ROBsPerRequest_perCall")) { + // This monitor has it's own binning for ROBs due to the fact that limited number of ROBs are associated with one ROS + unsigned robCounter = 0; + for (uint32_t robId : data.costROSData().getROBForROS(getName())) { + std::string robName = data.costROSData().getROBName(robId); + ATH_CHECK( getVariable("ROBsPerRequest_perCall").setBinLabel(robCounter+1, robName)); + + m_robIdToBin[robId] = robCounter; + ++robCounter; + } + } + } // Find all ROB requests that are both in request and correspond to this ROS bool networkRequestIncremented = false; for (size_t i = 0; i < robIdsPerRequest.size(); ++i) { - if (std::find(m_robIdsPerROS.begin(), m_robIdsPerROS.end(), robIdsPerRequest[i]) != m_robIdsPerROS.end()) { + if (m_robIdToBin.find(robIdsPerRequest[i]) != m_robIdToBin.end()) { ATH_CHECK( fill("ROBStatus_perCall", getROBHistoryBin(robs_history[i]), weight) ); // Status is ok when no status words are set if (robs_status[i] != 0) { @@ -64,6 +81,10 @@ StatusCode CounterROS::newEvent(const CostData& data, size_t index, const float else if (robs_history[i] == robmonitor::HLT_CACHED || robs_history[i] == robmonitor::DCM_CACHED) { ATH_CHECK( fill("CachedROBSize_perEvent", robs_size[i] / 500., weight) ); } + + if (variableExists("ROBsPerRequest_perCall")){ + ATH_CHECK( fill("ROBsPerRequest_perCall", m_robIdToBin.at(robIdsPerRequest[i]), weight) ); + } } } diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterROS.h b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterROS.h index 88115a3f27a54eda87d1d6e2685971b421a4d7d0..b9fffb09e2a155ad91860da2785dca47af1621f7 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterROS.h +++ b/Trigger/TrigCost/TrigCostAnalysis/src/counters/CounterROS.h @@ -26,6 +26,14 @@ class CounterROS : public CounterBase { */ CounterROS(const std::string& name, const MonitorBase* parent); + /** + * @brief Construct counter. + * @param[in] name Counter's name + * @param[in] nRobs Number of ROBs possible for this ROB + * @param[in] parent Counter's parent monitor, cached non-owning pointer. + */ + CounterROS(const std::string& name, unsigned nRobs, const MonitorBase* parent); + /** * @brief Default destructor. */ @@ -56,7 +64,7 @@ class CounterROS : public CounterBase { */ int getROBHistoryBin(const unsigned history); - std::vector<uint32_t> m_robIdsPerROS; //!< Cached mapping of ROB ids corresponding to ROS + std::map<uint32_t, unsigned> m_robIdToBin; //!< Cached mapping of rob id to bin in ROBsPerRequest_perEvent histogram }; #endif // TRIGCOSTANALYSIS_COUNTERROS_H \ No newline at end of file diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.cxx index d05063ed8441a592a9a0fd2ad67c071d2f88f96a..8d6442bd5e6e2c770cd68a514ad5f3b2dedd7248 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.cxx +++ b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.cxx @@ -13,13 +13,21 @@ StatusCode MonitorChain::newEvent(const CostData& data, const float weight) { const std::vector<TrigCompositeUtils::AlgToChainTool::ChainInfo>& seededChains = data.seededChains(); for (size_t i = 0; i < seededChains.size(); ++i){ - ATH_CHECK( getCounter(seededChains[i].name)->newEvent(data, i, weight) ); + std::string chainName = seededChains[i].name; + if (!counterExists(chainName)){ + // Create a new counter using specialized constructor in order to pass number of bins for some of the histograms + m_counters.insert( std::make_pair(chainName, newCounter(chainName, data.costROSData().getNROS())) ); + } + ATH_CHECK( getCounter(chainName)->newEvent(data, i, weight) ); } return StatusCode::SUCCESS; } - std::unique_ptr<CounterBase> MonitorChain::newCounter(const std::string& name) { return std::make_unique<CounterChain>(name, this); } + +std::unique_ptr<CounterBase> MonitorChain::newCounter(const std::string& name, unsigned nROS) { + return std::make_unique<CounterChain>(name, nROS, this); +} \ No newline at end of file diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.h b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.h index 3fe9643a8718f63525fa2746ba9d765cd4a8bf9a..b014c012f1fa505dcd363023386b86663610ecdb 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.h +++ b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorChain.h @@ -54,6 +54,14 @@ class MonitorChain : public MonitorBase { * @return Owning unique ptr object typed on the CounterBase base class which points to concrete Counter of specialised type. */ virtual std::unique_ptr<CounterBase> newCounter(const std::string& name) override; + + /** + * @brief Concrete counter instantiation. Mints named counter of CounterAlgorith type. + * @param[in] name Name of Counter to mint. + * @param[in] nROS Number of possible ROB ids to initialize ROB monitoring histograms + * @return Owning unique ptr object typed on the CounterBase base class which points to concrete Counter of specialised type. + */ + std::unique_ptr<CounterBase> newCounter(const std::string& name, unsigned nROS); }; #endif // TRIGCOSTANALYSIS_MONITORCHAIN_H diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorROS.cxx b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorROS.cxx index 660500303245ba0fd806dd9124c3bb5beaeed036..66670f1c906dd1590fa038dbc0b6e03baa173664 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorROS.cxx +++ b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorROS.cxx @@ -14,16 +14,6 @@ MonitorROS::MonitorROS(const std::string& name, const MonitoredRange* parent) StatusCode MonitorROS::newEvent(const CostData& data, const float weight) { - // Prepare ROB id per corresponding ROS name map - if (m_robToRos.empty()) { - const std::map<std::string, std::vector<uint32_t>>& rosToRobMap = data.rosToRobMap(); - for (const auto& rosRequest : rosToRobMap) { - for (uint32_t robId : rosRequest.second) { - m_robToRos[robId] = rosRequest.first; - } - } - } - if (data.rosCollection().empty()){ ATH_MSG_DEBUG("The ROS collection is empty!"); } @@ -33,14 +23,23 @@ StatusCode MonitorROS::newEvent(const CostData& data, const float weight) { // Create set of unique ROS for this request std::set<std::string> rosPerRequest; for (uint32_t robId : robIds) { - if (!m_robToRos.count(robId)){ + if (data.costROSData().getROSForROB(robId).empty()){ ATH_MSG_WARNING("ROS for ROB 0x" << std::hex << robId << " is missing"); continue; } - rosPerRequest.insert(m_robToRos.at(robId)); + std::string rosForROB = data.costROSData().getROSForROB(robId); + if (!rosForROB.empty()){ + rosPerRequest.insert(rosForROB); + } } for (const std::string& rosName : rosPerRequest) { + if (!counterExists(rosName)){ + // Create a new counter using specialized constructor in order to pass number of bins for some of the histograms + unsigned nRobs = data.costROSData().getROBForROS(rosName).size(); // Number of all possible ROBs for this ROS + m_counters.insert( std::make_pair(rosName, newCounter(rosName, nRobs)) ); + } + ATH_CHECK( getCounter(rosName)->newEvent(data, tc->index(), weight) ); } } @@ -52,3 +51,7 @@ StatusCode MonitorROS::newEvent(const CostData& data, const float weight) { std::unique_ptr<CounterBase> MonitorROS::newCounter(const std::string& name) { return std::make_unique<CounterROS>(name, this); } + +std::unique_ptr<CounterBase> MonitorROS::newCounter(const std::string& name, unsigned nRobs) { + return std::make_unique<CounterROS>(name, nRobs, this); +} \ No newline at end of file diff --git a/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorROS.h b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorROS.h index 47d59d3c50bc7cb5aef28525260ef21c62faa25c..b06965d2892a4fa5d1f23070b2bb27381eaeeb3d 100644 --- a/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorROS.h +++ b/Trigger/TrigCost/TrigCostAnalysis/src/monitors/MonitorROS.h @@ -54,8 +54,14 @@ class MonitorROS : public MonitorBase { */ virtual std::unique_ptr<CounterBase> newCounter(const std::string& name) override; - private: - std::map<uint32_t, std::string> m_robToRos; //!< Cache correspondis ROS per ROB id + /** + * @brief Creates named counter passing the nRobs argument. + * @param[in] name Name of Counter to mint. + * @param[in] nRobs Initialize ROB histograms with nRobs + * @return Owning unique ptr object typed on the CounterBase base class which points to concrete Counter of specialised type. + */ + std::unique_ptr<CounterBase> newCounter(const std::string& name, unsigned nRobs); + }; #endif // TRIGCOSTANALYSIS_MONITORROS_H \ No newline at end of file