9 #include <analysis/variables/TriggerVariables.h>
10 #include <analysis/dataobjects/Particle.h>
13 #include <mdst/dataobjects/TRGSummary.h>
14 #include <mdst/dataobjects/SoftwareTriggerResult.h>
17 #include <mdst/dbobjects/TRGGDLDBFTDLBits.h>
18 #include <mdst/dbobjects/TRGGDLDBPrescales.h>
21 #include <mdst/dbobjects/DBRepresentationOfSoftwareTriggerCut.h>
24 #include <framework/logging/Logger.h>
25 #include <framework/datastore/StoreObjPtr.h>
26 #include <framework/database/DBObjPtr.h>
27 #include <framework/utilities/Conversion.h>
30 #include <boost/algorithm/string.hpp>
56 std::string fullFormatIdentifier(
const std::string& identifier)
58 std::string out = identifier;
59 boost::replace_all(out,
" ",
"&");
60 if (identifier.substr(0, 21) !=
"software_trigger_cut&")
61 out =
"software_trigger_cut&" + out;
69 double extractSoftwareTriggerResultImplementation(
bool nonPrescaled,
const std::string& triggerIdentifier,
const Particle*)
72 StoreObjPtr<SoftwareTriggerResult> swtr;
74 return std::numeric_limits<double>::quiet_NaN();
80 swtcr = swtr->getNonPrescaledResult(fullFormatIdentifier(triggerIdentifier));
82 swtcr = swtr->getResult(fullFormatIdentifier(triggerIdentifier));
84 }
catch (
const std::out_of_range&) {
86 return std::numeric_limits<double>::quiet_NaN();
94 double L1Trigger(
const Particle*)
96 StoreObjPtr<TRGSummary> trg;
98 return std::numeric_limits<double>::quiet_NaN();
104 if (arguments.size() == 1) {
105 auto name = arguments[0];
106 auto func = [name](
const Particle*) ->
double {
107 StoreObjPtr<TRGSummary> trg;
109 return std::numeric_limits<double>::quiet_NaN();
111 return trg->testPsnm(name);
112 }
catch (
const std::exception&)
115 return std::numeric_limits<double>::quiet_NaN();
120 B2FATAL(
"Wrong number of arguments for L1PSNM function. The only argument must be the name of the PSNM trigger bit.");
126 if (arguments.size() == 1) {
129 testBit = Belle2::convertString<int>(arguments[0]);
130 }
catch (
const std::invalid_argument&) {
131 B2FATAL(
"Invalid argument for L1PSNMBit function. The argument must be an integer representing the PSNM trigger bit.");
133 auto func = [testBit](
const Particle*) ->
double {
134 StoreObjPtr<TRGSummary> trg;
136 return std::numeric_limits<double>::quiet_NaN();
138 return trg->testPsnm(testBit);
139 }
catch (
const std::exception&)
142 return std::numeric_limits<double>::quiet_NaN();
147 B2FATAL(
"Wrong number of arguments for L1PSNMBit function. The only argument must be the number of the PSNM trigger bit.");
153 if (arguments.size() == 1) {
154 auto name = arguments[0];
155 auto func = [name](
const Particle*) ->
double {
156 StoreObjPtr<TRGSummary> trg;
158 return std::numeric_limits<double>::quiet_NaN();
160 return trg->testFtdl(name);
161 }
catch (
const std::exception&)
164 return std::numeric_limits<double>::quiet_NaN();
169 B2FATAL(
"Wrong number of arguments for L1FTDL function. The only argument must be the name of the FTDL trigger bit.");
175 if (arguments.size() == 1) {
178 testBit = Belle2::convertString<int>(arguments[0]);
179 }
catch (
const std::invalid_argument&) {
180 B2FATAL(
"Invalid argument for L1FTDLBit function. The argument must be an integer representing the FTDL trigger bit.");
182 auto func = [testBit](
const Particle*) ->
double {
183 StoreObjPtr<TRGSummary> trg;
185 return std::numeric_limits<double>::quiet_NaN();
187 return trg->testFtdl(testBit);
188 }
catch (
const std::exception&)
191 return std::numeric_limits<double>::quiet_NaN();
196 B2FATAL(
"Wrong number of arguments for L1FTDLBit function. The only argument must be the number of the FTDL trigger bit.");
202 if (arguments.size() == 1) {
203 auto name = arguments[0];
204 auto func = [name](
const Particle*) ->
double {
205 StoreObjPtr<TRGSummary> trg;
207 return std::numeric_limits<double>::quiet_NaN();
209 return trg->testInput(name);
210 }
catch (
const std::exception&)
213 return std::numeric_limits<double>::quiet_NaN();
218 B2FATAL(
"Wrong number of arguments for L1Input function. The only argument must be the name of the input trigger bit.");
224 if (arguments.size() == 1) {
227 testBit = Belle2::convertString<int>(arguments[0]);
228 }
catch (
const std::invalid_argument&) {
229 B2FATAL(
"Invalid argument for L1InputBit function. The argument must be an integer representing the input trigger bit.");
231 auto func = [testBit](
const Particle*) ->
double {
232 StoreObjPtr<TRGSummary> trg;
234 return std::numeric_limits<double>::quiet_NaN();
236 return trg->testInput(testBit);
237 }
catch (
const std::exception&)
240 return std::numeric_limits<double>::quiet_NaN();
245 B2FATAL(
"Wrong number of arguments for L1Input function. The only argument must be the number of the input trigger bit.");
251 if (arguments.size() == 1) {
252 auto name = arguments[0];
253 auto func = [name](
const Particle*) ->
double {
254 static DBObjPtr<TRGGDLDBFTDLBits> ftdlBits;
255 if (!ftdlBits.isValid())
256 return std::numeric_limits<double>::quiet_NaN();
257 static DBObjPtr<TRGGDLDBPrescales> prescales;
258 if (!prescales.isValid())
259 return std::numeric_limits<double>::quiet_NaN();
262 if (std::string(ftdlBits->getoutbitname((
int)bit)) == name)
263 return prescales->getprescales(bit);
265 return std::numeric_limits<double>::quiet_NaN();
269 B2FATAL(
"Wrong number of arguments for L1Prescale function. The only argument must be the name of the PSNM trigger bit.");
275 if (arguments.size() == 1) {
278 testBit = Belle2::convertString<int>(arguments[0]);
279 }
catch (
const std::invalid_argument&) {
280 B2FATAL(
"Invalid argument for L1PSNMBitPrescale function. The argument must be an integer representing the PSNM trigger bit.");
282 auto func = [testBit](
const Particle*) ->
double {
284 return std::numeric_limits<double>::quiet_NaN();
285 static DBObjPtr<TRGGDLDBPrescales> prescales;
286 if (!prescales.isValid())
287 return std::numeric_limits<double>::quiet_NaN();
288 return prescales->getprescales(testBit);
292 B2FATAL(
"Wrong number of arguments for L1BitPrescale function. The only argument must be the number of the PSNM trigger bit.");
296 double L1TimeType(
const Particle*)
298 StoreObjPtr<TRGSummary> trg;
300 return std::numeric_limits<double>::quiet_NaN();
301 return trg->getTimType();
304 double L1TimeQuality(
const Particle*)
306 StoreObjPtr<TRGSummary> trg;
308 return std::numeric_limits<double>::quiet_NaN();
309 return trg->getTimQuality();
312 double isPoissonInInjectionVeto(
const Particle*)
314 StoreObjPtr<TRGSummary> trg;
316 return std::numeric_limits<double>::quiet_NaN();
317 return trg->isPoissonInInjectionVeto();
329 if (args.size() != 1)
330 B2FATAL(
"Wrong number of arguments for the function softwareTriggerResult");
331 std::string triggerIdentifier = args[0];
333 using namespace std::placeholders;
334 return std::bind(extractSoftwareTriggerResultImplementation,
false, triggerIdentifier, _1);
346 if (args.size() != 1)
347 B2FATAL(
"Wrong number of arguments for the function softwareTriggerResultNonPrescaled");
348 std::string triggerIdentifier = args[0];
350 using namespace std::placeholders;
351 return std::bind(extractSoftwareTriggerResultImplementation,
true, triggerIdentifier, _1);
354 double passesAnyHighLevelTrigger(
const Particle* p)
358 std::vector<std::string> hardcodedname
359 = {
"software_trigger_cut&filter&total_result" };
360 double swtcr = softwareTriggerResult(hardcodedname)(p);
361 if (swtcr > 0.5)
return 1.0;
374 if (args.size() != 1)
375 B2FATAL(
"Wrong number of arguments for the function softwareTriggerPrescaling");
376 std::string triggerIdentifier = args[0];
378 auto outputFunction = [triggerIdentifier](
const Particle*) ->
double {
380 DBObjPtr<DBRepresentationOfSoftwareTriggerCut> downloadedCut(fullFormatIdentifier(triggerIdentifier));
381 if (not downloadedCut)
382 return std::numeric_limits<double>::quiet_NaN();
383 return double(downloadedCut->getPreScaleFactor());
386 return outputFunction;
390 VARIABLE_GROUP(
"L1 Trigger");
391 REGISTER_VARIABLE(
"L1Trigger", L1Trigger ,
392 "[Eventbased] Returns 1 if at least one PSNM L1 trigger bit is true.");
393 REGISTER_VARIABLE(
"L1PSNM(name)", L1PSNM ,
394 "[Eventbased] Returns the PSNM (Prescale And Mask, after prescale) status of the trigger bit with the given name.");
395 REGISTER_VARIABLE(
"L1FTDL(name)", L1FTDL ,
396 "[Eventbased] Returns the FTDL (Final Trigger Decision Logic, before prescale) status of the trigger bit with the given name.");
397 REGISTER_VARIABLE(
"L1Input(name)", L1Input,
398 "[Eventbased] Returns the input bit status of the trigger bit with the given name.");
399 REGISTER_VARIABLE(
"L1Prescale(name)", L1PSNMPrescale,
400 "[Eventbased] Returns the PSNM (prescale and mask) prescale of the trigger bit with the given name.");
401 REGISTER_VARIABLE(
"L1PSNMBit(i)", L1PSNMBit,
402 "[Eventbased] Returns the PSNM (Prescale And Mask, after prescale) status of i-th trigger bit.");
403 REGISTER_VARIABLE(
"L1FTDLBit(i)", L1FTDLBit,
404 "[Eventbased] Returns the FTDL (Final Trigger Decision Logic, before prescale) status of i-th trigger bit.");
405 REGISTER_VARIABLE(
"L1InputBit(i)", L1InputBit,
406 "[Eventbased] Returns the input bit status of the i-th input trigger bit.");
407 REGISTER_VARIABLE(
"L1PSNMBitPrescale(i)", L1PSNMBitPrescale,
408 "[Eventbased] Returns the PSNM (prescale and mask) prescale of i-th trigger bit.");
409 REGISTER_VARIABLE(
"L1TimeType", L1TimeType,
410 "[Eventbased] Returns ETimingType time type.");
411 REGISTER_VARIABLE(
"L1TimeQuality", L1TimeQuality,
412 "[Eventbased] Returns ETimingQuality time quality.");
413 REGISTER_VARIABLE(
"isPoissonTriggerInInjectionVeto", isPoissonInInjectionVeto,
414 "[Eventbased] Returns 1 if the poisson random trigger is within the injection veto window.");
416 VARIABLE_GROUP(
"Software Trigger");
417 REGISTER_VARIABLE(
"SoftwareTriggerResult(triggerIdentifier)", softwareTriggerResult, R
"DOC(
418 [Eventbased] [Expert] returns the SoftwareTriggerCutResult, defined as reject (-1), accept (1), or noResult (0).
419 If the trigger identifier is not found, returns NaN.
425 SoftwareTriggerResult(filter 1_Estargt1_GeV_cluster_no_other_cluster_Estargt0.3_GeV)
427 which is equivalent to
431 SoftwareTriggerResult(software_trigger_cut&filter&1_Estargt1_GeV_cluster_no_other_cluster_Estargt0.3_GeV)
434 .. warning:: the meanings of these change depending if using trigger or the skim stage, hence expert.
436 .. seealso:: ``b2hlt_triggers`` for possible triggerIdentifiers.
440 REGISTER_VARIABLE("SoftwareTriggerResultNonPrescaled(triggerIdentifier)", softwareTriggerResultNonPrescaled,
441 "[Eventbased] [Expert] returns the SoftwareTriggerCutResult, "
442 "if this trigger would not be prescaled."
443 "Please note, this is not the final HLT decision! "
444 "It is defined as reject (-1), accept (1), or noResult (0). Note "
445 "that the meanings of these change depending if using trigger "
446 "or the skim stage, hence expert."
447 "If the trigger identifier is not found, returns NaN.");
448 REGISTER_VARIABLE(
"HighLevelTrigger", passesAnyHighLevelTrigger,
449 "[Eventbased] 1.0 if event passes the HLT trigger, 0.0 if not");
450 REGISTER_VARIABLE(
"SoftwareTriggerPrescaling(triggerIdentifier)", softwareTriggerPrescaling,
451 "[Eventbased] return the prescaling for the specific software trigger identifier. "
452 "Please note, this prescaling is taken from the currently setup database. It only corresponds "
453 "to the correct HLT prescale if you are using the online database!"
454 "If the trigger identifier is not found, returns NaN.");
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< double(const Particle *)> FunctionPtr
NOTE: the python interface is documented manually in analysis/doc/Variables.rst (because we use ROOT ...
SoftwareTriggerCutResult
Enumeration with all possible results of the SoftwareTriggerCut.
Abstract base class for different kinds of events.