54 std::map<std::string, std::set<std::string>> l1SeedsCheckForCPS;
58 for (
const auto& group: chain.groups() ) {
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 ) {
76 ATH_MSG_ERROR(
"Only one chain " << chains.front() <<
" in CPS group " << group <<
" that makes no sense");
77 return StatusCode::FAILURE;
81 for (
auto [group, l1SeedsSet]: l1SeedsCheckForCPS) {
82 if ( l1SeedsSet.size() != 1 ) {
83 ATH_MSG_ERROR(
"Chains in CPS group " << group <<
" have several different L1 seeds "
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();
138 CLHEP::HepRandomEngine* engine =
m_RNGEngines.getEngine( ctx );
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 ;
204 if (msgLvl(MSG::DEBUG)) {
205 ATH_MSG_DEBUG(
"Chains in CPS group '"<< groupName <<
"' sorted by PS : ");
206 for (
const ChainAndPrescale& ch: psValueSorted ) {
208 "prescale relative to the above " + std::to_string(ch.relativePrescale) :
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);
232 ATH_MSG_DEBUG(
"Chain " << ch <<
" is disabled, won't keep" );
237 return StatusCode::SUCCESS;