ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/Jeng/PVStudy/plugins/PVStudy.cc
Revision: 1.5
Committed: Wed Sep 9 05:56:50 2009 UTC (15 years, 8 months ago) by jengbou
Content type: text/plain
Branch: MAIN
Changes since 1.4: +22 -16 lines
Log Message:
update

File Contents

# User Rev Content
1 jengbou 1.1 // -*- C++ -*-
2     //
3     // Package: PVStudy
4     // Class: PVStudy
5     //
6     /**\class PVStudy PVStudy.cc UserCode/PVStudy/plugins/PVStudy.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     // Created: Thu Aug 20 11:55:40 CDT 2009
16 jengbou 1.5 // $Id: PVStudy.cc,v 1.4 2009/09/08 21:48:16 jengbou Exp $
17 jengbou 1.1 //
18     //
19    
20    
21     // system include files
22     #include <memory>
23     #include <string>
24     #include <vector>
25     #include <iostream>
26     #include <sstream>
27    
28     // user include files
29     #include "FWCore/Framework/interface/Frameworkfwd.h"
30     #include "FWCore/Framework/interface/EDAnalyzer.h"
31    
32     #include "FWCore/Framework/interface/Event.h"
33     #include "FWCore/Framework/interface/MakerMacros.h"
34    
35     #include "FWCore/ParameterSet/interface/ParameterSet.h"
36     #include "FWCore/Utilities/interface/InputTag.h"
37     #include "DataFormats/TrackReco/interface/Track.h"
38     #include "DataFormats/TrackReco/interface/TrackFwd.h"
39     #include "FWCore/ServiceRegistry/interface/Service.h"
40     #include "PhysicsTools/UtilAlgos/interface/TFileService.h"
41     #include "UserCode/PVStudy/interface/PVStudy.h"
42     //
43     #include "DataFormats/VertexReco/interface/Vertex.h"
44     #include "RecoVertex/VertexPrimitives/interface/TransientVertex.h"
45    
46     // simulated vertices,..., add <use name=SimDataFormats/Vertex> and <../Track>
47     #include <SimDataFormats/Vertex/interface/SimVertex.h>
48     #include <SimDataFormats/Vertex/interface/SimVertexContainer.h>
49     #include <SimDataFormats/Track/interface/SimTrack.h>
50     #include <SimDataFormats/Track/interface/SimTrackContainer.h>
51    
52     //root
53 jengbou 1.4 #include <TROOT.h>
54     #include <TF1.h>
55     #include <TString.h>
56     #include <TStyle.h>
57     #include <TPaveStats.h>
58     #include <TPad.h>
59 jengbou 1.1
60     using namespace std;
61    
62     PVStudy::PVStudy(const edm::ParameterSet& iConfig):
63 jengbou 1.3 nTrkMin_(10),nTrkMax_(100)
64 jengbou 1.1 {
65     simG4_ = iConfig.getParameter<edm::InputTag>( "simG4" );
66     tracksLabel_ = iConfig.getUntrackedParameter<edm::InputTag>("tracks");
67     vtxSample_ = iConfig.getUntrackedParameter<edm::InputTag>("vtxSample");
68     verbose_ = iConfig.getUntrackedParameter<bool>("verbose", false);
69     realData_ = iConfig.getUntrackedParameter<bool>("realData",false);
70 jengbou 1.2 analyze_ = iConfig.getUntrackedParameter<bool>("analyzeOnTheFly",false);
71 jengbou 1.3 outputfilename_ = iConfig.getUntrackedParameter<string>("OutputFileName");
72 jengbou 1.1
73     //now do what ever initialization is needed
74 jengbou 1.3 pvinfo.clear();
75 jengbou 1.1
76 jengbou 1.3 file_ = TFile::Open(outputfilename_.c_str(),"RECREATE");
77     ftree_ = new TTree("mytree","mytree");
78     ftree_->AutoSave();
79     ftree_->Branch("residual",&fres,"fres[3]/D");
80     ftree_->Branch("error",&ferror,"ferror[3]/D");
81     ftree_->Branch("nTrk",&fntrk,"fntrk/I");
82    
83 jengbou 1.1 edm::Service<TFileService> fs;
84 jengbou 1.4 TFileDirectory subDir = fs->mkdir( "Summary" );
85     TFileDirectory subDir1 = fs->mkdir( "Others" );
86     // TFileDirectory subSubDir = subDir.mkdir( "mySubSubDirectory" );
87    
88     setRootStyle();
89    
90     h["nTrk"] = subDir.make<TH1F>("nTrk","Num of total tracks",300,0,300);
91     h["nTrkPV"] = subDir.make<TH1F>("nTrkPV","Num of Tracks from PV",300,0,300);
92     h["trkPt"] = subDir.make<TH1D>("trkPt","Pt of all tracks",100,0,100);
93     h["trkPtPV"] = subDir.make<TH1D>("trkPtPV","Pt dist of tracks from PV",100,0,100);
94 jengbou 1.1
95     if (!realData_) {
96 jengbou 1.4 h["deltax"] = subDir.make<TH1D>("deltax","x-distance (Rec - Sim)",800,-0.04,0.04);
97     h["deltay"] = subDir.make<TH1D>("deltay","y-distance (Rec - Sim)",800,-0.04,0.04);
98     h["deltaz"] = subDir.make<TH1D>("deltaz","z-distance (Rec - Sim)",800,-0.04,0.04);
99     h["pullx"] = subDir.make<TH1D>("pullx","x-pull (Rec - Sim)",1000,-25.,25.);
100     h["pully"] = subDir.make<TH1D>("pully","y-pull (Rec - Sim)",1000,-25.,25.);
101     h["pullz"] = subDir.make<TH1D>("pullz","z-pull (Rec - Sim)",1000,-25.,25.);
102 jengbou 1.5 h["errPVx"] = subDir.make<TH1D>("errPVx","X vertex error",100,0.,0.02);
103     h["errPVy"] = subDir.make<TH1D>("errPVy","Y vertex error",100,0.,0.02);
104     h["errPVz"] = subDir.make<TH1D>("errPVz","Z vertex error",100,0.,0.02);
105 jengbou 1.2
106 jengbou 1.1 // Summary of analysis:
107 jengbou 1.2 if (analyze_) {
108 jengbou 1.4 h2["resx_nTrk"]= subDir.make<TH2D>("resx_ntrk","x-resolution (Rec - Sim) vs number of tracks",150,0,150,400,0.,200);
109     h2["resx_nTrk"]->SetMarkerStyle(21);
110     h2["resx_nTrk"]->SetMarkerColor(4);
111     h2["resx_nTrk"]->GetXaxis()->SetTitle("Num of tracks");
112     h2["resx_nTrk"]->GetYaxis()->SetTitle("#mum");
113     h2["resy_nTrk"]= subDir.make<TH2D>("resy_ntrk","y-resolution (Rec - Sim) vs number of tracks",150,0,150,400,0.,200);
114     h2["resy_nTrk"]->SetMarkerStyle(21);
115     h2["resy_nTrk"]->SetMarkerColor(4);
116     h2["resy_nTrk"]->GetXaxis()->SetTitle("Num of tracks");
117     h2["resy_nTrk"]->GetYaxis()->SetTitle("#mum");
118     h2["resz_nTrk"]= subDir.make<TH2D>("resz_ntrk","z-resolution (Rec - Sim) vs number of tracks",150,0,150,400,0.,200);
119     h2["resz_nTrk"]->SetMarkerStyle(21);
120     h2["resz_nTrk"]->SetMarkerColor(4);
121     h2["resz_nTrk"]->GetXaxis()->SetTitle("Num of tracks");
122     h2["resz_nTrk"]->GetYaxis()->SetTitle("#mum");
123     h2["pullx_nTrk"]= subDir.make<TH2D>("pullx_ntrk","x-pull (Rec - Sim) vs number of tracks",150,0,150,100,0.,2.);
124     h2["pullx_nTrk"]->SetMarkerStyle(21);
125     h2["pullx_nTrk"]->SetMarkerColor(4);
126     h2["pullx_nTrk"]->SetBit(TH1::kCanRebin);
127     h2["pullx_nTrk"]->GetXaxis()->SetTitle("Num of tracks");
128     h2["pully_nTrk"]= subDir.make<TH2D>("pully_ntrk","y-pull (Rec - Sim) vs number of tracks",150,0,150,100,0.,2.);
129     h2["pully_nTrk"]->SetMarkerStyle(21);
130     h2["pully_nTrk"]->SetMarkerColor(4);
131     h2["pully_nTrk"]->SetBit(TH1::kCanRebin);
132     h2["pully_nTrk"]->GetXaxis()->SetTitle("Num of tracks");
133     h2["pullz_nTrk"]= subDir.make<TH2D>("pullz_ntrk","z-pull (Rec - Sim) vs number of tracks",150,0,150,100,0.,2.);
134     h2["pullz_nTrk"]->SetMarkerStyle(21);
135     h2["pullz_nTrk"]->SetMarkerColor(4);
136     h2["pullz_nTrk"]->SetBit(TH1::kCanRebin);
137     h2["pullz_nTrk"]->GetXaxis()->SetTitle("Num of tracks");
138 jengbou 1.2 }
139 jengbou 1.1 for (int ntrk=nTrkMin_;ntrk<=nTrkMax_;++ntrk) {
140     stringstream ss;
141     ss << ntrk;
142     string suffix = ss.str();
143 jengbou 1.5 h["resx_"+suffix] = fs->make<TH1D>(TString("deltax_"+suffix),"x-distance (Rec - Sim)",100,-0.02,0.02);
144 jengbou 1.1 h["resx_"+suffix]->GetXaxis()->SetTitle("cm");
145 jengbou 1.5 h["resy_"+suffix] = fs->make<TH1D>(TString("deltay_"+suffix),"y-distance (Rec - Sim)",100,-0.02,0.02);
146 jengbou 1.1 h["resy_"+suffix]->GetXaxis()->SetTitle("cm");
147 jengbou 1.5 h["resz_"+suffix] = fs->make<TH1D>(TString("deltaz_"+suffix),"z-distance (Rec - Sim)",100,-0.02,0.02);
148 jengbou 1.1 h["resz_"+suffix]->GetXaxis()->SetTitle("cm");
149 jengbou 1.5 h["pullx_"+suffix] = fs->make<TH1D>(TString("pullx_"+suffix),"x-pull (Rec - Sim)",100,-10.,10.);
150     h["pully_"+suffix] = fs->make<TH1D>(TString("pully_"+suffix),"y-pull (Rec - Sim)",100,-10.,10.);
151     h["pullz_"+suffix] = fs->make<TH1D>(TString("pullz_"+suffix),"z-pull (Rec - Sim)",100,-10.,10.);
152     h["errPVx_"+suffix] = subDir1.make<TH1D>(TString("errPVx_"+suffix),"X vertex error",100,0.,0.02);
153     h["errPVy_"+suffix] = subDir1.make<TH1D>(TString("errPVy_"+suffix),"Y vertex error",100,0.,0.02);
154     h["errPVz_"+suffix] = subDir1.make<TH1D>(TString("errPVz_"+suffix),"Z vertex error",100,0.,0.02);
155 jengbou 1.1 suffix.clear();
156     }
157     }
158     }
159    
160    
161     PVStudy::~PVStudy()
162     {
163    
164     // do anything here that needs to be done at desctruction time
165     // (e.g. close files, deallocate resources etc.)
166    
167     }
168    
169 jengbou 1.4 void PVStudy::setRootStyle() {
170     //
171     gROOT->SetStyle("Plain");
172     gStyle->SetFillColor(1);
173     gStyle->SetOptDate();
174     // gStyle->SetOptStat(1111110);
175     // gStyle->SetOptFit(0111);
176     // gStyle->SetPadTickX(1);
177     // gStyle->SetPadTickY(1);
178     gStyle->SetMarkerSize(0.5);
179     gStyle->SetMarkerStyle(8);
180     gStyle->SetGridStyle(3);
181     //gStyle->SetPadGridX(1);
182     //gStyle->SetPadGridY(1);
183     gStyle->SetPaperSize(TStyle::kA4);
184     gStyle->SetStatW(0.25); // width of statistics box; default is 0.19
185     // gStyle->SetStatH(0.10); // height of statistics box; default is 0.1
186     gStyle->SetStatFormat("6.4g"); // leave default format for now
187     gStyle->SetTitleSize(0.055, ""); // size for pad title; default is 0.02
188     gStyle->SetLabelSize(0.03, "XYZ"); // size for axis labels; default is 0.04
189     gStyle->SetStatFontSize(0.08); // size for stat. box
190     gStyle->SetTitleFont(32, "XYZ"); // times-bold-italic font (p. 153) for axes
191     gStyle->SetTitleFont(32, ""); // same for pad title
192     gStyle->SetLabelFont(32, "XYZ"); // same for axis labels
193     gStyle->SetStatFont(32); // same for stat. box
194     gStyle->SetLabelOffset(0.006, "Y"); // default is 0.005
195     //
196     return;
197     }
198 jengbou 1.1 //
199     // member functions
200     //
201     std::vector<PVStudy::simPrimaryVertex> PVStudy::getSimPVs(const Handle<HepMCProduct> evtMC, std::string suffix="")
202     {
203     std::vector<PVStudy::simPrimaryVertex> simpv;
204     const HepMC::GenEvent* evt=evtMC->GetEvent();
205     if (evt) {
206     if(verbose_) {
207     cout << "process id " << evt->signal_process_id()<<endl;
208     cout << "signal process vertex " << ( evt->signal_process_vertex() ?
209     evt->signal_process_vertex()->barcode() : 0 ) <<endl;
210     cout << "number of vertices " << evt->vertices_size() << endl;
211     }
212    
213     int idx=0;
214     for(HepMC::GenEvent::vertex_const_iterator vitr= evt->vertices_begin();
215     vitr != evt->vertices_end(); ++vitr )
216     { // loop for vertex ...
217     HepMC::FourVector pos = (*vitr)->position();
218     //HepLorentzVector pos = (*vitr)->position();
219     if (pos.t()>0) { continue;} // ?
220    
221     bool hasMotherVertex=false;
222     // if(verbose_) cout << "mothers" << endl;
223     for ( HepMC::GenVertex::particle_iterator mother = (*vitr)->particles_begin(HepMC::parents);
224     mother != (*vitr)->particles_end(HepMC::parents); ++mother ) {
225     HepMC::GenVertex * mv=(*mother)->production_vertex();
226     if (mv) {hasMotherVertex=true;}
227     // if(verbose_) {
228     // cout << "\t";
229     // (*mother)->print();
230     // }
231     }
232    
233     if(hasMotherVertex) {continue;}
234    
235     // could be a new vertex, check all primaries found so far to avoid multiple entries
236     const double mm2cm=0.1;
237     simPrimaryVertex sv(pos.x()*mm2cm,pos.y()*mm2cm,pos.z()*mm2cm); // sim unit mm, rec unit cm
238     simPrimaryVertex *vp=NULL; // will become non-NULL if a vertex is found and then point to it
239     for(vector<simPrimaryVertex>::iterator v0=simpv.begin();
240     v0!=simpv.end(); v0++){
241     if( (fabs(sv.x-v0->x)<1e-5) && (fabs(sv.y-v0->y)<1e-5) && (fabs(sv.z-v0->z)<1e-5)){
242     vp=&(*v0);
243     break;
244     }
245     }
246    
247     if(!vp){
248     // this is a new vertex
249     if(verbose_) cout << "this is a new vertex " << sv.x << " " << sv.y << " " << sv.z << endl;
250     simpv.push_back(sv);
251     vp=&simpv.back();
252     }else{
253     if(verbose_) cout << "this is not a new vertex " << sv.x << " " << sv.y << " " << sv.z << endl;
254     }
255     vp->genVertex.push_back((*vitr)->barcode());
256     // collect final state descendants
257     for ( HepMC::GenVertex::particle_iterator
258     daughter = (*vitr)->particles_begin(HepMC::descendants);
259     daughter != (*vitr)->particles_end(HepMC::descendants);
260     ++daughter ) {
261     if (isFinalstateParticle(*daughter)){
262     if ( find(vp->finalstateParticles.begin(), vp->finalstateParticles.end(),(*daughter)->barcode())
263     == vp->finalstateParticles.end()){
264     vp->finalstateParticles.push_back((*daughter)->barcode());
265     HepMC::FourVector m=(*daughter)->momentum();
266     // the next four lines used to be "vp->ptot+=m;" in the days of CLHEP::HepLorentzVector
267     // but adding FourVectors seems not to be foreseen
268     vp->ptot.setPx(vp->ptot.px()+m.px());
269     vp->ptot.setPy(vp->ptot.py()+m.py());
270     vp->ptot.setPz(vp->ptot.pz()+m.pz());
271     vp->ptot.setE(vp->ptot.e()+m.e());
272     vp->ptsq+=(m.perp())*(m.perp());
273     if ( (m.perp()>0.8) && (fabs(m.pseudoRapidity())<2.5) && isCharged( *daughter ) ){
274     vp->nGenTrk++;
275     }
276     }
277     }
278     }
279     idx++;
280     }
281     }
282     return simpv;
283     }
284    
285     std::vector<PVStudy::simPrimaryVertex> PVStudy::getSimPVs(const Handle<HepMCProduct> evtMC,
286     const Handle<SimVertexContainer> simVtxs,
287     const Handle<SimTrackContainer> simTrks)
288     {
289     // simvertices don't have enough information to decide,
290     // genVertices don't have the simulated coordinates ( with VtxSmeared they might)
291     // go through simtracks to get the link between simulated and generated vertices
292     std::vector<PVStudy::simPrimaryVertex> simpv;
293     int idx=0;
294     for(SimTrackContainer::const_iterator t=simTrks->begin();
295     t!=simTrks->end(); ++t){
296     if ( !(t->noVertex()) && !(t->type()==-99) ){
297     double ptsq=0;
298     bool primary=false; // something coming directly from the primary vertex
299     bool resonance=false; // resonance
300     bool track=false; // undecayed, charged particle
301     HepMC::GenParticle* gp=evtMC->GetEvent()->barcode_to_particle( (*t).genpartIndex() );
302     if (gp) {
303     HepMC::GenVertex * gv=gp->production_vertex();
304     if (gv) {
305     for ( HepMC::GenVertex::particle_iterator
306     daughter = gv->particles_begin(HepMC::descendants);
307     daughter != gv->particles_end(HepMC::descendants);
308     ++daughter ) {
309     if (isFinalstateParticle(*daughter)){
310     ptsq+=(*daughter)->momentum().perp()*(*daughter)->momentum().perp();
311     }
312     }
313     primary = ( gv->position().t()==0);
314     //resonance= ( gp->mother() && isResonance(gp->mother())); // in CLHEP/HepMC days
315     // no more mother pointer in the improved HepMC GenParticle
316     resonance= ( isResonance(*(gp->production_vertex()->particles_in_const_begin())));
317     if (gp->status()==1){
318     //track=((pdt->particle(gp->pdg_id()))->charge() != 0);
319     track=not isCharged(gp);
320     }
321     }
322     }
323    
324     const HepMC::FourVector & v=(*simVtxs)[t->vertIndex()].position();
325     //const HepLorentzVector & v=(*simVtxs)[t->vertIndex()].position();
326     if(primary or resonance){
327     {
328     // check all primaries found so far to avoid multiple entries
329     bool newVertex=true;
330     for(std::vector<PVStudy::simPrimaryVertex>::iterator v0=simpv.begin();
331     v0!=simpv.end(); v0++){
332     if( (fabs(v0->x-v.x())<0.001) && (fabs(v0->y-v.y())<0.001) && (fabs(v0->z-v.z())<0.001) ){
333     if (track) {
334     v0->simTrackIndex.push_back(idx);
335     if (ptsq>(*v0).ptsq){(*v0).ptsq=ptsq;}
336     }
337     newVertex=false;
338     }
339     }
340     if(newVertex && !resonance){
341     PVStudy::simPrimaryVertex anotherVertex(v.x(),v.y(),v.z());
342     if (track) anotherVertex.simTrackIndex.push_back(idx);
343     anotherVertex.ptsq=ptsq;
344     simpv.push_back(anotherVertex);
345     }
346     }//
347     }
348    
349     }// simtrack has vertex and valid type
350     idx++;
351     }//simTrack loop
352     return simpv;
353     }
354    
355     // ------------ method called to for each event ------------
356     void
357     PVStudy::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
358     {
359     using namespace edm;
360 jengbou 1.3 using reco::TrackCollection;
361    
362     ftree_->SetBranchAddress("residual",&fres);
363     ftree_->SetBranchAddress("error",&ferror);
364     ftree_->SetBranchAddress("nTrk",&fntrk);
365 jengbou 1.1
366     Handle<TrackCollection> tracks;
367     iEvent.getByLabel(tracksLabel_,tracks);
368    
369     Handle<reco::VertexCollection> recVtxs;
370     iEvent.getByLabel(vtxSample_, recVtxs);
371    
372     if (!realData_) {
373     Handle<SimVertexContainer> simVtxs;
374     iEvent.getByLabel( simG4_, simVtxs);
375    
376     Handle<SimTrackContainer> simTrks;
377     iEvent.getByLabel( simG4_, simTrks);
378     }
379    
380     if(verbose_) printRecVtxs(recVtxs);
381    
382     try{
383     iSetup.getData(pdt);
384     }catch(const Exception&){
385     cout << "Some problem occurred with the particle data table. This may not work !." <<endl;
386     }
387    
388     if (!realData_) {
389     bool MC=false;
390     Handle<HepMCProduct> evtMC;
391     iEvent.getByLabel("generator",evtMC);
392     if (!evtMC.isValid()) {
393     MC=false;
394     if(verbose_){
395     cout << "no HepMCProduct found"<< endl;
396     }
397     } else {
398     if(verbose_){
399     cout << "generator HepMCProduct found"<< endl;
400     }
401     MC=true;
402     }
403    
404     if(MC){
405     // make a list of primary vertices:
406     std::vector<simPrimaryVertex> simpv;
407     simpv=getSimPVs(evtMC,"");
408     // simpv=getSimPVs(evtMC, simVtxs, simTrks);
409    
410     int nsimtrk=0;
411     int nrectrk=0;
412     for(std::vector<simPrimaryVertex>::iterator vsim=simpv.begin();
413     vsim!=simpv.end(); vsim++){
414     nsimtrk+=vsim->nGenTrk;
415     // look for a matching reconstructed vertex
416     vsim->recVtx=NULL;
417     for(reco::VertexCollection::const_iterator vrec=recVtxs->begin();
418     vrec!=recVtxs->end(); ++vrec){
419     nrectrk=vrec->tracksSize();
420     if(verbose_){
421     cout << "sim primary vertex x = " << vsim->x << "; y = " << vsim->y << "; z = " << vsim->z << endl;
422     cout << "Is matched? " << (matchVertex(*vsim,*vrec)?"Yes":"No") << endl;
423     }
424     if ( matchVertex(*vsim,*vrec) ){
425     // if the matching critera are fulfilled, accept the rec-vertex that is closest in z
426     if( ((vsim->recVtx) && (fabs(vsim->recVtx->position().z()-vsim->z)>fabs(vrec->z()-vsim->z)))
427     || (!vsim->recVtx) )
428     {
429     vsim->recVtx=&(*vrec);
430     }
431     }
432     }
433     if (vsim->recVtx){
434     if(verbose_) {
435     cout <<"primary matched " << vsim->x << " " << vsim->y << " " << vsim->z << endl;
436     }
437 jengbou 1.3 fres[0] = vsim->recVtx->x()-vsim->x;
438     fres[1] = vsim->recVtx->y()-vsim->y;
439     fres[2] = vsim->recVtx->z()-vsim->z;
440     ferror[0] = vsim->recVtx->xError();
441     ferror[1] = vsim->recVtx->yError();
442     ferror[2] = vsim->recVtx->zError();
443     fntrk = nrectrk;
444    
445 jengbou 1.4 h["deltax"]->Fill( fres[0] );
446     h["deltay"]->Fill( fres[1] );
447     h["deltaz"]->Fill( fres[2] );
448     h["pullx"]->Fill( fres[0]/ferror[0] );
449     h["pully"]->Fill( fres[1]/ferror[1] );
450     h["pullz"]->Fill( fres[2]/ferror[2] );
451 jengbou 1.5 h["errPVx"]->Fill( ferror[0] );
452     h["errPVy"]->Fill( ferror[1] );
453     h["errPVz"]->Fill( ferror[2] );
454 jengbou 1.4 pvinfo.push_back(PVStudy::PVInfo(res(fres[0], fres[1], fres[2]),
455     error(ferror[0], ferror[1], ferror[2]),
456 jengbou 1.3 nrectrk));
457     // Fill histo according to its track multiplicity
458 jengbou 1.4 fillHisto(res(fres[0], fres[1], fres[2]),
459     error(ferror[0], ferror[1], ferror[2]),
460 jengbou 1.3 nrectrk);
461 jengbou 1.4
462     ftree_->Fill();
463 jengbou 1.1 }
464     else{ // no rec vertex found for this simvertex
465     if(verbose_) {
466     cout <<"primary not found " << vsim->x << " " << vsim->y << " " << vsim->z << " nGenTrk=" << vsim->nGenTrk << endl;
467     }
468     }
469     }
470     }
471     }// With MC
472    
473     // Loop RecVtxs and find matched SimVtxs
474     for(reco::VertexCollection::const_iterator v=recVtxs->begin();
475     v!=recVtxs->end(); ++v){
476     try {
477     for(reco::Vertex::trackRef_iterator t = v->tracks_begin();
478     t!=v->tracks_end(); t++) {
479     // illegal charge
480     if ( (**t).charge() < -1 || (**t).charge() > 1 ) {
481 jengbou 1.4 // h["trkPtPV"]->Fill(0.);
482 jengbou 1.1 }
483     else {
484 jengbou 1.4 h["trkPtPV"]->Fill((**t).pt());
485 jengbou 1.1 }
486     }
487     }
488     catch (...) {
489     // exception thrown when trying to use linked track
490 jengbou 1.4 // h["trkPtPV"]->Fill(0.);
491 jengbou 1.1 }
492    
493 jengbou 1.4 h["nTrkPV"]->Fill(v->tracksSize());
494 jengbou 1.1
495     }
496    
497 jengbou 1.4 h["nTrk"]->Fill(tracks->size());
498 jengbou 1.1
499     for(TrackCollection::const_iterator itTrack = tracks->begin();
500     itTrack != tracks->end();
501     ++itTrack) {
502     int charge = 0;
503     charge = itTrack->charge();
504 jengbou 1.4 h["trkPt"]->Fill(itTrack->pt());
505 jengbou 1.1 }
506    
507     }
508    
509    
510     // ------------ method called once each job just before starting event loop ------------
511     void
512     PVStudy::beginJob()
513     {
514     }
515    
516     // ------------ method called once each job just after ending the event loop ------------
517     void
518     PVStudy::endJob() {
519     double sqt2 = sqrt(2.);
520     if (!realData_) {
521     if (verbose_) cout << "Analyzing PV info" << endl;
522     for (int ntrk=nTrkMin_;ntrk<=nTrkMax_;++ntrk) {
523     if (verbose_) cout << "Fill point of ntrk = " << ntrk << endl;
524     PVStudy::PVAnaInfo ipv = GetPVAnaInfo(ntrk);
525 jengbou 1.2 if (analyze_) {
526 jengbou 1.4 // if ( ipv.res_.x() > 0 ) h2["resx_nTrk"]->Fill(ntrk,ipv.res_.x()/sqt2, 1.);
527     // if ( ipv.res_.y() > 0 ) h2["resy_nTrk"]->Fill(ntrk,ipv.res_.y()/sqt2, 1.);
528     // if ( ipv.res_.z() > 0 ) h2["resz_nTrk"]->Fill(ntrk,ipv.res_.z()/sqt2, 1.);
529     if ( ipv.res_.x() > 0 ) h2["resx_nTrk"]->Fill(ntrk,ipv.res_.x(), 1.);
530     if ( ipv.res_.y() > 0 ) h2["resy_nTrk"]->Fill(ntrk,ipv.res_.y(), 1.);
531     if ( ipv.res_.z() > 0 ) h2["resz_nTrk"]->Fill(ntrk,ipv.res_.z(), 1.);
532     if ( ipv.pull_.x() > 0 ) h2["pullx_nTrk"]->Fill(ntrk,ipv.pull_.x(), 1.);
533     if ( ipv.pull_.y() > 0 ) h2["pully_nTrk"]->Fill(ntrk,ipv.pull_.y(), 1.);
534     if ( ipv.pull_.z() > 0 ) h2["pullz_nTrk"]->Fill(ntrk,ipv.pull_.z(), 1.);
535 jengbou 1.2 }
536 jengbou 1.1 }
537     }
538 jengbou 1.3 file_->cd();
539     ftree_->Write();
540     file_->Close();
541 jengbou 1.1 }
542    
543     bool PVStudy::matchVertex(const PVStudy::simPrimaryVertex & vsim,
544     const reco::Vertex & vrec)
545     {
546     return (fabs(vsim.z-vrec.z())<0.0500); // =500um
547     }
548    
549     bool PVStudy::isResonance(const HepMC::GenParticle * p){
550     double ctau=(pdt->particle( abs(p->pdg_id()) ))->lifetime();
551     if(verbose_) cout << "isResonance " << p->pdg_id() << " " << ctau << endl;
552     return ctau >0 && ctau <1e-6;
553     }
554    
555     bool PVStudy::isFinalstateParticle(const HepMC::GenParticle * p){
556     return ( !p->end_vertex() && p->status()==1 );
557     }
558    
559     bool PVStudy::isCharged(const HepMC::GenParticle * p){
560     const ParticleData * part = pdt->particle( p->pdg_id() );
561     if (part){
562     return part->charge()!=0;
563     }else{
564     // the new/improved particle table doesn't know anti-particles
565     return pdt->particle( -p->pdg_id() )!=0;
566     }
567     }
568    
569     void PVStudy::printSimVtxs(const Handle<SimVertexContainer> simVtxs){
570     int i=0;
571     for(SimVertexContainer::const_iterator vsim=simVtxs->begin();
572     vsim!=simVtxs->end(); ++vsim){
573     cout << i++ << ")" << scientific
574     << " evtid=" << vsim->eventId().event()
575     << " sim x=" << vsim->position().x()
576     << " sim y=" << vsim->position().y()
577     << " sim z=" << vsim->position().z()
578     << " sim t=" << vsim->position().t()
579     << " parent=" << vsim->parentIndex()
580     << endl;
581     }
582     }
583    
584     void PVStudy::printRecVtxs(const Handle<reco::VertexCollection> recVtxs){
585     int ivtx=0;
586     for(reco::VertexCollection::const_iterator v=recVtxs->begin();
587     v!=recVtxs->end(); ++v){
588     cout << "Recvtx "<< std::setw(3) << std::setfill(' ')<<ivtx++
589     << "#trk " << std::setw(3) << v->tracksSize()
590     << " chi2 " << std::setw(4) << v->chi2()
591     << " ndof " << std::setw(3) << v->ndof() << endl
592     << " x " << std::setw(8) <<std::fixed << std::setprecision(4) << v->x()
593     << " dx " << std::setw(8) << v->xError()<< endl
594     << " y " << std::setw(8) << v->y()
595     << " dy " << std::setw(8) << v->yError()<< endl
596     << " z " << std::setw(8) << v->z()
597     << " dz " << std::setw(8) << v->zError()
598     << endl;
599     }
600     }
601    
602     void PVStudy::printSimTrks(const Handle<SimTrackContainer> simTrks){
603     cout << " simTrks type, (momentum), vertIndex, genpartIndex" << endl;
604     int i=1;
605     for(SimTrackContainer::const_iterator t=simTrks->begin();
606     t!=simTrks->end(); ++t){
607     //HepMC::GenParticle* gp=evtMC->GetEvent()->particle( (*t).genpartIndex() );
608     cout << i++ << ")"
609     << (*t)
610     << " index="
611     << (*t).genpartIndex();
612     //if (gp) {
613     // HepMC::GenVertex *gv=gp->production_vertex();
614     // cout << " genvertex =" << (*gv);
615     //}
616     cout << endl;
617     }
618     }
619    
620 jengbou 1.4 void PVStudy::fillHisto(res r, error er, int ntk){
621 jengbou 1.3 stringstream ss;
622     ss << ntk;
623     string suffix = ss.str();
624     if (ntk < nTrkMin_ || ntk > nTrkMax_ ) return;
625     // Fill histograms of res and pull of ntk
626     h["resx_"+suffix]->Fill(r.x());
627     h["resy_"+suffix]->Fill(r.y());
628     h["resz_"+suffix]->Fill(r.z());
629 jengbou 1.4 h["pullx_"+suffix]->Fill(r.x()/er.x());
630     h["pully_"+suffix]->Fill(r.y()/er.y());
631     h["pullz_"+suffix]->Fill(r.z()/er.z());
632     h["errPVx_"+suffix]->Fill(er.x());
633     h["errPVy_"+suffix]->Fill(er.y());
634     h["errPVz_"+suffix]->Fill(er.z());
635 jengbou 1.3 }
636    
637 jengbou 1.1 PVStudy::PVAnaInfo PVStudy::GetPVAnaInfo(int ntk) {
638     map<int,double> data;
639 jengbou 1.2 data.clear();
640 jengbou 1.4 double fpar[2] = {-999,-999};
641 jengbou 1.1 double cm2um = 10000;
642     stringstream ss;
643     ss << ntk;
644     string suffix = ss.str();
645    
646 jengbou 1.3 if(analyze_) {
647     for ( int i = 0; i < 6; ++i) {
648     switch (i) {
649     case 0:
650     fit(h["resx_"+suffix], fpar);
651     data[i] = fpar[0]*cm2um;
652     break;
653     case 1:
654     fit(h["resy_"+suffix], fpar);
655     data[i] = fpar[0]*cm2um;
656     break;
657     case 2:
658     fit(h["resz_"+suffix], fpar);
659     data[i] = fpar[0]*cm2um;
660     break;
661     case 3:
662     fit(h["pullx_"+suffix], fpar);
663     data[i] = fpar[0];
664     break;
665     case 4:
666     fit(h["pully_"+suffix], fpar);
667     data[i] = fpar[0];
668     break;
669     case 5:
670     fit(h["pullz_"+suffix], fpar);
671     data[i] = fpar[0];
672     break;
673 jengbou 1.1 }
674 jengbou 1.3 if (verbose_ && data[i] > 0) cout << "data[" << i << "] = " << data[i] << (i<3?" micro m":" ") << endl;
675 jengbou 1.1 }
676 jengbou 1.3 }
677     else
678     for ( int i = 0; i < 6; ++i) {
679     data[i] = -999;
680 jengbou 1.1 }
681    
682 jengbou 1.3 return PVStudy::PVAnaInfo(res(data[0], data[1], data[2]),
683     error(0.,0.,0.),
684     pull(data[3], data[4], data[5]),
685     error(0.,0.,0.),
686 jengbou 1.1 ntk);
687     }
688    
689 jengbou 1.4 void PVStudy::fit(TH1 *&hdist, double fitPars[]){
690 jengbou 1.3 TAxis *axis0 = hdist->GetXaxis();
691     int nbin = axis0->GetLast();
692     double nOF = hdist->GetBinContent(nbin+1);
693     double nUF = hdist->GetBinContent(0);
694 jengbou 1.4 // double fitRange = axis0->GetBinUpEdge(nbin);
695     double fitRange = axis0->GetXmax();
696 jengbou 1.5 double sigMax[2] = {0.,0.};
697 jengbou 1.4
698 jengbou 1.3 if ( verbose_ ){
699     cout << "Last bin = " << nbin;
700     cout << "; hdist: Overflow Entries = " << nOF;
701     cout << "; Underflow Entries = " << nUF;
702 jengbou 1.4 cout << "; hdist->GetEntries() = " << hdist->GetEntries();
703     cout << "; fitting range = " << -fitRange << " to " << fitRange << endl;
704 jengbou 1.3 }
705 jengbou 1.4 if (hdist->GetEntries() - nOF - nUF >= 10) { // FIXME: for reasonable Gaussian fit
706     for (int bi = 0; bi < nbin; bi++) {
707     if ( (axis0->GetBinLowEdge(bi) < 0) && (hdist->GetBinContent(bi) > 0) ) {
708     sigMax[0] = axis0->GetBinLowEdge(bi);
709 jengbou 1.5 if ( abs(sigMax[0]) > abs(sigMax[1]) ) sigMax[1] = abs(sigMax[0]);
710 jengbou 1.4 }
711     if ( (axis0->GetBinLowEdge(bi) >= 0) && (hdist->GetBinContent(bi) > 0) ) {
712 jengbou 1.5 sigMax[0] = axis0->GetBinUpEdge(bi);
713     if ( abs(sigMax[0]) > abs(sigMax[1]) ) sigMax[1] = abs(sigMax[0]);
714 jengbou 1.4 }
715     }
716 jengbou 1.5 if (verbose_) cout << "Fit sigMax = " << sqrt(2.)*sigMax[1] << endl;
717 jengbou 1.4
718     TF1 *fgaus = new TF1("fgaus","gaus",-fitRange, fitRange);
719     fgaus->SetParameter(1, 0.);
720     fgaus->SetParLimits(1, -fitRange/40., fitRange/40.);
721 jengbou 1.5 fgaus->SetParLimits(2, 0., sqrt(2.)*sigMax[1]);
722 jengbou 1.4 fgaus->SetLineColor(4);
723     hdist->Fit(fgaus,"Q");
724     gPad->Update();
725     TPaveStats *s = (TPaveStats*) hdist->GetListOfFunctions()->FindObject("stats");
726     s->SetOptStat(1111111);
727     s->SetOptFit(0111);
728     gPad->Update();
729 jengbou 1.3 if (verbose_) cout << "got function" << endl;
730 jengbou 1.4 fitPars[0] = ((fgaus->GetParameter(2))?fgaus->GetParameter(2):-999);
731 jengbou 1.3 }
732 jengbou 1.4 else
733     fitPars[0] = -999;
734 jengbou 1.3 }
735    
736 jengbou 1.1 //define this as a plug-in
737     DEFINE_FWK_MODULE(PVStudy);