1 |
#include <memory>
|
2 |
#include <string>
|
3 |
#include <iostream>
|
4 |
#include "math.h"
|
5 |
|
6 |
// user include files
|
7 |
#include "DataFormats/Math/interface/Point3D.h"
|
8 |
|
9 |
#include "FWCore/Framework/interface/Frameworkfwd.h"
|
10 |
#include "FWCore/Framework/interface/EDAnalyzer.h"
|
11 |
|
12 |
#include "FWCore/Framework/interface/Event.h"
|
13 |
#include "FWCore/Framework/interface/Run.h"
|
14 |
#include "FWCore/Framework/interface/MakerMacros.h"
|
15 |
|
16 |
#include "FWCore/ParameterSet/interface/ParameterSet.h"
|
17 |
|
18 |
#include "DataFormats/L1Trigger/interface/L1ParticleMap.h"
|
19 |
#include "DataFormats/L1Trigger/interface/L1EmParticle.h"
|
20 |
#include "DataFormats/L1Trigger/interface/L1JetParticle.h"
|
21 |
#include "DataFormats/L1Trigger/interface/L1MuonParticle.h"
|
22 |
#include "DataFormats/L1Trigger/interface/L1EtMissParticle.h"
|
23 |
#include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
|
24 |
|
25 |
#include "DataFormats/JetReco/interface/CaloJetCollection.h"
|
26 |
#include "DataFormats/JetReco/interface/Jet.h"
|
27 |
|
28 |
#include "DataFormats/EgammaCandidates/interface/Photon.h"
|
29 |
#include "DataFormats/EgammaCandidates/interface/PhotonFwd.h"
|
30 |
|
31 |
#include "SimDataFormats/Track/interface/SimTrack.h"
|
32 |
#include "SimDataFormats/Track/interface/SimTrackContainer.h"
|
33 |
#include "TrackingTools/TransientTrack/interface/TransientTrack.h"
|
34 |
#include "DataFormats/TrackingRecHit/interface/TrackingRecHitFwd.h"
|
35 |
#include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
|
36 |
|
37 |
#include "DataFormats/TrackReco/interface/Track.h"
|
38 |
#include "DataFormats/TrackReco/interface/TrackFwd.h"
|
39 |
#include "DataFormats/TrackReco/interface/TrackExtraFwd.h"
|
40 |
#include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
|
41 |
|
42 |
#include "DataFormats/MuonReco/interface/Muon.h"
|
43 |
#include "DataFormats/MuonReco/interface/MuonFwd.h"
|
44 |
#include "DataFormats/JetReco/interface/JetTracksAssociation.h"
|
45 |
#include "DataFormats/Candidate/interface/Candidate.h"
|
46 |
#include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
|
47 |
#include "DataFormats/Math/interface/Vector3D.h"
|
48 |
|
49 |
// Math
|
50 |
#include "Math/GenVector/VectorUtil.h"
|
51 |
#include "Math/GenVector/PxPyPzE4D.h"
|
52 |
|
53 |
|
54 |
// MC truth matching
|
55 |
//#include "RecoBTag/MCTools/interface/JetFlavour.h"
|
56 |
//#include "RecoBTag/MCTools/interface/JetFlavourIdentifier.h"
|
57 |
#include <SimDataFormats/Track/interface/SimTrack.h>
|
58 |
#include <SimDataFormats/Track/interface/SimTrackContainer.h>
|
59 |
#include "HepMC/GenEvent.h"
|
60 |
|
61 |
|
62 |
#include "DataFormats/BTauReco/interface/JetTag.h"
|
63 |
//#include "DataFormats/BTauReco/interface/JetTagFwd.h"
|
64 |
|
65 |
|
66 |
#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
|
67 |
#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
|
68 |
#include "Geometry/CommonDetUnit/interface/GeomDet.h"
|
69 |
|
70 |
|
71 |
#include "DataFormats/HepMCCandidate/interface/GenParticle.h"
|
72 |
|
73 |
//
|
74 |
#include "TTree.h"
|
75 |
#include "TNtuple.h"
|
76 |
#include "TFile.h"
|
77 |
#include "TH1F.h"
|
78 |
#include "TH2F.h"
|
79 |
#include "TVector3.h"
|
80 |
#include "TLorentzVector.h"
|
81 |
#include "TF1.h"
|
82 |
#include "TRandom.h"
|
83 |
|
84 |
|
85 |
#include "kinematics.h"
|
86 |
#include "AnalysisTools.h"
|
87 |
#include "EdmAnalysisTools.h"
|
88 |
#include "lhapdfcc.h"
|
89 |
|
90 |
|
91 |
using namespace std;
|
92 |
|
93 |
using namespace edm;
|
94 |
using namespace reco;
|
95 |
using namespace l1extra ;
|
96 |
//using namespace HepMC;
|
97 |
|
98 |
#include "WZEdmAnalyzer.h"
|
99 |
|
100 |
void
|
101 |
WZEdmAnalyzer::fillGenJets(void)
|
102 |
{
|
103 |
|
104 |
//Loop over gen jets
|
105 |
if ( !hasGenJets ) {
|
106 |
if (totalProcessedEvts ==1) std::cout << "warning ... no genJets collection" << std::endl;
|
107 |
return;
|
108 |
}
|
109 |
|
110 |
if (_is_debug) std::cout << "check point ... fillGenJets() " << std::endl;
|
111 |
for( GenJetCollection::const_iterator gen = genJets->begin(); gen != genJets->end(); ++ gen ) {
|
112 |
if (gen->pt() < genJetMinPt ) continue;
|
113 |
|
114 |
_gen_jet_ *myJet = myEvent->addGenJet();
|
115 |
myJet->pt = gen->pt();
|
116 |
myJet->eta = gen->eta();
|
117 |
myJet->phi = gen->phi();
|
118 |
|
119 |
|
120 |
// jet flavor information need to be fix latter.
|
121 |
myJet->mc_flavor = mcflavorAssociation( *gen, theGenTag);
|
122 |
|
123 |
myJet->nConstituent = gen->nConstituents();
|
124 |
|
125 |
if (_is_debug) std::cout << "check info ... nConstituents = " << gen->nConstituents() << std::endl;
|
126 |
TLorentzVector jet4Vec(gen->momentum().X(),gen->momentum().Y(),gen->momentum().Z(), gen->energy());
|
127 |
|
128 |
}
|
129 |
|
130 |
|
131 |
if (_is_debug) std::cout << "check point ... finishing fillGenJets() " << std::endl;
|
132 |
|
133 |
}
|
134 |
|
135 |
|
136 |
void
|
137 |
WZEdmAnalyzer::fillAKGenJets(void)
|
138 |
{
|
139 |
|
140 |
//Loop over gen jets
|
141 |
if ( !hasGenJets ) {
|
142 |
if (totalProcessedEvts ==1) std::cout << "warning ... no genJets collection" << std::endl;
|
143 |
return;
|
144 |
}
|
145 |
|
146 |
if (_is_debug) std::cout << "check point ... fillAKGenJets() " << std::endl;
|
147 |
for( GenJetCollection::const_iterator gen = akGenJets->begin(); gen != akGenJets->end(); ++ gen ) {
|
148 |
if (gen->pt() < genJetMinPt ) continue;
|
149 |
|
150 |
_gen_jet_ *myJet = myEvent->addAKGenJet();
|
151 |
myJet->pt = gen->pt();
|
152 |
myJet->eta = gen->eta();
|
153 |
myJet->phi = gen->phi();
|
154 |
|
155 |
|
156 |
// jet flavor information need to be fix latter.
|
157 |
myJet->mc_flavor = mcflavorAssociation( *gen, theGenTag);
|
158 |
|
159 |
myJet->nConstituent = gen->nConstituents();
|
160 |
|
161 |
if (_is_debug) std::cout << "check info ... nConstituents = " << gen->nConstituents() << std::endl;
|
162 |
// TLorentzVector jet4Vec(gen->momentum().X(),gen->momentum().Y(),gen->momentum().Z(), gen->energy());
|
163 |
|
164 |
}
|
165 |
|
166 |
|
167 |
if (_is_debug) std::cout << "check point ... finishing fillAKGenJets() " << std::endl;
|
168 |
|
169 |
}
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
void WZEdmAnalyzer::fillSimTracks(void) {
|
175 |
|
176 |
if (!recoSimTracks) return;
|
177 |
if (_is_debug) std::cout << "check point ... fillSimTracks() " << std::endl;
|
178 |
|
179 |
for (edm::SimTrackContainer::const_iterator simTrack = (*recoSimTracks).begin(); simTrack != (*recoSimTracks).end(); simTrack ++) {
|
180 |
|
181 |
mySimTrack = myEvent->addSimTrack();
|
182 |
|
183 |
mySimTrack->pt = simTrack->momentum().pt();
|
184 |
mySimTrack->phi = simTrack->momentum().phi();
|
185 |
mySimTrack->eta = simTrack->momentum().eta();
|
186 |
|
187 |
mySimTrack->mcType = simTrack->type();
|
188 |
mySimTrack->charge = (Int_t)simTrack->charge();
|
189 |
}
|
190 |
}
|
191 |
|
192 |
|
193 |
void
|
194 |
WZEdmAnalyzer::fillMCInfo(_mc_process_ *mc)
|
195 |
{
|
196 |
|
197 |
if (_is_debug) {
|
198 |
std::cout << "check point ... fillMCInfo() " << std::endl;
|
199 |
// genEvt->print();
|
200 |
}
|
201 |
|
202 |
mc->Initialize(); // clean the object
|
203 |
|
204 |
// mc->mpi = genEvt->mpi();
|
205 |
mc->processId = genEvt->signal_process_id();
|
206 |
mc->eventNumber = genEvt->event_number();
|
207 |
if (genEvt->signal_process_vertex()) {
|
208 |
mc->vtxBarcode = genEvt->signal_process_vertex()->barcode();
|
209 |
}
|
210 |
|
211 |
mc->eventScale = genEvt->event_scale();
|
212 |
mc->alphaQCD = genEvt->alphaQCD();
|
213 |
mc->alphaQED = genEvt->alphaQED();
|
214 |
if (genEvt->pdf_info()) { // correct information
|
215 |
|
216 |
mc->x1 = genEvt->pdf_info()->x1();
|
217 |
mc->x2 = genEvt->pdf_info()->x2();
|
218 |
mc->flav1 = genEvt->pdf_info()->id1();
|
219 |
mc->flav2 = genEvt->pdf_info()->id2();
|
220 |
mc->scalePDF = genEvt->pdf_info()->scalePDF();
|
221 |
mc->xfx1 = genEvt->pdf_info()->pdf1();
|
222 |
mc->xfx2 = genEvt->pdf_info()->pdf2();
|
223 |
}
|
224 |
|
225 |
|
226 |
HepMC::GenParticle *q1=0, *q2=0;
|
227 |
HepMC::GenParticle *daug1= 0, *daug2= 0, *daug3= 0;
|
228 |
HepMC::GenParticle *dd1= 0, *dd2= 0;//direct daughters of the hard interaction
|
229 |
for ( HepMC::GenEvent::particle_const_iterator p = genEvt->particles_begin();
|
230 |
p != genEvt->particles_end(); ++p ) {
|
231 |
|
232 |
q1 = 0;
|
233 |
q2 = 0;
|
234 |
daug1 = 0;
|
235 |
daug2 = 0;
|
236 |
daug3 = 0;
|
237 |
dd1 = 0;
|
238 |
dd2 = 0;
|
239 |
|
240 |
|
241 |
// concentrate on s-channel vector boson process
|
242 |
if ( abs((*p)->pdg_id()) != 22
|
243 |
&& abs((*p)->pdg_id()) != 23
|
244 |
&& abs((*p)->pdg_id()) != 24
|
245 |
&& abs((*p)->pdg_id()) != 32
|
246 |
&& abs( (*p)->pdg_id()) != 34 ) continue;
|
247 |
|
248 |
if (_is_debug) {
|
249 |
|
250 |
std::cout << "check point ... interesting vector boson existing " << std::endl;
|
251 |
(*p)->print();
|
252 |
}
|
253 |
|
254 |
if ( !(*p)->production_vertex() || !(*p)->end_vertex() ) continue;
|
255 |
|
256 |
|
257 |
|
258 |
// 1) access the interacting quark information
|
259 |
for ( HepMC::GenVertex::particle_iterator mother = (*p)->production_vertex()->particles_begin(HepMC::parents);
|
260 |
mother != (*p)->production_vertex()->particles_end(HepMC::parents);
|
261 |
++mother ) {
|
262 |
// note the temporary change to deal with Wprime.
|
263 |
// if ((*mother)->status() != 3) continue;
|
264 |
|
265 |
if (!q1) q1 = *mother;
|
266 |
if (q1) q2 = *mother;
|
267 |
|
268 |
if (_is_debug) {
|
269 |
std::cout << endl;
|
270 |
(*mother)->print();
|
271 |
}
|
272 |
}
|
273 |
|
274 |
// something special for wprime
|
275 |
// if (abs( (*p)->pdg_id()) == 34) {
|
276 |
// if (!q1 || !q2) continue;
|
277 |
// } else {
|
278 |
if (!q1 || !q2 || q1 == q2) continue;
|
279 |
//}
|
280 |
|
281 |
|
282 |
// 2) access daughter informations
|
283 |
// this might only work for leptonic decays
|
284 |
int nphotons = 0;
|
285 |
for ( HepMC::GenVertex::particle_iterator des =(*p)->end_vertex()->particles_begin(HepMC::descendants);
|
286 |
des != (*p)->end_vertex()->particles_end(HepMC::descendants);
|
287 |
++ des ) {
|
288 |
|
289 |
// be careful about this
|
290 |
// try to access the intermediate daughter quarks to calculate
|
291 |
// the decay angles.
|
292 |
if ( (*des)->status() == 3
|
293 |
&& abs( (*des)->pdg_id() )< 22 ) {
|
294 |
|
295 |
if (!dd1) dd1 = *des;
|
296 |
if (dd1) dd2 = *des;
|
297 |
}
|
298 |
|
299 |
if ((*des)->status() != 1) continue; // skip decayed ones or documentation entries
|
300 |
if ( abs( (*des)->pdg_id() ) == 16 ) continue; // skip tau neutrino
|
301 |
if ( abs( (*des)->pdg_id() ) < 22 && !daug1) daug1 = (*des);
|
302 |
if ( abs( (*des)->pdg_id() ) < 22 && daug1) daug2 = (*des);
|
303 |
|
304 |
// most energetic radiated photon
|
305 |
if ( abs( (*des)->pdg_id() ) == 22 ) {
|
306 |
|
307 |
nphotons ++;
|
308 |
if ( !daug3) daug3 = (*des);
|
309 |
else if ( (*des)->momentum().e() > daug3->momentum().e() ) {
|
310 |
|
311 |
daug3 = (*des);
|
312 |
}
|
313 |
}
|
314 |
|
315 |
if (_is_debug) {
|
316 |
std::cout << endl;
|
317 |
(*des)->print();
|
318 |
}
|
319 |
}
|
320 |
|
321 |
if (dd1 && dd2 && (daug1 == daug2) ) { // Only one of 1-1 pair found, or none of 1-1 pair was found
|
322 |
if ( !daug1) {daug1 = dd1; daug2 = dd2;}
|
323 |
else {
|
324 |
if ( dd1->pdg_id() == daug1->pdg_id() ) {daug2 = dd2;}
|
325 |
else {daug2 = dd1;}
|
326 |
}
|
327 |
}
|
328 |
if ( !daug1 || !daug2 || daug1 == daug2) continue;
|
329 |
if (_is_debug) std::cout << "check point ... " << " getMCInfo() -- dauther/parents information " << std::endl;
|
330 |
|
331 |
|
332 |
|
333 |
|
334 |
|
335 |
|
336 |
// 3) now record some quantities;
|
337 |
// a) vector boson information
|
338 |
TLorentzVector vecbos((*p)->momentum().x(),
|
339 |
(*p)->momentum().y(),
|
340 |
(*p)->momentum().z(),
|
341 |
(*p)->momentum().t());
|
342 |
|
343 |
if (dd1) mc->decayType = abs( dd1->pdg_id() );
|
344 |
mc->bosPt = vecbos.Pt();
|
345 |
mc->bosPz = vecbos.Pz();
|
346 |
mc->bosPhi = vecbos.Phi();
|
347 |
mc->bosMass = vecbos.M();
|
348 |
if ( vecbos.Pt() ) mc->bosEta = vecbos.PseudoRapidity();
|
349 |
mc->bosRap = vecbos.Rapidity();
|
350 |
mc->bosId = (*p)->pdg_id();
|
351 |
|
352 |
|
353 |
// b) access daughter information.
|
354 |
if (_is_debug) std::cout << "check point ... " << " getMCInfo() (b)" << std::endl;
|
355 |
TLorentzVector muon, muonplus;
|
356 |
if (daug1->pdg_id() > 0) {
|
357 |
muon.SetXYZT(daug1->momentum().x(),
|
358 |
daug1->momentum().y(),
|
359 |
daug1->momentum().z(),
|
360 |
daug1->momentum().t() );
|
361 |
mc->muonId = daug1->pdg_id();
|
362 |
|
363 |
muonplus.SetXYZT(daug2->momentum().x(),
|
364 |
daug2->momentum().y(),
|
365 |
daug2->momentum().z(),
|
366 |
daug2->momentum().t() );
|
367 |
mc->muonBarId = daug2->pdg_id();
|
368 |
|
369 |
} else {
|
370 |
|
371 |
muon.SetXYZT(daug2->momentum().x(),
|
372 |
daug2->momentum().y(),
|
373 |
daug2->momentum().z(),
|
374 |
daug2->momentum().t() );
|
375 |
mc->muonId = daug2->pdg_id();
|
376 |
|
377 |
muonplus.SetXYZT(daug1->momentum().x(),
|
378 |
daug1->momentum().y(),
|
379 |
daug1->momentum().z(),
|
380 |
daug1->momentum().t() );
|
381 |
mc->muonBarId = daug1->pdg_id();
|
382 |
}
|
383 |
mc->muonPt = muon.Pt();
|
384 |
mc->muonPz = muon.Pz();
|
385 |
mc->muonEta = muon.PseudoRapidity();
|
386 |
mc->muonPhi = muon.Phi();
|
387 |
mc->muonEnergy = muon.E();
|
388 |
mc->muonBarPt = muonplus.Pt();
|
389 |
mc->muonBarPz = muonplus.Pz();
|
390 |
mc->muonBarEta = muonplus.PseudoRapidity();
|
391 |
mc->muonBarPhi = muonplus.Phi();
|
392 |
mc->muonBarEnergy = muonplus.E();
|
393 |
|
394 |
// c) calculate the decay angles.
|
395 |
// tmp1 is for the particle and tmp2 is for anti-particle.
|
396 |
if (_is_debug) std::cout << "check point ... " << " getMCInfo() (c)" << std::endl;
|
397 |
TLorentzVector tmp1, tmp2, quark;
|
398 |
if (dd1 && dd2 && (dd1 !=dd2) ) {
|
399 |
|
400 |
if (dd1->pdg_id() > 0) {
|
401 |
tmp1.SetXYZT(dd1->momentum().x(), dd1->momentum().y(), dd1->momentum().z(), dd1->momentum().t() );
|
402 |
tmp2.SetXYZT(dd2->momentum().x(), dd2->momentum().y(), dd2->momentum().z(), dd2->momentum().t() );
|
403 |
mc->nrmuonId = dd1->pdg_id(); mc->nrmuonBarId = dd2->pdg_id();
|
404 |
} else {
|
405 |
tmp1.SetXYZT(dd2->momentum().x(), dd2->momentum().y(), dd2->momentum().z(), dd2->momentum().t() );
|
406 |
tmp2.SetXYZT(dd1->momentum().x(), dd1->momentum().y(), dd1->momentum().z(), dd1->momentum().t() );
|
407 |
mc->nrmuonId = dd2->pdg_id(); mc->nrmuonBarId = dd1->pdg_id();
|
408 |
}
|
409 |
// Save the daughter muon information before radiation
|
410 |
mc->nrmuonPt = tmp1.Pt();
|
411 |
mc->nrmuonPz = tmp1.Pz();
|
412 |
mc->nrmuonEta = tmp1.PseudoRapidity();
|
413 |
mc->nrmuonPhi = tmp1.Phi();
|
414 |
mc->nrmuonEnergy = tmp1.E();
|
415 |
mc->nrmuonBarPt = tmp2.Pt();
|
416 |
mc->nrmuonBarPz = tmp2.Pz();
|
417 |
mc->nrmuonBarEta = tmp2.PseudoRapidity();
|
418 |
mc->nrmuonBarPhi = tmp2.Phi();
|
419 |
mc->nrmuonBarEnergy = tmp2.E();
|
420 |
|
421 |
if (q1->pdg_id() > 0) {
|
422 |
|
423 |
quark.SetXYZT(q1->momentum().x(), q1->momentum().y(), q1->momentum().z(), q1->momentum().t() );
|
424 |
} else {
|
425 |
quark.SetXYZT(q2->momentum().x(), q2->momentum().y(), q2->momentum().z(), q2->momentum().t() );
|
426 |
}
|
427 |
mc->cosTheta = calCosTheta(quark, tmp1, tmp2);
|
428 |
}
|
429 |
|
430 |
|
431 |
// d) dilepton information
|
432 |
if (_is_debug) std::cout << "check point ... " << " getMCInfo() (d)" << std::endl;
|
433 |
TLorentzVector dilepton( muon + muonplus );
|
434 |
mc->dileptonPt = dilepton.Pt();
|
435 |
mc->dileptonPz = dilepton.Pz();
|
436 |
mc->dileptonMass = dilepton.M();
|
437 |
mc->dileptonEta = dilepton.PseudoRapidity();
|
438 |
mc->dileptonRap = dilepton.Rapidity();
|
439 |
mc->dileptonPhi = dilepton.Phi();
|
440 |
mc->cosPhi = cos(muon.Vect().Angle( muonplus.Vect() ));
|
441 |
mc->nphotons = nphotons;
|
442 |
|
443 |
// e) radiated photon information
|
444 |
if (_is_debug) std::cout << "check point ... " << " getMCInfo() (e)" << std::endl;
|
445 |
if (daug3) {
|
446 |
|
447 |
mc->photonEnergy = daug3->momentum().e();
|
448 |
mc->photonEta = daug3->momentum().eta();
|
449 |
mc->photonPhi = daug3->momentum().phi();
|
450 |
|
451 |
TVector3 photonVec(daug3->momentum().x(), daug3->momentum().y(),daug3->momentum().z() );
|
452 |
mc->photonAngle = photonVec.Angle( dilepton.Vect() );
|
453 |
}
|
454 |
|
455 |
|
456 |
/**********************************************************************
|
457 |
*
|
458 |
* some specific information for each process
|
459 |
*
|
460 |
*********************************************************************/
|
461 |
// f.1) angular distributions.
|
462 |
if (_is_debug) std::cout << "check point ... getMCInfo() (f.1)" << std::endl;
|
463 |
double result[3];
|
464 |
calCSVariables(muon, muonplus, result, ( dilepton.Pz()<0 ));
|
465 |
mc->cosThetaCS = result[0];
|
466 |
mc->sin2ThetaCS = result[1];
|
467 |
mc->tanPhiCS = result[2];
|
468 |
|
469 |
// calculate the mistag-corrected angular distributions
|
470 |
bool swap_quark = false;
|
471 |
if (genEvt->pdf_info()) {
|
472 |
|
473 |
if ( genEvt->pdf_info()->id1() < 0 ) swap_quark = true;
|
474 |
|
475 |
} else {
|
476 |
if ( (q1->pdg_id() > 0 && q1->momentum().pz() < 0)
|
477 |
|| (q2->pdg_id() > 0 && q2->momentum().pz() < 0)) swap_quark = true;
|
478 |
}
|
479 |
calCSVariables(muon, muonplus, result, swap_quark);
|
480 |
mc->corCosThetaCS = result[0];
|
481 |
mc->corSin2ThetaCS = result[1];
|
482 |
mc->corTanPhiCS = result[2];
|
483 |
|
484 |
if ( (swap_quark == 0 && dilepton.Pz() >0 )
|
485 |
|| (swap_quark == 1 && dilepton.Pz() <0 ) ) {
|
486 |
mc->sameSign = 1;
|
487 |
} else {
|
488 |
mc->sameSign = -1;
|
489 |
}
|
490 |
|
491 |
|
492 |
// calculate the mistag rate for Z/gamma process
|
493 |
if (_is_debug) std::cout << "check point ... getMCInfo() (mistag Z/gamma*)" << std::endl;
|
494 |
double wx1 = 0, wx2 = 0;
|
495 |
wx1 = pdf_x1( mc->dileptonMass, mc->dileptonRap);
|
496 |
wx2 = pdf_x2( mc->dileptonMass, mc->dileptonRap);
|
497 |
|
498 |
if ((wx1 < xmax && wx1 >xmin)
|
499 |
&& (wx2 < xmax && wx2 >xmin) ) {
|
500 |
|
501 |
if ( abs( (*p)->pdg_id() ) != 24 ) {
|
502 |
|
503 |
mc->qqbar = qqbar(wx1, wx2, mc->dileptonMass );
|
504 |
mc->qbarq = qqbar(wx2, wx1, mc->dileptonMass );
|
505 |
|
506 |
// the mistag probability
|
507 |
if (wx1 > wx2) {
|
508 |
|
509 |
mc->mistag = mc->qbarq/(mc->qqbar + mc->qbarq);
|
510 |
} else {
|
511 |
|
512 |
mc->mistag = mc->qqbar/(mc->qqbar + mc->qbarq);
|
513 |
}
|
514 |
|
515 |
} else {
|
516 |
|
517 |
if ( (*p)->pdg_id() > 0) { // W+
|
518 |
|
519 |
mc->qqbar = qqbar(wx1, wx2, +1);
|
520 |
mc->qbarq = qqbar(wx2, wx1, +1);
|
521 |
|
522 |
} else { // W-
|
523 |
|
524 |
mc->qbarq = qqbar(wx1, wx2, -1);
|
525 |
mc->qqbar = qqbar(wx2, wx1, -1);
|
526 |
}
|
527 |
|
528 |
mc->fprob = (mc->qqbar * 0.875 + 0.125 * mc->qbarq)/(mc->qqbar + mc->qbarq);
|
529 |
mc->bprob = 1 - mc->fprob;
|
530 |
}
|
531 |
}
|
532 |
|
533 |
|
534 |
|
535 |
// for W production,
|
536 |
if (_is_debug) std::cout << "check point ... getMCInfo() (W)" << std::endl;
|
537 |
if ( abs(daug1->pdg_id()) == 11
|
538 |
|| abs(daug1->pdg_id()) == 13
|
539 |
|| abs(daug1->pdg_id()) == 15) {
|
540 |
mc->metX = (*p)->momentum().x() - daug1->momentum().x();
|
541 |
mc->metY = (*p)->momentum().y() - daug1->momentum().y();
|
542 |
|
543 |
TVector3 met(mc->metX , mc->metY, 0);
|
544 |
TLorentzVector mu(daug1->momentum().x(), daug1->momentum().y(), daug1->momentum().z(), daug1->momentum().t());
|
545 |
|
546 |
mc->delta = solveWdy(mu, met, PDG_W_MASS);
|
547 |
|
548 |
|
549 |
} else if (abs(daug2->pdg_id()) == 11
|
550 |
|| abs(daug2->pdg_id()) == 13
|
551 |
|| abs(daug2->pdg_id()) == 15) {
|
552 |
|
553 |
mc->metX = (*p)->momentum().x() - daug2->momentum().x();
|
554 |
mc->metY = (*p)->momentum().y() - daug2->momentum().y();
|
555 |
TVector3 met(mc->metX , mc->metY, 0);
|
556 |
TLorentzVector mu(daug2->momentum().x(), daug2->momentum().y(), daug2->momentum().z(), daug2->momentum().t());
|
557 |
mc->delta = solveWdy(muonplus, met, PDG_W_MASS);
|
558 |
}
|
559 |
|
560 |
break;
|
561 |
} // end of the loop
|
562 |
|
563 |
if (_is_debug) std::cout << "check point ... finishing getMCInfo() " << std::endl;
|
564 |
|
565 |
}
|
566 |
|
567 |
void
|
568 |
WZEdmAnalyzer::fillGenWZ(_genwz_ *genwz)
|
569 |
{
|
570 |
if (_is_debug) {
|
571 |
std::cout << "check point ... fillGenWZ() " << std::endl;
|
572 |
// genEvt->print();
|
573 |
}
|
574 |
|
575 |
// === Begin for WZ signal MC ONLY!
|
576 |
genwz->Initialize(); // clean the object
|
577 |
genwz->gdWZ = 0;
|
578 |
int gdZ = 0; int gdW = 0; TLorentzVector genZ, genW, angZ, angW;
|
579 |
// loop over all mc generated particles
|
580 |
for ( HepMC::GenEvent::particle_const_iterator p = genEvt->particles_begin();
|
581 |
p != genEvt->particles_end(); ++p ) {// (*p)->print();
|
582 |
|
583 |
// Interested particle list!
|
584 |
if (abs((*p)->pdg_id()) != 23 && // Z
|
585 |
abs((*p)->pdg_id()) != 24 // W
|
586 |
) continue;
|
587 |
|
588 |
// Production and Decay Vertex Check and Status Check
|
589 |
if ( !(*p)->production_vertex() || !(*p)->end_vertex() ) continue;
|
590 |
if ( (*p)->status() != 3 ) continue;
|
591 |
|
592 |
// (1). Save Z information
|
593 |
if (abs((*p)->pdg_id()) == 23 && gdZ == 0) { // Z candidate is here! (*p)->print();
|
594 |
HepMC::GenParticle *q1 = 0, *q2 = 0;
|
595 |
HepMC::GenParticle *daug1= 0, *daug2= 0, *daug3=0;
|
596 |
HepMC::GenParticle *dd1 = 0, *dd2 = 0; //direct daughters of the hard interaction
|
597 |
// 1) access the interacting quark information
|
598 |
for ( HepMC::GenVertex::particle_iterator mother = (*p)->production_vertex()->particles_begin(HepMC::parents);
|
599 |
mother != (*p)->production_vertex()->particles_end(HepMC::parents);
|
600 |
++mother ) {// (*mother)->print();
|
601 |
if (!q1) q1 = *mother;
|
602 |
if (q1) q2 = *mother;
|
603 |
}
|
604 |
// There is no any requirement for parent! now
|
605 |
int nphotons = 0;
|
606 |
for ( HepMC::GenVertex::particle_iterator des =(*p)->end_vertex()->particles_begin(HepMC::descendants);
|
607 |
des != (*p)->end_vertex()->particles_end(HepMC::descendants);
|
608 |
++ des ) {
|
609 |
if ( (*des)->status() == 3 && abs( (*des)->pdg_id() )< 22 ) {
|
610 |
if (!dd1) dd1 = *des;
|
611 |
if (dd1) dd2 = *des;
|
612 |
}
|
613 |
if ((*des)->status() != 1) continue; // skip decayed ones or documentation entries
|
614 |
if ( abs( (*des)->pdg_id() ) < 22 && !daug1) daug1 = (*des);
|
615 |
if ( abs( (*des)->pdg_id() ) < 22 && daug1) daug2 = (*des);
|
616 |
// most energetic radiated photon
|
617 |
if ( abs( (*des)->pdg_id() ) == 22 ) {
|
618 |
nphotons ++;
|
619 |
if ( !daug3) daug3 = (*des);
|
620 |
else if ( (*des)->momentum().e() > daug3->momentum().e() ) {
|
621 |
daug3 = (*des);
|
622 |
}
|
623 |
}
|
624 |
}
|
625 |
// Require there must be decay particles
|
626 |
daug1 = dd1; daug2 = dd2; // Save direct daughters information
|
627 |
if ( !daug1 || !daug2 || daug1 == daug2) continue;
|
628 |
gdZ = 1; genZ.SetXYZT((*p)->momentum().x(), (*p)->momentum().y(), (*p)->momentum().z(), (*p)->momentum().t());
|
629 |
// Save vector boson information
|
630 |
TLorentzVector vecbos((*p)->momentum().x(), (*p)->momentum().y(), (*p)->momentum().z(), (*p)->momentum().t());
|
631 |
if (dd1)
|
632 |
genwz->Z_decayType = abs( dd1->pdg_id() );
|
633 |
genwz->Z_bosPt = vecbos.Pt();
|
634 |
genwz->Z_bosPz = vecbos.Pz();
|
635 |
genwz->Z_bosPhi = vecbos.Phi();
|
636 |
genwz->Z_bosMass = vecbos.M();
|
637 |
if ( vecbos.Pt() )
|
638 |
genwz->Z_bosEta = vecbos.PseudoRapidity();
|
639 |
genwz->Z_bosRap = vecbos.Rapidity();
|
640 |
genwz->Z_bosId = (*p)->pdg_id();
|
641 |
// Save daughter information.
|
642 |
TLorentzVector dauA, dauB;
|
643 |
if (daug1->pdg_id() > 0) {
|
644 |
dauA.SetXYZT(daug1->momentum().x(), daug1->momentum().y(), daug1->momentum().z(), daug1->momentum().t());
|
645 |
genwz->Z_dauAId = daug1->pdg_id();
|
646 |
dauB.SetXYZT(daug2->momentum().x(), daug2->momentum().y(), daug2->momentum().z(), daug2->momentum().t());
|
647 |
genwz->Z_dauBId = daug2->pdg_id();
|
648 |
} else {
|
649 |
dauA.SetXYZT(daug2->momentum().x(), daug2->momentum().y(), daug2->momentum().z(), daug2->momentum().t() );
|
650 |
genwz->Z_dauAId = daug2->pdg_id();
|
651 |
dauB.SetXYZT(daug1->momentum().x(), daug1->momentum().y(), daug1->momentum().z(), daug1->momentum().t());
|
652 |
genwz->Z_dauBId = daug1->pdg_id();
|
653 |
}
|
654 |
genwz->Z_dauAPt = dauA.Pt();
|
655 |
genwz->Z_dauAPz = dauA.Pz();
|
656 |
genwz->Z_dauAEta = dauA.PseudoRapidity();
|
657 |
genwz->Z_dauAPhi = dauA.Phi();
|
658 |
genwz->Z_dauAEnergy = dauA.E();
|
659 |
genwz->Z_dauBPt = dauB.Pt();
|
660 |
genwz->Z_dauBPz = dauB.Pz();
|
661 |
genwz->Z_dauBEta = dauB.PseudoRapidity();
|
662 |
genwz->Z_dauBPhi = dauB.Phi();
|
663 |
genwz->Z_dauBEnergy = dauB.E();
|
664 |
// Save dilepton information
|
665 |
TLorentzVector dilepton( dauA + dauB );
|
666 |
genwz->Z_dileptonPt = dilepton.Pt();
|
667 |
genwz->Z_dileptonPz = dilepton.Pz();
|
668 |
genwz->Z_dileptonMass = dilepton.M();
|
669 |
genwz->Z_dileptonEta = dilepton.PseudoRapidity();
|
670 |
genwz->Z_dileptonRap = dilepton.Rapidity();
|
671 |
genwz->Z_dileptonPhi = dilepton.Phi();
|
672 |
genwz->Z_cosTheta = 0; // no value
|
673 |
genwz->Z_cosPhi = cos(dauA.Vect().Angle( dauB.Vect() ));
|
674 |
// Save radiation photon information
|
675 |
genwz->Z_nphotons = nphotons;
|
676 |
if (daug3) {
|
677 |
TVector3 photonVec(daug3->momentum().x(), daug3->momentum().y(),daug3->momentum().z());
|
678 |
genwz->Z_phoEnergy = daug3->momentum().e();
|
679 |
genwz->Z_phoEta = daug3->momentum().eta();
|
680 |
genwz->Z_phoPhi = daug3->momentum().phi();
|
681 |
genwz->Z_phoAngle = photonVec.Angle( dilepton.Vect() );
|
682 |
}
|
683 |
angZ = dauA;
|
684 |
}
|
685 |
|
686 |
// (2). Save W information
|
687 |
if (abs((*p)->pdg_id()) == 24 && gdW == 0) { // W candidate is here! (*p)->print();
|
688 |
HepMC::GenParticle *q1 = 0, *q2 = 0;
|
689 |
HepMC::GenParticle *daug1= 0, *daug2= 0, *daug3=0;
|
690 |
HepMC::GenParticle *dd1 = 0, *dd2 = 0; //direct daughters of the hard interaction
|
691 |
// 1) access the interacting quark information
|
692 |
for ( HepMC::GenVertex::particle_iterator mother = (*p)->production_vertex()->particles_begin(HepMC::parents);
|
693 |
mother != (*p)->production_vertex()->particles_end(HepMC::parents);
|
694 |
++mother ) {// (*mother)->print();
|
695 |
if (!q1) q1 = *mother;
|
696 |
if (q1) q2 = *mother;
|
697 |
}
|
698 |
// There is no any requirement for parent! now
|
699 |
int nphotons = 0;
|
700 |
for ( HepMC::GenVertex::particle_iterator des =(*p)->end_vertex()->particles_begin(HepMC::descendants);
|
701 |
des != (*p)->end_vertex()->particles_end(HepMC::descendants);
|
702 |
++ des ) {
|
703 |
if ( (*des)->status() == 3 && abs( (*des)->pdg_id() )< 22 ) {
|
704 |
if (!dd1) dd1 = *des;
|
705 |
if (dd1) dd2 = *des;
|
706 |
}
|
707 |
if ((*des)->status() != 1) continue; // skip decayed ones or documentation entries
|
708 |
if ( abs( (*des)->pdg_id() ) < 22 && !daug1) daug1 = (*des);
|
709 |
if ( abs( (*des)->pdg_id() ) < 22 && daug1) daug2 = (*des);
|
710 |
// most energetic radiated photon
|
711 |
if ( abs( (*des)->pdg_id() ) == 22 ) {
|
712 |
nphotons ++;
|
713 |
if ( !daug3) daug3 = (*des);
|
714 |
else if ( (*des)->momentum().e() > daug3->momentum().e() ) {
|
715 |
daug3 = (*des);
|
716 |
}
|
717 |
}
|
718 |
}
|
719 |
// Require there must be decay particles
|
720 |
daug1 = dd1; daug2 = dd2; // Save direct daughters information
|
721 |
if ( !daug1 || !daug2 || daug1 == daug2) continue;
|
722 |
gdW = 1; genW.SetXYZT((*p)->momentum().x(), (*p)->momentum().y(), (*p)->momentum().z(), (*p)->momentum().t());
|
723 |
// Save vector boson information
|
724 |
TLorentzVector vecbos((*p)->momentum().x(), (*p)->momentum().y(), (*p)->momentum().z(), (*p)->momentum().t());
|
725 |
if (dd1)
|
726 |
genwz->W_decayType = abs( dd1->pdg_id() );
|
727 |
genwz->W_bosPt = vecbos.Pt();
|
728 |
genwz->W_bosPz = vecbos.Pz();
|
729 |
genwz->W_bosPhi = vecbos.Phi();
|
730 |
genwz->W_bosMass = vecbos.M();
|
731 |
if ( vecbos.Pt() )
|
732 |
genwz->W_bosEta = vecbos.PseudoRapidity();
|
733 |
genwz->W_bosRap = vecbos.Rapidity();
|
734 |
genwz->W_bosId = (*p)->pdg_id();
|
735 |
// Save daughter information.
|
736 |
TLorentzVector dauA, dauB;
|
737 |
if (daug1->pdg_id() > 0) {
|
738 |
dauA.SetXYZT(daug1->momentum().x(), daug1->momentum().y(), daug1->momentum().z(), daug1->momentum().t());
|
739 |
genwz->W_dauAId = daug1->pdg_id();
|
740 |
dauB.SetXYZT(daug2->momentum().x(), daug2->momentum().y(), daug2->momentum().z(), daug2->momentum().t());
|
741 |
genwz->W_dauBId = daug2->pdg_id();
|
742 |
} else {
|
743 |
dauA.SetXYZT(daug2->momentum().x(), daug2->momentum().y(), daug2->momentum().z(), daug2->momentum().t() );
|
744 |
genwz->W_dauAId = daug2->pdg_id();
|
745 |
dauB.SetXYZT(daug1->momentum().x(), daug1->momentum().y(), daug1->momentum().z(), daug1->momentum().t());
|
746 |
genwz->W_dauBId = daug1->pdg_id();
|
747 |
}
|
748 |
genwz->W_dauAPt = dauA.Pt();
|
749 |
genwz->W_dauAPz = dauA.Pz();
|
750 |
genwz->W_dauAEta = dauA.PseudoRapidity();
|
751 |
genwz->W_dauAPhi = dauA.Phi();
|
752 |
genwz->W_dauAEnergy = dauA.E();
|
753 |
genwz->W_dauBPt = dauB.Pt();
|
754 |
genwz->W_dauBPz = dauB.Pz();
|
755 |
genwz->W_dauBEta = dauB.PseudoRapidity();
|
756 |
genwz->W_dauBPhi = dauB.Phi();
|
757 |
genwz->W_dauBEnergy = dauB.E();
|
758 |
// Save dilepton information
|
759 |
TLorentzVector dilepton( dauA + dauB );
|
760 |
genwz->W_dileptonPt = dilepton.Pt();
|
761 |
genwz->W_dileptonPz = dilepton.Pz();
|
762 |
genwz->W_dileptonMass = dilepton.M();
|
763 |
genwz->W_dileptonEta = dilepton.PseudoRapidity();
|
764 |
genwz->W_dileptonRap = dilepton.Rapidity();
|
765 |
genwz->W_dileptonPhi = dilepton.Phi();
|
766 |
genwz->W_cosTheta = 0; // no value
|
767 |
genwz->W_cosPhi = cos(dauA.Vect().Angle( dauB.Vect() ));
|
768 |
// Save radiation photon information
|
769 |
genwz->W_nphotons = nphotons;
|
770 |
if (daug3) {
|
771 |
TVector3 photonVec(daug3->momentum().x(), daug3->momentum().y(),daug3->momentum().z());
|
772 |
genwz->W_phoEnergy = daug3->momentum().e();
|
773 |
genwz->W_phoEta = daug3->momentum().eta();
|
774 |
genwz->W_phoPhi = daug3->momentum().phi();
|
775 |
genwz->W_phoAngle = photonVec.Angle( dilepton.Vect() );
|
776 |
}
|
777 |
angW = dauA;
|
778 |
}
|
779 |
|
780 |
if (gdZ==1 && gdW==1) { // Find both W and Z. Save information and break the loop
|
781 |
genwz->gdWZ = 1;
|
782 |
TLorentzVector wz( genZ + genW );
|
783 |
genwz->WZ_Pt = wz.Pt();
|
784 |
genwz->WZ_Pz = wz.Pz();
|
785 |
genwz->WZ_Phi = wz.Phi();
|
786 |
genwz->WZ_Mass = wz.M();
|
787 |
if ( wz.Pt() )
|
788 |
genwz->WZ_Eta = wz.PseudoRapidity();
|
789 |
genwz->WZ_Rap = wz.Rapidity();
|
790 |
|
791 |
// Decay angular
|
792 |
TVector3 Zboost = -genZ.BoostVector();
|
793 |
TLorentzVector Zsys(wz);
|
794 |
TLorentzVector Zdau(angZ);
|
795 |
Zsys.Boost(Zboost);
|
796 |
Zdau.Boost(Zboost);
|
797 |
genwz->WZ_cosAngZ = cos( Zsys.Vect().Angle( Zdau.Vect() ) );
|
798 |
|
799 |
TVector3 Wboost = -genW.BoostVector();
|
800 |
TLorentzVector Wsys(wz);
|
801 |
TLorentzVector Wdau(angW);
|
802 |
Wsys.Boost(Wboost);
|
803 |
Wdau.Boost(Wboost);
|
804 |
genwz->WZ_cosAngW = cos( Wsys.Vect().Angle( Wdau.Vect() ) );
|
805 |
|
806 |
break;
|
807 |
}
|
808 |
|
809 |
}
|
810 |
|
811 |
// === End for WZ signal MC ONLY!
|
812 |
if (_is_debug) std::cout << "check point ... finishing fillGenWZ() " << std::endl;
|
813 |
}
|
814 |
|
815 |
|
816 |
void WZEdmAnalyzer::fillRunInfo(void) {
|
817 |
|
818 |
// is automatically calculated at the end of each RUN -- units in nb
|
819 |
// is the precalculated one written in the cfg file -- units is pb
|
820 |
// myRunInfo = myEvent->getRunInfo();
|
821 |
|
822 |
// myRunInfo->autoXSec = runInfo->cross_section();
|
823 |
// myRunInfo->extXsec = runInfo->external_cross_section();
|
824 |
// myRunInfo->filterEff= runInfo->filter_efficiency();
|
825 |
|
826 |
if (_is_debug) {
|
827 |
|
828 |
LogDebug("Analyzer::RunInfo") << " xsec (pb-1) -- " << myRunInfo->autoXSec;
|
829 |
LogDebug("Analyzer::RunInfo") << " external xsec (pb-1) -- " << myRunInfo->extXsec;
|
830 |
LogDebug("Analyzer::RunInfo") << " filter efficiency -- " << myRunInfo->filterEff;
|
831 |
}
|
832 |
}
|
833 |
|