ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/Jeng/PVStudy/plugins/PVEffAnalyzer.cc
Revision: 1.6
Committed: Wed May 5 16:33:37 2010 UTC (15 years ago) by yygao
Content type: text/plain
Branch: MAIN
Changes since 1.5: +35 -12 lines
Log Message:
update

File Contents

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