]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG2/FORWARD/analysis2/AliBasedNdetaTask.cxx
Mostly documentation changes.
[u/mrichter/AliRoot.git] / PWG2 / FORWARD / analysis2 / AliBasedNdetaTask.cxx
CommitLineData
ce85db45 1//====================================================================
2#include "AliBasedNdetaTask.h"
3#include <TMath.h>
4#include <TH2D.h>
5#include <TH1D.h>
6#include <THStack.h>
7#include <TList.h>
e58000b7 8#include <TParameter.h>
ce85db45 9#include <AliAnalysisManager.h>
10#include <AliAODEvent.h>
11#include <AliAODHandler.h>
12#include <AliAODInputHandler.h>
13#include "AliForwardUtil.h"
14#include "AliAODForwardMult.h"
3846ec25 15#include <TFile.h>
ce85db45 16
17//____________________________________________________________________
18AliBasedNdetaTask::AliBasedNdetaTask()
19 : AliAnalysisTaskSE(),
ce85db45 20 fSums(0), // Container of sums
e1f47419 21 fOutput(0), // Container of output
ce85db45 22 fVtxMin(0), // Minimum v_z
23 fVtxMax(0), // Maximum v_z
24 fTriggerMask(0), // Trigger mask
25 fRebin(0), // Rebinning factor
26 fCutEdges(false),
27 fSymmetrice(true),
e58000b7 28 fCorrEmpty(true),
29 fTriggerEff(1),
3846ec25 30 fShapeCorr(0),
e1f47419 31 fListOfCentralities(0),
e1f47419 32 fSNNString(0),
33 fSysString(0),
e308a636 34 fCent(0),
ffca499d 35 fCentAxis(0),
36 fNormalizationScheme(kFull)
fb3430ac 37{
38 //
39 // Constructor
40 //
41}
ce85db45 42
43//____________________________________________________________________
44AliBasedNdetaTask::AliBasedNdetaTask(const char* name)
45 : AliAnalysisTaskSE(name),
ce85db45 46 fSums(0), // Container of sums
e1f47419 47 fOutput(0), // Container of output
ce85db45 48 fVtxMin(-10), // Minimum v_z
49 fVtxMax(10), // Maximum v_z
50 fTriggerMask(AliAODForwardMult::kInel),
51 fRebin(5), // Rebinning factor
52 fCutEdges(false),
53 fSymmetrice(true),
e58000b7 54 fCorrEmpty(true),
55 fTriggerEff(1),
3846ec25 56 fShapeCorr(0),
e1f47419 57 fListOfCentralities(0),
e1f47419 58 fSNNString(0),
59 fSysString(0),
e308a636 60 fCent(0),
ffca499d 61 fCentAxis(0),
62 fNormalizationScheme(kFull)
ce85db45 63{
fb3430ac 64 //
65 // Constructor
66 //
e308a636 67 fListOfCentralities = new TObjArray(1);
fb3430ac 68
ce85db45 69 // Output slot #1 writes into a TH1 container
70 DefineOutput(1, TList::Class());
71 DefineOutput(2, TList::Class());
72}
73
74//____________________________________________________________________
75AliBasedNdetaTask::AliBasedNdetaTask(const AliBasedNdetaTask& o)
76 : AliAnalysisTaskSE(o),
ce85db45 77 fSums(o.fSums), // TList* - Container of sums
e1f47419 78 fOutput(o.fOutput), // Container of output
ce85db45 79 fVtxMin(o.fVtxMin), // Double_t - Minimum v_z
80 fVtxMax(o.fVtxMax), // Double_t - Maximum v_z
81 fTriggerMask(o.fTriggerMask),// Int_t - Trigger mask
82 fRebin(o.fRebin), // Int_t - Rebinning factor
83 fCutEdges(o.fCutEdges), // Bool_t - Whether to cut edges when rebinning
84 fSymmetrice(true),
e58000b7 85 fCorrEmpty(true),
86 fTriggerEff(o.fTriggerEff),
3846ec25 87 fShapeCorr(o.fShapeCorr),
e1f47419 88 fListOfCentralities(o.fListOfCentralities),
e1f47419 89 fSNNString(o.fSNNString),
90 fSysString(o.fSysString),
e308a636 91 fCent(o.fCent),
ffca499d 92 fCentAxis(o.fCentAxis),
93 fNormalizationScheme(o.fNormalizationScheme)
ce85db45 94{}
95
96//____________________________________________________________________
97AliBasedNdetaTask::~AliBasedNdetaTask()
98{
fb3430ac 99 //
100 // Destructor
101 //
ce85db45 102 if (fSums) {
103 fSums->Delete();
104 delete fSums;
105 fSums = 0;
106 }
e1f47419 107 if (fOutput) {
108 fOutput->Delete();
109 delete fOutput;
110 fOutput = 0;
ce85db45 111 }
112}
113
e1f47419 114//________________________________________________________________________
115void
e308a636 116AliBasedNdetaTask::SetCentralityAxis(UShort_t n, Short_t* bins)
117{
118 if (!fCentAxis) {
119 fCentAxis = new TAxis();
120 fCentAxis->SetName("centAxis");
121 fCentAxis->SetTitle("Centrality [%]");
122 }
123 TArrayD dbins(n+1);
124 for (UShort_t i = 0; i <= n; i++)
125 dbins[i] = (bins[i] == 100 ? 100.1 : bins[i]);
126 fCentAxis->Set(n, dbins.GetArray());
127}
128
129//________________________________________________________________________
130void
131AliBasedNdetaTask::AddCentralityBin(UShort_t at, Short_t low, Short_t high)
e1f47419 132{
133 //
134 // Add a centrality bin
135 //
136 // Parameters:
137 // low Low cut
138 // high High cut
139 //
e308a636 140 CentralityBin* bin = MakeCentralityBin(GetName(), low, high);
141 AliInfo(Form("Adding centrality bin %p [%3d,%3d] @ %d", bin, low, high, at));
142 fListOfCentralities->AddAtAndExpand(bin, at);
e1f47419 143}
144
145//________________________________________________________________________
146AliBasedNdetaTask::CentralityBin*
147AliBasedNdetaTask::MakeCentralityBin(const char* name,
148 Short_t low, Short_t high) const
149{
150 //
151 // Make a centrality bin
152 //
153 // Parameters:
154 // name Name used for histograms
155 // low Low cut in percent
156 // high High cut in percent
157 //
158 // Return:
159 // A newly created centrality bin
160 //
161 return new CentralityBin(name, low, high);
162}
ffca499d 163//________________________________________________________________________
164void
165AliBasedNdetaTask::SetNormalizationScheme(const char* what)
166{
167 //
168 // Set normalisation scheme
169 //
170 UShort_t scheme = 0;
171 TString twhat(what);
172 twhat.ToUpper();
173 TObjString* opt;
174 TIter next(twhat.Tokenize(" ,|"));
175 while ((opt = static_cast<TObjString*>(next()))) {
176 TString s(opt->GetString());
177 if (s.IsNull()) continue;
178 if (s.CompareTo("EVENT") == 0) scheme |= kEventLevel;
179 else if (s.CompareTo("ALTEVENT") == 0) scheme |= kAltEventLevel;
180 else if (s.CompareTo("SHAPE") == 0) scheme |= kShape;
181 else if (s.CompareTo("BACKGROUND")== 0) scheme |= kBackground;
182 else if (s.CompareTo("FULL") == 0) scheme |= kFull;
183 else if (s.CompareTo("ALTFULL") == 0) scheme |= kAltFull;
184 else if (s.CompareTo("NONE") == 0) scheme |= kNone;
185 else
186 Warning("SetNormalizationScheme", "Unknown option %s", s.Data());
187 }
188 SetNormalizationScheme(scheme);
189}
190
ce85db45 191//________________________________________________________________________
192void
193AliBasedNdetaTask::SetTriggerMask(const char* mask)
194{
fb3430ac 195 //
196 // Set the trigger maskl
197 //
198 // Parameters:
199 // mask Trigger mask
200 //
ce85db45 201 UShort_t trgMask = 0;
202 TString trgs(mask);
203 trgs.ToUpper();
204 TObjString* trg;
205 TIter next(trgs.Tokenize(" ,|"));
206 while ((trg = static_cast<TObjString*>(next()))) {
207 TString s(trg->GetString());
208 if (s.IsNull()) continue;
209 if (s.CompareTo("INEL") == 0) trgMask = AliAODForwardMult::kInel;
210 else if (s.CompareTo("INEL>0")== 0) trgMask = AliAODForwardMult::kInelGt0;
211 else if (s.CompareTo("NSD") == 0) trgMask = AliAODForwardMult::kNSD;
212 else
213 Warning("SetTriggerMask", "Unknown trigger %s", s.Data());
214 }
215 if (trgMask == 0) trgMask = 1;
216 SetTriggerMask(trgMask);
217}
218
e58000b7 219//________________________________________________________________________
220void
221AliBasedNdetaTask::SetShapeCorrection(const TH1* c)
222{
fb3430ac 223 //
224 // Set the shape correction (a.k.a., track correction) for selected
225 // trigger(s)
226 //
227 // Parameters:
228 // h Correction
229 //
e58000b7 230 if (!c) return;
231 fShapeCorr = static_cast<TH1*>(c->Clone());
232 fShapeCorr->SetDirectory(0);
233}
234
ce85db45 235//________________________________________________________________________
236void
237AliBasedNdetaTask::UserCreateOutputObjects()
238{
fb3430ac 239 //
240 // Create output objects.
241 //
242 // This is called once per slave process
243 //
ce85db45 244 fSums = new TList;
245 fSums->SetName(Form("%s_sums", GetName()));
246 fSums->SetOwner();
247
e1f47419 248 // Automatically add 'all' centrality bin if nothing has been defined.
e308a636 249 AddCentralityBin(0, 0, 0);
250 if (fCentAxis && fCentAxis->GetNbins() > 0 && fCentAxis->GetXbins()) {
251 const TArrayD* bins = fCentAxis->GetXbins();
252 Int_t nbin = fCentAxis->GetNbins();
253 for (Int_t i = 0; i < nbin; i++)
254 AddCentralityBin(i+1, Short_t((*bins)[i]), Short_t((*bins)[i+1]));
255 }
256 fSums->Add(fCentAxis);
257
ce85db45 258
e1f47419 259 // Centrality histogram
260 fCent = new TH1D("cent", "Centrality", 100, 0, 100);
261 fCent->SetDirectory(0);
262 fCent->SetXTitle(0);
263 fSums->Add(fCent);
264
265 // Loop over centrality bins
266 TIter next(fListOfCentralities);
267 CentralityBin* bin = 0;
268 while ((bin = static_cast<CentralityBin*>(next())))
269 bin->CreateOutputObjects(fSums);
ce85db45 270
271 // Check that we have an AOD input handler
272 AliAnalysisManager* am = AliAnalysisManager::GetAnalysisManager();
273 AliAODInputHandler* ah =
274 dynamic_cast<AliAODInputHandler*>(am->GetInputEventHandler());
275 if (!ah) AliFatal("No AOD input handler set in analysis manager");
276
277 // Post data for ALL output slots >0 here, to get at least an empty histogram
278 PostData(1, fSums);
279}
ce85db45 280//____________________________________________________________________
281void
282AliBasedNdetaTask::UserExec(Option_t *)
283{
fb3430ac 284 //
285 // Process a single event
286 //
287 // Parameters:
288 // option Not used
289 //
ce85db45 290 // Main loop
291 AliAODEvent* aod = dynamic_cast<AliAODEvent*>(InputEvent());
292 if (!aod) {
293 AliError("Cannot get the AOD event");
294 return;
295 }
e58000b7 296
e1f47419 297 TObject* obj = aod->FindListObject("Forward");
298 if (!obj) {
299 AliWarning("No forward object found");
300 return;
678a4979 301 }
e1f47419 302 AliAODForwardMult* forward = static_cast<AliAODForwardMult*>(obj);
e308a636 303
e1f47419 304 // Fill centrality histogram
e308a636 305 Float_t cent = forward->GetCentrality();
306 fCent->Fill(cent);
e1f47419 307
ce85db45 308 // Get the histogram(s)
e58000b7 309 TH2D* data = GetHistogram(aod, false);
ce85db45 310 TH2D* dataMC = GetHistogram(aod, true);
311
e1f47419 312 // Loop over centrality bins
ffca499d 313 CentralityBin* allBin =
314 static_cast<CentralityBin*>(fListOfCentralities->At(0));
e308a636 315 allBin->ProcessEvent(forward, fTriggerMask, fVtxMin, fVtxMax, data, dataMC);
316
317 // Find this centrality bin
318 if (fCentAxis && fCentAxis->GetNbins() > 0) {
319 Int_t icent = fCentAxis->FindBin(cent);
320 CentralityBin* thisBin = 0;
321 if (icent >= 1 && icent <= fCentAxis->GetNbins())
322 thisBin = static_cast<CentralityBin*>(fListOfCentralities->At(icent));
323 if (thisBin)
ffca499d 324 thisBin->ProcessEvent(forward, fTriggerMask, fVtxMin, fVtxMax,
325 data, dataMC);
e308a636 326 }
ce85db45 327
e1f47419 328 // Here, we get the update
329 if (!fSNNString) {
330 UShort_t sNN = forward->GetSNN();
331 fSNNString = new TNamed("sNN", "");
332 fSNNString->SetTitle(AliForwardUtil::CenterOfMassEnergyString(sNN));
333 fSNNString->SetUniqueID(sNN);
334 fSums->Add(fSNNString);
e58000b7 335
e1f47419 336 UShort_t sys = forward->GetSystem();
337 fSysString = new TNamed("sys", "");
338 fSysString->SetTitle(AliForwardUtil::CollisionSystemString(sys));
339 fSysString->SetUniqueID(sys);
340 fSums->Add(fSysString);
3846ec25 341 }
e58000b7 342
ce85db45 343 PostData(1, fSums);
344}
345
346//________________________________________________________________________
347void
348AliBasedNdetaTask::SetHistogramAttributes(TH1D* h, Int_t colour, Int_t marker,
349 const char* title, const char* ytitle)
350{
fb3430ac 351 //
352 // Set histogram graphical options, etc.
353 //
354 // Parameters:
355 // h Histogram to modify
356 // colour Marker color
357 // marker Marker style
358 // title Title of histogram
359 // ytitle Title on y-axis.
360 //
ce85db45 361 h->SetTitle(title);
362 h->SetMarkerColor(colour);
363 h->SetMarkerStyle(marker);
364 h->SetMarkerSize(1);
365 h->SetFillStyle(0);
366 h->SetYTitle(ytitle);
367 h->GetXaxis()->SetTitleFont(132);
368 h->GetXaxis()->SetLabelFont(132);
369 h->GetXaxis()->SetNdivisions(10);
370 h->GetYaxis()->SetTitleFont(132);
371 h->GetYaxis()->SetLabelFont(132);
372 h->GetYaxis()->SetNdivisions(10);
373 h->GetYaxis()->SetDecimals();
374 h->SetStats(0);
375}
376
377//________________________________________________________________________
378TH1D*
379AliBasedNdetaTask::ProjectX(const TH2D* h,
380 const char* name,
381 Int_t firstbin,
382 Int_t lastbin,
383 bool corr,
e1f47419 384 bool error)
ce85db45 385{
fb3430ac 386 //
387 // Project onto the X axis
388 //
389 // Parameters:
390 // h 2D histogram
391 // name New name
392 // firstbin First bin to use
393 // lastbin Last bin to use
394 // error Whether to calculate errors
395 //
396 // Return:
397 // Newly created histogram or null
398 //
ce85db45 399 if (!h) return 0;
e1f47419 400#if USE_ROOT_PROJECT
401 return h->ProjectionX(name, firstbin, lastbin, (error ? "e" : ""));
402#endif
ce85db45 403
404 TAxis* xaxis = h->GetXaxis();
405 TAxis* yaxis = h->GetYaxis();
406 TH1D* ret = new TH1D(name, h->GetTitle(), xaxis->GetNbins(),
407 xaxis->GetXmin(), xaxis->GetXmax());
408 static_cast<const TAttLine*>(h)->Copy(*ret);
409 static_cast<const TAttFill*>(h)->Copy(*ret);
410 static_cast<const TAttMarker*>(h)->Copy(*ret);
411 ret->GetXaxis()->ImportAttributes(xaxis);
412
413 Int_t first = firstbin;
414 Int_t last = lastbin;
415 if (first < 0) first = 0;
416 else if (first >= yaxis->GetNbins()+1) first = yaxis->GetNbins();
417 if (last < 0) last = yaxis->GetNbins();
418 else if (last > yaxis->GetNbins()+1) last = yaxis->GetNbins();
419 if (last-first < 0) {
e1f47419 420 AliWarningGeneral("AliBasedNdetaTask",
421 Form("Nothing to project [%d,%d]", first, last));
ce85db45 422 return 0;
423
424 }
425
426 // Loop over X bins
427 // AliInfo(Form("Projecting bins [%d,%d] of %s", first, last, h->GetName()));
428 Int_t ybins = (last-first+1);
429 for (Int_t xbin = 0; xbin <= xaxis->GetNbins()+1; xbin++) {
430 Double_t content = 0;
431 Double_t error2 = 0;
432 Int_t nbins = 0;
433
434
435 for (Int_t ybin = first; ybin <= last; ybin++) {
436 Double_t c1 = h->GetCellContent(xbin, ybin);
437 Double_t e1 = h->GetCellError(xbin, ybin);
438
439 // Ignore empty bins
440 if (c1 < 1e-12) continue;
441 if (e1 < 1e-12) {
442 if (error) continue;
443 e1 = 1;
444 }
445
446 content += c1;
447 error2 += e1*e1;
448 nbins++;
449 } // for (ybin)
450 if(content > 0 && nbins > 0) {
451 Double_t factor = (corr ? Double_t(ybins) / nbins : 1);
452 if (error) {
453 // Calculate weighted average
454 ret->SetBinContent(xbin, content * factor);
455 ret->SetBinError(xbin, factor * TMath::Sqrt(error2));
456 }
457 else
458 ret->SetBinContent(xbin, factor * content);
459 }
460 } // for (xbin)
461
462 return ret;
463}
464
465//________________________________________________________________________
466void
467AliBasedNdetaTask::Terminate(Option_t *)
468{
fb3430ac 469 //
470 // Called at end of event processing..
471 //
472 // This is called once in the master
473 //
474 // Parameters:
475 // option Not used
476 //
ce85db45 477 // Draw result to screen, or perform fitting, normalizations Called
478 // once at the end of the query
479
480 fSums = dynamic_cast<TList*> (GetOutputData(1));
481 if(!fSums) {
482 AliError("Could not retrieve TList fSums");
483 return;
484 }
485
e1f47419 486 fOutput = new TList;
487 fOutput->SetName(Form("%s_result", GetName()));
488 fOutput->SetOwner();
e58000b7 489
e1f47419 490 fSNNString = static_cast<TNamed*>(fSums->FindObject("sNN"));
491 fSysString = static_cast<TNamed*>(fSums->FindObject("sys"));
e308a636 492 fCentAxis = static_cast<TAxis*>(fSums->FindObject("centAxis"));
ce85db45 493
e1f47419 494 if(fSysString && fSNNString &&
495 fSysString->GetUniqueID() == AliForwardUtil::kPP)
496 LoadNormalizationData(fSysString->GetUniqueID(),
497 fSNNString->GetUniqueID());
ce85db45 498
e1f47419 499 // Loop over centrality bins
500 TIter next(fListOfCentralities);
501 CentralityBin* bin = 0;
502 while ((bin = static_cast<CentralityBin*>(next())))
ffca499d 503 bin->End(fSums, fOutput, fNormalizationScheme, fShapeCorr, fTriggerEff,
e1f47419 504 fSymmetrice, fRebin, fCorrEmpty, fCutEdges,
ffca499d 505 fVtxMin, fVtxMax, fTriggerMask, GetColor(), GetMarker());
ce85db45 506
e1f47419 507 // Output collision energy string
508 if (fSNNString) fOutput->Add(fSNNString->Clone());
ce85db45 509
e1f47419 510 // Output collision system string
511 if (fSysString) fOutput->Add(fSysString->Clone());
ce85db45 512
e308a636 513 // Output centrality axis
514 if (fCentAxis) fOutput->Add(fCentAxis);
515
e1f47419 516 // Output trigger string
ce85db45 517 TNamed* trigString =
518 new TNamed("trigString", AliAODForwardMult::GetTriggerString(fTriggerMask));
519 trigString->SetUniqueID(fTriggerMask);
520 fOutput->Add(trigString);
521
e1f47419 522 // Output vertex axis
ce85db45 523 TAxis* vtxAxis = new TAxis(1,fVtxMin,fVtxMax);
524 vtxAxis->SetName("vtxAxis");
525 vtxAxis->SetTitle(Form("v_{z}#in[%+5.1f,%+5.1f]cm", fVtxMin,fVtxMax));
526 fOutput->Add(vtxAxis);
e1f47419 527
528 // Output trigger efficiency and shape correction
e58000b7 529 fOutput->Add(new TParameter<Double_t>("triggerEff", fTriggerEff));
530 if (fShapeCorr) fOutput->Add(fShapeCorr);
ffca499d 531
532 TString tscheme;
533 if (fNormalizationScheme & kEventLevel) tscheme.Append("EVENTLEVEL,");
534 if (fNormalizationScheme & kAltEventLevel) tscheme.Append("ALTEVENTLEVEL,");
535 if (fNormalizationScheme & kBackground) tscheme.Append("BACKGROUND,");
536 if (fNormalizationScheme & kShape) tscheme.Append("SHAPE,");
e58000b7 537
ffca499d 538 TNamed* scheme = new TNamed("scheme", tscheme.Data());
539 scheme->SetUniqueID(fNormalizationScheme);
540 fOutput->Add(scheme);
541
ce85db45 542 PostData(2, fOutput);
543}
3846ec25 544//________________________________________________________________________
545void
546AliBasedNdetaTask::LoadNormalizationData(UShort_t sys, UShort_t energy)
547{
e1f47419 548 // Load the normalisation data for dN/deta for pp INEL, INEL>0, and NSD
3846ec25 549 TString type("pp");
3846ec25 550 TString snn("900");
551 if(energy == 7000) snn.Form("7000");
552 if(energy == 2750) snn.Form("2750");
553
e1f47419 554 if(fShapeCorr && (fTriggerEff != 1)) {
555 AliInfo("Objects already set for normalization - no action taken");
556 return;
557 }
3846ec25 558
e1f47419 559 TFile* fin = TFile::Open(Form("$ALICE_ROOT/PWG2/FORWARD/corrections/"
560 "Normalization/normalizationHists_%s_%s.root",
561 type.Data(),snn.Data()));
562 if(!fin) {
563 AliWarning(Form("no file for normalization of %d/%d", sys, energy));
564 return;
565 }
3846ec25 566
e1f47419 567 // Shape correction
568 TString shapeCorName(Form("h%sNormalization",
569 fTriggerMask == AliAODForwardMult::kInel ? "Inel" :
570 fTriggerMask == AliAODForwardMult::kNSD ? "NSD" :
571 fTriggerMask == AliAODForwardMult::kInelGt0 ?
572 "InelGt0" : "All"));
573 TH2F* shapeCor = dynamic_cast<TH2F*>(fin->Get(shapeCorName));
574 if (shapeCor) SetShapeCorrection(shapeCor);
ce85db45 575
e1f47419 576 // Trigger efficiency
577 TString effName(Form("%sTriggerEff",
578 fTriggerMask == AliAODForwardMult::kInel ? "inel" :
579 fTriggerMask == AliAODForwardMult::kNSD ? "nsd" :
580 fTriggerMask == AliAODForwardMult::kInelGt0 ?
581 "inelgt0" : "all"));
582 TParameter<float>* eff = static_cast<TParameter<float>*>(fin->Get(effName));
583 if (eff) SetTriggerEff(eff->GetVal());
3846ec25 584
e1f47419 585 // Print - out
586 if (shapeCor && eff) AliInfo("Loaded objects for normalization.");
3846ec25 587}
ce85db45 588//________________________________________________________________________
589TH1D*
e1f47419 590AliBasedNdetaTask::Rebin(const TH1D* h, Int_t rebin, Bool_t cutEdges)
ce85db45 591{
fb3430ac 592 //
593 // Make a copy of the input histogram and rebin that histogram
594 //
595 // Parameters:
596 // h Histogram to rebin
597 //
598 // Return:
599 // New (rebinned) histogram
600 //
e1f47419 601 if (rebin <= 1) return 0;
ce85db45 602
603 Int_t nBins = h->GetNbinsX();
e1f47419 604 if(nBins % rebin != 0) {
605 AliWarningGeneral("AliBasedNdetaTask",
606 Form("Rebin factor %d is not a devisor of current number "
607 "of bins %d in the histogram %s",
608 rebin, nBins, h->GetName()));
ce85db45 609 return 0;
610 }
611
612 // Make a copy
613 TH1D* tmp = static_cast<TH1D*>(h->Clone(Form("%s_rebin%02d",
e1f47419 614 h->GetName(), rebin)));
615 tmp->Rebin(rebin);
ce85db45 616 tmp->SetDirectory(0);
617
618 // The new number of bins
e1f47419 619 Int_t nBinsNew = nBins / rebin;
ce85db45 620 for(Int_t i = 1;i<= nBinsNew; i++) {
621 Double_t content = 0;
622 Double_t sumw = 0;
623 Double_t wsum = 0;
624 Int_t nbins = 0;
e1f47419 625 for(Int_t j = 1; j<=rebin;j++) {
626 Int_t bin = (i-1)*rebin + j;
ce85db45 627 Double_t c = h->GetBinContent(bin);
ce85db45 628 if (c <= 0) continue;
678a4979 629
e1f47419 630 if (cutEdges) {
ce85db45 631 if (h->GetBinContent(bin+1)<=0 ||
3846ec25 632 h->GetBinContent(bin-1)<=0) {
e1f47419 633#if 0
634 AliWarningGeneral("AliBasedNdetaTask",
635 Form("removing bin %d=%f of %s (%d=%f,%d=%f)",
636 bin, c, h->GetName(),
637 bin+1, h->GetBinContent(bin+1),
638 bin-1, h->GetBinContent(bin-1)));
639#endif
ce85db45 640 continue;
641 }
642 }
643 Double_t e = h->GetBinError(bin);
644 Double_t w = 1 / (e*e); // 1/c/c
645 content += c;
646 sumw += w;
647 wsum += w * c;
648 nbins++;
649 }
650
651 if(content > 0 && nbins > 0) {
652 tmp->SetBinContent(i, wsum / sumw);
653 tmp->SetBinError(i,1./TMath::Sqrt(sumw));
654 }
655 }
656
657 return tmp;
658}
659
660//__________________________________________________________________
ce85db45 661TH1*
e1f47419 662AliBasedNdetaTask::Symmetrice(const TH1* h)
ce85db45 663{
fb3430ac 664 //
665 // Make an extension of @a h to make it symmetric about 0
666 //
667 // Parameters:
668 // h Histogram to symmertrice
669 //
670 // Return:
671 // Symmetric extension of @a h
672 //
ce85db45 673 Int_t nBins = h->GetNbinsX();
674 TH1* s = static_cast<TH1*>(h->Clone(Form("%s_mirror", h->GetName())));
675 s->SetTitle(Form("%s (mirrored)", h->GetTitle()));
676 s->Reset();
677 s->SetBins(nBins, -h->GetXaxis()->GetXmax(), -h->GetXaxis()->GetXmin());
678 s->SetMarkerColor(h->GetMarkerColor());
679 s->SetMarkerSize(h->GetMarkerSize());
680 s->SetMarkerStyle(h->GetMarkerStyle()+4);
681 s->SetFillColor(h->GetFillColor());
682 s->SetFillStyle(h->GetFillStyle());
683 s->SetDirectory(0);
684
685 // Find the first and last bin with data
686 Int_t first = nBins+1;
687 Int_t last = 0;
688 for (Int_t i = 1; i <= nBins; i++) {
689 if (h->GetBinContent(i) <= 0) continue;
690 first = TMath::Min(first, i);
691 last = TMath::Max(last, i);
692 }
693
694 Double_t xfirst = h->GetBinCenter(first-1);
695 Int_t f1 = h->GetXaxis()->FindBin(-xfirst);
696 Int_t l2 = s->GetXaxis()->FindBin(xfirst);
697 for (Int_t i = f1, j=l2; i <= last; i++,j--) {
698 s->SetBinContent(j, h->GetBinContent(i));
699 s->SetBinError(j, h->GetBinError(i));
700 }
701 // Fill in overlap bin
702 s->SetBinContent(l2+1, h->GetBinContent(first));
703 s->SetBinError(l2+1, h->GetBinError(first));
704 return s;
705}
e1f47419 706
707//====================================================================
708AliBasedNdetaTask::CentralityBin::CentralityBin()
709 : TNamed("", ""),
710 fSums(0),
711 fOutput(0),
712 fSum(0),
713 fSumMC(0),
714 fTriggers(0),
715 fLow(0),
716 fHigh(0)
717{
718 //
719 // Constructor
720 //
721}
722//____________________________________________________________________
723AliBasedNdetaTask::CentralityBin::CentralityBin(const char* name,
724 Short_t low, Short_t high)
725 : TNamed(name, ""),
726 fSums(0),
727 fOutput(0),
728 fSum(0),
729 fSumMC(0),
730 fTriggers(0),
731 fLow(low),
732 fHigh(high)
733{
734 //
735 // Constructor
736 //
737 // Parameters:
738 // name Name used for histograms (e.g., Forward)
739 // low Lower centrality cut in percent
740 // high Upper centrality cut in percent
741 //
742 if (low <= 0 && high <= 0) {
743 fLow = 0;
744 fHigh = 0;
745 SetTitle("All centralities");
746 }
747 else {
748 fLow = low;
749 fHigh = high;
750 SetTitle(Form("Centrality bin from %3d%% to %3d%%", low, high));
751 }
752}
753//____________________________________________________________________
754AliBasedNdetaTask::CentralityBin::CentralityBin(const CentralityBin& o)
755 : TNamed(o),
756 fSums(o.fSums),
757 fOutput(o.fOutput),
758 fSum(o.fSum),
759 fSumMC(o.fSumMC),
760 fTriggers(o.fTriggers),
761 fLow(o.fLow),
762 fHigh(o.fHigh)
763{
764 //
765 // Copy constructor
766 //
767 // Parameters:
768 // other Object to copy from
769 //
770}
771//____________________________________________________________________
772AliBasedNdetaTask::CentralityBin::~CentralityBin()
773{
774 //
775 // Destructor
776 //
777 if (fSums) fSums->Delete();
778 if (fOutput) fOutput->Delete();
779}
780
781//____________________________________________________________________
782AliBasedNdetaTask::CentralityBin&
783AliBasedNdetaTask::CentralityBin::operator=(const CentralityBin& o)
784{
785 //
786 // Assignment operator
787 //
788 // Parameters:
789 // other Object to assign from
790 //
791 // Return:
792 // Reference to this
793 //
794 SetName(o.GetName());
795 SetTitle(o.GetTitle());
796 fSums = o.fSums;
797 fOutput = o.fOutput;
798 fSum = o.fSum;
799 fSumMC = o.fSumMC;
800 fTriggers = o.fTriggers;
801 fLow = o.fLow;
802 fHigh = o.fHigh;
803
804 return *this;
805}
806//____________________________________________________________________
807const char*
808AliBasedNdetaTask::CentralityBin::GetListName() const
809{
810 //
811 // Get the list name
812 //
813 // Return:
814 // List Name
815 //
816 if (IsAllBin()) return "all";
817 return Form("cent%03d_%03d", fLow, fHigh);
818}
819//____________________________________________________________________
820void
821AliBasedNdetaTask::CentralityBin::CreateOutputObjects(TList* dir)
822{
823 //
824 // Create output objects
825 //
826 // Parameters:
827 // dir Parent list
828 //
829 fSums = new TList;
830 fSums->SetName(GetListName());
831 fSums->SetOwner();
832 dir->Add(fSums);
833
ffca499d 834 fTriggers = AliAODForwardMult::MakeTriggerHistogram("triggers");
835 fTriggers->SetDirectory(0);
e1f47419 836 fSums->Add(fTriggers);
837}
838//____________________________________________________________________
839void
840AliBasedNdetaTask::CentralityBin::CreateSums(const TH2D* data, const TH2D* mc)
841{
842 //
843 // Create sum histogram
844 //
845 // Parameters:
846 // data Data histogram to clone
847 // mc (optional) MC histogram to clone
848 //
849 fSum = static_cast<TH2D*>(data->Clone(GetName()));
850 fSum->SetDirectory(0);
851 fSum->Reset();
852 fSums->Add(fSum);
853
854 // If no MC data is given, then do not create MC sum histogram
855 if (!mc) return;
856
857 fSumMC = static_cast<TH2D*>(mc->Clone(Form("%sMC", GetName())));
858 fSumMC->SetDirectory(0);
859 fSumMC->Reset();
860 fSums->Add(fSumMC);
861}
862
863//____________________________________________________________________
864Bool_t
865AliBasedNdetaTask::CentralityBin::CheckEvent(const AliAODForwardMult* forward,
866 Int_t triggerMask,
867 Double_t vzMin, Double_t vzMax)
868{
869 //
870 // Check the trigger, vertex, and centrality
871 //
872 // Parameters:
873 // aod Event input
874 //
875 // Return:
876 // true if the event is to be used
877 //
878 if (!forward) return false;
e1f47419 879
ffca499d 880 // We do not check for centrality here - it's already done
881 return forward->CheckEvent(triggerMask, vzMin, vzMax, 0, 0, fTriggers);
e1f47419 882}
883
884
885//____________________________________________________________________
886void
887AliBasedNdetaTask::CentralityBin::ProcessEvent(const AliAODForwardMult* forward,
888 Int_t triggerMask,
889 Double_t vzMin, Double_t vzMax,
890 const TH2D* data, const TH2D* mc)
891{
892 //
893 // Process an event
894 //
895 // Parameters:
896 // forward Forward data (for trigger, vertex, & centrality)
897 // triggerMask Trigger mask
898 // vzMin Minimum IP z coordinate
899 // vzMax Maximum IP z coordinate
900 // data Data histogram
901 // mc MC histogram
902 //
903 if (!CheckEvent(forward, triggerMask, vzMin, vzMax)) return;
904 if (!data) return;
905 if (!fSum) CreateSums(data, mc);
906
907 fSum->Add(data);
908 if (mc) fSumMC->Add(mc);
909}
910
911//________________________________________________________________________
912void
913AliBasedNdetaTask::CentralityBin::End(TList* sums,
914 TList* results,
ffca499d 915 UShort_t scheme,
e1f47419 916 const TH1* shapeCorr,
917 Double_t trigEff,
918 Bool_t symmetrice,
919 Int_t rebin,
920 Bool_t corrEmpty,
921 Bool_t cutEdges,
922 Double_t vzMin,
923 Double_t vzMax,
ffca499d 924 Int_t triggerMask,
925 Int_t color,
926 Int_t marker)
e1f47419 927{
928 //
929 // End of processing
930 //
931 // Parameters:
932 // sums List of sums
933 // results Output list of results
934 // shapeCorr Shape correction or nil
935 // trigEff Trigger efficiency
936 // symmetrice Whether to symmetrice the results
937 // rebin Whether to rebin the results
938 // corrEmpty Whether to correct for empty bins
939 // cutEdges Whether to cut edges when rebinning
940 // vzMin Minimum IP z coordinate
941 // vzMax Maximum IP z coordinate
942 // triggerMask Trigger mask
943 //
944
945 fSums = dynamic_cast<TList*>(sums->FindObject(GetListName()));
946 if(!fSums) {
947 AliError("Could not retrieve TList fSums");
948 return;
949 }
950
951 fOutput = new TList;
952 fOutput->SetName(GetListName());
953 fOutput->SetOwner();
954 results->Add(fOutput);
955
956 fSum = static_cast<TH2D*>(fSums->FindObject(GetName()));
957 fSumMC = static_cast<TH2D*>(fSums->FindObject(Form("%sMC", GetName())));
ffca499d 958 fTriggers = static_cast<TH1I*>(fSums->FindObject("triggers"));
e1f47419 959
960 if (!fTriggers) {
961 AliError("Couldn't find histogram 'triggers' in list");
962 return;
963 }
964 if (!fSum) {
e308a636 965 AliError(Form("Couldn't find histogram '%s' in list", GetName()));
e1f47419 966 return;
967 }
ffca499d 968
969 TH1I& t = *fTriggers;
970 Int_t nAll = Int_t(t.GetBinContent(AliAODForwardMult::kBinAll));
971 Int_t nB = Int_t(t.GetBinContent(AliAODForwardMult::kBinB));
972 Int_t nA = Int_t(t.GetBinContent(AliAODForwardMult::kBinA));
973 Int_t nC = Int_t(t.GetBinContent(AliAODForwardMult::kBinC));
974 Int_t nE = Int_t(t.GetBinContent(AliAODForwardMult::kBinE));
975 Int_t nMB = Int_t(t.GetBinContent(AliAODForwardMult::kBinInel));
976 Int_t nTriggered = Int_t(t.GetBinContent(AliAODForwardMult::kWithTrigger));
977 Int_t nWithVertex = Int_t(t.GetBinContent(AliAODForwardMult::kWithVertex));
978 Int_t nAccepted = Int_t(t.GetBinContent(AliAODForwardMult::kAccepted));
e1f47419 979 Int_t nGood = nB - nA - nC + 2 * nE;
e308a636 980
e1f47419 981
e308a636 982 if (nTriggered <= 0.1) {
e1f47419 983 AliError("Number of triggered events <= 0");
984 return;
985 }
e308a636 986 if (nWithVertex <= 0.1) {
987 AliError("Number of events with vertex <= 0");
988 return;
989 }
990 if (nGood <= 0.1) {
e1f47419 991 AliWarning(Form("Number of good events=%d=%d-%d-%d+2*%d<=0",
992 nGood, nB, nA, nC, nE));
993 nGood = nMB;
994 }
e308a636 995
996
997 // Scaling
998 // N_A + N_A/N_V (N_T - N_V) = N_A + N_A/N_V*N_T - N_A
999 // = N_A/N_V * N_T
e308a636 1000 // where
1001 // N_A = nAccepted
1002 // N_V = nWithVertex
1003 // N_T = nTriggered
1004 // so that the normalisation is simply
1005 // N_A / E_V
1006 // where
1007 // E_V=N_V/N_T is the vertex efficiency from data
1008 //
ffca499d 1009 // If we calculate the number of events with no vertex as
1010 // (N_T - N_A), we get
1011 //
1012 // N_A + N_A/N_V (N_T - N_A) = N_A (1 + 1/N_V (N_T - N_A))
1013 // = N_A (1 + N_T/N_V - N_A/N_V)
1014 // = N_A (1 + 1/E_V - N_A/N_V)
1015 //
e308a636 1016 // Double_t alpha = Double_t(nAccepted) / nWithVertex;
1017 // Double_t vNorm = nAccepted + alpha*(nTriggered - nWithVertex);
ffca499d 1018 Double_t ntotal = 1;
1019 Double_t vtxEff = double(nWithVertex) / double(nTriggered);;
1020 Bool_t shape = (scheme & kShape);
1021 if (scheme & kEventLevel) {
1022 AliInfo(Form("Calculating event normalisation as "
1023 "1 / trigEff * nAccepted * nTriggered / nWithVertex "
1024 "= 1/%f * %d * %d / %d = %f",
1025 trigEff, nAccepted, nTriggered, nWithVertex,
1026 1. / trigEff * nAccepted * double(nTriggered) / nWithVertex));
1027 ntotal = vtxEff * trigEff;
1028 }
1029 else if (scheme & kAltEventLevel) {
1030 AliInfo(Form("Calculating event normalisation as "
1031 "1 / trigEff * nAccepted * (1 + nTriggered / nWithVertex - "
1032 "nAccepted / nWithVertex) = "
1033 "1/ %f * %d (1 + %d / %d - %d / %d) = %f",
1034 trigEff, nAccepted, nTriggered, nWithVertex,
1035 nAccepted, nWithVertex,
1036 1/trigEff * nAccepted * (1 + double(nTriggered)/nWithVertex -
1037 double(nAccepted) / nWithVertex)));
1038 ntotal = trigEff * 1 / (1 + double(nTriggered)/nWithVertex -
1039 double(nAccepted) / nWithVertex);
1040 }
e308a636 1041
e1f47419 1042 AliInfo(Form("Total of %9d events for %s\n"
e308a636 1043 " of these %9d are triggered minimum bias\n"
e1f47419 1044 " of these %9d has a %s trigger\n"
1045 " of these %9d has a vertex\n"
1046 " of these %9d were in [%+4.1f,%+4.1f]cm\n"
1047 " Triggers by type:\n"
1048 " B = %9d\n"
1049 " A|C = %9d (%9d+%-9d)\n"
1050 " E = %9d\n"
1051 " Implies %9d good triggers\n"
e308a636 1052 " Vertex efficiency: %f\n"
1053 " Trigger efficiency: %f\n"
1054 " Total number of events: %f\n",
e1f47419 1055 nAll, GetTitle(), nMB, nTriggered,
1056 AliAODForwardMult::GetTriggerString(triggerMask),
1057 nWithVertex, nAccepted,
1058 vzMin, vzMax,
e308a636 1059 nB, nA+nC, nA, nC, nE, nGood, vtxEff, trigEff, ntotal));
e1f47419 1060
1061 const char* name = GetName();
1062
1063 // Get acceptance normalisation from underflow bins
1064 TH1D* norm = ProjectX(fSum, Form("norm%s",name), 0, 0, corrEmpty, false);
1065 norm->SetDirectory(0);
1066
1067 // Scale by shape correction
ffca499d 1068 if(shape && shapeCorr) fSum->Divide(shapeCorr);
e1f47419 1069 else AliInfo("No shape correction specified, or disabled");
1070
1071 // Project on X axis
1072 TH1D* dndeta = ProjectX(fSum, Form("dndeta%s",name), 1, fSum->GetNbinsY(),
1073 corrEmpty);
1074 dndeta->SetDirectory(0);
1075
1076 // Normalize to the acceptance -
1077 dndeta->Divide(norm);
1078
1079 // Scale by the vertex efficiency
e308a636 1080 dndeta->Scale(ntotal, "width");
e1f47419 1081
ffca499d 1082 SetHistogramAttributes(dndeta, color, marker, Form("ALICE %s", name));
1083 SetHistogramAttributes(norm, color, marker, Form("ALICE %s normalisation",
1084 name));
e1f47419 1085
1086 fOutput->Add(fTriggers->Clone());
1087 if (symmetrice) fOutput->Add(Symmetrice(dndeta));
1088 fOutput->Add(dndeta);
1089 fOutput->Add(norm);
1090 fOutput->Add(Rebin(dndeta, rebin, cutEdges));
1091 if (symmetrice) fOutput->Add(Symmetrice(Rebin(dndeta, rebin, cutEdges)));
1092
1093 if (fSumMC) {
1094 // Get acceptance normalisation from underflow bins
1095 TH1D* normMC = ProjectX(fSumMC,Form("norm%sMC", name), 0, 1,
1096 corrEmpty, false);
1097 // Project onto eta axis - _ignoring_underflow_bins_!
1098 TH1D* dndetaMC = ProjectX(fSumMC,Form("dndeta%sMC", name),1,
1099 fSum->GetNbinsY(), corrEmpty);
1100 // Normalize to the acceptance
1101 dndetaMC->Divide(normMC);
1102 // Scale by the vertex efficiency
ffca499d 1103 dndetaMC->Scale(ntotal, "width");
e1f47419 1104 normMC->Scale(1. / nAccepted);
1105
ffca499d 1106 SetHistogramAttributes(dndetaMC, color+2, marker,
1107 Form("ALICE %s (MC)",name));
1108 SetHistogramAttributes(normMC, color+2, marker,
1109 Form("ALICE %s (MC) normalisation",name));
e1f47419 1110
1111 fOutput->Add(dndetaMC);
1112 if (symmetrice) fOutput->Add(Symmetrice(dndetaMC));
1113
1114 fOutput->Add(normMC);
1115 fOutput->Add(Rebin(dndetaMC, rebin, cutEdges));
1116
1117 if (symmetrice)
1118 fOutput->Add(Symmetrice(Rebin(dndetaMC, rebin, cutEdges)));
1119 }
e308a636 1120
1121 // Temporary stuff
ffca499d 1122 if (!IsAllBin()) return;
1123
e308a636 1124 TFile* forward = TFile::Open("forward.root", "READ");
1125 if (!forward) {
1126 AliWarning(Form("No forward.root file found"));
1127 return;
1128 }
1129
1130 TH1D* shapeCorrProj = 0;
1131 if (shapeCorr) {
1132 shapeCorrProj = static_cast<const TH2D*>(shapeCorr)->ProjectionX();
1133 shapeCorrProj->Scale(1. / shapeCorr->GetNbinsY());
1134 shapeCorrProj->SetDirectory(0);
1135 fOutput->Add(shapeCorrProj);
1136 }
1137
1138 TList* official = static_cast<TList*>(forward->Get("official"));
1139 if (official) {
1140 TH1F* histEta = static_cast<TH1F*>(official->FindObject("fHistEta"));
1141 if (histEta) {
1142 TH1D* oEta = new TH1D("tracks", "", histEta->GetNbinsX(),
1143 histEta->GetXaxis()->GetXmin(),
1144 histEta->GetXaxis()->GetXmax());
1145 for (Int_t i = 1; i < histEta->GetNbinsX(); i++) {
1146 oEta->SetBinContent(i, histEta->GetBinContent(i));
1147 oEta->SetBinError(i, histEta->GetBinError(i));
1148 }
1149 if (shapeCorrProj) oEta->Divide(shapeCorrProj);
1150 oEta->Scale(ntotal/nAccepted, "width");
1151 oEta->SetDirectory(0);
ffca499d 1152 oEta->SetMarkerStyle(marker+4);
1153 oEta->SetMarkerColor(color+5);
e308a636 1154 fOutput->Add(oEta);
1155 fOutput->Add(Rebin(oEta, rebin, false));
1156 }
1157 else
1158 AliWarning(Form("Couldn't find histogram fHistEta in list %s",
1159 official->GetName()));
1160 }
1161 else
1162 AliWarning(Form("Couldn't find list 'official' in %s",forward->GetName()));
1163
1164 TList* tracks = static_cast<TList*>(forward->Get("tracks"));
1165 if (tracks) {
1166 TH1F* histEta = static_cast<TH1F*>(tracks->FindObject("fHistEta"));
1167 if (histEta) {
1168 TH1D* oEta = new TH1D("tracks", "", histEta->GetNbinsX(),
1169 histEta->GetXaxis()->GetXmin(),
1170 histEta->GetXaxis()->GetXmax());
1171 for (Int_t i = 1; i < histEta->GetNbinsX(); i++) {
1172 oEta->SetBinContent(i, histEta->GetBinContent(i));
1173 oEta->SetBinError(i, histEta->GetBinError(i));
1174 }
1175 if (shapeCorrProj) oEta->Divide(shapeCorrProj);
1176 oEta->Scale(ntotal/nAccepted, "width");
1177 oEta->SetDirectory(0);
ffca499d 1178 oEta->SetMarkerStyle(marker);
1179 oEta->SetMarkerColor(color+5);
e308a636 1180 fOutput->Add(oEta);
1181 fOutput->Add(Rebin(oEta, rebin, false));
1182 }
1183 else
1184 AliWarning(Form("Couldn't find histogram fHistEta in list %s",
1185 tracks->GetName()));
1186 }
1187 else
1188 AliWarning(Form("Couldn't find list 'tracks' in %s",forward->GetName()));
1189
1190 forward->Close();
e1f47419 1191}
1192
fb3430ac 1193//
1194// EOF
1195//