Skip to content
Snippets Groups Projects
Commit 385ffc78 authored by Frank Winklmeier's avatar Frank Winklmeier
Browse files

Merge branch 'MTCalibPeb-more-features' into 'master'

MTCalibPeb features: time burning and ROB requests

See merge request atlas/athena!16168
parents 8b83d42b 0b2826ee
No related branches found
No related tags found
No related merge requests found
......@@ -55,9 +55,25 @@ hypo.HypoOutputDecisions = "MTCalibPebDecisions"
hypoTool1 = MTCalibPebHypoTool("HLT_MTCalibPeb1")
hypoTool1.RandomAcceptRate = 0.75
hypoTool1.BurnTimePerCycleMillisec = 100
hypoTool1.NumBurnCycles = 3
hypoTool2 = MTCalibPebHypoTool("HLT_MTCalibPeb2")
hypoTool2.RandomAcceptRate = 0.25
hypoTool2.BurnTimePerCycleMillisec = 200
hypoTool2.NumBurnCycles = 10
hypoTool2.TimeBetweenROBReqMillisec = 100
hypoTool2.ROBAccessDict = {
"01 :ADD: Preload ": [ 0x42002a, 0x42002b ], # robs for 1st preload
"02 :ADD: Preload ": [ 0x42002e, 0x42002f ], # robs for 2nd preload
"03 :GET: Retrieve ": [ 0x42002e, 0x420060 ], # robs for 1st retrieval
"04 :ADD: Preload ": [ 0x420060 ], # robs for 3rd preload
"05 :ADD: Preload ": [ 0x420064 ], # robs for 4th preload
"06 :ADD: Preload ": [ 0x42002e, 0x420060 ], # robs for 5th preload
"07 :GET: Retrieve ": [ 0x420060 ], # robs for 2nd retrieval
"08 :GET: Retrieve ": [ 0x420064 ], # robs for 3rd retrieval
"09 :COL: Ev.Build ": [ 0x0 ] # event building
} # This is just an example with a few ROBs (LAr in this case) for testing the ROBDataProvider
hypo.HypoTools = [hypoTool1, hypoTool2]
......@@ -77,6 +93,10 @@ stmaker.ChainDecisions = "HLTFinalDecisions"
stmaker.ChainToStream = {}
stmaker.ChainToStream["HLT_MTCalibPeb1"] = "DataScouting_05_Jets"
stmaker.ChainToStream["HLT_MTCalibPeb2"] = "Main"
stmaker.StreamSubDets = {}
stmaker.StreamSubDets["Main"] = [0x41, 0x42]
stmaker.StreamRobs = {}
stmaker.StreamRobs["Main"] = [0x42002e, 0x420060, 0x420064]
# Tool adding HLT bits to HLT result
bitsmaker = TriggerBitsMakerTool()
......
......@@ -28,6 +28,7 @@ MTCalibPebHypoAlg::~MTCalibPebHypoAlg() {}
// =============================================================================
StatusCode MTCalibPebHypoAlg::initialize() {
ATH_MSG_INFO("Initialising " << name());
ATH_CHECK(m_hypoTools.retrieve());
return StatusCode::SUCCESS;
}
......@@ -36,6 +37,7 @@ StatusCode MTCalibPebHypoAlg::initialize() {
// =============================================================================
StatusCode MTCalibPebHypoAlg::finalize() {
ATH_MSG_INFO("Finalising " << name());
ATH_CHECK(m_hypoTools.release());
return StatusCode::SUCCESS;
}
......@@ -50,12 +52,11 @@ StatusCode MTCalibPebHypoAlg::execute_r(const EventContext& eventContext) const
auto aux = std::make_unique<DecisionAuxContainer>();
decisions->setStore(aux.get());
// Prepare input for hypo tools
std::vector<MTCalibPebHypoTool::Input> toolInput;
// Create new decision
Decision* newd = newDecisionIn(decisions.get()); // DecisionContainer decisions owns the pointer
toolInput.emplace_back(newd);
// Prepare input for hypo tools
MTCalibPebHypoTool::Input toolInput(newd, eventContext);
// Call the hypo tools
for (const auto& tool: m_hypoTools) {
......
......@@ -2,15 +2,54 @@
Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
*/
// Trigger includes
#include "MTCalibPebHypoTool.h"
// Athena includes
#include "AthenaKernel/Timeout.h"
// System includes
#include <random>
#include <thread>
#include <sstream>
// Local implementation-specific helper methods
namespace {
/// Returns a reference to static thread-local random number generator
std::mt19937& threadLocalGenerator() {
static thread_local std::random_device rd; // used only to ensure different seeds for mt19937
static thread_local std::mt19937 generator(rd());
return generator;
}
/// Basic random real number generation
template<typename T> T randomRealNumber(const T min, const T max) {
std::uniform_real_distribution<T> distribution(min, max);
return distribution(threadLocalGenerator());
}
/// Basic random integer generation
template<typename T> T randomInteger(const T min, const T max) {
std::uniform_int_distribution<T> distribution(min, max);
return distribution(threadLocalGenerator());
}
/// Random bool with a given true rate
bool randomAccept(const double acceptRate) {
static thread_local std::mt19937 generator;
std::uniform_real_distribution<double> distribution(0.0, 1.0);
return (distribution(generator) < acceptRate);
return (randomRealNumber(0.0, 1.0) < acceptRate);
}
/// ROBFragments vector print helper
std::ostream& operator<<(std::ostream& str, const IROBDataProviderSvc::VROBFRAG& robFragments) {
for (const IROBDataProviderSvc::ROBF* robf : robFragments) {
str << "---> ROB ID = 0x" << std::hex << robf->rob_source_id() << std::dec << std::endl
<< " ROD ID = 0x" << std::hex << robf->rod_source_id() << std::dec << std::endl
<< " ROD Level-1 ID = " << robf->rod_lvl1_id() << std::endl;
}
return str;
}
/// ROB ID vector print helper
std::string robIdVecToString(const std::vector<uint32_t>& robIdVec) {
std::ostringstream str;
for (const uint32_t robId : robIdVec)
str << "0x" << std::hex << robId << std::dec << " ";
return str.str();
}
}
......@@ -19,6 +58,7 @@ namespace {
// =============================================================================
MTCalibPebHypoTool::MTCalibPebHypoTool(const std::string& type, const std::string& name, const IInterface* parent)
: AthAlgTool(type,name,parent),
m_robDataProviderSvc("ROBDataProviderSvc", name),
m_decisionId (HLT::Identifier::fromToolName(name)) {}
// =============================================================================
......@@ -31,21 +71,86 @@ MTCalibPebHypoTool::~MTCalibPebHypoTool() {}
// =============================================================================
StatusCode MTCalibPebHypoTool::initialize() {
ATH_MSG_INFO("Initialising " << name());
ATH_CHECK(m_robDataProviderSvc.retrieve());
return StatusCode::SUCCESS;
}
// =============================================================================
StatusCode MTCalibPebHypoTool::decide(const std::vector<MTCalibPebHypoTool::Input>& inputs) const {
// Implementation of AthAlgTool::finalize
// =============================================================================
StatusCode MTCalibPebHypoTool::finalize() {
ATH_MSG_INFO("Finalising " << name());
ATH_CHECK(m_robDataProviderSvc.release());
return StatusCode::SUCCESS;
}
bool accept = randomAccept(m_acceptRate);
for (auto& in : inputs) {
if (accept) {
ATH_MSG_DEBUG("Decision " << m_decisionId << " is accept");
TrigCompositeUtils::addDecisionID(m_decisionId, in.decision);
// =============================================================================
StatusCode MTCalibPebHypoTool::decide(const MTCalibPebHypoTool::Input& input) const {
// ---------------------------------------------------------------------------
// Burn CPU time
// ---------------------------------------------------------------------------
for (unsigned int iCycle = 0; iCycle < m_numBurnCycles; ++iCycle) {
if (Athena::Timeout::instance(input.eventContext).reached()) {
if (m_failOnTimeout) {
ATH_MSG_ERROR("Timeout reached in CPU time burning cycle # " << iCycle+1 << " and FailOnTimeout is true");
return StatusCode::FAILURE;
}
ATH_MSG_INFO("Timeout reached in CPU time burning cycle # " << iCycle+1);
break;
}
unsigned int burnTime = m_burnTimeRandomly
? randomInteger<unsigned int>(0, m_burnTimePerCycleMillisec)
: m_burnTimePerCycleMillisec.value();
ATH_MSG_VERBOSE("CPU time burning cycle # " << iCycle+1 << ", burn time [ms] = " << burnTime);
std::this_thread::sleep_for(std::chrono::milliseconds(burnTime));
}
// ---------------------------------------------------------------------------
// Prefetch or retrieve ROBs
// ---------------------------------------------------------------------------
for (const auto& p : m_robAccessDict) {
// Check for timeout
if (Athena::Timeout::instance(input.eventContext).reached()) {
ATH_MSG_INFO("Timeout reached in ROB retrieval loop");
break;
}
const std::string& instruction = p.first;
const std::vector<uint32_t>& robs = p.second;
if (instruction.find(":ADD:")!=std::string::npos) {
// Prefetch ROBs
ATH_MSG_DEBUG("Preloading ROBs: " << robIdVecToString(robs));
m_robDataProviderSvc->addROBData(input.eventContext, robs, name()+"-ADD");
}
else {
ATH_MSG_DEBUG("Decision " << m_decisionId << " is reject");
if (instruction.find(":GET:")!=std::string::npos) {
// Retrieve ROBs
ATH_MSG_DEBUG("Retrieving ROBs: " << robIdVecToString(robs));
// VROBFRAG = std::vector<const eformat::ROBFragment<const uint32_t*>* >
IROBDataProviderSvc::VROBFRAG robFragments;
m_robDataProviderSvc->getROBData(input.eventContext, robs, robFragments, name()+"-GET");
ATH_MSG_DEBUG("Number of ROBs retrieved: " << robFragments.size());
if (!robFragments.empty())
ATH_MSG_DEBUG("List of ROBs found: " << std::endl << robFragments);
}
if (instruction.find(":COL:")!=std::string::npos) {
// Event building
ATH_MSG_DEBUG("Requesting full event ROBs");
int nrobs = m_robDataProviderSvc->collectCompleteEventData(input.eventContext, name()+"-COL");
ATH_MSG_DEBUG("Number of ROBs retrieved: " << nrobs);
}
std::this_thread::sleep_for(std::chrono::milliseconds(m_timeBetweenRobReqMillisec));
}
// ---------------------------------------------------------------------------
// Random accept decision
// ---------------------------------------------------------------------------
bool accept = randomAccept(m_acceptRate);
if (accept) {
ATH_MSG_DEBUG("Decision " << m_decisionId << " is accept");
TrigCompositeUtils::addDecisionID(m_decisionId, input.decision);
}
else {
ATH_MSG_DEBUG("Decision " << m_decisionId << " is reject");
}
return StatusCode::SUCCESS;
......
......@@ -6,18 +6,19 @@
#define TRIGEXPARTIALEB_MTCALIBPEBHYPOTOOL_H
// Trigger includes
#include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h"
#include "DecisionHandling/HLTIdentifier.h"
#include "DecisionHandling/TrigCompositeUtils.h"
// Athena includes
#include "AthenaBaseComps/AthAlgTool.h"
// Gaudi includes
#include "Gaudi/Parsers/Factory.h" // needed to declare less common Property types
// TDAQ includes
#include "eformat/StreamTag.h"
// System includes
#include <random>
/** @class MTCalibPebHypoTool
* @brief Base class for tools used by MTCalibPebHypoAlg
**/
......@@ -30,26 +31,55 @@ public:
// ------------------------- AthAlgTool methods ------------------------------
virtual StatusCode initialize() override;
virtual StatusCode finalize() override;
// ------------------------- Public types ------------------------------------
struct Input {
Input(TrigCompositeUtils::Decision* d)
: decision(d) {}
Input(TrigCompositeUtils::Decision* d, const EventContext& ctx)
: decision(d), eventContext(ctx) {}
TrigCompositeUtils::Decision* decision;
const EventContext& eventContext;
};
// ------------------------- Specific methods of this class ------------------
/// Decides whether to accept the event
StatusCode decide(const std::vector<Input>& inputs) const;
StatusCode decide(const Input& input) const;
private:
// ------------------------- Properties --------------------------------------
Gaudi::Property<double> m_acceptRate {
this,
"RandomAcceptRate",
-1,
this, "RandomAcceptRate", -1,
"Rate of random accepts, <=0 is never, >=1 is always"
};
Gaudi::Property<unsigned int> m_burnTimePerCycleMillisec {
this, "BurnTimePerCycleMillisec", 0,
"Burn time per cycle in milliseconds"
};
Gaudi::Property<unsigned int> m_numBurnCycles {
this, "NumBurnCycles", 0,
"Number of time burning cycles"
};
Gaudi::Property<bool> m_burnTimeRandomly {
this, "BurnTimeRandomly", true,
"If true, burn time per cycle is a random value from uniform distribution between 0 and the given value"
};
Gaudi::Property<bool> m_failOnTimeout {
this, "FailOnTimeout", true,
"If true, the execution will return StatusCode::FAILURE when Athena timeout is detected"
};
Gaudi::Property<std::map<std::string,std::vector<uint32_t> > > m_robAccessDict {
this, "ROBAccessDict", {},
"List of prefetch/retrieve operations with given ROB IDs."
"The string key has to contain :ADD: (prefetch), :GET: (retrieve), or :COL: (full event building)."
"The value is a vector of corresponding ROB IDs."
};
Gaudi::Property<unsigned int> m_timeBetweenRobReqMillisec {
this, "TimeBetweenROBReqMillisec", 0,
"Delay in milliseconds between subsequent ROB request operations from ROBAccessDict"
};
// ------------------------- Service or tool handles -------------------------
ServiceHandle<IROBDataProviderSvc> m_robDataProviderSvc;
// ------------------------- Other private members ---------------------------
/// The decision id of the tool instance
......
......@@ -10,14 +10,28 @@ StreamTagMakerTool::StreamTagMakerTool( const std::string& type, const std::stri
StreamTagMakerTool::~StreamTagMakerTool() {}
StatusCode StreamTagMakerTool::initialize() {
// decode mapping
StatusCode StreamTagMakerTool::initialize() {
ATH_CHECK( m_finalChainDecisions.initialize() );
// decode mapping - temporary solution for testing
for ( auto& chainAndStream: m_chainToStreamProperty ) {
struct { std::string chain, stream; } conf { chainAndStream.first, chainAndStream.second };
struct { std::string chain, stream; } conf { chainAndStream.first, chainAndStream.second };
ATH_MSG_DEBUG( "Chain " << conf.chain << " accepts events to stream " << conf.stream );
m_mapping[ HLT::Identifier( conf.chain ) ] = eformat::helper::StreamTag( conf.stream, "physics", true );
// find subdets
std::set<eformat::SubDetector> dets;
const auto itSubDetMap = m_streamSubDets.value().find(conf.stream);
if (itSubDetMap != m_streamSubDets.value().cend()) {
for (const uint32_t detid : itSubDetMap->second)
dets.insert(static_cast<eformat::SubDetector>(detid & 0xFF)); // cast from uint32_t
}
// find robs
std::set<uint32_t> robs;
const auto itRobsMap = m_streamRobs.value().find(conf.stream);
if (itRobsMap != m_streamRobs.value().cend()) {
for (const uint32_t robid : itRobsMap->second)
robs.insert(robid);
}
// create the stream tag
m_mapping[ HLT::Identifier( conf.chain ) ] = eformat::helper::StreamTag( conf.stream, "physics", true, robs, dets );
}
return StatusCode::SUCCESS;
......@@ -29,14 +43,14 @@ StatusCode StreamTagMakerTool::finalize() {
StatusCode StreamTagMakerTool::fill( HLT::HLTResultMT& resultToFill ) const {
// obtain chain decisions,
// obtain chain decisions,
auto chainsHandle = SG::makeHandle( m_finalChainDecisions );
// for each accepted chain lookup the map of chainID -> ST
for ( TrigCompositeUtils::DecisionID chain: TrigCompositeUtils::decisionIDs( chainsHandle->at( 0 )) ) {
auto mappingIter = m_mapping.find( chain );
// each chain has to have stream
if( mappingIter == m_mapping.end() ) {
if( mappingIter == m_mapping.end() ) {
ATH_MSG_ERROR("Each chain has to have stream associated whereas the " << HLT::Identifier( chain ) << " does not" );
return StatusCode::FAILURE;
}
......@@ -44,5 +58,5 @@ StatusCode StreamTagMakerTool::fill( HLT::HLTResultMT& resultToFill ) const {
}
ATH_MSG_DEBUG("Number of streams for event " << resultToFill.getStreamTags().size() );
return StatusCode::SUCCESS;
return StatusCode::SUCCESS;
}
......@@ -10,6 +10,7 @@
#include "AthenaBaseComps/AthAlgTool.h"
#include "TrigOutputHandling/HLTResultMTMakerTool.h"
#include "DecisionHandling/TrigCompositeUtils.h"
#include "Gaudi/Parsers/Factory.h" // needed to declare less common Property types
#include "eformat/StreamTag.h"
/**
......@@ -29,7 +30,9 @@ public:
private:
SG::ReadHandleKey<TrigCompositeUtils::DecisionContainer> m_finalChainDecisions { this, "ChainDecisions", "UNDEFINED", "Container with final chain decisions" };
Gaudi::Property<std::map<std::string, std::string>> m_chainToStreamProperty { this, "ChainToStream", {}, "Mapping from the chain name to string name, (temporary solution, will be replaced)"};
Gaudi::Property<std::map<std::string, std::string>> m_chainToStreamProperty { this, "ChainToStream", {}, "Mapping from the chain name to string name (temporary solution, will be replaced)"};
Gaudi::Property<std::map<std::string, std::vector<uint32_t>>> m_streamSubDets { this, "StreamSubDets", {}, "Mapping from the stream name to subdetector IDs (temporary solution, will be replaced)"};
Gaudi::Property<std::map<std::string, std::vector<uint32_t>>> m_streamRobs { this, "StreamRobs", {}, "Mapping from the stream name to ROB IDs (temporary solution, will be replaced)"};
typedef std::map< TrigCompositeUtils::DecisionID, eformat::helper::StreamTag> ChainToStreamMap;
ChainToStreamMap m_mapping;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment