ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/Jeng/PVStudy/plugins/PVEffAnalyzer.cc
Revision: 1.1
Committed: Mon Apr 19 16:07:17 2010 UTC (15 years, 1 month ago) by yygao
Content type: text/plain
Branch: MAIN
Log Message:
Add primary vertex efficiency analyzer

File Contents

# Content
1 // -*- C++ -*-
2 //
3 // Package: PVEffAnalyzer
4 // Class: PVEffAnalyzer
5 //
6 /**\class PVEffAnalyzer PVEffAnalyzer.cc UserCode/PVEffAnalyzer/plugins/PVEffAnalyzer.cc
7
8 Description: <one line class summary>
9
10 Implementation:
11 <Notes on implementation>
12 */
13 //
14 // Original Author: "Geng-yuan Jeng/UC Riverside"
15 // "Yanyan Gao/Fermilab ygao@fnal.gov"
16 // Created: Thu Aug 20 11:55:40 CDT 2009
17 // $Id: PVEffAnalyzer.cc,v 1.22 2010/03/29 15:27:24 yygao Exp $
18 //
19 //
20
21
22 // system include files
23 #include <memory>
24 #include <string>
25 #include <vector>
26 #include <iostream>
27 #include <sstream>
28
29 // user include files
30 #include "FWCore/Framework/interface/Frameworkfwd.h"
31 #include "FWCore/Framework/interface/EDAnalyzer.h"
32
33 #include "FWCore/Framework/interface/Event.h"
34 #include "FWCore/Framework/interface/MakerMacros.h"
35
36 #include "FWCore/ParameterSet/interface/ParameterSet.h"
37 #include "FWCore/Utilities/interface/InputTag.h"
38 #include "DataFormats/TrackReco/interface/Track.h"
39 #include "DataFormats/TrackReco/interface/TrackFwd.h"
40 #include "FWCore/ServiceRegistry/interface/Service.h"
41 #include "CommonTools/UtilAlgos/interface/TFileService.h"
42 #include "UserCode/PVStudy/interface/PVEffAnalyzer.h"
43 //
44 #include "DataFormats/VertexReco/interface/Vertex.h"
45 #include "RecoVertex/VertexPrimitives/interface/TransientVertex.h"
46
47 // simulated vertices,..., add <use name=SimDataFormats/Vertex> and <../Track>
48 #include <SimDataFormats/Vertex/interface/SimVertex.h>
49 #include <SimDataFormats/Vertex/interface/SimVertexContainer.h>
50 #include <SimDataFormats/Track/interface/SimTrack.h>
51 #include <SimDataFormats/Track/interface/SimTrackContainer.h>
52 // BeamSpot
53 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
54
55 //root
56 #include <TROOT.h>
57 #include <TF1.h>
58 #include <TString.h>
59 #include <TStyle.h>
60 #include <TPaveStats.h>
61 #include <TPad.h>
62
63 using namespace std;
64 typedef math::XYZTLorentzVectorF LorentzVector;
65 typedef math::XYZPoint Point;
66
67 PVEffAnalyzer::PVEffAnalyzer(const edm::ParameterSet& iConfig)
68 {
69 //=======================================================================
70 // Get configuration for TrackTupleMaker
71 //=======================================================================
72 simG4_ = iConfig.getParameter<edm::InputTag>( "simG4" );
73 trackCollectionTag_ = iConfig.getUntrackedParameter<edm::InputTag>("trackCollection");
74 splitTrackCollection1Tag_ = iConfig.getUntrackedParameter<edm::InputTag>("splitTrackCollection1");
75 splitTrackCollection2Tag_ = iConfig.getUntrackedParameter<edm::InputTag>("splitTrackCollection2");
76 vertexCollectionTag_ = iConfig.getUntrackedParameter<edm::InputTag>("vertexCollection");
77 splitVertexCollection1Tag_ = iConfig.getUntrackedParameter<edm::InputTag>("splitVertexCollection1");
78 splitVertexCollection2Tag_ = iConfig.getUntrackedParameter<edm::InputTag>("splitVertexCollection2");
79 verbose_ = iConfig.getUntrackedParameter<bool>("verbose",false);
80 realData_ = iConfig.getUntrackedParameter<bool>("realData",false);
81 histoFileName_ = iConfig.getUntrackedParameter<std::string> ("histoFileName");
82 nTrkMin_ = iConfig.getUntrackedParameter<int>("nTrkMin");
83 nTrkMax_ = iConfig.getUntrackedParameter<int>("nTrkMax");
84 zsigncut_ = iConfig.getUntrackedParameter<double>("zsigncut");
85 bsSrc = iConfig.getParameter< edm::InputTag >("beamSpot");
86
87
88 // Specify the data mode vector
89 if(realData_) datamode.push_back(0);
90 else {
91 datamode.push_back(0);
92 datamode.push_back(1);
93 }
94
95 theFile = new TFile(histoFileName_.c_str(), "RECREATE");
96 theFile->mkdir("Summary");
97 theFile->cd();
98
99 // Book MC only plots
100 if (!realData_) {
101 h_gen = new PVEffHistograms();
102 h_gen->Init("generator");
103 }
104
105 h_summary = new PVEffHistograms();
106 //Book histograms sensitive to data/mc
107 for (vector<int>::const_iterator it= datamode.begin(); it != datamode.end() ; ++it) {
108 string suffix;
109 edm::LogInfo("Debug")<<"datamode = "<< *it<<endl;
110 switch(*it) {
111 case 0: suffix = "";
112 break;
113 case 1: suffix = "_mct";
114 break;
115 }
116 h_summary->Init("summary",suffix, nTrkMin_, nTrkMax_);
117 }
118
119 }
120
121 PVEffAnalyzer::~PVEffAnalyzer()
122 {
123
124 // do anything here that needs to be done at desctruction time
125 // (e.g. close files, deallocate resources etc.)
126 theFile->cd();
127 theFile->cd("Summary");
128 h_summary->Save();
129 if (!realData_)
130 h_gen->Save();
131 theFile->Close();
132 }
133
134 //
135 // member functions
136 //
137 std::vector<PVEffAnalyzer::simPrimaryVertex> PVEffAnalyzer::getSimPVs(const Handle<HepMCProduct> evtMC, std::string suffix="")
138 {
139 std::vector<PVEffAnalyzer::simPrimaryVertex> simpv;
140 const HepMC::GenEvent* evt=evtMC->GetEvent();
141 if (evt) {
142 edm::LogInfo("SimPVs") << "[getSimPVs] process id " << evt->signal_process_id()<<endl;
143 edm::LogInfo("SimPVs") << "[getSimPVs] signal process vertex " << ( evt->signal_process_vertex() ?
144 evt->signal_process_vertex()->barcode() : 0 ) <<endl;
145 edm::LogInfo("SimPVs") << "[getSimPVs] number of vertices " << evt->vertices_size() << endl;
146
147 int idx=0; int npv=0;
148 for(HepMC::GenEvent::vertex_const_iterator vitr= evt->vertices_begin();
149 vitr != evt->vertices_end(); ++vitr ) { // loop for vertex ...
150 HepMC::FourVector pos = (*vitr)->position();
151 //HepLorentzVector pos = (*vitr)->position();
152
153 // t component of PV:
154 for ( HepMC::GenVertex::particle_iterator mother = (*vitr)->particles_begin(HepMC::parents);
155 mother != (*vitr)->particles_end(HepMC::parents); ++mother ) {
156 // edm::LogInfo("SimPVs") << "Status = " << (*mother)->status() << endl;
157 HepMC::GenVertex * mv=(*mother)->production_vertex();
158 if( ((*mother)->status() == 3) && (!mv)) {
159 // edm::LogInfo("SimPVs") << "npv= " << npv << endl;
160 if (npv == 0) {
161 h_gen->Fill1d("genPart_cT", pos.t()); // mm
162 h_gen->Fill1d("genPart_T", pos.t()/299.792458); // ns
163 }
164 npv++;
165 }
166 }
167 // if (pos.t()>0) { continue;} // for 22X when t of PV was not smeared
168
169 bool hasMotherVertex=false;
170 if (verbose_) cout << "[getSimPVs] mothers of vertex[" << ++idx << "]: " << endl;
171 for ( HepMC::GenVertex::particle_iterator mother = (*vitr)->particles_begin(HepMC::parents);
172 mother != (*vitr)->particles_end(HepMC::parents); ++mother ) {
173 HepMC::GenVertex * mv=(*mother)->production_vertex();
174 // if (verbose_) cout << "Status = " << (*mother)->status() << endl;
175 if (mv) {
176 hasMotherVertex=true;
177 if(!verbose_) break; //if verbose_, print all particles of gen vertices
178 }
179 if(verbose_) {
180 cout << "\t";
181 (*mother)->print();
182 }
183 }
184
185 if(hasMotherVertex) continue;
186
187 // could be a new vertex, check all primaries found so far to avoid multiple entries
188 const double mm2cm=0.1;
189 simPrimaryVertex sv(pos.x()*mm2cm,pos.y()*mm2cm,pos.z()*mm2cm); // sim unit mm, rec unit cm
190 simPrimaryVertex *vp=NULL; // will become non-NULL if a vertex is found and then point to it
191 for(vector<simPrimaryVertex>::iterator v0=simpv.begin();
192 v0!=simpv.end(); v0++){
193 if( (fabs(sv.x-v0->x)<1e-5) && (fabs(sv.y-v0->y)<1e-5) && (fabs(sv.z-v0->z)<1e-5)){
194 vp=&(*v0);
195 break;
196 }
197 }
198
199 if(!vp){
200 // this is a new vertex
201 edm::LogInfo("SimPVs") << "[getSimPVs] this is a new vertex " << sv.x << " " << sv.y << " " << sv.z << endl;
202 simpv.push_back(sv);
203 vp=&simpv.back();
204 }else{
205 edm::LogInfo("SimPVs") << "[getSimPVs] this is not a new vertex " << sv.x << " " << sv.y << " " << sv.z << endl;
206 }
207 vp->genVertex.push_back((*vitr)->barcode());
208 // collect final state descendants
209 for ( HepMC::GenVertex::particle_iterator daughter = (*vitr)->particles_begin(HepMC::descendants);
210 daughter != (*vitr)->particles_end(HepMC::descendants);
211 ++daughter ) {
212 if (isFinalstateParticle(*daughter)){
213 if ( find(vp->finalstateParticles.begin(), vp->finalstateParticles.end(),(*daughter)->barcode())
214 == vp->finalstateParticles.end()){
215 vp->finalstateParticles.push_back((*daughter)->barcode());
216 HepMC::FourVector m=(*daughter)->momentum();
217 // the next four lines used to be "vp->ptot+=m;" in the days of CLHEP::HepLorentzVector
218 // but adding FourVectors seems not to be foreseen
219 vp->ptot.setPx(vp->ptot.px()+m.px());
220 vp->ptot.setPy(vp->ptot.py()+m.py());
221 vp->ptot.setPz(vp->ptot.pz()+m.pz());
222 vp->ptot.setE(vp->ptot.e()+m.e());
223 vp->ptsq+=(m.perp())*(m.perp());
224 if ( (m.perp()>0.8) && (fabs(m.pseudoRapidity())<2.5) && isCharged( *daughter ) ){
225 vp->nGenTrk++;
226 }
227 }
228 }
229 }//loop MC vertices daughters
230 }//loop MC vertices
231 }
232 return simpv;
233 }
234
235 std::vector<PVEffAnalyzer::simPrimaryVertex> PVEffAnalyzer::getSimPVs(const Handle<HepMCProduct> evtMC,
236 const Handle<SimVertexContainer> simVtxs,
237 const Handle<SimTrackContainer> simTrks)
238 {
239 // simvertices don't have enough information to decide,
240 // genVertices don't have the simulated coordinates ( with VtxSmeared they might)
241 // go through simtracks to get the link between simulated and generated vertices
242 std::vector<PVEffAnalyzer::simPrimaryVertex> simpv;
243 int idx=0;
244 for(SimTrackContainer::const_iterator t=simTrks->begin();
245 t!=simTrks->end(); ++t){
246 if ( !(t->noVertex()) && !(t->type()==-99) ){
247 double ptsq=0;
248 bool primary=false; // something coming directly from the primary vertex
249 bool resonance=false; // resonance
250 bool track=false; // undecayed, charged particle
251 HepMC::GenParticle* gp=evtMC->GetEvent()->barcode_to_particle( (*t).genpartIndex() );
252 if (gp) {
253 HepMC::GenVertex * gv=gp->production_vertex();
254 if (gv) {
255 for ( HepMC::GenVertex::particle_iterator
256 daughter = gv->particles_begin(HepMC::descendants);
257 daughter != gv->particles_end(HepMC::descendants);
258 ++daughter ) {
259 if (isFinalstateParticle(*daughter)){
260 ptsq+=(*daughter)->momentum().perp()*(*daughter)->momentum().perp();
261 }
262 }
263 //primary = ( gv->position().t()==0 );
264 primary = true;
265 h_gen->Fill1d("genPart_cT", gv->position().t()); // mm
266 h_gen->Fill1d("genPart_T", gv->position().t()/299.792458); // ns
267
268 //resonance= ( gp->mother() && isResonance(gp->mother())); // in CLHEP/HepMC days
269 // no more mother pointer in the improved HepMC GenParticle
270 resonance= ( isResonance(*(gp->production_vertex()->particles_in_const_begin())));
271 if (gp->status()==1){
272 //track=((pdt->particle(gp->pdg_id()))->charge() != 0);
273 track=not isCharged(gp);
274 }
275 }
276 }
277
278 const HepMC::FourVector & v=(*simVtxs)[t->vertIndex()].position();
279 //const HepLorentzVector & v=(*simVtxs)[t->vertIndex()].position();
280 if(primary or resonance){
281 {
282 // check all primaries found so far to avoid multiple entries
283 bool newVertex=true;
284 for(std::vector<PVEffAnalyzer::simPrimaryVertex>::iterator v0=simpv.begin();
285 v0!=simpv.end(); v0++){
286 if( (fabs(v0->x-v.x())<0.001) && (fabs(v0->y-v.y())<0.001) && (fabs(v0->z-v.z())<0.001) ){
287 if (track) {
288 v0->simTrackIndex.push_back(idx);
289 if (ptsq>(*v0).ptsq){(*v0).ptsq=ptsq;}
290 }
291 newVertex=false;
292 }
293 }
294 if(newVertex && !resonance){
295 PVEffAnalyzer::simPrimaryVertex anotherVertex(v.x(),v.y(),v.z());
296 if (track) anotherVertex.simTrackIndex.push_back(idx);
297 anotherVertex.ptsq=ptsq;
298 simpv.push_back(anotherVertex);
299 }
300 }//
301 }
302
303 }// simtrack has vertex and valid type
304 idx++;
305 }//simTrack loop
306 return simpv;
307 }
308
309 // ------------ method called to for each event ------------
310 void
311 PVEffAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
312 {
313 using namespace edm;
314 using namespace reco;
315
316 //========================================================================
317 // Step 0: Prepare root variables and get information from the Event
318 //========================================================================
319
320 edm::LogInfo("Debug")<<"[PVEffAnalyzer]"<<endl;
321
322 // ====== TrackCollection
323 static const reco::TrackCollection s_empty_trackColl;
324 const reco::TrackCollection *trackColl = &s_empty_trackColl;
325 edm::Handle<reco::TrackCollection> trackCollectionHandle;
326 iEvent.getByLabel(trackCollectionTag_, trackCollectionHandle);
327 if( iEvent.getByLabel(trackCollectionTag_, trackCollectionHandle)) {
328 trackColl = trackCollectionHandle.product();
329 } else {
330 edm::LogInfo("Debug") << "[PVEffAnalyzer] trackCollection cannot be found -> using empty collection of same type." <<endl;
331 }
332 // ====== splitTrackCollection1
333 static const reco::TrackCollection s_empty_splitTrackColl1;
334 const reco::TrackCollection *splitTrackColl1 = &s_empty_splitTrackColl1;
335 edm::Handle<reco::TrackCollection> splitTrackCollection1Handle;
336 iEvent.getByLabel(splitTrackCollection1Tag_, splitTrackCollection1Handle);
337 if( iEvent.getByLabel(splitTrackCollection1Tag_, splitTrackCollection1Handle)) {
338 splitTrackColl1 = splitTrackCollection1Handle.product();
339 } else {
340 edm::LogInfo("Debug") << "[PVEffAnalyzer] splitTrackCollection1 cannot be found -> using empty collection of same type." <<endl;
341 }
342 // ====== splitTrackCollection2
343 static const reco::TrackCollection s_empty_splitTrackColl2;
344 const reco::TrackCollection *splitTrackColl2 = &s_empty_splitTrackColl2;
345 edm::Handle<reco::TrackCollection> splitTrackCollection2Handle;
346 iEvent.getByLabel(splitTrackCollection2Tag_, splitTrackCollection2Handle);
347 if( iEvent.getByLabel(splitTrackCollection2Tag_, splitTrackCollection2Handle)) {
348 splitTrackColl2 = splitTrackCollection2Handle.product();
349 } else {
350 edm::LogInfo("Debug") << "[PVEffAnalyzer] splitTrackCollection2 cannot be found -> using empty collection of same type." <<endl;
351 }
352
353 // ======= PrimaryVertexCollection
354 static const reco::VertexCollection s_empty_vertexColl;
355 const reco::VertexCollection *vertexColl = &s_empty_vertexColl;
356 edm::Handle<reco::VertexCollection> vertexCollectionHandle;
357 iEvent.getByLabel(vertexCollectionTag_, vertexCollectionHandle);
358 if( iEvent.getByLabel(vertexCollectionTag_, vertexCollectionHandle)) {
359 vertexColl = vertexCollectionHandle.product();
360 } else {
361 edm::LogInfo("Debug") << "[PVEffAnalyzer] vertexCollection cannot be found -> using empty collection of same type." <<endl;
362 }
363 // ====== splitVertexCollection1
364 static const reco::VertexCollection s_empty_splitVertexColl1;
365 const reco::VertexCollection *splitVertexColl1 = &s_empty_splitVertexColl1;
366 edm::Handle<reco::VertexCollection> splitVertexCollection1Handle;
367 iEvent.getByLabel(splitVertexCollection1Tag_, splitVertexCollection1Handle);
368 if( iEvent.getByLabel(splitVertexCollection1Tag_, splitVertexCollection1Handle)) {
369 splitVertexColl1 = splitVertexCollection1Handle.product();
370 } else {
371 edm::LogInfo("Debug") << "[PVEffAnalyzer] splitVertexCollection1 cannot be found -> using empty collection of same type." <<endl;
372 }
373 // ====== splitVertexCollection2
374 static const reco::VertexCollection s_empty_splitVertexColl2;
375 const reco::VertexCollection *splitVertexColl2 = &s_empty_splitVertexColl2;
376 edm::Handle<reco::VertexCollection> splitVertexCollection2Handle;
377 iEvent.getByLabel(splitVertexCollection2Tag_, splitVertexCollection2Handle);
378 if( iEvent.getByLabel(splitVertexCollection2Tag_, splitVertexCollection2Handle)) {
379 splitVertexColl2 = splitVertexCollection2Handle.product();
380 } else {
381 edm::LogInfo("Debug") << "[PVEffAnalyzer] splitVertexCollection2 cannot be found -> using empty collection of same type." <<endl;
382 }
383
384
385 // ======== BeamSpot accessors
386 edm::Handle<reco::BeamSpot> recoBeamSpotHandle;
387 iEvent.getByLabel(bsSrc,recoBeamSpotHandle);
388 reco::BeamSpot bs = *recoBeamSpotHandle;
389 const Point beamSpot = recoBeamSpotHandle.isValid() ? Point(recoBeamSpotHandle->x0(), recoBeamSpotHandle->y0(), recoBeamSpotHandle->z0()) : Point(0, 0, 0);
390
391 edm::LogInfo("Debug")<<"[PVEffAnalyzer] End accessing the track, beamSpot, primary vertex collections"<<endl;
392
393 // ========== MC simvtx accessor
394 if (!realData_) {
395 edm::Handle<SimVertexContainer> simVtxs;
396 iEvent.getByLabel( simG4_, simVtxs);
397
398 edm::Handle<SimTrackContainer> simTrks;
399 iEvent.getByLabel( simG4_, simTrks);
400 }
401
402 // ========== GET PDT
403 try{
404 iSetup.getData(pdt);
405 }catch(const Exception&){
406 edm::LogInfo("Debug") << "[PVEffAnalyzer] Some problem occurred with the particle data table. This may not work !." <<endl;
407 }
408
409 //setUpVectors(RealData, nTrkMin_, nTrkMax_ ) ;
410
411 // ======= Analyze MC efficiency
412 if (!realData_) {
413 bool MC=false;
414 Handle<HepMCProduct> evtMC;
415 iEvent.getByLabel("generator",evtMC);
416 if (!evtMC.isValid()) {
417 MC=false;
418 edm::LogInfo("Debug") << "[PVEffAnalyzer] no HepMCProduct found"<< endl;
419 } else {
420 edm::LogInfo("Debug") << "[PVEffAnalyzer] generator HepMCProduct found"<< endl;
421 MC=true;
422 }
423 if(MC){
424 TString suffix = "_mct";
425 // make a list of primary vertices:
426 std::vector<simPrimaryVertex> simpv;
427 simpv=getSimPVs(evtMC,"");
428 // simpv=getSimPVs(evtMC, simVtxs, simTrks);
429 h_gen->Fill1d("nsimPV", simpv.size());
430
431 int isimpv = 0;
432
433 for(std::vector<simPrimaryVertex>::iterator vsim=simpv.begin();
434 vsim!=simpv.end(); vsim++, isimpv++){
435 //nsimTrkPV_[isimpv] =vsim->nGenTrk;
436 //simx_[isimpv] = vsim->x;
437 //simy_[isimpv] = vsim->y;
438 //simz_[isimpv] = vsim->y;
439 //simptsq_[isimpv] = vsim->ptsq;
440 if(verbose_ && simpv.size() > 1 )
441 std::cout<<"Simulated Vertex # " << isimpv << ": ptsq = " << vsim->ptsq<<std::endl;
442 }
443
444 // Just analyze the first vertex in the collection
445 simPrimaryVertex vsim = *simpv.begin();
446 h_summary->Fill1d(TString("denom_ntrack"+suffix), int(vsim.nGenTrk));
447 if ( isAssoVertex(vsim, *vertexColl->begin(), zsigncut_) )
448 h_summary->Fill1d(TString("numer_ntrack"+suffix), int(vsim.nGenTrk));
449 }
450 } // End of Analyzing MC Efficiency
451
452 // ======= Analyze efficiency with split method
453 if ( !isGoodSplitEvent( *vertexColl->begin()) ) return;
454 if ( isGoodTagVertex( *splitVertexColl2->begin(), *vertexColl->begin(), zsigncut_) ) {
455 if(verbose_) {
456 std::cout<<"splitTrackColl1->size() = " << int(splitTrackColl1->size()) << std::endl;
457 std::cout<<"splitTrackColl2->size() = " << int(splitTrackColl2->size()) << std::endl;
458 }
459 h_summary->Fill1d("denom_ntrack", int(splitTrackColl1->size()));
460 if ( isGoodProbeVertex( *splitVertexColl1->begin(), *vertexColl->begin(), zsigncut_) )
461 h_summary->Fill1d("numer_ntrack", int(splitTrackColl1->size()) );
462 }
463 }
464
465
466 // ------------ method called once each job just before starting event loop ------------
467 void
468 PVEffAnalyzer::beginJob()
469 {
470 }
471
472 // ------------ method called once each job just after ending the event loop ------------
473 void
474 PVEffAnalyzer::endJob() {
475 edm::LogInfo("Analysis") << "[endJob] Analyzing PV info" << endl;
476
477 for (vector<int>::const_iterator it= datamode.begin(); it != datamode.end() ; ++it) {
478 string suffix;
479 edm::LogInfo("Debug")<<"datamode = "<< *it<<endl;
480 switch(*it) {
481 case 0: suffix = "";
482 break;
483 case 1: suffix = "_mct";
484 break;
485 }
486 MakeEff(h_summary->ReadHisto1D(TString("numer_ntrack"+suffix)), h_summary->ReadHisto1D(TString("denom_ntrack"+suffix)), h_summary->ReadHisto1D(TString("eff_ntrack"+suffix)), false, 1);
487 }
488 }
489
490
491
492 bool PVEffAnalyzer::isResonance(const HepMC::GenParticle * p){
493 double ctau=(pdt->particle( abs(p->pdg_id()) ))->lifetime();
494 edm::LogInfo("Debug") << "[isResonance] isResonance " << p->pdg_id() << " " << ctau << endl;
495 return ctau >0 && ctau <1e-6;
496 }
497
498 bool PVEffAnalyzer::isFinalstateParticle(const HepMC::GenParticle * p){
499 return ( !p->end_vertex() && p->status()==1 );
500 }
501
502 bool PVEffAnalyzer::isCharged(const HepMC::GenParticle * p){
503 const ParticleData * part = pdt->particle( p->pdg_id() );
504 if (part){
505 return part->charge()!=0;
506 }else{
507 // the new/improved particle table doesn't know anti-particles
508 return pdt->particle( -p->pdg_id() )!=0;
509 }
510 }
511
512 void PVEffAnalyzer::printSimVtxs(const Handle<SimVertexContainer> simVtxs){
513 int i=0;
514 for(SimVertexContainer::const_iterator vsim=simVtxs->begin();
515 vsim!=simVtxs->end(); ++vsim){
516 cout << i++ << ")" << scientific
517 << " evtid=" << vsim->eventId().event()
518 << " sim x=" << vsim->position().x()
519 << " sim y=" << vsim->position().y()
520 << " sim z=" << vsim->position().z()
521 << " sim t=" << vsim->position().t()
522 << " parent=" << vsim->parentIndex()
523 << endl;
524 }
525 }
526
527 void PVEffAnalyzer::printRecVtxs(const Handle<reco::VertexCollection> recVtxs){
528 int ivtx=0;
529 for(reco::VertexCollection::const_iterator v=recVtxs->begin();
530 v!=recVtxs->end(); ++v){
531 cout << "Recvtx "<< std::setw(3) << std::setfill(' ')<<ivtx++
532 << "#trk " << std::setw(3) << v->tracksSize()
533 << " chi2 " << std::setw(4) << v->chi2()
534 << " ndof " << std::setw(3) << v->ndof() << endl
535 << " x " << std::setw(8) <<std::fixed << std::setprecision(4) << v->x()
536 << " dx " << std::setw(8) << v->xError()<< endl
537 << " y " << std::setw(8) << v->y()
538 << " dy " << std::setw(8) << v->yError()<< endl
539 << " z " << std::setw(8) << v->z()
540 << " dz " << std::setw(8) << v->zError()
541 << endl;
542 }
543 }
544
545 void PVEffAnalyzer::printRecVtx(const reco::Vertex & v){
546
547 cout << "#trk " << std::setw(3) << v.tracksSize()
548 << " chi2 " << std::setw(4) << v.chi2()
549 << " ndof " << std::setw(3) << v.ndof() << endl
550 << " x " << std::setw(8) <<std::fixed << std::setprecision(4) << v.x()
551 << " dx " << std::setw(8) << v.xError()<< endl
552 << " y " << std::setw(8) << v.y()
553 << " dy " << std::setw(8) << v.yError()<< endl
554 << " z " << std::setw(8) << v.z()
555 << " dz " << std::setw(8) << v.zError()
556 << endl;
557 }
558
559 void PVEffAnalyzer::printSimTrks(const Handle<SimTrackContainer> simTrks){
560 cout << " simTrks type, (momentum), vertIndex, genpartIndex" << endl;
561 int i=1;
562 for(SimTrackContainer::const_iterator t=simTrks->begin();
563 t!=simTrks->end(); ++t){
564 //HepMC::GenParticle* gp=evtMC->GetEvent()->particle( (*t).genpartIndex() );
565 cout << i++ << ")"
566 << (*t)
567 << " index="
568 << (*t).genpartIndex();
569 //if (gp) {
570 // HepMC::GenVertex *gv=gp->production_vertex();
571 // cout << " genvertex =" << (*gv);
572 //}
573 cout << endl;
574 }
575 }
576
577 // Select based on the highest SumPtSq Vertex
578 // Require at least 6 tracks with track weight > ~ 0.8
579 // vtx.ndof = 2*Sum(trackWeight) - 3
580
581 bool PVEffAnalyzer::isGoodSplitEvent( const reco::Vertex & org_vtx)
582 //, const reco::Vertex & tag_vtx, const reco::Vertex & probe_vtx)
583 {
584 return ( org_vtx.tracksSize() >= 6 && org_vtx.ndof() >= 6 );
585 // tag_vtx.tracksSize() > = 2 && probe_vtx.tracksSize() > = 2 ) ;
586 }
587
588 // Comparing the tag vertex with the unsplit vertex position in z
589 bool PVEffAnalyzer::isGoodTagVertex( const reco::Vertex & tag_vtx, const reco::Vertex & org_vtx, double & zsign_cut)
590 {
591 if(tag_vtx.isValid () && !tag_vtx.isFake()) {
592 float zsign = TMath::Abs(tag_vtx.z() - org_vtx.z() ) / TMath::Max(tag_vtx.zError(), org_vtx.zError() );
593 return (zsign < zsign_cut) ;
594 }
595 else
596 return false;
597 }
598
599 // Comparing the probe vertex with the unsplit vertex position in z
600 bool PVEffAnalyzer::isGoodProbeVertex( const reco::Vertex & probe_vtx, const reco::Vertex & org_vtx, double & zsign_cut)
601 {
602 if(probe_vtx.isValid () && !probe_vtx.isFake()) {
603 float zsign = TMath::Abs(probe_vtx.z() - org_vtx.z() ) / TMath::Max(probe_vtx.zError(), org_vtx.zError() );
604 return (zsign < zsign_cut) ;
605 }
606 else
607 return false;
608 }
609
610
611 bool PVEffAnalyzer::isAssoVertex(const PVEffAnalyzer::simPrimaryVertex & vsim,
612 const reco::Vertex & vrec, double & zsign_cut)
613 {
614 if(vrec.isValid() && !vrec.isFake() )
615 return (TMath::Abs(vsim.z-vrec.z()) < zsign_cut * vrec.zError() );
616 else
617 return false;
618 }
619
620
621 void PVEffAnalyzer::MakeEff(TH1D* numer, TH1D* denom, TH1D* eff, //TGraphAsymmErrors* & gr_eff,
622 const bool rebin, const Float_t n ) {
623 eff->Divide( numer, denom, 1,1,"B" );
624
625 if( rebin ) {
626 std::vector<Double_t> binEdges;
627 Int_t bin = denom->GetNbinsX() + 1;
628 binEdges.push_back(denom->GetBinLowEdge(bin));
629 Float_t nEntries = 0;
630 while (bin > 1) {
631 bin --;
632 nEntries = denom->GetBinContent(bin);
633 while (nEntries < n && bin > 1) {
634 bin --;
635 nEntries += denom->GetBinContent(bin);
636 }
637 binEdges.push_back(denom->GetBinLowEdge(bin));
638 }
639
640 Double_t *array = new Double_t[binEdges.size()];
641
642 Int_t j = 0;
643 for (Int_t i = binEdges.size(); i > 0; --i) {
644 array[j] = binEdges[i - 1];
645 ++j;
646 }
647 }
648
649 for (int i = 1; i<eff->GetNbinsX()+1; i++) {
650 if(numer->GetBinContent(i) == 0 || denom->GetBinContent(i) == 0 ) continue;
651 float error = eff->GetBinContent(i)*sqrt(pow(numer->GetBinError(i)/numer->GetBinContent(i),2)
652 +pow(denom->GetBinError(i)/denom->GetBinContent(i),2));
653 eff->SetBinError(i, error);
654 }
655 }
656
657 /*
658 // Copied from Validation/RecoTrack
659 void PVEffAnalyzer::setUpVectors(bool isRealData, int & nTrkMin_, int & nTrkMax_ ) {
660 std::vector<int> totTAGv_ntracks, totPROBEv_ntracks;
661 if(!isRealData)
662 std::vector<int> totSIMv_ntracks,totASSv_ntracks;
663 for (int k=nTrkMin_;k<nTrkMax_+1;k++) {
664 totTAGv_ntracks.push_back(0);
665 totPROBEv_ntracks.push_back(0);
666 if(!realData) {
667 totSIMv_ntracks.push_back(0);
668 totASSv_ntracks.push_back(0);
669 }
670 }
671
672 totTAG_ntracks.push_back(totTAGv_ntracks);
673 totPROBE_ntracks.push_back(totPROBEv_ntracks);
674 if(!realData) {
675 totSIM_ntracks.push_back(totSIMv_ntracks);
676 totASS_ntracks.push_back(totASSv_ntracks);
677 }
678 }
679
680 */