ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/Jeng/PVStudy/plugins/PVStudy.cc
Revision: 1.6
Committed: Wed Sep 9 23:05:38 2009 UTC (15 years, 8 months ago) by jengbou
Content type: text/plain
Branch: MAIN
CVS Tags: CMSSW_3_1_X_20091008
Changes since 1.5: +85 -65 lines
Log Message:
add histos, remove pos.t()>0

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