10 #include <analysis/variables/TriggerVariables.h>
12 #include <analysis/dataobjects/Particle.h>
15 #include <mdst/dataobjects/TRGSummary.h>
16 #include <mdst/dataobjects/SoftwareTriggerResult.h>
19 #include <mdst/dbobjects/TRGGDLDBFTDLBits.h>
20 #include <mdst/dbobjects/TRGGDLDBPrescales.h>
23 #include <mdst/dbobjects/DBRepresentationOfSoftwareTriggerCut.h>
26 #include <framework/logging/Logger.h>
27 #include <framework/datastore/StoreObjPtr.h>
28 #include <framework/database/DBObjPtr.h>
29 #include <framework/utilities/Conversion.h>
32 #include <boost/algorithm/string.hpp>
58 std::string fullFormatIdentifier(
const std::string& identifier)
60 std::string out = identifier;
61 boost::replace_all(out,
" ",
"&");
62 if (identifier.substr(0, 21) !=
"software_trigger_cut&")
63 out =
"software_trigger_cut&" + out;
71 double extractSoftwareTriggerResultImplementation(
bool nonPrescaled,
const std::string& triggerIdentifier,
const Particle*)
74 StoreObjPtr<SoftwareTriggerResult> swtr;
76 return std::numeric_limits<double>::quiet_NaN();
82 swtcr = swtr->getNonPrescaledResult(fullFormatIdentifier(triggerIdentifier));
84 swtcr = swtr->getResult(fullFormatIdentifier(triggerIdentifier));
86 }
catch (
const std::out_of_range&) {
88 return std::numeric_limits<double>::quiet_NaN();
96 double L1Trigger(
const Particle*)
98 StoreObjPtr<TRGSummary> trg;
100 return std::numeric_limits<double>::quiet_NaN();
106 if (arguments.size() == 1) {
107 auto name = arguments[0];
108 auto func = [name](
const Particle*) ->
double {
109 StoreObjPtr<TRGSummary> trg;
111 return std::numeric_limits<double>::quiet_NaN();
114 return trg->testPsnm(name);
115 }
catch (
const std::exception&)
118 return std::numeric_limits<double>::quiet_NaN();
123 B2FATAL(
"Wrong number of arguments for L1PSNM function. The only argument must be the name of the PSNM trigger bit.");
127 double L1PSNMBit(
const Particle*,
const std::vector<double>& arguments)
129 if (arguments.size() == 1) {
130 int testBit = std::lround(arguments[0]);
132 StoreObjPtr<TRGSummary> trg;
134 return std::numeric_limits<double>::quiet_NaN();
136 return trg->testPsnm(testBit);
137 }
catch (
const std::exception&) {
139 return std::numeric_limits<double>::quiet_NaN();
142 B2FATAL(
"Wrong number of arguments for L1PSNMBit function. The only argument must be the number of the PSNM trigger bit.");
148 if (arguments.size() == 1) {
149 auto name = arguments[0];
150 auto func = [name](
const Particle*) ->
double {
151 StoreObjPtr<TRGSummary> trg;
153 return std::numeric_limits<double>::quiet_NaN();
156 return trg->testFtdl(name);
157 }
catch (
const std::exception&)
160 return std::numeric_limits<double>::quiet_NaN();
165 B2FATAL(
"Wrong number of arguments for L1FTDL function. The only argument must be the name of the FTDL trigger bit.");
169 double L1FTDLBit(
const Particle*,
const std::vector<double>& arguments)
171 if (arguments.size() == 1) {
172 int testBit = std::lround(arguments[0]);
174 StoreObjPtr<TRGSummary> trg;
176 return std::numeric_limits<double>::quiet_NaN();
178 return trg->testFtdl(testBit);
179 }
catch (
const std::exception&) {
181 return std::numeric_limits<double>::quiet_NaN();
184 B2FATAL(
"Wrong number of arguments for L1FTDLBit function. The only argument must be the number of the FTDL trigger bit.");
190 if (arguments.size() == 1) {
191 auto name = arguments[0];
192 auto func = [name](
const Particle*) ->
double {
193 StoreObjPtr<TRGSummary> trg;
195 return std::numeric_limits<double>::quiet_NaN();
198 return trg->testInput(name);
199 }
catch (
const std::exception&)
202 return std::numeric_limits<double>::quiet_NaN();
207 B2FATAL(
"Wrong number of arguments for L1Input function. The only argument must be the name of the input trigger bit.");
211 double L1InputBit(
const Particle*,
const std::vector<double>& arguments)
213 if (arguments.size() == 1) {
214 int testBit = std::lround(arguments[0]);
216 StoreObjPtr<TRGSummary> trg;
218 return std::numeric_limits<double>::quiet_NaN();
220 return trg->testInput(testBit);
221 }
catch (
const std::exception&) {
223 return std::numeric_limits<double>::quiet_NaN();
226 B2FATAL(
"Wrong number of arguments for L1Input function. The only argument must be the number of the input trigger bit.");
232 if (arguments.size() == 1) {
233 auto name = arguments[0];
234 auto func = [name](
const Particle*) ->
double {
235 static DBObjPtr<TRGGDLDBFTDLBits> ftdlBits;
236 if (!ftdlBits.isValid())
237 return std::numeric_limits<double>::quiet_NaN();
238 static DBObjPtr<TRGGDLDBPrescales> prescales;
239 if (!prescales.isValid())
240 return std::numeric_limits<double>::quiet_NaN();
243 if (std::string(ftdlBits->getoutbitname((
int)bit)) == name)
244 return prescales->getprescales(bit);
246 return std::numeric_limits<double>::quiet_NaN();
250 B2FATAL(
"Wrong number of arguments for L1Prescale function. The only argument must be the name of the PSNM trigger bit.");
254 double L1PSNMBitPrescale(
const Particle*,
const std::vector<double>& arguments)
256 if (arguments.size() == 1) {
257 int testBit = std::lround(arguments[0]);
260 return std::numeric_limits<double>::quiet_NaN();
261 static DBObjPtr<TRGGDLDBPrescales> prescales;
262 if (!prescales.isValid())
263 return std::numeric_limits<double>::quiet_NaN();
264 return prescales->getprescales(testBit);
266 B2FATAL(
"Wrong number of arguments for L1BitPrescale function. The only argument must be the number of the PSNM trigger bit.");
270 double L1TimeType(
const Particle*)
272 StoreObjPtr<TRGSummary> trg;
274 return std::numeric_limits<double>::quiet_NaN();
275 return trg->getTimType();
278 double L1TimeQuality(
const Particle*)
280 StoreObjPtr<TRGSummary> trg;
282 return std::numeric_limits<double>::quiet_NaN();
283 return trg->getTimQuality();
286 double isPoissonInInjectionVeto(
const Particle*)
288 StoreObjPtr<TRGSummary> trg;
290 return std::numeric_limits<double>::quiet_NaN();
291 return trg->isPoissonInInjectionVeto();
303 if (args.size() != 1)
304 B2FATAL(
"Wrong number of arguments for the function softwareTriggerResult");
305 std::string triggerIdentifier = args[0];
307 using namespace std::placeholders;
308 return std::bind(extractSoftwareTriggerResultImplementation,
false, triggerIdentifier, _1);
320 if (args.size() != 1)
321 B2FATAL(
"Wrong number of arguments for the function softwareTriggerResultNonPrescaled");
322 std::string triggerIdentifier = args[0];
324 using namespace std::placeholders;
325 return std::bind(extractSoftwareTriggerResultImplementation,
true, triggerIdentifier, _1);
328 bool passesAnyHighLevelTrigger(
const Particle* p)
332 std::vector<std::string> hardcodedname
333 = {
"software_trigger_cut&filter&total_result" };
334 double swtcr = std::get<double>(softwareTriggerResult(hardcodedname)(p));
335 if (swtcr > 0.5)
return true;
348 if (args.size() != 1)
349 B2FATAL(
"Wrong number of arguments for the function softwareTriggerPrescaling");
350 std::string triggerIdentifier = args[0];
352 auto outputFunction = [triggerIdentifier](
const Particle*) ->
double {
354 DBObjPtr<DBRepresentationOfSoftwareTriggerCut> downloadedCut(fullFormatIdentifier(triggerIdentifier));
355 if (not downloadedCut)
356 return std::numeric_limits<double>::quiet_NaN();
357 return double(downloadedCut->getPreScaleFactor());
360 return outputFunction;
364 VARIABLE_GROUP(
"L1 Trigger");
365 REGISTER_VARIABLE(
"L1Trigger", L1Trigger,
366 "[Eventbased] Returns 1 if at least one PSNM L1 trigger bit is true.");
367 REGISTER_METAVARIABLE(
"L1PSNM(name)", L1PSNM,
368 "[Eventbased] Returns the PSNM (Prescale And Mask, after prescale) status of the trigger bit with the given name.",
369 Manager::VariableDataType::c_double);
370 REGISTER_METAVARIABLE(
"L1FTDL(name)", L1FTDL,
371 "[Eventbased] Returns the FTDL (Final Trigger Decision Logic, before prescale) status of the trigger bit with the given name.",
372 Manager::VariableDataType::c_double);
373 REGISTER_METAVARIABLE(
"L1Input(name)", L1Input,
374 "[Eventbased] Returns the input bit status of the trigger bit with the given name.", Manager::VariableDataType::c_double);
375 REGISTER_METAVARIABLE(
"L1Prescale(name)", L1PSNMPrescale,
376 "[Eventbased] Returns the PSNM (prescale and mask) prescale of the trigger bit with the given name.",
377 Manager::VariableDataType::c_double);
378 REGISTER_VARIABLE(
"L1PSNMBit(i)", L1PSNMBit,
380 [Eventbased] Returns the PSNM (Prescale And Mask, after prescale) status of i-th trigger bit.
383 It is recommended to use this variable only for debugging and to use :b2:var:`L1PSNM`
384 with the explicit trigger bit name for physics analyses or performance studies.
386 REGISTER_VARIABLE("L1FTDLBit(i)", L1FTDLBit,
388 [Eventbased] Returns the FTDL (Final Trigger Decision Logic, before prescale) status of i-th trigger bit.
391 It is recommended to use this variable only for debugging and to use :b2:var:`L1FTDL`
392 with the explicit trigger bit name for physics analyses or performance studies.
394 REGISTER_VARIABLE("L1InputBit(i)", L1InputBit,
396 [Eventbased] Returns the input bit status of the i-th input trigger bit.
399 It is recommended to use this variable only for debugging and to use :b2:var:`L1Input`
400 with the explicit trigger bit name for physics analyses or performance studies.
402 REGISTER_VARIABLE("L1PSNMBitPrescale(i)", L1PSNMBitPrescale,
404 [Eventbased] Returns the PSNM (prescale and mask) prescale of i-th trigger bit.
407 It is recommended to use this variable only for debugging and to use :b2:var:`L1Prescale`
408 with the explicit trigger bit name for physics analyses or performance studies.
410 REGISTER_VARIABLE("L1TimeType", L1TimeType,
411 "[Eventbased] Returns ETimingType time type.");
412 REGISTER_VARIABLE(
"L1TimeQuality", L1TimeQuality,
413 "[Eventbased] Returns ETimingQuality time quality.");
414 REGISTER_VARIABLE(
"isPoissonTriggerInInjectionVeto", isPoissonInInjectionVeto,
415 "[Eventbased] Returns 1 if the poisson random trigger is within the injection veto window.");
417 VARIABLE_GROUP(
"Software Trigger");
418 REGISTER_METAVARIABLE(
"SoftwareTriggerResult(triggerIdentifier)", softwareTriggerResult, R
"DOC(
419 [Eventbased] [Expert] returns the SoftwareTriggerCutResult, defined as reject (-1), accept (1), or noResult (0).
420 If the trigger identifier is not found, returns NaN.
426 SoftwareTriggerResult(filter 1_Estargt1_GeV_cluster_no_other_cluster_Estargt0.3_GeV)
428 which is equivalent to
432 SoftwareTriggerResult(software_trigger_cut&filter&1_Estargt1_GeV_cluster_no_other_cluster_Estargt0.3_GeV)
435 .. warning:: the meanings of these change depending if using trigger or the skim stage, hence expert.
437 .. seealso:: ``b2hlt_triggers`` for possible triggerIdentifiers.
439 )DOC", Manager::VariableDataType::c_double);
441 REGISTER_METAVARIABLE("SoftwareTriggerResultNonPrescaled(triggerIdentifier)", softwareTriggerResultNonPrescaled,
442 "[Eventbased] [Expert] returns the SoftwareTriggerCutResult, "
443 "if this trigger would not be prescaled."
444 "Please note, this is not the final HLT decision! "
445 "It is defined as reject (-1), accept (1), or noResult (0). Note "
446 "that the meanings of these change depending if using trigger "
447 "or the skim stage, hence expert."
448 "If the trigger identifier is not found, returns NaN.", Manager::VariableDataType::c_double);
449 REGISTER_VARIABLE(
"HighLevelTrigger", passesAnyHighLevelTrigger,
450 "[Eventbased] True if event passes the HLT trigger, false if not");
451 REGISTER_METAVARIABLE(
"SoftwareTriggerPrescaling(triggerIdentifier)", softwareTriggerPrescaling,
452 "[Eventbased] return the prescaling for the specific software trigger identifier. "
453 "Please note, this prescaling is taken from the currently setup database. It only corresponds "
454 "to the correct HLT prescale if you are using the online database!"
455 "If the trigger identifier is not found, returns NaN.", Manager::VariableDataType::c_double);
static const unsigned int c_trgWordSize
size of a l1 trigger word
static const unsigned int c_ntrgWords
number of l1 trigger words
std::function< VarVariant(const Particle *)> FunctionPtr
functions stored take a const Particle* and return VarVariant.
SoftwareTriggerCutResult
Enumeration with all possible results of the SoftwareTriggerCut.
Abstract base class for different kinds of events.