ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/Jeng/scripts/pvHistory.C
Revision: 1.1
Committed: Thu Jan 28 22:19:26 2010 UTC (15 years, 3 months ago) by jengbou
Content type: text/plain
Branch: MAIN
Log Message:
FWlite Script from Wolfgang to compare PV and Beam spot. Modified with CMS style for approval.

File Contents

# User Rev Content
1 jengbou 1.1 #if !defined(__CINT__) && !defined(__MAKECINT__)
2     #include "DataFormats/FWLite/interface/Handle.h"
3     #include "DataFormats/FWLite/interface/Event.h"
4     #include "DataFormats/FWLite/interface/ChainEvent.h"
5     //Headers for the data items
6     #include "DataFormats/VertexReco/interface/Vertex.h"
7     #include "DataFormats/BeamSpot/interface/BeamSpot.h"
8    
9     #endif
10    
11     #include "TROOT.h"
12     #include "TH2F.h"
13     #include "TFile.h"
14     #include "TF1.h"
15     #include "TCanvas.h"
16     #include "TMath.h"
17     #include "TBox.h"
18     #include <vector>
19     #include <map>
20     #include <string>
21    
22     using namespace std;
23     typedef map<unsigned int, unsigned int> RunNumberMap;
24    
25     //
26     // iterative fit of +- 2 sigma Gaussian core on a 1d histogram
27     //
28     bool fitHistogram (TH1* slice, TF1& fg, double* pars, double* epars, bool dbg = false) {
29     // initialization of parameters
30     pars[0] = slice->GetMaximum();
31     pars[1] = slice->GetMean();
32     pars[2] = slice->GetRMS();
33     epars[0] = 0;
34     epars[1] = 0;
35     epars[2] = 0;
36     // some iterations
37     bool converged(false);
38     for ( unsigned int it=0; it<10; ++it) {
39     const double nSigRange = 2.;
40     fg.SetParameters(pars);
41     double oldMean = pars[1];
42     double oldWidth = pars[2];
43     if ( it>0 ) {
44     fg.SetRange(pars[1]-nSigRange*pars[2],
45     pars[1]+nSigRange*pars[2]);
46     // if ( dbg ) {
47     // cout << "Setting range to " << pars[1]-nSigRange*pars[2]
48     // << " " << pars[1]+nSigRange*pars[2] << endl;
49     // }
50     }
51     else {
52     fg.SetRange(slice->GetXaxis()->GetXmin(),
53     slice->GetXaxis()->GetXmax());
54     // if ( dbg ) {
55     // cout << "Setting range to " << slice->GetXaxis()->GetXmin()
56     // << " " << slice->GetXaxis()->GetXmax() << endl;
57     // }
58     }
59     if ( dbg )
60     slice->Fit(&fg,"QLR+");
61     else
62     slice->Fit(&fg,"QLR");
63     fg.GetParameters(pars);
64     epars[0] = fg.GetParError(0);
65     epars[1] = fg.GetParError(1);
66     epars[2] = fg.GetParError(2);
67     if ( converged ) {
68     cout << "terminating at iteration " << it << " "
69     << pars[1] << " " << oldMean << " " << epars[1] << " "
70     << pars[2] << " " << oldWidth << " " << epars[2] << endl;
71     break;
72     }
73     else if ( dbg ) {
74     cout << " at iteration " << it << " "
75     << pars[1] << " " << oldMean << " " << epars[1] << " "
76     << pars[2] << " " << oldWidth << " " << epars[2] << endl;
77     }
78     // convergence criterion
79     if ( it>2 &&
80     fabs((pars[1]-oldMean))<max(fabs(0.01*epars[1]),0.0010) &&
81     fabs((pars[2]-oldWidth))<max(fabs(0.01*epars[2]),0.0010) ) {
82     converged = true;
83     }
84     }
85    
86     return converged;
87     }
88    
89     //
90     // fit Gaussian to slices of the 2d "run" histogram
91     //
92     void fitRunHistogram (TH2* histo, TH1*& hmean, TH1*& hwidth) {
93     //
94     // create histograms for mean and width vs. run
95     //
96     TDirectory* saveDir = gDirectory;
97     gROOT->cd();
98     int nbin = histo->GetNbinsX();
99     string title = histo->GetName();
100     TAxis* xhisto = histo->GetXaxis();
101     hmean = new TH1F((title+"Mean").c_str(),title.c_str(),nbin,-0.5,nbin-0.5);
102     TAxis* xhmean = hmean->GetXaxis();
103     hwidth = new TH1F((title+"Width").c_str(),title.c_str(),nbin,-0.5,nbin-0.5);
104     TAxis* xhwidth = hwidth->GetXaxis();
105     //
106     // fit function
107     //
108     TF1 fg("fg","gaus");
109     //
110     // loop over runs
111     //
112     bool converged;
113     double pars[3];
114     double epars[3];
115     for ( unsigned int ib=1; ib<=nbin; ++ib ) {
116     //
117     // initialize mean and width to 0 error
118     //
119     hmean->SetBinError(ib,0.);
120     hwidth->SetBinError(ib,0.);
121     //
122     // get slice
123     //
124     TH1* slice =
125     histo->ProjectionY((title+xhisto->GetBinLabel(ib)).c_str(),ib,ib);
126     // drop histograms with too few entries
127     if ( slice->GetEntries()<100 ) {
128     delete slice;
129     continue;
130     }
131     //
132     // fit slice
133     //
134     converged = fitHistogram(slice,fg,pars,epars);
135     if ( converged ) {
136     // copy parameters and errors
137     hmean->SetBinContent(ib,pars[1]);
138     hmean->SetBinError(ib,epars[1]);
139     hwidth->SetBinContent(ib,pars[2]);
140     hwidth->SetBinError(ib,epars[2]);
141     }
142     else {
143     cout << "No convergence for " << histo->GetName() << " / run "
144     << histo->GetXaxis()->GetBinLabel(ib) << endl;
145     // refit with debug flag
146     // fitHistogram(slice,fg,pars,epars,true);
147     hmean->SetBinContent(ib,pars[1]);
148     hmean->SetBinError(ib,epars[1]);
149     hwidth->SetBinContent(ib,pars[2]);
150     hwidth->SetBinError(ib,epars[2]);
151     }
152     // keep failing fits for debugging
153     // if ( converged ) delete slice;
154     xhmean->SetBinLabel(ib,xhisto->GetBinLabel(ib));
155     xhwidth->SetBinLabel(ib,xhisto->GetBinLabel(ib));
156     }
157    
158     saveDir->cd();
159     }
160    
161     //
162     // set x-axis labels to run number
163     //
164     void setRunNumberLabels (TH1* histo, RunNumberMap& runNumbers) {
165     char label[32];
166     TAxis* axis = histo->GetXaxis();
167     for ( RunNumberMap::const_iterator i=runNumbers.begin();
168     i!=runNumbers.end(); ++i ) {
169     sprintf(label,"%d",(*i).first);
170     axis->SetBinLabel((*i).second+1,label);
171     }
172     }
173    
174    
175     //
176     // plot PV distribution for a single run with indication of BS position
177     //
178     void plotRun (char coord, int run)
179     {
180     char title[64];
181    
182     sprintf(title,"pv%cVsRun%d",coord,run);
183     TH1* hpv = (TH1*)gROOT->FindObject(title);
184     if ( hpv==0 ) return;
185    
186     sprintf(title,"pv%cRun%d",coord,run);
187     TCanvas* c = new TCanvas(title);
188    
189     hpv->Draw();
190    
191     sprintf(title,"bs%cVsRunMean",coord);
192     TH1* hbs = (TH1*)gROOT->FindObject(title);
193     sprintf(title,"%d",run);
194     double vbs(0.);
195     double ebs(0.);
196     for ( unsigned int ib=1; ib<=hbs->GetNbinsX(); ++ib ) {
197     const char* label = hbs->GetXaxis()->GetBinLabel(ib);
198     if ( strcmp(title,label)==0 ) {
199     vbs = hbs->GetBinContent(ib);
200     ebs = hbs->GetBinError(ib);
201     break;
202     }
203     }
204     TBox* box = new TBox(vbs-ebs,0,vbs+ebs,hpv->GetMaximum());
205     box->SetFillStyle(1001);
206     box->SetFillColor(7);
207     box->Draw();
208    
209     hpv->Draw("same");
210    
211     sprintf(title,"pv%cRun%d.png",coord,run);
212     c->SaveAs(title);
213     delete c;
214     }
215     //
216     // summary plots (PV + BS) vs run
217     //
218     void plotPvVsBs () {
219     char coord[] = { "xyz" };
220     for ( int ic=0; ic<3; ++ic ) {
221     string canvasTitle("pvVsBs");
222     canvasTitle += coord[ic];
223     TCanvas* c = new TCanvas(canvasTitle.c_str(),canvasTitle.c_str(),
224     700,500);
225     string bsTitle("bs.VsRunMean");
226     bsTitle.replace(2,1,1,coord[ic]);
227     TH1* bsVsRun = (TH1*)gROOT->FindObject(bsTitle.c_str());
228     string pvTitle("pv.VsRunMean");
229     pvTitle.replace(2,1,1,coord[ic]);
230     TH1* pvVsRun = (TH1*)gROOT->FindObject(pvTitle.c_str());
231     pvVsRun->SetMarkerStyle(20);
232     pvVsRun->Draw();
233     bsVsRun->SetFillStyle(1001);
234     bsVsRun->SetFillColor(7);
235     bsVsRun->Draw("E2 same");
236     pvVsRun->Draw("same");
237     }
238     }
239    
240     //
241     // main entry point
242     //
243     void pvHistory (const vector<string>& fileNames) {
244    
245     fwlite::ChainEvent ev(fileNames);
246    
247     fwlite::Handle< reco::BeamSpot > bsHandle;
248     fwlite::Handle< vector<reco::Vertex> > pvHandle;
249     //
250     // create list of runs with > 100 PVs
251     //
252     RunNumberMap runNumberCounts;
253     int lastRun(0);
254     for( ev.toBegin(); !ev.atEnd(); ++ev) {
255     unsigned int run = ev.id().run();
256     pvHandle.getByLabel(ev,"offlinePrimaryVertices");
257    
258     const reco::Vertex& pv = (*pvHandle)[0];
259     if ( pv.tracksSize()>0 && pv.ndof()>2 &&
260     (pv.ndof()+3.)/2./pv.tracksSize()>0.5 ) {
261     ++runNumberCounts[run];
262     }
263     }
264     // create list of bin indices
265     unsigned int nRun(0);
266     RunNumberMap runNumberIndices;
267     for ( RunNumberMap::iterator i=runNumberCounts.begin();
268     i!=runNumberCounts.end(); ++i ) {
269     if ( (*i).second>100 ) runNumberIndices[(*i).first] = nRun++;
270     }
271     cout << "Found " << nRun << " run numbers" << endl;
272     //
273     // create histograms
274     //
275     TDirectory* saveDir = gDirectory;
276     gROOT->cd();
277     TH2* pvxVsRun = new TH2F("pvxVsRun","pvxVsRun",nRun,-0.5,nRun-0.5,80,-0.1,0.3);
278     TH2* pvyVsRun = new TH2F("pvyVsRun","pvyVsRun",nRun,-0.5,nRun-0.5,80,-0.2,0.2);
279     TH2* pvzVsRun = new TH2F("pvzVsRun","pvzVsRun",nRun,-0.5,nRun-0.5,80,-20,20);
280     TH2* bsxVsRun = new TH2F("bsxVsRun","bsxVsRun",nRun,-0.5,nRun-0.5,80,0,0.4);
281     TH2* bsyVsRun = new TH2F("bsyVsRun","bsyVsRun",nRun,-0.5,nRun-0.5,80,0,0.4);
282     TH2* bszVsRun = new TH2F("bszVsRun","bszVsRun",nRun,-0.5,nRun-0.5,80,-20,20);
283     TH1* bsxVsRunMean = new TH1F("bsxVsRunMean","bsxVsRunMean",nRun,-0.5,nRun-0.5);
284     TH1* bsyVsRunMean = new TH1F("bsyVsRunMean","bsyVsRunMean",nRun,-0.5,nRun-0.5);
285     TH1* bszVsRunMean = new TH1F("bszVsRunMean","bszVsRunMean",nRun,-0.5,nRun-0.5);
286     saveDir->cd();
287    
288     //
289     // fill histograms
290     //
291     lastRun = -1;
292     int idx(-1);
293     int nev(0);
294     for( ev.toBegin(); !ev.atEnd(); ++ev) {
295     int run = ev.id().run();
296     // if ( (++nev)%1000 == 0 ) cout << "processing record " << nev << " ( run "
297     // << ev.id().run() << " " << " evt "
298     // << ev.id().event() << " )" << endl;
299     //
300     // update bin index if run changed
301     //
302     if ( run!=lastRun ) {
303     RunNumberMap::const_iterator irun = runNumberIndices.find(run);
304     if ( irun == runNumberIndices.end() ) {
305     idx = -1;
306     }
307     else {
308     idx = (*irun).second;
309     }
310     lastRun = run;
311     // cout << "Run " << run << " idx " << idx << endl;
312     }
313     if ( idx<0 ) continue;
314    
315     //
316     // retrieve beam spot and PV
317     //
318     bsHandle.getByLabel(ev,"offlineBeamSpot");
319     pvHandle.getByLabel(ev,"offlinePrimaryVertices");
320     //
321     // fill PV histograms (after quality cut)
322     //
323     const reco::Vertex& pv = (*pvHandle)[0];
324     if ( pv.tracksSize()>0 && pv.ndof()>2 &&
325     (pv.ndof()+3.)/2./pv.tracksSize()>0.5 ) {
326     pvxVsRun->Fill(idx,pv.x());
327     pvyVsRun->Fill(idx,pv.y());
328     pvzVsRun->Fill(idx,pv.z());
329     }
330     //
331     // fill BS histograms
332     //
333     bsxVsRun->Fill(idx,bsHandle->x0());
334     bsyVsRun->Fill(idx,bsHandle->y0());
335     bszVsRun->Fill(idx,bsHandle->z0());
336     if ( idx>=0 && idx<bsxVsRun->GetNbinsX() ) {
337     // assume BS is constant / run: fill current value into 1d histogram
338     bsxVsRunMean->SetBinContent(idx+1,bsHandle->x0());
339     bsxVsRunMean->SetBinError(idx+1,bsHandle->x0Error());
340     bsyVsRunMean->SetBinContent(idx+1,bsHandle->y0());
341     bsyVsRunMean->SetBinError(idx+1,bsHandle->y0Error());
342     bszVsRunMean->SetBinContent(idx+1,bsHandle->z0());
343     bszVsRunMean->SetBinError(idx+1,bsHandle->z0Error());
344     }
345    
346     }
347     saveDir = gDirectory;
348     //
349     // number of entries / run
350     //
351     gROOT->cd();
352     TH1* npvVsRun = pvzVsRun->ProjectionX("npvVsRun");
353     npvVsRun->SetTitle("npvVsRun");
354     TH1* nbsVsRun = bszVsRun->ProjectionX("nbsVsRun");
355     npvVsRun->SetTitle("nbsVsRun");
356     saveDir->cd();
357     //
358     // set run numbers on x-axis labels
359     //
360     setRunNumberLabels(npvVsRun,runNumberIndices);
361     setRunNumberLabels(pvxVsRun,runNumberIndices);
362     setRunNumberLabels(pvyVsRun,runNumberIndices);
363     setRunNumberLabels(pvzVsRun,runNumberIndices);
364     setRunNumberLabels(nbsVsRun,runNumberIndices);
365     setRunNumberLabels(bsxVsRun,runNumberIndices);
366     setRunNumberLabels(bsyVsRun,runNumberIndices);
367     setRunNumberLabels(bszVsRun,runNumberIndices);
368     setRunNumberLabels(bsxVsRunMean,runNumberIndices);
369     setRunNumberLabels(bsyVsRunMean,runNumberIndices);
370     setRunNumberLabels(bszVsRunMean,runNumberIndices);
371     //
372     // fit histograms
373     //
374     TH1* pvxMean; TH1* pvxWidth;
375     fitRunHistogram(pvxVsRun,pvxMean,pvxWidth);
376     TH1* pvyMean; TH1* pvyWidth;
377     fitRunHistogram(pvyVsRun,pvyMean,pvyWidth);
378     TH1* pvzMean; TH1* pvzWidth;
379     fitRunHistogram(pvzVsRun,pvzMean,pvzWidth);
380    
381     // cout << pvxMean << endl;
382     // cout << pvxMean->GetNbinsX() << " " << pvxMean->GetXaxis() << endl;
383     //
384     // summary table
385     //
386     for ( unsigned int i=1; i<=pvxMean->GetNbinsX(); ++i ) {
387     if ( pvxMean->GetBinError(i)>1.e-10 ||
388     pvxMean->GetBinError(i)>1.e-10 ||
389     pvxMean->GetBinError(i)>1.e-10 ) {
390     printf(" %-6s : %8.4f +- %6.4f %6.4f +- %6.4f %8.4f +- %6.4f %6.4f +- %6.4f %9.4f +- %7.4f %6.4f +- %7.4f\n",
391     pvxMean->GetXaxis()->GetBinLabel(i),
392     pvxMean->GetBinContent(i),pvxMean->GetBinError(i),
393     pvxWidth->GetBinContent(i),pvxWidth->GetBinError(i),
394     pvyMean->GetBinContent(i),pvyMean->GetBinError(i),
395     pvyWidth->GetBinContent(i),pvyWidth->GetBinError(i),
396     pvzMean->GetBinContent(i),pvzMean->GetBinError(i),
397     pvzWidth->GetBinContent(i),pvzWidth->GetBinError(i));
398     }
399     }
400    
401     //
402     // save histograms
403     //
404     TFile* fo = new TFile("../skim_BSC0_AND_40OR41_MinBias_Dec19th_v1.root","recreate");
405     pvxVsRun->Write();
406     pvyVsRun->Write();
407     pvzVsRun->Write();
408     pvxMean->Write();
409     pvxWidth->Write();
410     pvyMean->Write();
411     pvyWidth->Write();
412     pvzMean->Write();
413     pvzWidth->Write();
414     fo->Write();
415     delete fo;
416    
417     plotPvVsBs();
418     //
419     // plot inidividual histograms / run
420     //
421     // for ( RunNumberMap::iterator i=runNumberIndices.begin();
422     // i!=runNumberIndices.end(); ++i ) {
423     // plotRun('x',(*i).first);
424     // plotRun('y',(*i).first);
425     // plotRun('z',(*i).first);
426     // }
427    
428     }
429     //
430     // call with single file name
431     //
432     void pvHistory (const char* fileName) {
433     vector<string> fileNames(1,fileName);
434     pvHistory(fileNames);
435     }