Writing OpenHLT emulations
page under construction
Aim : give guidelines and examples to implement emulations in a concise way.
Introduction
The emulations are implemented in
OHltTreeOpen.cpp, and sometimes require some modifications of
OHltTree.h.
The main function, OHltTree::CheckOpenHlt relies on matching trigger names :
else if (menu->GetTriggerName(it).CompareTo("OpenHLT_Jet30") == 0) {
if (map_L1BitOfStandardHLTPath.find(menu->GetTriggerName(it))->second==1) {
if(OpenHlt1CorJetPassed(30)>=1) {
if (prescaleResponse(menu,cfg,rcounter,it)) { triggerBit[it] = true; }
}
}
}
else if (menu->GetTriggerName(it).CompareTo("OpenHLT_Jet50") == 0) {
if (map_L1BitOfStandardHLTPath.find(menu->GetTriggerName(it))->second==1) {
if(OpenHlt1CorJetPassed(50)>=1) {
if (prescaleResponse(menu,cfg,rcounter,it)) { triggerBit[it] = true; }
}
}
}
else if (menu->GetTriggerName(it).CompareTo("OpenHLT_Jet80") == 0) {
if (map_L1BitOfStandardHLTPath.find(menu->GetTriggerName(it))->second==1) {
if(OpenHlt1CorJetPassed(80)>=1) {
if (prescaleResponse(menu,cfg,rcounter,it)) { triggerBit[it] = true; }
}
}
}
...
The above implementation is fine when a reasonable number of emulations is needed, but, as time goes by, we keep adding more emulations and end up with thousand lines of code
(it makes it hard to see mistakes). This may be made more concise using regexp matching (and for more complicated objects, maps). There is no need to be an expert in regexp though, just mimic the examples...
Jets, MET, MHT, HT....objects using a single threshold
First example with a single object path
Taking up the above example with jets, this can be made more concise using regexp matching as follows :
else if (isJetXTrigger(triggerName, thresholds)) <--- this has to be defined "elsewhere"
{
if (map_L1BitOfStandardHLTPath.find(triggerName)->second==1)
{
if (prescaleResponse(menu, cfg, rcounter, it))
{
if (OpenHlt1CorJetPassed(thresholds[0])>=1)
{
triggerBit[it] = true;
}
}
}
}
The function
isJetXTrigger(triggerName, thresholds)
takes as argument a TString (triggerName) defined at the begining of OHltTree::CheckOpenHlt (line 1938 at the time of writing), and a vector of double filled by
isJetXTrigger
. This function is defined before OHltTree::CheckOpenHlt as follows :
bool isJetXTrigger(TString triggerName, vector<double> &thresholds)
{
TString pattern = "(OpenHLT_Jet([0-9]+)){1}$";
TPRegexp matchThreshold(pattern);
if (matchThreshold.MatchB(triggerName))
{
TObjArray *subStrL = TPRegexp(pattern).MatchS(triggerName);
double thresholdJet = (((TObjString *)subStrL->At(2))->GetString()).Atof();
thresholds.push_back(thresholdJet);
delete subStrL;
return true;
}
else
return false;
}
subStrL
, the list of substrings returned by root contains 0) the full string 1) the substring within which the pattern has been found, that is the largest brackets enclosing the pattern, 2) the pattern itself. Hence the "At(2)".
The {1} ensures that the full string is matched once exactly (not mandatory provided we don't try exotic names)
Example with a cross-trigger path
To store the jet threshold, a double would have been sufficient in the single jet example. However, for the sake of harmonization, a vector is used, so that we can have cross triggers like
bool isHTX_MHTXTrigger(TString triggerName, vector<double> &thresholds)
{
TString pattern = "(OpenHLT_HT([0-9]+)_MHT([0-9]+))$";
TPRegexp matchThreshold(pattern);
if (matchThreshold.MatchB(triggerName))
{
TObjArray *subStrL = TPRegexp(pattern).MatchS(triggerName);
double thresholdHT = (((TObjString *)subStrL->At(2))->GetString()).Atof();
double thresholdMHT = (((TObjString *)subStrL->At(3))->GetString()).Atof();
thresholds.push_back(thresholdHT);
thresholds.push_back(thresholdMHT);
delete subStrL;
return true;
}
else
return false;
}
called in :
else if (isHTX_MHTXTrigger(triggerName, thresholds))
{
if (map_L1BitOfStandardHLTPath.find(triggerName)->second==1)
{
if (prescaleResponse(menu, cfg, rcounter, it))
{
if (OpenHltMHT(thresholds[1], 30.)==1 && (OpenHltSumCorHTPassed(
thresholds[0],
40.) == 1))
{
triggerBit[it] = true;
}
}
}
}
Be careful that you call the thresholds in "the proper order".
Muons...objects using a set of three thresholds depending on a double
Muons trigger name reads one threshold ("L3") but actually relies on a set of three : L1 pt, L2 pt and L3 pt.
These thresholds are defined in map_muThresholds in
OHltTree.h, which use follows :
map_muThresholds[3.].push_back(0.);
map_muThresholds[3.].push_back(0.);
map_muThresholds[3.].push_back(3.);
map_muThresholds[5.].push_back(0.);
map_muThresholds[5.].push_back(3.);
map_muThresholds[5.].push_back(5.);
map_muThresholds[8.].push_back(0.);
map_muThresholds[8.].push_back(3.);
map_muThresholds[8.].push_back(8.);
.....
defined thresholds : 3, 5, 8, 12, 13, 15, 17, 20, 24, 30, 40, 60, 100.
Disclaimer : this won't give reliable rates if the muons used by your path are non-standard.
For the record, the boolean function and the else if blocks look like :
bool isMuXTrigger(TString triggerName, vector<double> &thresholds)
{
TString pattern = "(OpenHLT_Mu([0-9]+)){1}$";
TPRegexp matchThreshold(pattern);
if (matchThreshold.MatchB(triggerName))
{
TObjArray *subStrL = TPRegexp(pattern).MatchS(triggerName);
double thresholdL3Mu = (((TObjString *)subStrL->At(2))->GetString()).Atof();
thresholds.push_back(thresholdL3Mu);
delete subStrL;
return true;
}
else
return false;
}
****************************************************************************************
else if (isMuXTrigger(triggerName, thresholds))
{
if (map_L1BitOfStandardHLTPath.find(triggerName)->second==1)
{
if (prescaleResponse(menu, cfg, rcounter, it))
{
if (OpenHlt1MuonPassed(map_muThresholds[thresholds[0]], 2., 0)>=1)
{
triggerBit[it] = true;
}
}
}
}
EGamma...objects that calls set of thresholds summarized in strings
How to implement Ele?_CaloId?_CaloIso?_TrkId?_TrkIso? for any set of ? in (int, {VL, L, T, VT}, {VL, L, T, VT} etc...) in a
single emulation (that is a single else if block) ?
First some maps have been implemented in OHltTree.h (look for _map_EG) :...
Mixing the above
Jets, MET, muons, electrons, photons may of course be mixed in cross triggers. One last example :
The examples given here might still be subject to improvements
--
LucieGAUTHIER - 06-Jul-2011