]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG0/dNdEta/dNdEtaAnalysis.cxx
added new enum that describes the type of analysis, passed to all analysis classes
[u/mrichter/AliRoot.git] / PWG0 / dNdEta / dNdEtaAnalysis.cxx
CommitLineData
dc740de4 1/* $Id$ */
2
75ec0f41 3#include "dNdEtaAnalysis.h"
4
ceb5d1b5 5#include <TFile.h>
45e97e28 6#include <TH3F.h>
74fd10b3 7#include <TH2F.h>
8#include <TH1F.h>
ceb5d1b5 9#include <TMath.h>
10#include <TCanvas.h>
7029240a 11#include <TCollection.h>
12#include <TIterator.h>
13#include <TList.h>
fcf2fb36 14#include <TLegend.h>
74fd10b3 15#include <TLine.h>
fcf2fb36 16
45e97e28 17#include "AlidNdEtaCorrection.h"
74fd10b3 18#include <AliCorrection.h>
19#include <AliPWG0Helper.h>
20#include <AliCorrectionMatrix2D.h>
21#include <AliCorrectionMatrix3D.h>
ceb5d1b5 22
75ec0f41 23//____________________________________________________________________
b7f4a1fd 24ClassImp(dNdEtaAnalysis)
75ec0f41 25
1afae8ff 26//____________________________________________________________________
27dNdEtaAnalysis::dNdEtaAnalysis() :
28 TNamed(),
29 fData(0),
1afae8ff 30 fPtDist(0)
31{
32 // default constructor
33
34 for (Int_t i=0; i<kVertexBinning; ++i)
35 {
36 fdNdEta[i] = 0;
37 fdNdEtaPtCutOffCorrected[i] = 0;
38 }
39}
40
75ec0f41 41//____________________________________________________________________
770a1f1d 42dNdEtaAnalysis::dNdEtaAnalysis(Char_t* name, Char_t* title, AliPWG0Helper::AnalysisMode analysisMode) :
16e24ca3 43 TNamed(name, title),
45e97e28 44 fData(0),
1afae8ff 45 fPtDist(0)
7029240a 46{
6bf0714d 47 // constructor
4dd2ad81 48
0f67a57c 49 // TODO this binning has to be the same than in AliCorrection, somehow passed?!
74fd10b3 50 Float_t binLimitsPt[] = {0.0, 0.05, 0.1, 0.125, 0.15, 0.175, 0.2, 0.225, 0.25, 0.275, 0.3, 0.325, 0.35, 0.375, 0.4, 0.425, 0.45, 0.475, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.5, 2.0, 5.0, 10.0, 100.0};
6bf0714d 51
770a1f1d 52 fData = new AliCorrection("Analysis", Form("%s Analysis", title), analysisMode);
45e97e28 53
74fd10b3 54 // do not add this hists to the directory
55 Bool_t oldStatus = TH1::AddDirectoryStatus();
56 TH1::AddDirectory(kFALSE);
1afae8ff 57
0448e811 58 fdNdEta[0] = new TH1F("dNdEta", "dN_{ch}/d#eta;#eta;dN_{ch}/d#eta", 40, -2, 2);
74fd10b3 59
60 fdNdEtaPtCutOffCorrected[0] = dynamic_cast<TH1F*> (fdNdEta[0]->Clone(Form("%s_corrected", fdNdEta[0]->GetName())));
1afae8ff 61
45e97e28 62 for (Int_t i=1; i<kVertexBinning; ++i)
7029240a 63 {
74fd10b3 64 fdNdEta[i] = dynamic_cast<TH1F*> (fdNdEta[0]->Clone(Form("%s_%d", fdNdEta[0]->GetName(), i)));
65 fdNdEtaPtCutOffCorrected[i] = dynamic_cast<TH1F*> (fdNdEtaPtCutOffCorrected[0]->Clone(Form("%s_%d", fdNdEtaPtCutOffCorrected[0]->GetName(), i)));
7029240a 66 }
75ec0f41 67
74fd10b3 68 fPtDist = new TH1F("Pt", "p_{T} distribution;p_{T} [GeV/c];#frac{dN}{d#eta dp_{T}} [c/GeV]", 28, binLimitsPt);
69
70 TH1::AddDirectory(oldStatus);
75ec0f41 71}
72
16e24ca3 73//____________________________________________________________________
74dNdEtaAnalysis::~dNdEtaAnalysis()
75{
76 // destructor
77
0ab29cfa 78 if (fData)
79 {
80 delete fData;
81 fData = 0;
82 }
16e24ca3 83
16e24ca3 84 for (Int_t i=0; i<kVertexBinning; ++i)
85 {
0ab29cfa 86 if (fdNdEta[i])
87 {
88 delete fdNdEta[i];
89 fdNdEta[i] = 0;
90 }
91 if (fdNdEtaPtCutOffCorrected[i])
92 {
93 delete fdNdEtaPtCutOffCorrected[i];
94 fdNdEtaPtCutOffCorrected[i] = 0;
95 }
16e24ca3 96 }
1afae8ff 97
0ab29cfa 98 if (fPtDist)
99 {
100 delete fPtDist;
101 fPtDist = 0;
102 }
16e24ca3 103}
104
105//_____________________________________________________________________________
106dNdEtaAnalysis::dNdEtaAnalysis(const dNdEtaAnalysis &c) :
107 TNamed(c),
45e97e28 108 fData(0),
1afae8ff 109 fPtDist(0)
16e24ca3 110{
111 //
112 // dNdEtaAnalysis copy constructor
113 //
114
115 ((dNdEtaAnalysis &) c).Copy(*this);
116}
117
118//_____________________________________________________________________________
119dNdEtaAnalysis &dNdEtaAnalysis::operator=(const dNdEtaAnalysis &c)
120{
121 //
122 // Assignment operator
123 //
124
125 if (this != &c) ((dNdEtaAnalysis &) c).Copy(*this);
126 return *this;
127}
128
129//_____________________________________________________________________________
130void dNdEtaAnalysis::Copy(TObject &c) const
131{
132 //
133 // Copy function
134 //
135
136 dNdEtaAnalysis& target = (dNdEtaAnalysis &) c;
137
74fd10b3 138 target.fData = dynamic_cast<AliCorrection*> (fData->Clone());
16e24ca3 139
140 for (Int_t i=0; i<kVertexBinning; ++i)
1afae8ff 141 {
74fd10b3 142 target.fdNdEta[i] = dynamic_cast<TH1F*> (fdNdEta[i]->Clone());
143 target.fdNdEtaPtCutOffCorrected[i] = dynamic_cast<TH1F*> (fdNdEtaPtCutOffCorrected[i]->Clone());
1afae8ff 144 }
16e24ca3 145
74fd10b3 146 target.fPtDist = dynamic_cast<TH1F*> (fPtDist->Clone());
45e97e28 147
16e24ca3 148 TNamed::Copy((TNamed &) c);
149}
150
75ec0f41 151//____________________________________________________________________
74fd10b3 152void dNdEtaAnalysis::FillTrack(Float_t vtx, Float_t eta, Float_t pt)
6bf0714d 153{
154 // fills a track into the histograms
155
74fd10b3 156 fData->GetTrackCorrection()->FillMeas(vtx, eta, pt);
75ec0f41 157}
158
159//____________________________________________________________________
74fd10b3 160void dNdEtaAnalysis::FillEvent(Float_t vtx, Float_t n)
6bf0714d 161{
162 // fills an event into the histograms
163
74fd10b3 164 fData->GetEventCorrection()->FillMeas(vtx, n);
75ec0f41 165}
166
167//____________________________________________________________________
74fd10b3 168void dNdEtaAnalysis::Finish(AlidNdEtaCorrection* correction, Float_t ptCut, AlidNdEtaCorrection::CorrectionType correctionType)
fcf2fb36 169{
74fd10b3 170 //
171 // correct with the given correction values and calculate dNdEta and pT distribution
172 // the corrections that are applied can be steered by the flag correctionType
173 //
174
175 // TODO put tag somewhere which corrections have been applied
176
177 // set corrections to 1
178 fData->SetCorrectionToUnity();
179
180 if (correction && correctionType != AlidNdEtaCorrection::kNone)
181 {
182 TH3F* trackCorr = fData->GetTrackCorrection()->GetCorrectionHistogram();
183 TH2F* eventCorr = fData->GetEventCorrection()->GetCorrectionHistogram();
184
185 if (correctionType >= AlidNdEtaCorrection::kTrack2Particle)
186 trackCorr->Multiply(correction->GetTrack2ParticleCorrection()->GetTrackCorrection()->GetCorrectionHistogram());
6bf0714d 187
dd367a14 188 if (correctionType >= AlidNdEtaCorrection::kVertexReco)
74fd10b3 189 {
190 trackCorr->Multiply(correction->GetVertexRecoCorrection()->GetTrackCorrection()->GetCorrectionHistogram());
191 eventCorr->Multiply(correction->GetVertexRecoCorrection()->GetEventCorrection()->GetCorrectionHistogram());
dd367a14 192 }
74fd10b3 193
194 switch (correctionType)
195 {
196 case AlidNdEtaCorrection::kINEL :
197 {
198 trackCorr->Multiply(correction->GetTriggerBiasCorrectionINEL()->GetTrackCorrection()->GetCorrectionHistogram());
199 eventCorr->Multiply(correction->GetTriggerBiasCorrectionINEL()->GetEventCorrection()->GetCorrectionHistogram());
200 break;
201 }
202 case AlidNdEtaCorrection::kNSD :
203 {
204 trackCorr->Multiply(correction->GetTriggerBiasCorrectionNSD()->GetTrackCorrection()->GetCorrectionHistogram());
205 eventCorr->Multiply(correction->GetTriggerBiasCorrectionNSD()->GetEventCorrection()->GetCorrectionHistogram());
206 break;
207 }
208 case AlidNdEtaCorrection::kND :
209 {
210 trackCorr->Multiply(correction->GetTriggerBiasCorrectionND()->GetTrackCorrection()->GetCorrectionHistogram());
211 eventCorr->Multiply(correction->GetTriggerBiasCorrectionND()->GetEventCorrection()->GetCorrectionHistogram());
212 break;
213 }
214 default : break;
215 }
216 }
217 else
fcf2fb36 218 printf("INFO: No correction applied\n");
219
74fd10b3 220 fData->Multiply();
221
222 TH3F* dataHist = fData->GetTrackCorrection()->GetGeneratedHistogram();
223
224 // integrate multiplicity axis out (include under/overflow bins!!!)
225 TH2F* tmp = fData->GetEventCorrection()->GetGeneratedHistogram();
226 TH1D* vertexHist = tmp->ProjectionX("_px", 0, tmp->GetNbinsY() + 1, "e");
fcf2fb36 227
1afae8ff 228 // create pt hist
229 {
230 // reset all ranges
74fd10b3 231 dataHist->GetXaxis()->SetRange(0, 0);
232 dataHist->GetYaxis()->SetRange(0, 0);
233 dataHist->GetZaxis()->SetRange(0, 0);
1afae8ff 234
235 // vtx cut
74fd10b3 236 Int_t vertexBinBegin = dataHist->GetXaxis()->FindBin(-5);
237 Int_t vertexBinEnd = dataHist->GetXaxis()->FindBin(5);
238 dataHist->GetXaxis()->SetRange(vertexBinBegin, vertexBinEnd);
239 Float_t nEvents = vertexHist->Integral(vertexBinBegin, vertexBinEnd);
1afae8ff 240
74fd10b3 241 if (nEvents > 0)
242 {
243 // eta cut
244 dataHist->GetYaxis()->SetRange(dataHist->GetYaxis()->FindBin(-0.8), dataHist->GetYaxis()->FindBin(0.8));
245 Float_t etaWidth = 1.6;
1afae8ff 246
74fd10b3 247 TH1D* ptHist = dynamic_cast<TH1D*> (dataHist->Project3D("ze"));
1afae8ff 248
74fd10b3 249 for (Int_t i=1; i<=fPtDist->GetNbinsX(); ++i)
250 {
251 Float_t binSize = fPtDist->GetBinWidth(i);
252 fPtDist->SetBinContent(i, ptHist->GetBinContent(i) / binSize / nEvents / etaWidth);
253 fPtDist->SetBinError(i, ptHist->GetBinError(i) / binSize / nEvents / etaWidth);
254 }
1afae8ff 255
74fd10b3 256 delete ptHist;
257 }
258 else
259 printf("ERROR: nEvents is 0!\n");
1afae8ff 260 }
261
262 // reset all ranges
74fd10b3 263 dataHist->GetXaxis()->SetRange(0, 0);
264 dataHist->GetYaxis()->SetRange(0, 0);
265 dataHist->GetZaxis()->SetRange(0, 0);
1afae8ff 266
847489f7 267 // integrate over pt (with pt cut)
1afae8ff 268 Int_t ptLowBin = 1;
269 if (ptCut > 0)
74fd10b3 270 ptLowBin = dataHist->GetZaxis()->FindBin(ptCut);
1afae8ff 271
74fd10b3 272 dataHist->GetZaxis()->SetRange(ptLowBin, dataHist->GetZaxis()->GetNbins());
273 printf("range %d %d\n", ptLowBin, dataHist->GetZaxis()->GetNbins());
274 TH2D* vtxVsEta = dynamic_cast<TH2D*> (dataHist->Project3D("yx2e"));
275
276 dataHist->GetZaxis()->SetRange(0, 0);
277 vtxVsEta->GetXaxis()->SetTitle(dataHist->GetXaxis()->GetTitle());
278 vtxVsEta->GetYaxis()->SetTitle(dataHist->GetYaxis()->GetTitle());
1afae8ff 279
847489f7 280 if (vtxVsEta == 0)
281 {
282 printf("ERROR: pt integration failed\n");
283 return;
fcf2fb36 284 }
285
144ff489 286 //new TCanvas; vtxVsEta->DrawCopy();
287 //vtxVsEta->Rebin2D(1, 4);
288
0448e811 289 const Float_t vertexRange = 9.99;
b4b9cacc 290
74fd10b3 291 for (Int_t iEta=1; iEta<=vtxVsEta->GetNbinsY(); iEta++)
5af55649 292 {
7029240a 293 // do we have several histograms for different vertex positions?
b4b9cacc 294 Int_t vertexBinGlobalBegin = vertexHist->GetXaxis()->FindBin(-vertexRange);
295 Int_t vertexBinWidth = (vertexHist->GetXaxis()->FindBin(vertexRange) - vertexBinGlobalBegin + 1) / (kVertexBinning-1);
296 //printf("vertexBinGlobalBegin = %d, vertexBinWidth = %d\n", vertexBinGlobalBegin, vertexBinWidth);
7029240a 297 for (Int_t vertexPos=0; vertexPos<kVertexBinning; ++vertexPos)
298 {
2e88424e 299
b4b9cacc 300 Int_t vertexBinBegin = vertexBinGlobalBegin;
2e88424e 301 Int_t vertexBinEnd = vertexBinGlobalBegin + vertexBinWidth * (kVertexBinning-1);
fcf2fb36 302
303 // the first histogram is always for the whole vertex range
304 if (vertexPos > 0)
305 {
b4b9cacc 306 vertexBinBegin = vertexBinGlobalBegin + vertexBinWidth * (vertexPos-1);
fcf2fb36 307 vertexBinEnd = vertexBinBegin + vertexBinWidth;
308 }
7029240a 309
b4b9cacc 310 //printf("vertexBinBegin = %d, vertexBinEnd = %d\n", vertexBinBegin, vertexBinEnd);
311
74fd10b3 312 Float_t totalEvents = vertexHist->Integral(vertexBinBegin, vertexBinEnd - 1);
5af55649 313 if (totalEvents == 0)
314 {
315 printf("WARNING: No events for hist %d %d %d\n", vertexPos, vertexBinBegin, vertexBinEnd);
316 continue;
7029240a 317 }
7029240a 318
5af55649 319 Float_t sum = 0;
320 Float_t sumError2 = 0;
321 for (Int_t iVtx = vertexBinBegin; iVtx < vertexBinEnd; iVtx++)
2e88424e 322 {
144ff489 323 if (vtxVsEta->GetBinContent(iVtx, iEta) != 0)
5af55649 324 {
847489f7 325 sum = sum + vtxVsEta->GetBinContent(iVtx, iEta);
2e88424e 326
144ff489 327 if (sumError2 > 10e30)
328 printf("WARNING: sum of error2 is dangerously large - be prepared for crash... ");
2e88424e 329
847489f7 330 sumError2 = sumError2 + TMath::Power(vtxVsEta->GetBinError(iVtx, iEta),2);
5af55649 331 }
332 }
7029240a 333
1afae8ff 334 Float_t ptCutOffCorrection = 1;
74fd10b3 335 if (correction && ptCut > 0)
336 ptCutOffCorrection = correction->GetMeasuredFraction(correctionType, ptCut, vtxVsEta->GetYaxis()->GetBinCenter(iEta));
1afae8ff 337
847489f7 338 if (ptCutOffCorrection <= 0)
339 {
340 printf("UNEXPECTED: ptCutOffCorrection is %f for hist %d %d %d\n", ptCutOffCorrection, vertexPos, vertexBinBegin, vertexBinEnd);
341 continue;
342 }
343
9e952c39 344 //printf("Eta: %d Vertex Range: %d %d, Event Count %f, Track Sum: %f, Track Sum corrected: %f\n", iEta, vertexBinBegin, vertexBinEnd, totalEvents, sum, sum / ptCutOffCorrection);
345
144ff489 346 Int_t bin = fdNdEta[vertexPos]->FindBin(vtxVsEta->GetYaxis()->GetBinCenter(iEta));
347 if (bin > 0 && bin < fdNdEta[vertexPos]->GetNbinsX())
348 {
349 Float_t dndeta = sum / totalEvents;
350 Float_t error = TMath::Sqrt(sumError2) / totalEvents;
7029240a 351
144ff489 352 dndeta = dndeta / fdNdEta[vertexPos]->GetBinWidth(bin);
353 error = error / fdNdEta[vertexPos]->GetBinWidth(bin);
7029240a 354
144ff489 355 fdNdEta[vertexPos]->SetBinContent(bin, dndeta);
356 fdNdEta[vertexPos]->SetBinError(bin, error);
1afae8ff 357
144ff489 358 dndeta /= ptCutOffCorrection;
359 error /= ptCutOffCorrection;
1afae8ff 360
144ff489 361 fdNdEtaPtCutOffCorrected[vertexPos]->SetBinContent(bin, dndeta);
362 fdNdEtaPtCutOffCorrected[vertexPos]->SetBinError(bin, error);
2e88424e 363
dd367a14 364 //Printf("Bin %d has dN/deta = %f", bin, dndeta);
144ff489 365 }
75ec0f41 366 }
847489f7 367 }
144ff489 368
dd367a14 369 //new TCanvas; fdNdEta[0]->DrawCopy();
75ec0f41 370}
371
75ec0f41 372//____________________________________________________________________
6bf0714d 373void dNdEtaAnalysis::SaveHistograms()
374{
375 // save the histograms to a directory with the name of this class (retrieved from TNamed)
75ec0f41 376
7029240a 377 gDirectory->mkdir(GetName());
378 gDirectory->cd(GetName());
5fbd0b17 379
1afae8ff 380 if (fData)
381 {
74fd10b3 382 fData->SaveHistograms();
1afae8ff 383 }
384 else
385 printf("dNdEtaAnalysis::SaveHistograms: UNEXPECTED: fData is 0\n");
386
d09fb536 387 if (fPtDist)
388 fPtDist ->Write();
389 else
390 printf("dNdEtaAnalysis::SaveHistograms: UNEXPECTED: fPtDist is 0\n");
391
7029240a 392 for (Int_t i=0; i<kVertexBinning; ++i)
1afae8ff 393 {
394 if (fdNdEta[i])
395 fdNdEta[i]->Write();
396 else
397 printf("dNdEtaAnalysis::SaveHistograms: UNEXPECTED: fdNdEta[%d] is 0\n", i);
398
399 if (fdNdEtaPtCutOffCorrected[i])
400 fdNdEtaPtCutOffCorrected[i]->Write();
401 else
402 printf("dNdEtaAnalysis::SaveHistograms: UNEXPECTED: fdNdEtaPtCutOffCorrected[%d] is 0\n", i);
403 }
75ec0f41 404
405 gDirectory->cd("../");
406}
407
74fd10b3 408void dNdEtaAnalysis::LoadHistograms(const Char_t* dir)
5fbd0b17 409{
6bf0714d 410 // loads the histograms from a directory with the name of this class (retrieved from TNamed)
411
74fd10b3 412 if (!dir)
413 dir = GetName();
5fbd0b17 414
74fd10b3 415 gDirectory->cd(dir);
5fbd0b17 416
74fd10b3 417 fData->LoadHistograms();
5fbd0b17 418
419 for (Int_t i=0; i<kVertexBinning; ++i)
1afae8ff 420 {
74fd10b3 421 fdNdEta[i] = dynamic_cast<TH1F*> (gDirectory->Get(fdNdEta[i]->GetName()));
422 fdNdEtaPtCutOffCorrected[i] = dynamic_cast<TH1F*> (gDirectory->Get(fdNdEtaPtCutOffCorrected[i]->GetName()));
1afae8ff 423 }
5fbd0b17 424
74fd10b3 425 fPtDist = dynamic_cast<TH1F*> (gDirectory->Get(fPtDist->GetName()));
0ab29cfa 426
5fbd0b17 427 gDirectory->cd("../");
428}
429
ceb5d1b5 430//____________________________________________________________________
74fd10b3 431void dNdEtaAnalysis::DrawHistograms(Bool_t simple)
ceb5d1b5 432{
6bf0714d 433 // draws the histograms
74fd10b3 434
435 if (!simple)
436 {
437 if (fData)
438 fData->DrawHistograms(GetName());
6bf0714d 439
74fd10b3 440 TCanvas* canvas = new TCanvas(Form("%s_dNdEtaAnalysis", GetName()), Form("%s_dNdEtaAnalysis", GetName()), 800, 400);
441 canvas->Divide(2, 1);
ceb5d1b5 442
74fd10b3 443 canvas->cd(1);
444 if (fdNdEtaPtCutOffCorrected[0])
144ff489 445 fdNdEtaPtCutOffCorrected[0]->DrawCopy();
ceb5d1b5 446
74fd10b3 447 if (fdNdEta[0])
448 {
449 fdNdEta[0]->SetLineColor(kRed);
144ff489 450 fdNdEta[0]->DrawCopy("SAME");
74fd10b3 451 }
1afae8ff 452
74fd10b3 453 canvas->cd(2);
454 if (fPtDist)
144ff489 455 fPtDist->DrawCopy();
1afae8ff 456 }
457
fcf2fb36 458 // histograms for different vertices?
459 if (kVertexBinning > 0)
460 {
461 // doesnt work, but i dont get it, giving up...
74fd10b3 462 TCanvas* canvas2 = new TCanvas(Form("%s_dNdEtaAnalysisVtx", GetName()), Form("%s_dNdEtaAnalysisVtx", GetName()), 450, 450);
463 TCanvas* canvas3 = 0;
464 if (!simple)
465 canvas3 = new TCanvas(Form("%s_dNdEtaAnalysisVtx_noptcutoff", GetName()), Form("%s_dNdEtaAnalysisVtx_noptcutoff", GetName()), 450, 450);
466
fcf2fb36 467 //Int_t yPads = (Int_t) TMath::Ceil(((Double_t) kVertexBinning - 1) / 2);
468 //printf("%d\n", yPads);
469 //canvas2->Divide(2, yPads);
470
0448e811 471 TLegend* legend = new TLegend(0.4, 0.2, 0.6, 0.4);
fcf2fb36 472
5af55649 473 for (Int_t i=0; i<kVertexBinning; ++i)
fcf2fb36 474 {
1afae8ff 475 if (fdNdEtaPtCutOffCorrected[i])
fcf2fb36 476 {
74fd10b3 477 canvas2->cd();
478
1afae8ff 479 fdNdEtaPtCutOffCorrected[i]->SetLineColor(i+1);
144ff489 480 fdNdEtaPtCutOffCorrected[i]->DrawCopy((i == 0) ? "" : "SAME");
1afae8ff 481 legend->AddEntry(fdNdEtaPtCutOffCorrected[i], (i == 0) ? "Vtx All" : Form("Vtx Bin %d", i-1));
fcf2fb36 482 }
74fd10b3 483 if (canvas3 && fdNdEta[i])
484 {
485 canvas3->cd();
486
487 fdNdEta[i]->SetLineColor(i+1);
144ff489 488 fdNdEta[i]->DrawCopy((i == 0) ? "" : "SAME");
74fd10b3 489 }
fcf2fb36 490 }
491
74fd10b3 492 canvas2->cd();
fcf2fb36 493 legend->Draw();
74fd10b3 494 canvas2->SaveAs(Form("%s_%s.gif", canvas2->GetName(), GetName()));
495
496 if (canvas3)
497 {
498 canvas3->cd();
499 legend->Draw();
500 }
fcf2fb36 501 }
74fd10b3 502
503 if (kVertexBinning == 3)
504 {
505 TH1* clone = dynamic_cast<TH1*> (fdNdEtaPtCutOffCorrected[1]->Clone("clone"));
506 TH1* clone2 = dynamic_cast<TH1*> (fdNdEtaPtCutOffCorrected[2]->Clone("clone2"));
507
508 if (clone && clone2)
509 {
510 TCanvas* canvas4 = new TCanvas(Form("%s_dNdEtaAnalysisVtxRatios", GetName()), Form("%s_dNdEtaAnalysisVtxRatios", GetName()), 450, 450);
511
512 clone->Divide(fdNdEtaPtCutOffCorrected[0]);
513 clone->GetYaxis()->SetRangeUser(0.95, 1.05);
144ff489 514 clone->DrawCopy();
74fd10b3 515
516 clone2->Divide(fdNdEtaPtCutOffCorrected[0]);
144ff489 517 clone2->DrawCopy("SAME");
74fd10b3 518
519 TLine* line = new TLine(-1, 1, 1, 1);
520 line->Draw();
521
522 canvas4->SaveAs(Form("%s_%s.gif", canvas4->GetName(), GetName()));
523 }
524 }
7029240a 525}
526
527Long64_t dNdEtaAnalysis::Merge(TCollection* list)
528{
529 // Merges a list of dNdEtaAnalysis objects with this one.
530 // This is needed for PROOF.
531 // Returns the number of merged objects (including this)
532
533 if (!list)
534 return 0;
535
536 if (list->IsEmpty())
537 return 1;
538
539 TIterator* iter = list->MakeIterator();
540 TObject* obj;
541
542 // sub collections
74fd10b3 543 const Int_t nCollections = 2 * kVertexBinning + 2; // 2 standalone hists, two arrays of size kVertexBinning
7029240a 544 TList* collections[nCollections];
545 for (Int_t i=0; i<nCollections; ++i)
546 collections[i] = new TList;
547
548 Int_t count = 0;
549 while ((obj = iter->Next()))
550 {
551 dNdEtaAnalysis* entry = dynamic_cast<dNdEtaAnalysis*> (obj);
552 if (entry == 0)
553 continue;
554
45e97e28 555 collections[0]->Add(entry->fData);
74fd10b3 556 collections[1]->Add(entry->fPtDist);
7029240a 557
558 for (Int_t i=0; i<kVertexBinning; ++i)
1afae8ff 559 {
74fd10b3 560 collections[2+i]->Add(entry->fdNdEta[i]);
561 collections[2+kVertexBinning+i]->Add(entry->fdNdEtaPtCutOffCorrected[i]);
1afae8ff 562 }
7029240a 563
564 ++count;
565 }
566
45e97e28 567 fData->Merge(collections[0]);
74fd10b3 568 fPtDist->Merge(collections[1]);
7029240a 569 for (Int_t i=0; i<kVertexBinning; ++i)
1afae8ff 570 {
74fd10b3 571 fdNdEta[i]->Merge(collections[2+i]);
572 fdNdEta[i]->Merge(collections[2+kVertexBinning+i]);
1afae8ff 573 }
7029240a 574
575 for (Int_t i=0; i<nCollections; ++i)
576 delete collections[i];
577
578 return count+1;
ceb5d1b5 579}