Skip to content
Snippets Groups Projects
Commit 6ec3aabd authored by Rafal Bielski's avatar Rafal Bielski :wave:
Browse files

add time burning option to MTCalibPebHypoTool

also change the tool input from a vector to a single object (no need for multiple inputs)
parent 76367b3b
No related branches found
No related tags found
No related merge requests found
......@@ -55,9 +55,13 @@ hypo.HypoOutputDecisions = "MTCalibPebDecisions"
hypoTool1 = MTCalibPebHypoTool("HLT_MTCalibPeb1")
hypoTool1.RandomAcceptRate = 0.75
hypoTool1.BurnTimePerCycleMillisec = 200
hypoTool1.NumBurnCycles = 3
hypoTool2 = MTCalibPebHypoTool("HLT_MTCalibPeb2")
hypoTool2.RandomAcceptRate = 0.25
hypoTool2.BurnTimePerCycleMillisec = 1000
hypoTool2.NumBurnCycles = 10
hypo.HypoTools = [hypoTool1, hypoTool2]
......
......@@ -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,37 @@
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>
// 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);
}
}
......@@ -35,17 +57,37 @@ StatusCode MTCalibPebHypoTool::initialize() {
}
// =============================================================================
StatusCode MTCalibPebHypoTool::decide(const std::vector<MTCalibPebHypoTool::Input>& inputs) const {
StatusCode MTCalibPebHypoTool::decide(const MTCalibPebHypoTool::Input& input) const {
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);
}
else {
ATH_MSG_DEBUG("Decision " << m_decisionId << " is reject");
// ---------------------------------------------------------------------------
// 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));
}
// ---------------------------------------------------------------------------
// 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;
......
......@@ -15,9 +15,6 @@
// TDAQ includes
#include "eformat/StreamTag.h"
// System includes
#include <random>
/** @class MTCalibPebHypoTool
* @brief Base class for tools used by MTCalibPebHypoAlg
**/
......@@ -33,23 +30,38 @@ public:
// ------------------------- 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"
};
// ------------------------- Other private members ---------------------------
/// The decision id of the tool instance
......
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