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 ago) by yygao
Content type: text/plain
Branch: MAIN
Log Message:
Add primary vertex efficiency analyzer

File Contents

# User Rev Content
1 yygao 1.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     */