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>
31#include <boost/algorithm/string.hpp>
57 std::string fullFormatIdentifier(
const std::string& identifier)
59 std::string out = identifier;
60 boost::replace_all(out,
" ",
"&");
61 if (identifier.substr(0, 21) !=
"software_trigger_cut&")
62 out =
"software_trigger_cut&" + out;
70 double extractSoftwareTriggerResultImplementation(
bool nonPrescaled,
const std::string& triggerIdentifier,
const Particle*)
73 StoreObjPtr<SoftwareTriggerResult> swtr;
81 swtcr = swtr->getNonPrescaledResult(fullFormatIdentifier(triggerIdentifier));
83 swtcr = swtr->getResult(fullFormatIdentifier(triggerIdentifier));
85 }
catch (
const std::out_of_range&) {
95 double L1Trigger(
const Particle*)
97 StoreObjPtr<TRGSummary> trg;
105 if (arguments.size() == 1) {
106 auto name = arguments[0];
107 auto func = [name](
const Particle*) ->
double {
108 StoreObjPtr<TRGSummary> trg;
113 return trg->testPsnm(name);
114 }
catch (
const std::exception&)
122 B2FATAL(
"Wrong number of arguments for L1PSNM function. The only argument must be the name of the PSNM trigger bit.");
126 double L1PSNMBit(
const Particle*,
const std::vector<double>& arguments)
128 if (arguments.size() == 1) {
129 int testBit = std::lround(arguments[0]);
131 StoreObjPtr<TRGSummary> trg;
135 return trg->testPsnm(testBit);
136 }
catch (
const std::exception&) {
141 B2FATAL(
"Wrong number of arguments for L1PSNMBit function. The only argument must be the number of the PSNM trigger bit.");
147 if (arguments.size() == 1) {
148 auto name = arguments[0];
149 auto func = [name](
const Particle*) ->
double {
150 StoreObjPtr<TRGSummary> trg;
155 return trg->testFtdl(name);
156 }
catch (
const std::exception&)
164 B2FATAL(
"Wrong number of arguments for L1FTDL function. The only argument must be the name of the FTDL trigger bit.");
168 double L1FTDLBit(
const Particle*,
const std::vector<double>& arguments)
170 if (arguments.size() == 1) {
171 int testBit = std::lround(arguments[0]);
173 StoreObjPtr<TRGSummary> trg;
177 return trg->testFtdl(testBit);
178 }
catch (
const std::exception&) {
183 B2FATAL(
"Wrong number of arguments for L1FTDLBit function. The only argument must be the number of the FTDL trigger bit.");
189 if (arguments.size() == 1) {
190 auto name = arguments[0];
191 auto func = [name](
const Particle*) ->
double {
192 StoreObjPtr<TRGSummary> trg;
197 return trg->testInput(name);
198 }
catch (
const std::exception&)
206 B2FATAL(
"Wrong number of arguments for L1Input function. The only argument must be the name of the input trigger bit.");
210 double L1InputBit(
const Particle*,
const std::vector<double>& arguments)
212 if (arguments.size() == 1) {
213 int testBit = std::lround(arguments[0]);
215 StoreObjPtr<TRGSummary> trg;
219 return trg->testInput(testBit);
220 }
catch (
const std::exception&) {
225 B2FATAL(
"Wrong number of arguments for L1Input function. The only argument must be the number of the input trigger bit.");
231 if (arguments.size() == 1) {
232 auto name = arguments[0];
233 auto func = [name](
const Particle*) ->
double {
234 static DBObjPtr<TRGGDLDBFTDLBits> ftdlBits;
235 if (!ftdlBits.isValid())
237 static DBObjPtr<TRGGDLDBPrescales> prescales;
238 if (!prescales.isValid())
242 if (std::string(ftdlBits->getoutbitname((
int)bit)) == name)
243 return prescales->getprescales(bit);
249 B2FATAL(
"Wrong number of arguments for L1Prescale function. The only argument must be the name of the PSNM trigger bit.");
253 double L1PSNMBitPrescale(
const Particle*,
const std::vector<double>& arguments)
255 if (arguments.size() == 1) {
256 int testBit = std::lround(arguments[0]);
260 static DBObjPtr<TRGGDLDBPrescales> prescales;
261 if (!prescales.isValid())
263 return prescales->getprescales(testBit);
265 B2FATAL(
"Wrong number of arguments for L1BitPrescale function. The only argument must be the number of the PSNM trigger bit.");
269 double L1TimeType(
const Particle*)
271 StoreObjPtr<TRGSummary> trg;
274 return trg->getTimType();
277 double L1TimeQuality(
const Particle*)
279 StoreObjPtr<TRGSummary> trg;
282 return trg->getTimQuality();
285 double isPoissonInInjectionVeto(
const Particle*)
287 StoreObjPtr<TRGSummary> trg;
290 return trg->isPoissonInInjectionVeto();
302 if (args.size() != 1)
303 B2FATAL(
"Wrong number of arguments for the function softwareTriggerResult");
304 std::string triggerIdentifier = args[0];
306 using namespace std::placeholders;
307 return std::bind(extractSoftwareTriggerResultImplementation,
false, triggerIdentifier, _1);
319 if (args.size() != 1)
320 B2FATAL(
"Wrong number of arguments for the function softwareTriggerResultNonPrescaled");
321 std::string triggerIdentifier = args[0];
323 using namespace std::placeholders;
324 return std::bind(extractSoftwareTriggerResultImplementation,
true, triggerIdentifier, _1);
327 bool passesAnyHighLevelTrigger(
const Particle* p)
331 std::vector<std::string> hardcodedname
332 = {
"software_trigger_cut&filter&total_result" };
333 double swtcr = std::get<double>(softwareTriggerResult(hardcodedname)(p));
334 if (swtcr > 0.5)
return true;
347 if (args.size() != 1)
348 B2FATAL(
"Wrong number of arguments for the function softwareTriggerPrescaling");
349 std::string triggerIdentifier = args[0];
351 auto outputFunction = [triggerIdentifier](
const Particle*) ->
double {
353 DBObjPtr<DBRepresentationOfSoftwareTriggerCut> downloadedCut(fullFormatIdentifier(triggerIdentifier));
354 if (not downloadedCut)
356 return double(downloadedCut->getPreScaleFactor());
359 return outputFunction;
363 VARIABLE_GROUP(
"L1 Trigger");
364 REGISTER_VARIABLE(
"L1Trigger", L1Trigger,
365 "[Eventbased] Returns 1 if at least one PSNM L1 trigger bit is true.");
366 REGISTER_METAVARIABLE(
"L1PSNM(name)", L1PSNM,
368[Eventbased] Returns the PSNM (Prescale And Mask, after prescale) status (1 or 0) of the output trigger bit with the given name.
369For some output trigger bits, we assign a prescale factor to reduce the number of triggered events.
370For example, we want to keep only 1% of Bhabha events. A prescale factor of 100 is then assigned to ``bha_3D`` (Bhabha selected in 3D criteria).
371Prescale factor of a given output trigger bit could be different in different datasets.
372It is recommended to use prescaled trigger bits (L1PSNM) or un-prescaled trigger bits (L1FTDL) for your analysis.
373In run-independent MC, configuration of the prescales in TSIM (trigger simulation) can be different from data, so L1 FTDL is recommended.
374In run-dependent MC, configuration of the prescales in TSIM is consistent with data, so L1PSNM is recommended.
375Please check on `the dedicated XWiki page <https://xwiki.desy.de/xwiki/rest/p/2471f>`__ or `the dedicated Belle II notes <https://docs.belle2.org/search?ln=en&p=%22Trigger+Summary%22&f=&action_search=Search&c=Belle+II+Notes>`__ to find out the definition of trigger bits.
377 Manager::VariableDataType::c_double);
378 REGISTER_METAVARIABLE("L1FTDL(name)", L1FTDL,
380[Eventbased] Returns the FTDL (Final Trigger Decision Logic, before prescale) status (1 or 0) of the output trigger bit with the given name. Output bits are the outputs of GDL, combining different input trigger bits for final decision. For example, ``ty_0/1/2/3`` is one of the input trigger bits meaning the number of neuro 3D tracks is one/two/three/more than three. While ``yyy`` is one of the output trigger bits meaning ``(ty_2 or ty_3) and !veto``. Please check on `the dedicated XWiki page <https://xwiki.desy.de/xwiki/rest/p/2471f>`__ or `the dedicated Belle II notes <https://docs.belle2.org/search?ln=en&p=%22Trigger+Summary%22&f=&action_search=Search&c=Belle+II+Notes>`__ to find out the definition of trigger bits.
382 Manager::VariableDataType::c_double);
383 REGISTER_METAVARIABLE("L1Input(name)", L1Input,
385[Eventbased] Returns the input bit status (1 or 0) of the trigger bit with the given name. Input trigger bits are predefined selections from each sub-detector, with adjustment of the delay and width, in order to fix latency on GDL. For example, ``ty_0/1/2/3`` is one of the input trigger bits meaning the number of neuro 3D tracks is one/two/three/more than three. Please check on `the dedicated XWiki page <https://xwiki.desy.de/xwiki/rest/p/2471f>`__ or `the dedicated Belle II notes <https://docs.belle2.org/search?ln=en&p=%22Trigger+Summary%22&f=&action_search=Search&c=Belle+II+Notes>`__ to find out the definition of trigger bits.
387 Manager::VariableDataType::c_double);
388 REGISTER_METAVARIABLE("L1Prescale(name)", L1PSNMPrescale,
390[Eventbased] Returns the PSNM (prescale and mask) prescale factor of the trigger bit with the given name. Definition of prescale factor is shown in a few lines before in `L1PSNM`. Prescale factors are usually dependent on different datasets.
392 Manager::VariableDataType::c_double);
393 REGISTER_VARIABLE("L1PSNMBit(i)", L1PSNMBit,
395[Eventbased] Returns the PSNM (Prescale And Mask, after prescale) status (1 or 0) of i-th trigger bit.
398 It is recommended to use this variable only for debugging and to use :b2:var:`L1PSNM`
399 with the explicit trigger bit name for physics analyses or performance studies.
401 REGISTER_VARIABLE("L1FTDLBit(i)", L1FTDLBit,
403[Eventbased] Returns the FTDL (Final Trigger Decision Logic, before prescale) status (1 or 0) of i-th trigger bit.
406 It is recommended to use this variable only for debugging and to use :b2:var:`L1FTDL`
407 with the explicit trigger bit name for physics analyses or performance studies.
409 REGISTER_VARIABLE("L1InputBit(i)", L1InputBit,
411[Eventbased] Returns the input bit status (1 or 0) of the i-th input trigger bit.
414 It is recommended to use this variable only for debugging and to use :b2:var:`L1Input`
415 with the explicit trigger bit name for physics analyses or performance studies.
417 REGISTER_VARIABLE("L1PSNMBitPrescale(i)", L1PSNMBitPrescale,
419[Eventbased] Returns the PSNM (prescale and mask) prescale of i-th trigger bit.
422 It is recommended to use this variable only for debugging and to use :b2:var:`L1Prescale`
423 with the explicit trigger bit name for physics analyses or performance studies.
425 REGISTER_VARIABLE("L1TimeType", L1TimeType,
426 "[Eventbased] Returns kind of detector which determines the Level1 trigger timing. 0:ECL, 1:TOP, 2:SELF(timing of PSNM bit), 3:CDC, 5:delayed bhabha, 7: random, 13:poisson.");
427 REGISTER_VARIABLE(
"L1TimeQuality", L1TimeQuality,
428 "[Eventbased] Returns expected Level1 timing resolution. This flag will be used for SVD 3-point sampling in future. 0:None; 1:Coarse (sigma > x ns); 2:FINE (sigma < x ns); x has been set to about 5ns before LS1 but can be changed in future");
429 REGISTER_VARIABLE(
"isPoissonTriggerInInjectionVeto", isPoissonInInjectionVeto,
430 "[Eventbased] Returns 1 if the poisson random trigger is within the injection veto window.");
432 VARIABLE_GROUP(
"Software Trigger");
433 REGISTER_METAVARIABLE(
"SoftwareTriggerResult(triggerIdentifier)", softwareTriggerResult, R
"DOC(
434[Eventbased] [Expert] returns the SoftwareTriggerCutResult, defined as reject (-1), accept (1), or noResult (0).
435If the trigger identifier is not found, returns NaN.
441 SoftwareTriggerResult(filter 1_Estargt1_GeV_cluster_no_other_cluster_Estargt0.3_GeV)
443which is equivalent to
447 SoftwareTriggerResult(software_trigger_cut&filter&1_Estargt1_GeV_cluster_no_other_cluster_Estargt0.3_GeV)
450.. warning:: the meanings of these change depending if using trigger or the skim stage, hence expert.
452.. seealso:: ``b2hlt_triggers`` for possible triggerIdentifiers.
454 )DOC", Manager::VariableDataType::c_double);
456 REGISTER_METAVARIABLE("SoftwareTriggerResultNonPrescaled(triggerIdentifier)", softwareTriggerResultNonPrescaled,
457 "[Eventbased] [Expert] returns the SoftwareTriggerCutResult, "
458 "if this trigger would not be prescaled."
459 "Please note, this is not the final HLT decision! "
460 "It is defined as reject (-1), accept (1), or noResult (0). Note "
461 "that the meanings of these change depending if using trigger "
462 "or the skim stage, hence expert."
463 "If the trigger identifier is not found, returns NaN.", Manager::VariableDataType::c_double);
464 REGISTER_VARIABLE(
"HighLevelTrigger", passesAnyHighLevelTrigger,
465 "[Eventbased] True if event passes the HLT trigger, false if not");
466 REGISTER_METAVARIABLE(
"SoftwareTriggerPrescaling(triggerIdentifier)", softwareTriggerPrescaling,
467 "[Eventbased] return the prescaling for the specific software trigger identifier. "
468 "Please note, this prescaling is taken from the currently setup database. It only corresponds "
469 "to the correct HLT prescale if you are using the online database!"
470 "If the trigger identifier is not found, returns NaN.", Manager::VariableDataType::c_double);
static const double doubleNaN
quiet_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< 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.