ATLAS Offline Software
Loading...
Searching...
No Matches
FakeBkgInternals.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8#include <string>
9#include <sstream>
10#include <regex>
11#include <algorithm>
12
13using namespace FakeBkgTools;
14using namespace CP;
15
16
17float Efficiency::value(const CP::BaseFakeBkgTool* tool) const
18{
19 float val = nominal;
20 for(const auto* su = tool->m_selectedUncertainties; su; su = su->next())
21 {
22 auto unc = uncertainties.find(su->UID);
23 if(unc != uncertainties.end())
24 {
25 val += su->sigma * ((su->sigma>=0)? unc->second.up : unc->second.down);
26 }
27 }
28 return val;
29}
30
31FinalState::FinalState(size_t h, const unsigned nparticles, const std::string& strSelection, const std::string& strProc, std::string& error) : m_hash(h)
32{
33 error.clear();
34 if(!parseProcess(strProc, error)) return;
35 if(!parseSelection(nparticles, strSelection, error)) return;
36}
37
38bool FinalState::parseProcess(std::string strProc, std::string& error)
39{
40 strProc.erase(std::remove_if(strProc.begin(), strProc.end(),
41 [](char c){ return std::isspace(c); }), strProc.end());
42 std::stringstream ss(strProc);
43 std::string token;
44 std::regex rx0("([<>]=?)([0-9])([FR])(?:\\[(L|!?T)\\])?");
45 std::regex rx1("=?([0-9])(-[0-9])?([FR])(?:\\[(L|!?T)\\])?");
46 std::smatch sm;
47 bool empty = true;
48 m_wmin = 0x0;
49 m_wmax = 0x3FFFFFFF;
50 while(std::getline(ss,token,','))
51 {
52 uint8_t nmin = 0, nmax = 0x7F;
53 empty = false;
54 if(std::regex_match(token, sm, rx0))
55 {
56 bool strict = (sm[1].str()[1] != '=');
57 if(sm[1].str()[0]=='>') nmin = sm[2].str()[0] - '0' + strict*1;
58 else
59 {
60 nmax = sm[2].str()[0] - '0';
61 if(strict && !nmax)
62 {
63 error = "number of leptons constrained to be negative in the 'process' argument: \"" + strProc + "\"";
64 }
65 nmax -= strict*1;
66 }
67 }
68 else if(std::regex_match(token, sm, rx1))
69 {
70 nmin = sm[1].str()[0] - '0';
71 if(sm[2].length()) nmax = sm[2].str()[1] - '0';
72 else nmax = nmin;
73 }
74 else
75 {
76 error = "unable to understand the specified 'process' argument: \"" + strProc + "\"";
77 return false;
78 }
81 unsigned char offset = ((sm[3]=="F")? 15 : 0);
82 if(sm[4] == "!T") offset += 5;
83 else if(sm[4] == "L") offset += 10;
84 nmin = std::max(nmin, uint8_t((m_wmin>>offset)&0xF));
85 nmax = std::min(nmax, uint8_t((m_wmax>>offset)&0xF));
87 m_wmin = (m_wmin&~(0xF<<offset)) | (nmin<<offset);
88 m_wmax = (m_wmax&~(0xF<<offset)) | (nmax<<offset);
89 if(nmin > nmax)
90 {
91 error = "unexpected error (nmin>nmax) while parsing the specified 'process' argument: \"" + strProc + "\"";
92 return false;
93 }
94 }
95 if(empty)
96 {
97 error = "the 'process' argument is empty";
98 return false;
99 }
100 m_wmin &= ~0x21084210;
101 m_wmax &= ~0x21084210;
102 return true;
103}
104
105bool FinalState::parseSelection(const unsigned short nparticles, std::string strSelection, std::string& error)
106{
108 const unsigned nc = (1 << nparticles);
109 selection.reset();
110 strSelection.erase(std::remove_if(strSelection.begin(), strSelection.end(),
111 [](char c){ return std::isspace(c); }), strSelection.end());
112 std::stringstream ss(strSelection);
113
114 std::string word = "(?:!?T){" + std::to_string(nparticles) + "}(\\+(?:!?T){" + std::to_string(nparticles) + "})*";
115
116 if(std::regex_match(strSelection, std::regex(word)))
117 {
118 while(std::getline(ss, word, '+'))
119 {
120 if(!word.length()) continue;
121 std::size_t pos;
122 while((pos=word.find("!T")) != std::string::npos) word.replace(pos, 2, 1, 'A');
123 std::reverse(word.begin(), word.end());
124 std::bitset<FakeBkgTools::maxParticles()> combination(word, 0, std::string::npos, 'A', 'T');
125 selection.set(combination.to_ulong());
126 }
127 return true;
128 }
129
130 std::regex rx0("([<>]=?)([0-9])(!?T)");
131 std::regex rx1("=?([0-9])(-[0-9])?(!?T)");
132 std::regex rx2("(OS|SS)");
133 std::smatch sm;
134 for(unsigned i=0;i<nc;++i) selection.set(i);
135 bool empty = true;
136 uint8_t maxT=15, maxL=15, minT=0, minL=0;
137 while(std::getline(ss, word, ','))
138 {
139 uint8_t nmin = 0, nmax = 0x7F;
140 if(std::regex_match(word, sm, rx0))
141 {
142 uint8_t o = (sm[1].length()<=1)? 1 : 0;
143 if(sm[1].str()[0]=='>') nmin = sm[2].str()[0] - '0' + o;
144 else
145 {
146 nmax = sm[2].str()[0] - '0';
147 if(o && !nmax)
148 {
149 error = "number of leptons constrained to be negative in the 'selection' argument: \"" + strSelection + "\"";
150 selection.reset();
151 return false;
152 }
153 nmax -= o;
154 }
155 }
156 else if(std::regex_match(word, sm, rx1))
157 {
158 nmin = sm[1].str()[0] - '0';
159 if(sm[2].length()) nmax = sm[2].str()[1] - '0';
160 else nmax = nmin;
161 }
162 else if(std::regex_match(word, sm, rx2))
163 {
165 {
166 error = "both OS and SS requirements were specifed in the 'selection' argument: \"" + strSelection + "\"; this is not allowed";
167 selection.reset();
168 return false;
169 }
170 if(sm[0].str()[0]=='S') setSS();
171 else setOS();
172 continue;
173 }
174 else
175 {
176 error = "unable to understand the specified 'selection' argument: \"" + strSelection + "\"";
177 selection.reset();
178 return false;
179 }
180 if(nmin > nmax)
181 {
182 error = "unexpected error (nmin>nmax) while parsing the specified 'selection' argument: \"" + strSelection + "\"";
183 selection.reset();
184 return false;
185 }
186 bool count_loose = sm[sm.size()-1] == "!T";
187 if(count_loose)
188 {
189 minL = std::max(minL, nmin);
190 maxL = std::min(maxL, nmax);
191 }
192 else
193 {
194 minT = std::max(minT, nmin);
195 maxT = std::min(maxT, nmax);
196 }
197 for(unsigned i=0;i<nc;++i)
198 {
199 auto n = FSBitset(i).count();
200 if(count_loose) n = nparticles - n;
201 if(n<nmin || n>nmax) selection.reset(i);
202 }
203 empty = false;
204 }
205 if(empty)
206 {
207 error = "the 'selection' argument is empty";
208 selection.reset();
209 return false;
210 }
211
213 if((((m_wmin+(m_wmin>>15))&0x1F) > maxT) // minRT + minFT > maxT
214 || (((m_wmax+(m_wmax>>15))&0x1F) < minT) // maxRT + maxFT < minT
215 || ((((m_wmin>>5)+(m_wmin>>20))&0x1F) > maxL) // minRL + minFL > maxL
216 || ((((m_wmax>>5)+(m_wmax>>20))&0x1F) < minL) // maxRL + maxFL < maxL
217 || ((((m_wmin>>10)+(m_wmin>>25))&0x1F) > maxL+maxT) // minR + minF > maxL + maxT
218 ||((((m_wmax>>10)+(m_wmax>>25))&0x1F) < minL+minT)) // maxR + maxF < minL + minT
219 {
220 error = "the specified 'selection' and 'process' arguments are not consistent";
221 selection.reset();
222 return false;
223 }
224
225 return true;
226}
double length(const pvec &v)
static Double_t ss
const int nmax(200)
static const Attributes_t empty
void setSS(bool set=true)
void setOS(bool set=true)
bool parseSelection(const unsigned short nparticles, std::string strSelection, std::string &error)
bool parseProcess(std::string process, std::string &error)
Select isolated Photons, Electrons and Muons.
std::bitset< maxCombinations()> FSBitset
constexpr uint8_t maxParticles()
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
float value(const CP::BaseFakeBkgTool *tool) const
std::map< uint16_t, FakeBkgTools::Uncertainty > uncertainties