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