3 #include "dNdEtaAnalysis.h"
11 #include <TCollection.h>
12 #include <TIterator.h>
17 #include "AlidNdEtaCorrection.h"
18 #include <AliCorrection.h>
19 #include <AliPWG0Helper.h>
20 #include <AliCorrectionMatrix2D.h>
21 #include <AliCorrectionMatrix3D.h>
23 //____________________________________________________________________
24 ClassImp(dNdEtaAnalysis)
26 //____________________________________________________________________
27 dNdEtaAnalysis::dNdEtaAnalysis() :
33 // default constructor
35 for (Int_t i=0; i<kVertexBinning; ++i)
38 fdNdEtaPtCutOffCorrected[i] = 0;
42 //____________________________________________________________________
43 dNdEtaAnalysis::dNdEtaAnalysis(Char_t* name, Char_t* title, AliPWG0Helper::AnalysisMode analysisMode) :
51 // TODO this binning has to be the same than in AliCorrection, somehow passed?!
52 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};
54 fData = new AliCorrection("Analysis", Form("%s Analysis", title), analysisMode);
56 // do not add this hists to the directory
57 Bool_t oldStatus = TH1::AddDirectoryStatus();
58 TH1::AddDirectory(kFALSE);
60 fMult = new TH1F("TriggeredMultiplicity", "Triggered Events;raw multiplicity;entries", 1000, -0.5, 999.5);
62 fdNdEta[0] = new TH1F("dNdEta", "dN_{ch}/d#eta;#eta;dN_{ch}/d#eta", 40, -2, 2);
64 fdNdEtaPtCutOffCorrected[0] = dynamic_cast<TH1F*> (fdNdEta[0]->Clone(Form("%s_corrected", fdNdEta[0]->GetName())));
66 for (Int_t i=1; i<kVertexBinning; ++i)
68 fdNdEta[i] = dynamic_cast<TH1F*> (fdNdEta[0]->Clone(Form("%s_%d", fdNdEta[0]->GetName(), i)));
69 fdNdEtaPtCutOffCorrected[i] = dynamic_cast<TH1F*> (fdNdEtaPtCutOffCorrected[0]->Clone(Form("%s_%d", fdNdEtaPtCutOffCorrected[0]->GetName(), i)));
72 fPtDist = new TH1F("Pt", "p_{T} distribution;p_{T} [GeV/c];#frac{dN}{d#eta dp_{T}} [c/GeV]", 28, binLimitsPt);
74 TH1::AddDirectory(oldStatus);
77 //____________________________________________________________________
78 dNdEtaAnalysis::~dNdEtaAnalysis()
94 for (Int_t i=0; i<kVertexBinning; ++i)
101 if (fdNdEtaPtCutOffCorrected[i])
103 delete fdNdEtaPtCutOffCorrected[i];
104 fdNdEtaPtCutOffCorrected[i] = 0;
115 //_____________________________________________________________________________
116 dNdEtaAnalysis::dNdEtaAnalysis(const dNdEtaAnalysis &c) :
123 // dNdEtaAnalysis copy constructor
126 ((dNdEtaAnalysis &) c).Copy(*this);
129 //_____________________________________________________________________________
130 dNdEtaAnalysis &dNdEtaAnalysis::operator=(const dNdEtaAnalysis &c)
133 // Assignment operator
136 if (this != &c) ((dNdEtaAnalysis &) c).Copy(*this);
140 //_____________________________________________________________________________
141 void dNdEtaAnalysis::Copy(TObject &c) const
147 dNdEtaAnalysis& target = (dNdEtaAnalysis &) c;
149 target.fData = dynamic_cast<AliCorrection*> (fData->Clone());
150 target.fMult = dynamic_cast<TH1F*> (fMult->Clone());
152 for (Int_t i=0; i<kVertexBinning; ++i)
154 target.fdNdEta[i] = dynamic_cast<TH1F*> (fdNdEta[i]->Clone());
155 target.fdNdEtaPtCutOffCorrected[i] = dynamic_cast<TH1F*> (fdNdEtaPtCutOffCorrected[i]->Clone());
158 target.fPtDist = dynamic_cast<TH1F*> (fPtDist->Clone());
160 TNamed::Copy((TNamed &) c);
163 //____________________________________________________________________
164 void dNdEtaAnalysis::FillTrack(Float_t vtx, Float_t eta, Float_t pt)
166 // fills a track into the histograms
168 fData->GetTrackCorrection()->FillMeas(vtx, eta, pt);
171 //____________________________________________________________________
172 void dNdEtaAnalysis::FillEvent(Float_t vtx, Float_t n)
174 // fills an event into the histograms
176 fData->GetEventCorrection()->FillMeas(vtx, n);
179 //____________________________________________________________________
180 void dNdEtaAnalysis::FillTriggeredEvent(Float_t n)
182 // fills a triggered event into the histograms
187 //____________________________________________________________________
188 void dNdEtaAnalysis::Finish(AlidNdEtaCorrection* correction, Float_t ptCut, AlidNdEtaCorrection::CorrectionType correctionType, const char* tag)
191 // correct with the given correction values and calculate dNdEta and pT distribution
192 // the corrections that are applied can be steered by the flag correctionType
193 // the measured result is not used up to a multiplicity of multCut (the bin at multCut is the first that is used!)
196 // TODO put tag somewhere which corrections have been applied
198 Printf("\n\nCorrecting dN/deta spectrum >>> %s <<<. Correction type: %d, pt cut: %.2f.", tag, (Int_t) correctionType, ptCut);
200 // set corrections to 1
201 fData->SetCorrectionToUnity();
203 if (correction && correctionType != AlidNdEtaCorrection::kNone)
205 /* Printf("FAKE: Rebinning. For test only");
206 correction->GetVertexRecoCorrection()->GetEventCorrection()->Rebin(2, 1);
207 correction->GetTriggerBiasCorrectionINEL()->GetEventCorrection()->Rebin(2, 1);
208 correction->GetTriggerBiasCorrectionNSD()->GetEventCorrection()->Rebin(2, 1);
209 fData->GetEventCorrection()->Rebin(2, 1);*/
211 TH3F* trackCorr = fData->GetTrackCorrection()->GetCorrectionHistogram();
212 TH2F* eventCorr = fData->GetEventCorrection()->GetCorrectionHistogram();
214 if (correctionType >= AlidNdEtaCorrection::kTrack2Particle)
215 trackCorr->Multiply(correction->GetTrack2ParticleCorrection()->GetTrackCorrection()->GetCorrectionHistogram());
217 if (correctionType >= AlidNdEtaCorrection::kVertexReco)
219 trackCorr->Multiply(correction->GetVertexRecoCorrection()->GetTrackCorrection()->GetCorrectionHistogram());
220 eventCorr->Multiply(correction->GetVertexRecoCorrection()->GetEventCorrection()->GetCorrectionHistogram());
222 // set bin with multiplicity 0 to unity (correction has no meaning in this bin)
223 for (Int_t i=0; i<=eventCorr->GetNbinsX()+1; i++)
224 eventCorr->SetBinContent(i, 1, 1);
227 switch (correctionType)
229 case AlidNdEtaCorrection::kINEL :
231 trackCorr->Multiply(correction->GetTriggerBiasCorrectionINEL()->GetTrackCorrection()->GetCorrectionHistogram());
232 eventCorr->Multiply(correction->GetTriggerBiasCorrectionINEL()->GetEventCorrection()->GetCorrectionHistogram());
235 case AlidNdEtaCorrection::kNSD :
237 trackCorr->Multiply(correction->GetTriggerBiasCorrectionNSD()->GetTrackCorrection()->GetCorrectionHistogram());
238 eventCorr->Multiply(correction->GetTriggerBiasCorrectionNSD()->GetEventCorrection()->GetCorrectionHistogram());
241 case AlidNdEtaCorrection::kND :
243 trackCorr->Multiply(correction->GetTriggerBiasCorrectionND()->GetTrackCorrection()->GetCorrectionHistogram());
244 eventCorr->Multiply(correction->GetTriggerBiasCorrectionND()->GetEventCorrection()->GetCorrectionHistogram());
251 printf("INFO: No correction applied\n");
255 if (correctionType >= AlidNdEtaCorrection::kVertexReco)
257 // There are no events with vertex that have 0 multiplicity, therefore
258 // populate bin with 0 multiplicity with the following idea:
259 // alpha = triggered events with vertex at a given vertex position / all triggered events with vertex
260 // triggered events without vertex and 0 multiplicity at a given vertex position = alpha * all triggered events with 0 multiplicity
261 // afterwards we still correct for the trigger efficiency
263 TH2* measuredEvents = fData->GetEventCorrection()->GetMeasuredHistogram();
264 TH2* correctedEvents = fData->GetEventCorrection()->GetGeneratedHistogram();
266 //new TCanvas; correctedEvents->DrawCopy("TEXT");
268 // start above 0 mult. bin with integration
269 TH1* vertexDist = correctedEvents->ProjectionX("vertexdist_measured", 2);
270 //new TCanvas; vertexDist->DrawCopy();
272 Int_t allEventsWithVertex = (Int_t) vertexDist->Integral(0, vertexDist->GetNbinsX()+1); // include under/overflow!
273 Int_t triggeredEventsWith0Mult = (Int_t) fMult->GetBinContent(1);
275 Printf("%d triggered events with 0 mult. -- %d triggered events with vertex", triggeredEventsWith0Mult, allEventsWithVertex);
277 for (Int_t i = 1; i <= measuredEvents->GetNbinsX(); i++)
279 Double_t alpha = vertexDist->GetBinContent(i) / allEventsWithVertex;
280 Double_t events = alpha * triggeredEventsWith0Mult;
282 // multiply with trigger correction if set above
283 events *= fData->GetEventCorrection()->GetCorrectionHistogram()->GetBinContent(i, 1);
285 Printf("Bin %d, alpha is %.2f, number of events with 0 mult.: %.2f", i, alpha, events);
287 correctedEvents->SetBinContent(i, 1, events);
290 //new TCanvas; correctedEvents->DrawCopy("TEXT");
293 fData->PrintInfo(ptCut);
295 TH3F* dataHist = fData->GetTrackCorrection()->GetGeneratedHistogram();
297 // integrate multiplicity axis out (include under/overflow bins!!!)
298 TH2F* tmp = fData->GetEventCorrection()->GetGeneratedHistogram();
300 TH1D* vertexHist = (TH1D*) tmp->ProjectionX("_px", 0, tmp->GetNbinsY() + 1, "e");
305 dataHist->GetXaxis()->SetRange(0, 0);
306 dataHist->GetYaxis()->SetRange(0, 0);
307 dataHist->GetZaxis()->SetRange(0, 0);
310 Int_t vertexBinBegin = dataHist->GetXaxis()->FindBin(-5);
311 Int_t vertexBinEnd = dataHist->GetXaxis()->FindBin(5);
312 dataHist->GetXaxis()->SetRange(vertexBinBegin, vertexBinEnd);
313 Float_t nEvents = vertexHist->Integral(vertexBinBegin, vertexBinEnd);
318 dataHist->GetYaxis()->SetRange(dataHist->GetYaxis()->FindBin(-0.8), dataHist->GetYaxis()->FindBin(0.8));
319 Float_t etaWidth = 1.6;
321 TH1D* ptHist = dynamic_cast<TH1D*> (dataHist->Project3D("ze"));
323 for (Int_t i=1; i<=fPtDist->GetNbinsX(); ++i)
325 Float_t binSize = fPtDist->GetBinWidth(i);
326 fPtDist->SetBinContent(i, ptHist->GetBinContent(i) / binSize / nEvents / etaWidth);
327 fPtDist->SetBinError(i, ptHist->GetBinError(i) / binSize / nEvents / etaWidth);
333 printf("ERROR: nEvents is 0!\n");
337 dataHist->GetXaxis()->SetRange(0, 0);
338 dataHist->GetYaxis()->SetRange(0, 0);
339 dataHist->GetZaxis()->SetRange(0, 0);
341 // integrate over pt (with pt cut)
344 ptLowBin = dataHist->GetZaxis()->FindBin(ptCut);
346 dataHist->GetZaxis()->SetRange(ptLowBin, dataHist->GetZaxis()->GetNbins()+1);
347 printf("pt range %d %d\n", ptLowBin, dataHist->GetZaxis()->GetNbins()+1);
348 TH2D* vtxVsEta = dynamic_cast<TH2D*> (dataHist->Project3D("yx2e"));
350 dataHist->GetZaxis()->SetRange(0, 0);
351 vtxVsEta->GetXaxis()->SetTitle(dataHist->GetXaxis()->GetTitle());
352 vtxVsEta->GetYaxis()->SetTitle(dataHist->GetYaxis()->GetTitle());
356 printf("ERROR: pt integration failed\n");
360 //new TCanvas; vtxVsEta->DrawCopy("COLZ");
361 //vtxVsEta->Rebin2D(1, 4);
363 const Float_t vertexRange = 9.99;
365 for (Int_t iEta=1; iEta<=vtxVsEta->GetNbinsY(); iEta++)
367 // do we have several histograms for different vertex positions?
368 Int_t vertexBinGlobalBegin = vertexHist->GetXaxis()->FindBin(-vertexRange);
369 Int_t vertexBinWidth = (vertexHist->GetXaxis()->FindBin(vertexRange) - vertexBinGlobalBegin + 1) / (kVertexBinning-1);
370 //printf("vertexBinGlobalBegin = %d, vertexBinWidth = %d\n", vertexBinGlobalBegin, vertexBinWidth);
371 for (Int_t vertexPos=0; vertexPos<kVertexBinning; ++vertexPos)
373 Int_t vertexBinBegin = vertexBinGlobalBegin;
374 Int_t vertexBinEnd = vertexBinGlobalBegin + vertexBinWidth * (kVertexBinning-1);
376 // the first histogram is always for the whole vertex range
379 vertexBinBegin = vertexBinGlobalBegin + vertexBinWidth * (vertexPos-1);
380 vertexBinEnd = vertexBinBegin + vertexBinWidth;
383 //printf("vertexBinBegin = %d, vertexBinEnd = %d\n", vertexBinBegin, vertexBinEnd);
385 Float_t totalEvents = vertexHist->Integral(vertexBinBegin, vertexBinEnd - 1);
386 if (totalEvents == 0)
388 printf("WARNING: No events for hist %d %d %d\n", vertexPos, vertexBinBegin, vertexBinEnd);
393 Float_t sumError2 = 0;
394 for (Int_t iVtx = vertexBinBegin; iVtx < vertexBinEnd; iVtx++)
396 if (vtxVsEta->GetBinContent(iVtx, iEta) != 0)
398 sum = sum + vtxVsEta->GetBinContent(iVtx, iEta);
400 if (sumError2 > 10e30)
401 printf("WARNING: sum of error2 is dangerously large - be prepared for crash... ");
403 sumError2 = sumError2 + TMath::Power(vtxVsEta->GetBinError(iVtx, iEta),2);
407 Float_t ptCutOffCorrection = 1;
408 if (correction && ptCut > 0)
409 ptCutOffCorrection = correction->GetMeasuredFraction(correctionType, ptCut, vtxVsEta->GetYaxis()->GetBinCenter(iEta));
411 if (ptCutOffCorrection <= 0)
413 printf("UNEXPECTED: ptCutOffCorrection is %f for hist %d %d %d\n", ptCutOffCorrection, vertexPos, vertexBinBegin, vertexBinEnd);
417 //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);
419 Int_t bin = fdNdEta[vertexPos]->FindBin(vtxVsEta->GetYaxis()->GetBinCenter(iEta));
420 if (bin > 0 && bin < fdNdEta[vertexPos]->GetNbinsX())
422 Float_t dndeta = sum / totalEvents;
423 Float_t error = TMath::Sqrt(sumError2) / totalEvents;
425 dndeta = dndeta / fdNdEta[vertexPos]->GetBinWidth(bin);
426 error = error / fdNdEta[vertexPos]->GetBinWidth(bin);
428 fdNdEta[vertexPos]->SetBinContent(bin, dndeta);
429 fdNdEta[vertexPos]->SetBinError(bin, error);
431 dndeta /= ptCutOffCorrection;
432 error /= ptCutOffCorrection;
434 fdNdEtaPtCutOffCorrected[vertexPos]->SetBinContent(bin, dndeta);
435 fdNdEtaPtCutOffCorrected[vertexPos]->SetBinError(bin, error);
437 //Printf("Bin %d has dN/deta = %f", bin, dndeta);
442 //new TCanvas; fdNdEta[0]->DrawCopy();
445 //____________________________________________________________________
446 void dNdEtaAnalysis::SaveHistograms()
448 // save the histograms to a directory with the name of this class (retrieved from TNamed)
450 gDirectory->mkdir(GetName());
451 gDirectory->cd(GetName());
455 fData->SaveHistograms();
458 printf("dNdEtaAnalysis::SaveHistograms: UNEXPECTED: fData is 0\n");
465 printf("dNdEtaAnalysis::SaveHistograms: UNEXPECTED: fMult is 0\n");
470 printf("dNdEtaAnalysis::SaveHistograms: UNEXPECTED: fPtDist is 0\n");
472 for (Int_t i=0; i<kVertexBinning; ++i)
477 printf("dNdEtaAnalysis::SaveHistograms: UNEXPECTED: fdNdEta[%d] is 0\n", i);
479 if (fdNdEtaPtCutOffCorrected[i])
480 fdNdEtaPtCutOffCorrected[i]->Write();
482 printf("dNdEtaAnalysis::SaveHistograms: UNEXPECTED: fdNdEtaPtCutOffCorrected[%d] is 0\n", i);
485 gDirectory->cd("../");
488 void dNdEtaAnalysis::LoadHistograms(const Char_t* dir)
490 // loads the histograms from a directory with the name of this class (retrieved from TNamed)
497 fData->LoadHistograms();
498 fMult = dynamic_cast<TH1F*> (gDirectory->Get(fMult->GetName()));
500 for (Int_t i=0; i<kVertexBinning; ++i)
502 fdNdEta[i] = dynamic_cast<TH1F*> (gDirectory->Get(fdNdEta[i]->GetName()));
503 fdNdEtaPtCutOffCorrected[i] = dynamic_cast<TH1F*> (gDirectory->Get(fdNdEtaPtCutOffCorrected[i]->GetName()));
506 fPtDist = dynamic_cast<TH1F*> (gDirectory->Get(fPtDist->GetName()));
508 gDirectory->cd("../");
511 //____________________________________________________________________
512 void dNdEtaAnalysis::DrawHistograms(Bool_t simple)
514 // draws the histograms
519 fData->DrawHistograms(GetName());
521 TCanvas* canvas = new TCanvas(Form("%s_dNdEtaAnalysis", GetName()), Form("%s_dNdEtaAnalysis", GetName()), 800, 400);
522 canvas->Divide(2, 1);
525 if (fdNdEtaPtCutOffCorrected[0])
526 fdNdEtaPtCutOffCorrected[0]->DrawCopy();
530 fdNdEta[0]->SetLineColor(kRed);
531 fdNdEta[0]->DrawCopy("SAME");
539 // histograms for different vertices?
540 if (kVertexBinning > 0)
542 // doesnt work, but i dont get it, giving up...
543 TCanvas* canvas2 = new TCanvas(Form("%s_dNdEtaAnalysisVtx", GetName()), Form("%s_dNdEtaAnalysisVtx", GetName()), 450, 450);
544 TCanvas* canvas3 = 0;
546 canvas3 = new TCanvas(Form("%s_dNdEtaAnalysisVtx_noptcutoff", GetName()), Form("%s_dNdEtaAnalysisVtx_noptcutoff", GetName()), 450, 450);
548 //Int_t yPads = (Int_t) TMath::Ceil(((Double_t) kVertexBinning - 1) / 2);
549 //printf("%d\n", yPads);
550 //canvas2->Divide(2, yPads);
552 TLegend* legend = new TLegend(0.4, 0.2, 0.6, 0.4);
554 for (Int_t i=0; i<kVertexBinning; ++i)
556 if (fdNdEtaPtCutOffCorrected[i])
560 fdNdEtaPtCutOffCorrected[i]->SetLineColor(i+1);
561 fdNdEtaPtCutOffCorrected[i]->DrawCopy((i == 0) ? "" : "SAME");
562 legend->AddEntry(fdNdEtaPtCutOffCorrected[i], (i == 0) ? "Vtx All" : Form("Vtx Bin %d", i-1));
564 if (canvas3 && fdNdEta[i])
568 fdNdEta[i]->SetLineColor(i+1);
569 fdNdEta[i]->DrawCopy((i == 0) ? "" : "SAME");
575 canvas2->SaveAs(Form("%s_%s.gif", canvas2->GetName(), GetName()));
584 if (kVertexBinning == 3)
586 TH1* clone = dynamic_cast<TH1*> (fdNdEtaPtCutOffCorrected[1]->Clone("clone"));
587 TH1* clone2 = dynamic_cast<TH1*> (fdNdEtaPtCutOffCorrected[2]->Clone("clone2"));
591 TCanvas* canvas4 = new TCanvas(Form("%s_dNdEtaAnalysisVtxRatios", GetName()), Form("%s_dNdEtaAnalysisVtxRatios", GetName()), 450, 450);
593 clone->Divide(fdNdEtaPtCutOffCorrected[0]);
594 clone->GetYaxis()->SetRangeUser(0.95, 1.05);
597 clone2->Divide(fdNdEtaPtCutOffCorrected[0]);
598 clone2->DrawCopy("SAME");
600 TLine* line = new TLine(-1, 1, 1, 1);
603 canvas4->SaveAs(Form("%s_%s.gif", canvas4->GetName(), GetName()));
608 Long64_t dNdEtaAnalysis::Merge(TCollection* list)
610 // Merges a list of dNdEtaAnalysis objects with this one.
611 // This is needed for PROOF.
612 // Returns the number of merged objects (including this)
620 TIterator* iter = list->MakeIterator();
624 const Int_t nCollections = 2 * kVertexBinning + 3; // 3 standalone hists, 3 arrays of size kVertexBinning
625 TList* collections[nCollections];
626 for (Int_t i=0; i<nCollections; ++i)
627 collections[i] = new TList;
630 while ((obj = iter->Next()))
632 dNdEtaAnalysis* entry = dynamic_cast<dNdEtaAnalysis*> (obj);
636 collections[0]->Add(entry->fData);
637 collections[1]->Add(entry->fMult);
638 collections[2]->Add(entry->fPtDist);
640 for (Int_t i=0; i<kVertexBinning; ++i)
642 collections[3+i]->Add(entry->fdNdEta[i]);
643 collections[3+kVertexBinning+i]->Add(entry->fdNdEtaPtCutOffCorrected[i]);
649 fData->Merge(collections[0]);
650 fMult->Merge(collections[1]);
651 fPtDist->Merge(collections[2]);
653 for (Int_t i=0; i<kVertexBinning; ++i)
655 fdNdEta[i]->Merge(collections[3+i]);
656 fdNdEtaPtCutOffCorrected[i]->Merge(collections[3+kVertexBinning+i]);
659 for (Int_t i=0; i<nCollections; ++i)
660 delete collections[i];