12 #include <TMultiGraph.h>
14 #include <TGraphErrors.h>
16 #include "AliAODForwardMult.h"
17 #include "OtherData.C"
20 * Draw the data stored in the AOD
25 * Root> .L $ALICE_ROOT/PWG2/FORWARD/analysis2/Compile.C
26 * Root> Compile("$ALICE_ROOT/PWG2/FORWARD/analysis2/DrawRes.C")
28 * Root> dr.Run("AliAODs.root",-10,10,5,AliAODForwardMult::kInel,900)
31 * The output is stored in a ROOT file
33 * See also the script Pass2.C
35 * @ingroup pwg2_forward_analysis_scripts
43 AliAODForwardMult* fAOD;
46 /** Summed histogram */
48 /** Vertex efficiency */
50 /** Title to put on the plot */
53 //__________________________________________________________________
66 //__________________________________________________________________
68 * Reset internal structures
71 void Clear(Option_t* )
73 if (fTree && fTree->GetCurrentFile()) {
74 fTree->GetCurrentFile()->Close();
81 if (fSum) delete fSum;
88 //__________________________________________________________________
92 * @param file Input file with AOD tree
93 * @param vzMin Minimum interaction point z coordinate
94 * @param vzMax Maximum interaction point z coordinate
95 * @param rebin How many times to re-bin the @f$ dN_{ch}/d\eta@f$
96 * @param mask Trigger mask
97 * @param energy Collision energy @f$ \sqrt{s}@f$ or @f$\sqrt{s_{NN}}@f$
98 * @param title Title to put on the plot
100 * @return True on success, false otherwise
102 Bool_t Run(const char* file="AliAODs.root",
103 Double_t vzMin=-10, Double_t vzMax=10, Int_t rebin=1,
104 Int_t mask=AliAODForwardMult::kInel, Int_t energy=900,
105 const char* title="")
108 if (mask & AliAODForwardMult::kInel) trgName.Append("inel-");
109 if (mask & AliAODForwardMult::kInelGt0) trgName.Append("inelgt0-");
110 if (mask & AliAODForwardMult::kNSD) trgName.Append("nsd-");
111 if (trgName.EndsWith("-")) trgName.Remove(trgName.Length()-1);
112 if (trgName.IsNull()) trgName = "unknown";
114 TString::Format("dndeta_%04dGeV_%c%02d-%c%02dcm_rb%02d_%s.root",
116 vzMin < 0 ? 'm' : 'p', Int_t(TMath::Abs(vzMin)+.5),
117 vzMax < 0 ? 'm' : 'p', Int_t(TMath::Abs(vzMax)+.5),
118 rebin, trgName.Data());
120 if (!Open(file, outName)) return kFALSE;
121 if (!Process(vzMin,vzMax,mask)) return kFALSE;
122 if (!Finish(rebin, mask, energy)) return kFALSE;
126 //__________________________________________________________________
128 * Open the files @a fname containg the tree with AliAODEvent objects,
129 * and also open the output file @a outname for writting.
131 * @param fname Input file name
132 * @param outname Output file name
134 * @return true on success, false otherwise
136 Bool_t Open(const char* fname, const char* outname)
140 TFile* file = TFile::Open(fname, "READ");
142 Error("Open", "Cannot open file %s", fname);
147 fTree = static_cast<TTree*>(file->Get("aodTree"));
149 Error("Init", "Couldn't get the tree");
153 // Set the branch pointer
154 fTree->SetBranchAddress("Forward", &fAOD);
156 fOut = TFile::Open(outname, "RECREATE");
158 Error("Open", "Couldn't open %s", outname);
163 //__________________________________________________________________
167 * @param vzMin Minimum interaction point z coordinate
168 * @param vzMax Maximum interaction point z coordinate
169 * @param mask Trigger mask
171 * @return true on success, false otherwise
173 Bool_t Process(Double_t vzMin, Double_t vzMax, Int_t mask)
175 Int_t nTriggered = 0; // # of triggered ev.
176 Int_t nWithVertex = 0; // # of ev. w/vertex
177 Int_t nAccepted = 0; // # of ev. used
178 Int_t nAvailable = fTree->GetEntries(); // How many entries
180 for (int i = 0; i < nAvailable; i++) {
183 // Create sum histogram on first event - to match binning to input
185 fSum = static_cast<TH2D*>(fAOD->GetHistogram().Clone("d2ndetadphi"));
186 Info("Process", "Created sum histogram (%d,%f,%f)x(%d,%f,%f)",
188 fSum->GetXaxis()->GetXmin(),
189 fSum->GetXaxis()->GetXmax(),
191 fSum->GetYaxis()->GetXmin(),
192 fSum->GetYaxis()->GetXmax());
196 // Other trigger/event requirements could be defined
197 if (!fAOD->IsTriggerBits(mask)) continue;
200 // Check if there's a vertex
201 if (!fAOD->HasIpZ()) continue;
204 // Select vertex range (in centimeters)
205 if (!fAOD->InRange(vzMin, vzMax)) continue;
208 // Add contribution from this event
209 fSum->Add(&(fAOD->GetHistogram()));
211 fVtxEff = Double_t(nWithVertex)/nTriggered;
213 Info("Process", "Total of %9d events\n"
214 " %9d has a trigger\n"
215 " %9d has a vertex\n"
217 nAvailable, nTriggered, nWithVertex, nAccepted);
221 //__________________________________________________________________
223 * Finish the stuff and draw
225 * @param rebin How many times to rebin
226 * @param energy Collision energy
227 * @param mask Trigger mask
229 * @return true on success, false otherwise
231 Bool_t Finish(Int_t rebin, Int_t mask, Int_t energy)
235 // Get acceptance normalisation from underflow bins
236 TH1D* norm = fSum->ProjectionX("norm", 0, 1, "");
237 // Project onto eta axis - _ignoring_underflow_bins_!
238 TH1D* dndeta = fSum->ProjectionX("dndeta", 1, -1, "e");
239 dndeta->SetTitle("1/N dN_{ch}/d#eta|_{forward}");
240 // Normalize to the acceptance
241 dndeta->Divide(norm);
242 // Scale by the vertex efficiency
243 dndeta->Scale(fVtxEff, "width");
244 dndeta->SetMarkerColor(kRed+1);
245 dndeta->SetMarkerStyle(20);
246 dndeta->SetMarkerSize(1);
247 dndeta->SetFillStyle(0);
249 TH1* sym = Symmetrice(dndeta);
251 Rebin(dndeta, rebin);
254 THStack* stack = new THStack("results", "Results");
258 TString hhdName(fOut->GetName());
259 hhdName.ReplaceAll("dndeta", "hhd");
260 TH1* hhd = GetHHD(hhdName.Data(), mask & AliAODForwardMult::kNSD);
263 hhdsym = Symmetrice(hhd);
268 TMultiGraph* mg = GetData(energy, mask);
270 gStyle->SetOptTitle(0);
271 Double_t yd = (mg->GetListOfGraphs()->GetEntries() ? 0.3 : 0);
272 TCanvas* c = new TCanvas("c", "C", 900, 800);
278 TPad* p1 = new TPad("p1", "p1", 0, yd, 1.0, 1.0, 0, 0);
279 p1->SetTopMargin(0.05);
280 p1->SetBottomMargin(0.001);
281 p1->SetRightMargin(0.05);
286 stack->SetMinimum(-0.1);
287 FixAxis(stack, 1/(1-yd)/1.5, "#frac{1}{N} #frac{dN_{ch}}{#eta}");
289 stack->DrawClone("nostack e1");
292 THStack* ratios = new THStack("ratios", "Ratios");
293 TGraphAsymmErrors* o = 0;
294 TIter nextG(mg->GetListOfGraphs());
295 while ((o = static_cast<TGraphAsymmErrors*>(nextG()))) {
297 ratios->Add(Ratio(dndeta, o));
298 ratios->Add(Ratio(sym, o));
299 ratios->Add(Ratio(hhd, o));
300 ratios->Add(Ratio(hhdsym, o));
303 TH1F* t1 = static_cast<TH1F*>(dndeta->Clone(Form("%s_%s",
306 t1->SetTitle(Form("%s / %s", dndeta->GetTitle(), hhd->GetTitle()));
307 TH1F* t2 = static_cast<TH1F*>(sym->Clone(Form("%s_%s",
309 hhdsym->GetName())));
310 t2->SetTitle(Form("%s / %s", sym->GetTitle(), hhdsym->GetTitle()));
318 TString trigs(AliAODForwardMult::GetTriggerString(mask));
319 TLegend* l = p1->BuildLegend(.3,p1->GetBottomMargin()+.01,.7,.4,
320 Form("#sqrt{s}=%dGeV, %s",
321 energy, trigs.Data()));
328 if (!ratios->GetHists() || ratios->GetHists()->GetEntries() <= 0) {
329 p1->SetPad(0, 0, 1, 1);
330 p1->SetBottomMargin(0.1);
332 FixAxis(stack, (1-yd)/1, "#frac{1}{N} #frac{dN_{ch}}{#eta}",false);
337 TPad* p2 = new TPad("p2", "p2", 0, 0.0, 1.0, yd, 0, 0);
338 p2->SetTopMargin(0.001);
339 p2->SetRightMargin(0.05);
340 p2->SetBottomMargin(1/yd * 0.07);
345 FixAxis(ratios, 1/yd/1.5, "Ratios");
347 ratios->DrawClone("nostack e1");
349 TLegend* l2 = p2->BuildLegend(.3,p2->GetBottomMargin()+.01,.7,.6);
352 l2->SetBorderSize(0);
355 TGraphErrors* band = new TGraphErrors(2);
356 band->SetPoint(0, sym->GetXaxis()->GetXmin(), 1);
357 band->SetPoint(1, dndeta->GetXaxis()->GetXmax(), 1);
358 band->SetPointError(0, 0, .1);
359 band->SetPointError(1, 0, .1);
360 band->SetFillColor(kYellow+2);
361 band->SetFillStyle(3002);
362 band->Draw("3 same");
363 ratios->DrawClone("nostack e1 same");
368 TLatex* tit = new TLatex(0.10, 0.95, fTitle.Data());
370 tit->SetTextSize(0.05);
373 TString imgName(fOut->GetName());
374 imgName.ReplaceAll(".root", ".png");
375 c->SaveAs(imgName.Data());
385 //__________________________________________________________________
387 * Get the result from previous analysis code
389 * @param fn File to open
391 * @return null or result of previous analysis code
393 TH1* GetHHD(const char* fn="fmd_dNdeta_mult.root", bool nsd=false)
395 TDirectory* savdir = gDirectory;
396 TFile* file = TFile::Open(fn, "READ");
398 Warning("GetHHD", "couldn't open HHD file %s", fn);
402 TString hist(Form("dNdeta_dNdeta%s", (nsd ? "NSD" : "")));
403 TH1* h = static_cast<TH1*>(file->Get(hist.Data()));
405 Warning("GetHHD", "Couldn't find HHD histogram %s in %s",
412 TH1* r = static_cast<TH1*>(h->Clone("dndeta_hhd"));
413 r->SetTitle("1/N dN_{ch}/d#eta (HHD)");
416 r->SetMarkerStyle(21);
417 r->SetMarkerColor(kPink+1);
418 r->SetDirectory(savdir);
424 //__________________________________________________________________
426 * Fix the apperance of the axis in a stack
428 * @param stack stack of histogram
429 * @param s Scaling factor
430 * @param ytitle Y axis title
431 * @param force Whether to draw the stack first or not
433 void FixAxis(THStack* stack, Double_t s, const char* ytitle,
436 if (force) stack->Draw("nostack e1");
438 TH1* h = stack->GetHistogram();
441 h->SetXTitle("#eta");
442 h->SetYTitle(ytitle);
443 TAxis* xa = h->GetXaxis();
444 TAxis* ya = h->GetYaxis();
446 xa->SetTitle("#eta");
447 // xa->SetTicks("+-");
448 xa->SetTitleSize(s*xa->GetTitleSize());
449 xa->SetLabelSize(s*xa->GetLabelSize());
450 xa->SetTickLength(s*xa->GetTickLength());
453 ya->SetTitle(ytitle);
454 // ya->SetTicks("+-");
455 ya->SetNdivisions(10);
456 ya->SetTitleSize(s*ya->GetTitleSize());
457 ya->SetLabelSize(s*ya->GetLabelSize());
460 //__________________________________________________________________
462 * Compute the ratio of @a h to @a g. @a g is evaluated at the bin
470 TH1* Ratio(const TH1* h, const TGraph* g) const
472 if (!h || !g) return 0;
474 TH1* ret = static_cast<TH1*>(h->Clone("tmp"));
475 ret->SetName(Form("%s_over_%s", h->GetName(), g->GetName()));
476 ret->SetTitle(Form("%s / %s", h->GetTitle(), g->GetTitle()));
478 ret->SetMarkerStyle(h->GetMarkerStyle());
479 ret->SetMarkerColor(g->GetMarkerColor());
480 ret->SetMarkerSize(0.7*g->GetMarkerSize());
481 Double_t xlow = g->GetX()[0];
482 Double_t xhigh = g->GetX()[g->GetN()-1];
483 if (xlow > xhigh) { Double_t t = xhigh; xhigh = xlow; xlow = t; }
485 for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
486 Double_t c = h->GetBinContent(i);
487 if (c <= 0) continue;
489 Double_t x = h->GetBinCenter(i);
490 if (x < xlow || x > xhigh) continue;
492 Double_t f = g->Eval(x);
493 if (f <= 0) continue;
495 ret->SetBinContent(i, c / f);
496 ret->SetBinError(i, h->GetBinError(i) / f);
498 if (ret->GetEntries() <= 0) { delete ret; ret = 0; }
502 //__________________________________________________________________
504 * Make an extension of @a h to make it symmetric about 0
506 * @param h Histogram to symmertrice
508 * @return Symmetric extension of @a h
510 TH1* Symmetrice(const TH1* h) const
512 Int_t nBins = h->GetNbinsX();
513 TH1* s = new TH1D(Form("%s_mirror", h->GetName()),
514 Form("%s (mirrored)", h->GetTitle()),
516 -h->GetXaxis()->GetXmax(),
517 -h->GetXaxis()->GetXmin());
518 s->SetMarkerColor(h->GetMarkerColor());
519 s->SetMarkerSize(h->GetMarkerSize());
520 s->SetMarkerStyle(h->GetMarkerStyle()+4);
521 s->SetFillColor(h->GetFillColor());
522 s->SetFillStyle(h->GetFillStyle());
524 // Find the first and last bin with data
525 Int_t first = nBins+1;
527 for (Int_t i = 1; i <= nBins; i++) {
528 if (h->GetBinContent(i) <= 0) continue;
529 first = TMath::Min(first, i);
530 last = TMath::Max(last, i);
533 Double_t xfirst = h->GetBinCenter(first-1);
534 Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
535 Int_t l2 = s->GetXaxis()->FindBin(xfirst);
536 for (Int_t i = f1, j=l2; i <= last; i++,j--) {
537 s->SetBinContent(j, h->GetBinContent(i));
538 s->SetBinError(j, h->GetBinError(i));
542 //__________________________________________________________________
546 * @param h Histogram to rebin
547 * @param rebin Rebinning factor
551 virtual void Rebin(TH1* h, Int_t rebin) const
553 if (rebin <= 1) return;
555 Int_t nBins = h->GetNbinsX();
556 if(nBins % rebin != 0) {
557 Warning("Rebin", "Rebin factor %d is not a devisor of current number "
558 "of bins %d in the histogram %s", rebin, nBins, h->GetName());
563 TH1* tmp = static_cast<TH1*>(h->Clone("tmp"));
565 tmp->SetDirectory(0);
567 // The new number of bins
568 Int_t nBinsNew = nBins / rebin;
569 for(Int_t i = 1;i<= nBinsNew; i++) {
570 Double_t content = 0;
574 for(Int_t j = 1; j<=rebin;j++) {
575 Int_t bin = (i-1)*rebin + j;
576 if(h->GetBinContent(bin) <= 0) continue;
577 Double_t c = h->GetBinContent(bin);
578 Double_t w = 1 / TMath::Power(c,2);
586 tmp->SetBinContent(i, wsum / sumw);
587 tmp->SetBinError(i,TMath::Sqrt(sumw));
591 // Finally, rebin the histogram, and set new content
593 for(Int_t i =1;i<=nBinsNew; i++) {
594 h->SetBinContent(i,tmp->GetBinContent(i));
595 // h->SetBinError(i,tmp->GetBinError(i));
602 //____________________________________________________________________