1 |
// Dear emacs, this is -*- c++ -*-
|
2 |
|
3 |
#include "include/EventCalc.h"
|
4 |
|
5 |
#include <iostream>
|
6 |
|
7 |
EventCalc* EventCalc::m_instance = NULL;
|
8 |
|
9 |
EventCalc* EventCalc::Instance()
|
10 |
{
|
11 |
// Get a pointer to the object handler.
|
12 |
// This is the only way to access this class,
|
13 |
// since it's a singleton. This method is accessible
|
14 |
// from everywhere.
|
15 |
|
16 |
if (m_instance == NULL){
|
17 |
m_instance = new EventCalc();
|
18 |
}
|
19 |
return m_instance;
|
20 |
}
|
21 |
|
22 |
EventCalc::EventCalc() : m_logger( "EventCalc" )
|
23 |
{
|
24 |
// constructor: initialise all variables
|
25 |
m_logger << DEBUG << "Constructor called." << SLogger::endmsg;
|
26 |
m_bcc = NULL;
|
27 |
m_lumi = NULL;
|
28 |
m_primlep = NULL;
|
29 |
m_ttgen = NULL;
|
30 |
}
|
31 |
|
32 |
EventCalc::~EventCalc()
|
33 |
{
|
34 |
// default destructor
|
35 |
}
|
36 |
|
37 |
void EventCalc::Reset()
|
38 |
{
|
39 |
// reset: set all booleans to false
|
40 |
// this has to be done at the beginning of each event
|
41 |
// after a call to reset all quantities will be re-calculated
|
42 |
// when they are accessed
|
43 |
|
44 |
// (re-)set the pointers using the ObjectHandler
|
45 |
|
46 |
//m_bcc = ?
|
47 |
//m_lumi = ?
|
48 |
|
49 |
// reset booleans
|
50 |
b_HT = false;
|
51 |
b_HTlep = false;
|
52 |
b_Reconstruction = false;
|
53 |
|
54 |
m_TotalWeight = 1.;
|
55 |
|
56 |
m_primlep = NULL;
|
57 |
delete m_ttgen;
|
58 |
m_ttgen = NULL;
|
59 |
|
60 |
}
|
61 |
|
62 |
void EventCalc::SetBaseCycleContainer(BaseCycleContainer* bcc)
|
63 |
{
|
64 |
// set the internal pointer to the container with all objects
|
65 |
m_bcc = bcc;
|
66 |
m_logger << DEBUG << "Pointer to BaseCycleContainer set." << SLogger::endmsg;
|
67 |
}
|
68 |
|
69 |
void EventCalc::SetLumiHandler(LuminosityHandler* lh)
|
70 |
{
|
71 |
// set the internal pointer to the container with all objects
|
72 |
m_lumi = lh;
|
73 |
m_logger << DEBUG << "Pointer to LumiHandler set." << SLogger::endmsg;
|
74 |
}
|
75 |
|
76 |
BaseCycleContainer* EventCalc::GetBaseCycleContainer()
|
77 |
{
|
78 |
// return the pointer to the container with all objects
|
79 |
if (!m_bcc){
|
80 |
m_logger << WARNING << "Pointer to BaseCycleContainer is NULL." << SLogger::endmsg;
|
81 |
}
|
82 |
return m_bcc;
|
83 |
}
|
84 |
|
85 |
LuminosityHandler* EventCalc::GetLumiHandler()
|
86 |
{
|
87 |
// return the pointer to the container with all objects
|
88 |
if (!m_lumi){
|
89 |
m_logger << WARNING << "Pointer to LumiHandler is NULL." << SLogger::endmsg;
|
90 |
}
|
91 |
return m_lumi;
|
92 |
}
|
93 |
|
94 |
double EventCalc::GetHT()
|
95 |
{
|
96 |
// calculate HT, which is defined as the scalar sum of all
|
97 |
// jets, leptons and missing transverse momentum in the event
|
98 |
if (!b_HT){
|
99 |
|
100 |
b_HT = true;
|
101 |
m_HT = 0;
|
102 |
|
103 |
// add lepton pt and MET
|
104 |
m_HT += GetHTlep();
|
105 |
|
106 |
// sum over pt of all jets
|
107 |
if(m_bcc->jets){
|
108 |
for(unsigned int i=0; i<m_bcc->jets->size(); ++i){
|
109 |
m_HT += m_bcc->jets->at(i).pt();
|
110 |
}
|
111 |
}
|
112 |
|
113 |
}
|
114 |
return m_HT;
|
115 |
}
|
116 |
|
117 |
double EventCalc::GetHTlep()
|
118 |
{
|
119 |
// calculate HT_lep, which is defined as the scalar sum of all
|
120 |
// leptons and missing transverse momentum in the event
|
121 |
if (!b_HTlep){
|
122 |
|
123 |
b_HTlep = true;
|
124 |
m_HTlep=0;
|
125 |
|
126 |
// sum over pt of all electrons
|
127 |
if(m_bcc->electrons){
|
128 |
for(unsigned int i=0; i<m_bcc->electrons->size(); ++i){
|
129 |
m_HTlep += m_bcc->electrons->at(i).pt();
|
130 |
}
|
131 |
}
|
132 |
|
133 |
// sum over pt of all muons
|
134 |
if(m_bcc->muons){
|
135 |
for(unsigned int i=0; i<m_bcc->muons->size(); ++i){
|
136 |
m_HTlep += m_bcc->muons->at(i).pt();
|
137 |
}
|
138 |
}
|
139 |
|
140 |
// sum over pt of all taus
|
141 |
if(m_bcc->taus){
|
142 |
for(unsigned int i=0; i<m_bcc->taus->size(); ++i){
|
143 |
m_HTlep += m_bcc->taus->at(i).pt();
|
144 |
}
|
145 |
}
|
146 |
|
147 |
// add MET
|
148 |
if(m_bcc->met) m_HTlep += m_bcc->met->pt();
|
149 |
|
150 |
}
|
151 |
return m_HTlep;
|
152 |
}
|
153 |
|
154 |
Particle* EventCalc::GetPrimaryLepton(){
|
155 |
|
156 |
if(!m_primlep){
|
157 |
double ptmax = -999;
|
158 |
for(unsigned int i=0; i<m_bcc->electrons->size(); ++i){
|
159 |
if(m_bcc->electrons->at(i).pt()>ptmax){
|
160 |
ptmax = m_bcc->electrons->at(i).pt();
|
161 |
m_primlep = &m_bcc->electrons->at(i);
|
162 |
}
|
163 |
}
|
164 |
for(unsigned int i=0; i<m_bcc->muons->size(); ++i){
|
165 |
if(m_bcc->muons->at(i).pt()>ptmax){
|
166 |
ptmax = m_bcc->muons->at(i).pt();
|
167 |
m_primlep = &m_bcc->muons->at(i);
|
168 |
}
|
169 |
}
|
170 |
}
|
171 |
|
172 |
return m_primlep;
|
173 |
}
|
174 |
|
175 |
TTbarGen* EventCalc::GetTTbarGen(){
|
176 |
|
177 |
if(!m_ttgen){
|
178 |
m_ttgen = new TTbarGen(m_bcc);
|
179 |
}
|
180 |
|
181 |
return m_ttgen;
|
182 |
}
|
183 |
|
184 |
|
185 |
std::vector<LorentzVector> EventCalc::NeutrinoReconstruction(const LorentzVector lepton, const LorentzVector met){
|
186 |
|
187 |
|
188 |
TVector3 lepton_pT = toVector(lepton);
|
189 |
lepton_pT.SetZ(0);
|
190 |
|
191 |
TVector3 neutrino_pT = toVector(met);
|
192 |
neutrino_pT.SetZ(0);
|
193 |
|
194 |
const float mass_w = 80.399;
|
195 |
float mu = mass_w * mass_w / 2 + lepton_pT * neutrino_pT;
|
196 |
|
197 |
float A = - (lepton_pT * lepton_pT);
|
198 |
float B = mu * lepton.pz();
|
199 |
float C = mu * mu - lepton.e() * lepton.e() * (neutrino_pT * neutrino_pT);
|
200 |
|
201 |
float discriminant = B * B - A * C;
|
202 |
|
203 |
std::vector<LorentzVector> solutions;
|
204 |
|
205 |
if (0 >= discriminant)
|
206 |
{
|
207 |
// Take only real part of the solution
|
208 |
//
|
209 |
LorentzVectorXYZE solution (0,0,0,0);
|
210 |
solution.SetPx(met.Px());
|
211 |
solution.SetPy(met.Py());
|
212 |
solution.SetPz(-B / A);
|
213 |
solution.SetE(toVector(solution).Mag());
|
214 |
|
215 |
solutions.push_back(toPtEtaPhi(solution));
|
216 |
|
217 |
//_solutions = 0 > discriminant ? 0 : 1;
|
218 |
}
|
219 |
else
|
220 |
{
|
221 |
discriminant = sqrt(discriminant);
|
222 |
|
223 |
LorentzVectorXYZE solution (0,0,0,0);
|
224 |
solution.SetPx(met.Px());
|
225 |
solution.SetPy(met.Py());
|
226 |
solution.SetPz((-B - discriminant) / A);
|
227 |
solution.SetE(toVector(solution).Mag());
|
228 |
|
229 |
solutions.push_back(toPtEtaPhi(solution));
|
230 |
|
231 |
LorentzVectorXYZE solution2 (0,0,0,0);
|
232 |
solution2.SetPx(met.Px());
|
233 |
solution2.SetPy(met.Py());
|
234 |
solution2.SetPz((-B + discriminant) / A);
|
235 |
solution2.SetE(toVector(solution2).Mag());
|
236 |
|
237 |
solutions.push_back(toPtEtaPhi(solution2));
|
238 |
|
239 |
//_solutions = 2;
|
240 |
}
|
241 |
|
242 |
return solutions;
|
243 |
}
|
244 |
|
245 |
void EventCalc::FillHighMassTTbarHypotheses(){
|
246 |
|
247 |
if(b_Reconstruction) return;
|
248 |
b_Reconstruction=true;
|
249 |
|
250 |
//clear hypothesis list
|
251 |
m_bcc->recoHyps->clear();
|
252 |
|
253 |
//find primary charged lepton
|
254 |
Particle* lepton = GetPrimaryLepton();
|
255 |
|
256 |
//reconstruct neutrino
|
257 |
std::vector<LorentzVector> neutrinos = NeutrinoReconstruction( lepton->v4(), m_bcc->met->v4());
|
258 |
|
259 |
ReconstructionHypothesis hyp;
|
260 |
|
261 |
hyp.set_lepton(*lepton);
|
262 |
|
263 |
//loop over neutrino solutions and jet assignments to fill hyotheses
|
264 |
for(unsigned int i=0; i< neutrinos.size();++i){
|
265 |
|
266 |
hyp.set_neutrino_v4(neutrinos[i]);
|
267 |
LorentzVector wlep_v4 = lepton->v4()+neutrinos[i];
|
268 |
|
269 |
unsigned int n_jets = m_bcc->jets->size();
|
270 |
if(n_jets>10) n_jets=10; //avoid crashes in events with many jets
|
271 |
unsigned int max_j = myPow(3, n_jets);
|
272 |
for (unsigned int j=0; j < max_j; j++) {
|
273 |
LorentzVector tophad_v4(0,0,0,0);
|
274 |
LorentzVector toplep_v4 = wlep_v4;
|
275 |
int hadjets=0;
|
276 |
int lepjets=0;
|
277 |
int num = j;
|
278 |
hyp.clear_jetindices();
|
279 |
for (unsigned int k=0; k<n_jets; k++) {
|
280 |
// num is the k-th digit of j if you
|
281 |
// write j in a base-3 system. According
|
282 |
// to the value of this digit (which takes
|
283 |
// values from 0 to 2,
|
284 |
// in all possible combinations with the other digits),
|
285 |
// decide how to treat the jet.
|
286 |
|
287 |
if(num%3==0) {
|
288 |
tophad_v4 = tophad_v4 + m_bcc->jets->at(k).v4();
|
289 |
hyp.add_tophad_jet_index(k);
|
290 |
hadjets++;
|
291 |
}
|
292 |
|
293 |
if(num%3==1) {
|
294 |
toplep_v4 = toplep_v4 + m_bcc->jets->at(k).v4();
|
295 |
hyp.add_toplep_jet_index(k);
|
296 |
lepjets++;
|
297 |
}
|
298 |
//if(num%3==2); //do not take this jet
|
299 |
|
300 |
//shift the trigits of num to the right:
|
301 |
num /= 3;
|
302 |
}
|
303 |
|
304 |
//search jet with highest pt assigned to leptonic top
|
305 |
float maxpt=-999;
|
306 |
int maxind=-1;
|
307 |
for(unsigned int i=0; i<hyp.toplep_jets_indices().size(); ++i){
|
308 |
float pt = m_bcc->jets->at(hyp.toplep_jets_indices().at(i)).pt();
|
309 |
if(pt>maxpt){
|
310 |
maxpt=pt;
|
311 |
maxind=hyp.toplep_jets_indices().at(i);
|
312 |
}
|
313 |
}
|
314 |
hyp.set_blep_index(maxind);
|
315 |
|
316 |
|
317 |
//fill only hypotheses with at least one jet assigned to each top quark
|
318 |
if(hadjets>0 && lepjets>0){
|
319 |
hyp.set_tophad_v4(tophad_v4);
|
320 |
hyp.set_toplep_v4(toplep_v4);
|
321 |
m_bcc->recoHyps->push_back(hyp);
|
322 |
}
|
323 |
}
|
324 |
}
|
325 |
|
326 |
}
|
327 |
|
328 |
|
329 |
void EventCalc::PrintEventContent(){
|
330 |
|
331 |
m_logger << INFO << "----------------- event content -----------------" << SLogger::endmsg;
|
332 |
m_logger << INFO << "run: " << m_bcc->run << " lumi block:" << m_bcc->luminosityBlock << " event: " << m_bcc->event << SLogger::endmsg;
|
333 |
m_logger << INFO << "MET = " << m_bcc->met->pt() << " METphi = " << m_bcc->met->phi() << " HTlep = " << GetHTlep() << SLogger::endmsg;
|
334 |
if(m_bcc->electrons){m_logger << INFO << "Electrons:" << SLogger::endmsg;
|
335 |
for(unsigned int i=0; i<m_bcc->electrons->size(); ++i){
|
336 |
m_logger << INFO << " " << i+1 << " pt = " << m_bcc->electrons->at(i).pt() <<" eta = " << m_bcc->electrons->at(i).eta()
|
337 |
<< " supercluster eta = " <<m_bcc->electrons->at(i).supercluster_eta() << " IP wrt bsp = " << fabs(m_bcc->electrons->at(i).gsfTrack_dxy_vertex(m_bcc->pvs->at(0).x(), m_bcc->pvs->at(0).y()))
|
338 |
<< " pass conv veto = " << m_bcc->electrons->at(i).passconversionveto() << " mvaTrigV0 = " << m_bcc->electrons->at(i).mvaTrigV0()
|
339 |
<< " dEtaIn = " << m_bcc->electrons->at(i).dEtaIn() << " sigmaIEtaIEta = " << m_bcc->electrons->at(i).sigmaIEtaIEta()
|
340 |
<< " HoverE = " << m_bcc->electrons->at(i).HoverE() << " EcalEnergy = " << m_bcc->electrons->at(i).EcalEnergy()
|
341 |
<< " EoverPIn = " << m_bcc->electrons->at(i).EoverPIn() << " trackMomentumAtVtx = " << m_bcc->electrons->at(i).EcalEnergy()/m_bcc->electrons->at(i).EoverPIn()
|
342 |
<< SLogger::endmsg;
|
343 |
}
|
344 |
}
|
345 |
if(m_bcc->muons){m_logger << INFO << "Muons:" << SLogger::endmsg;
|
346 |
for(unsigned int i=0; i<m_bcc->muons->size(); ++i){
|
347 |
m_logger << INFO << " " << i+1 << " pt = " << m_bcc->muons->at(i).pt() <<" eta = " << m_bcc->muons->at(i).eta() << SLogger::endmsg;
|
348 |
}
|
349 |
}
|
350 |
if(m_bcc->taus){m_logger << INFO << "Taus:" << SLogger::endmsg;
|
351 |
for(unsigned int i=0; i<m_bcc->taus->size(); ++i){
|
352 |
m_logger << INFO << " " << i+1 << " pt = " << m_bcc->taus->at(i).pt() <<" eta = " << m_bcc->taus->at(i).eta() << SLogger::endmsg;
|
353 |
}
|
354 |
}
|
355 |
if(m_bcc->jets){m_logger << INFO << "Jets:" << SLogger::endmsg;
|
356 |
for(unsigned int i=0; i<m_bcc->jets->size(); ++i){
|
357 |
m_logger << INFO << " " << i+1 << " pt = " << m_bcc->jets->at(i).pt() <<" eta = " << m_bcc->jets->at(i).eta() << " genjet_pt = " << m_bcc->jets->at(i).genjet_pt() << " genjet_eta = " << m_bcc->jets->at(i).genjet_eta() <<SLogger::endmsg;
|
358 |
}
|
359 |
}
|
360 |
if(m_bcc->topjets){m_logger << INFO << "TopJets:" << SLogger::endmsg;
|
361 |
for(unsigned int i=0; i<m_bcc->topjets->size(); ++i){
|
362 |
m_logger << INFO << " " << i+1 << " pt = " << m_bcc->topjets->at(i).pt() <<" eta = " << m_bcc->topjets->at(i).eta() << SLogger::endmsg;
|
363 |
}
|
364 |
}
|
365 |
if(m_bcc->photons){m_logger << INFO << "Photons:" << SLogger::endmsg;
|
366 |
for(unsigned int i=0; i<m_bcc->photons->size(); ++i){
|
367 |
m_logger << INFO << " " << i+1 << " pt = " << m_bcc->photons->at(i).pt() <<" eta = " << m_bcc->photons->at(i).eta() << SLogger::endmsg;
|
368 |
}
|
369 |
}
|
370 |
}
|
371 |
|
372 |
|
373 |
void EventCalc::ProduceWeight(double weight)
|
374 |
{
|
375 |
m_TotalWeight = m_TotalWeight * weight;
|
376 |
}
|
377 |
|
378 |
double EventCalc::GetWeight()
|
379 |
{
|
380 |
|
381 |
return m_TotalWeight;
|
382 |
}
|
383 |
|
384 |
void EventCalc::PrintGenParticles(string name)
|
385 |
{
|
386 |
|
387 |
m_logger << INFO << "Printing generator particles for event " << GetEventNum() << " (name = " << name << ")" << SLogger::endmsg;
|
388 |
if (GetGenParticles()->size()>0){
|
389 |
|
390 |
std::cout << setw(10) << "index" << '|';
|
391 |
std::cout << setw(10) << "pdgId" << '|';
|
392 |
std::cout << setw(10) << "status" << '|';
|
393 |
std::cout << setw(20) << "mother1" << '|';
|
394 |
std::cout << setw(20) << "mother2" << '|';
|
395 |
std::cout << setw(20) << "daughter1" << '|';
|
396 |
std::cout << setw(20) << "daughter2" << '|';
|
397 |
std::cout << setw(10) << "Px" << '|';
|
398 |
std::cout << setw(10) << "Py" << '|';
|
399 |
std::cout << setw(10) << "Pz"<< '|';
|
400 |
std::cout << setw(10) << "energy" << '|';
|
401 |
std::cout << setw(10) << "Pt" << '|';
|
402 |
std::cout << setw(10) << "M" << std::endl;
|
403 |
|
404 |
std::cout.fill('-');
|
405 |
std::cout << setw(11) << "+";
|
406 |
std::cout << setw(11) << "+";
|
407 |
std::cout << setw(11) << "+";
|
408 |
std::cout << setw(21) << "+";
|
409 |
std::cout << setw(21) << "+";
|
410 |
std::cout << setw(21) << "+";
|
411 |
std::cout << setw(21) << "+";
|
412 |
std::cout << setw(11) << "+";
|
413 |
std::cout << setw(11) << "+";
|
414 |
std::cout << setw(11) << "+";
|
415 |
std::cout << setw(11) << "+";
|
416 |
std::cout << setw(11) << "+";
|
417 |
std::cout << setw(11) << "" << std::endl;
|
418 |
std::cout.fill(' ');
|
419 |
|
420 |
for (unsigned int i=0; i<GetGenParticles()->size(); ++i){
|
421 |
GenParticle gp = GetGenParticles()->at(i);
|
422 |
gp.Print(GetGenParticles());
|
423 |
}
|
424 |
std::cout << std::endl;
|
425 |
} else {
|
426 |
m_logger << INFO << "No generator particles found." << SLogger::endmsg;
|
427 |
}
|
428 |
|
429 |
}
|