9 #include "GaudiKernel/IToolSvc.h"
10 #include "CLHEP/Random/RandomEngine.h"
11 #include "CLHEP/Random/Ranlux64Engine.h"
14 const std::function< CLHEP::HepRandomEngine*(void) >
PSTRanluxFactory = []()->CLHEP::HepRandomEngine*{
15 return new CLHEP::Ranlux64Engine();
20 const std::string&
name,
21 const IInterface*
parent ) :
37 <<
"This is OK for testing but do not use this in production");
41 return StatusCode::SUCCESS;
54 std::map<std::string, std::set<std::string>> l1SeedsCheckForCPS;
59 if (
group.find(
"CPS") != std::string::npos) {
61 l1SeedsCheckForCPS[
group].insert(
chain.l1item());
69 ATH_MSG_ERROR(
"Chain " << chainID <<
" belongs to more than one CPS groups");
70 return StatusCode::FAILURE;
75 if (
chains.size() == 1 ) {
77 return StatusCode::FAILURE;
81 for (
auto [
group, l1SeedsSet]: l1SeedsCheckForCPS) {
82 if ( l1SeedsSet.size() != 1 ) {
84 << std::vector<std::string>(l1SeedsSet.begin(), l1SeedsSet.end()));
85 return StatusCode::FAILURE;
89 return StatusCode::SUCCESS;
96 bool forExpressStream)
const {
97 if ( initiallyActive.empty() ) {
98 return StatusCode::SUCCESS;
102 remainActive.clear();
107 remainActive.reserve( initiallyActive.size() );
108 for(
const auto &
ch : initiallyActive ) {
109 remainActive.push_back(
ch);
112 return StatusCode::SUCCESS;
125 remainActive.reserve( initiallyActive.size() );
135 CHECK( eventInfoHandle.isValid() );
136 size_t seed = eventInfoHandle->timeStamp() ^ eventInfoHandle->timeStampNSOffset();
139 engine->setSeed( seed, 0 );
143 if (forExpressStream) {
144 return hltPrescaleSet->prescale_express(
ch.numeric() );
146 return hltPrescaleSet->
prescale(
ch.numeric() );
148 }
catch(
const std::out_of_range & ex) {
151 ATH_MSG_DEBUG(
"No prescale value for chain " <<
ch <<
", keeping it because "
160 auto decisionPerChain = [&](
const HLT::Identifier&
ch,
double prescaleValue ) ->
bool {
161 auto flat = engine->flat();
166 return flat < 1./ prescaleValue;
169 struct ChainAndPrescale {
172 double relativePrescale{};
178 if ( forExpressStream ||
std::find(initiallyActive.begin(), initiallyActive.end(), chainIDs.front()) != initiallyActive.end() ) {
179 std::vector<ChainAndPrescale> psValueSorted;
183 if ( forExpressStream &&
std::find(initiallyActive.begin(), initiallyActive.end(),
ch) == initiallyActive.end() ) {
186 auto ps = getPrescale(
ch);
188 psValueSorted.emplace_back( ChainAndPrescale({
ch, ps}) );
190 if ( psValueSorted.empty() ) {
193 std::sort(psValueSorted.begin(), psValueSorted.end(), [](
const ChainAndPrescale&
a,
const ChainAndPrescale&
b){
194 return a.ps.prescale < b.ps.prescale;
198 psValueSorted.front().relativePrescale = psValueSorted.front().ps.prescale;
199 if ( psValueSorted.size() > 1 ) {
200 for (
auto i = psValueSorted.begin()+1;
i < psValueSorted.end(); ++
i ) {
201 i->relativePrescale =
i->ps.prescale / (
i-1)->ps.prescale ;
206 for (
const ChainAndPrescale&
ch: psValueSorted ) {
213 for (
const ChainAndPrescale&
ch: psValueSorted ) {
214 const bool decision = decisionPerChain(
ch.id,
ch.relativePrescale);
215 if ( not decision ) {
break;}
216 remainActive.push_back(
ch.id );
223 if (
std::find( initiallyActive.begin(), initiallyActive.end(),
ch ) != initiallyActive.end() ) {
224 auto prescale = getPrescale(
ch);
225 if ( prescale.enabled ) {
226 const bool decision = decisionPerChain(
ch, prescale.prescale);
228 remainActive.push_back(
ch );
230 ATH_MSG_DEBUG(
"Prescaling decision for chain " <<
ch <<
" " << decision);
237 return StatusCode::SUCCESS;