ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/PingTan/src/CopyMCInfo.cc
Revision: 1.1
Committed: Tue Oct 5 17:09:41 2010 UTC (14 years, 6 months ago) by ptan
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Error occurred while calculating annotation data.
Log Message:
*** empty log message ***

File Contents

# Content
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