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

# Content
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 // $Id: PVStudy.cc,v 1.3 2009/09/08 07:15:38 jengbou Exp $
17 //
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 #include <TROOT.h>
54 #include <TF1.h>
55 #include <TString.h>
56 #include <TStyle.h>
57 #include <TPaveStats.h>
58 #include <TPad.h>
59
60 using namespace std;
61
62 PVStudy::PVStudy(const edm::ParameterSet& iConfig):
63 nTrkMin_(10),nTrkMax_(100)
64 {
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 analyze_ = iConfig.getUntrackedParameter<bool>("analyzeOnTheFly",false);
71 outputfilename_ = iConfig.getUntrackedParameter<string>("OutputFileName");
72
73 //now do what ever initialization is needed
74 pvinfo.clear();
75
76 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 edm::Service<TFileService> fs;
84 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
95 if (!realData_) {
96 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
103 // Summary of analysis:
104 if (analyze_) {
105 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 }
136 for (int ntrk=nTrkMin_;ntrk<=nTrkMax_;++ntrk) {
137 stringstream ss;
138 ss << ntrk;
139 string suffix = ss.str();
140 h["resx_"+suffix] = fs->make<TH1D> (TString("deltax_"+suffix),"x-distance (Rec - Sim)",100,-0.02,0.02);
141 h["resx_"+suffix]->GetXaxis()->SetTitle("cm");
142 h["resy_"+suffix] = fs->make<TH1D> (TString("deltay_"+suffix),"y-distance (Rec - Sim)",100,-0.02,0.02);
143 h["resy_"+suffix]->GetXaxis()->SetTitle("cm");
144 h["resz_"+suffix] = fs->make<TH1D> (TString("deltaz_"+suffix),"z-distance (Rec - Sim)",100,-0.02,0.02);
145 h["resz_"+suffix]->GetXaxis()->SetTitle("cm");
146 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 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 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 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 //
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 using reco::TrackCollection;
358
359 ftree_->SetBranchAddress("residual",&fres);
360 ftree_->SetBranchAddress("error",&ferror);
361 ftree_->SetBranchAddress("nTrk",&fntrk);
362
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 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 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 nrectrk));
451 // Fill histo according to its track multiplicity
452 fillHisto(res(fres[0], fres[1], fres[2]),
453 error(ferror[0], ferror[1], ferror[2]),
454 nrectrk);
455
456 ftree_->Fill();
457 }
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 // h["trkPtPV"]->Fill(0.);
476 }
477 else {
478 h["trkPtPV"]->Fill((**t).pt());
479 }
480 }
481 }
482 catch (...) {
483 // exception thrown when trying to use linked track
484 // h["trkPtPV"]->Fill(0.);
485 }
486
487 h["nTrkPV"]->Fill(v->tracksSize());
488
489 }
490
491 h["nTrk"]->Fill(tracks->size());
492
493 for(TrackCollection::const_iterator itTrack = tracks->begin();
494 itTrack != tracks->end();
495 ++itTrack) {
496 int charge = 0;
497 charge = itTrack->charge();
498 h["trkPt"]->Fill(itTrack->pt());
499 }
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 if (analyze_) {
520 // 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 }
530 }
531 }
532 file_->cd();
533 ftree_->Write();
534 file_->Close();
535 }
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 void PVStudy::fillHisto(res r, error er, int ntk){
615 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 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 }
630
631 PVStudy::PVAnaInfo PVStudy::GetPVAnaInfo(int ntk) {
632 map<int,double> data;
633 data.clear();
634 double fpar[2] = {-999,-999};
635 double cm2um = 10000;
636 stringstream ss;
637 ss << ntk;
638 string suffix = ss.str();
639
640 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 }
668 if (verbose_ && data[i] > 0) cout << "data[" << i << "] = " << data[i] << (i<3?" micro m":" ") << endl;
669 }
670 }
671 else
672 for ( int i = 0; i < 6; ++i) {
673 data[i] = -999;
674 }
675
676 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 ntk);
681 }
682
683 void PVStudy::fit(TH1 *&hdist, double fitPars[]){
684 TAxis *axis0 = hdist->GetXaxis();
685 int nbin = axis0->GetLast();
686 double nOF = hdist->GetBinContent(nbin+1);
687 double nUF = hdist->GetBinContent(0);
688 // double fitRange = axis0->GetBinUpEdge(nbin);
689 double fitRange = axis0->GetXmax();
690 double sigMax[3] = {0.,0.,0.};
691
692 if ( verbose_ ){
693 cout << "Last bin = " << nbin;
694 cout << "; hdist: Overflow Entries = " << nOF;
695 cout << "; Underflow Entries = " << nUF;
696 cout << "; hdist->GetEntries() = " << hdist->GetEntries();
697 cout << "; fitting range = " << -fitRange << " to " << fitRange << endl;
698 }
699 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 if (verbose_) cout << "got function" << endl;
724 fitPars[0] = ((fgaus->GetParameter(2))?fgaus->GetParameter(2):-999);
725 }
726 else
727 fitPars[0] = -999;
728 }
729
730 //define this as a plug-in
731 DEFINE_FWK_MODULE(PVStudy);