]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/AliFMDHistCollector.cxx
Segregated the Landau+Gaus function from the AliForwardUtil dumping ground. Other...
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / AliFMDHistCollector.cxx
CommitLineData
7984e5f7 1//
2// This class collects the event histograms into single histograms,
3// one for each ring in each vertex bin.
4//
5// Input:
6// - AliESDFMD object possibly corrected for sharing
7//
8// Output:
9// - 5 RingHistos objects - each with a number of vertex dependent
10// 2D histograms of the inclusive charge particle density
11//
12// HistCollector used:
13// - AliFMDCorrSecondaryMap
14//
7e4038b5 15#include "AliFMDHistCollector.h"
16#include <AliESDFMD.h>
17#include <TAxis.h>
18#include <TList.h>
19#include <TMath.h>
0bd4b00f 20#include "AliForwardCorrectionManager.h"
8449e3e0 21#include "AliFMDCorrSecondaryMap.h"
7e4038b5 22#include "AliLog.h"
23#include <TH2D.h>
4f9319f3 24#include <TH3D.h>
7e4038b5 25#include <TH1I.h>
26#include <TProfile.h>
27#include <TProfile2D.h>
8449e3e0 28#include <TObjArray.h>
7e4038b5 29#include <TArrayI.h>
0bd4b00f 30#include <TROOT.h>
31#include <iostream>
32#include <iomanip>
7e4038b5 33
34ClassImp(AliFMDHistCollector)
35#if 0
36; // For Emacs
37#endif
38
5bb5d1f6 39//____________________________________________________________________
40AliFMDHistCollector::AliFMDHistCollector()
41 : fNCutBins(0),
42 fCorrectionCut(0),
5bb5d1f6 43 fDebug(0),
44 fList(0),
45 fSumRings(0),
46 fCoverage(0),
77f97e3f 47 fSkipped(0),
5bb5d1f6 48 fMergeMethod(kStraightMean),
ce731b9f 49 fFiducialMethod(kByCut),
50 fSkipFMDRings(0),
8449e3e0 51 fBgAndHitMaps(false),
52 fVtxList(0),
53 fByCent(0),
54 fDoByCent(false)
6ab100ec 55{
5ca83fee 56 DGUARD(fDebug, 3, "Default CTOR of AliFMDHistCollector");
6ab100ec 57}
5bb5d1f6 58
59//____________________________________________________________________
60AliFMDHistCollector::AliFMDHistCollector(const char* title)
61 : TNamed("fmdHistCollector", title),
62 fNCutBins(2),
63 fCorrectionCut(0.5),
5bb5d1f6 64 fDebug(0),
65 fList(0),
66 fSumRings(0),
67 fCoverage(0),
77f97e3f 68 fSkipped(0),
5bb5d1f6 69 fMergeMethod(kStraightMean),
ce731b9f 70 fFiducialMethod(kByCut),
71 fSkipFMDRings(0),
8449e3e0 72 fBgAndHitMaps(false),
73 fVtxList(0),
74 fByCent(0),
75 fDoByCent(false)
5bb5d1f6 76{
5ca83fee 77 DGUARD(fDebug, 3, "Named CTOR of AliFMDHistCollector: %s", title);
5bb5d1f6 78}
79//____________________________________________________________________
80AliFMDHistCollector::AliFMDHistCollector(const AliFMDHistCollector& o)
81 : TNamed(o),
82 fNCutBins(o.fNCutBins),
83 fCorrectionCut(o.fCorrectionCut),
5bb5d1f6 84 fDebug(o.fDebug),
85 fList(o.fList),
86 fSumRings(o.fSumRings),
87 fCoverage(o.fCoverage),
77f97e3f 88 fSkipped(o.fSkipped),
5bb5d1f6 89 fMergeMethod(o.fMergeMethod),
ce731b9f 90 fFiducialMethod(o.fFiducialMethod),
91 fSkipFMDRings(o.fSkipFMDRings),
8449e3e0 92 fBgAndHitMaps(o.fBgAndHitMaps),
93 fVtxList(o.fVtxList),
94 fByCent(o.fByCent),
95 fDoByCent(o.fDoByCent)
6ab100ec 96{
5ca83fee 97 DGUARD(fDebug, 3, "Copy CTOR of AliFMDHistCollector");
6ab100ec 98}
5bb5d1f6 99
12fffad7 100//____________________________________________________________________
101AliFMDHistCollector::~AliFMDHistCollector()
102{
6ab100ec 103 DGUARD(fDebug, 3, "DTOR of AliFMDHistCollector");
b7ab8a2c 104 // if (fList) delete fList;
12fffad7 105}
7e4038b5 106//____________________________________________________________________
107AliFMDHistCollector&
108AliFMDHistCollector::operator=(const AliFMDHistCollector& o)
109{
7984e5f7 110 //
111 // Assignement operator
112 //
113 // Parameters:
114 // o Object to assign from
115 //
116 // Return:
117 // Reference to this object
118 //
6ab100ec 119 DGUARD(fDebug, 3, "Assignment of AliFMDHistCollector");
d015ecfe 120 if (&o == this) return *this;
ea3e5d95 121 TNamed::operator=(o);
7e4038b5 122
123 fNCutBins = o.fNCutBins;
124 fCorrectionCut = o.fCorrectionCut;
ea3e5d95 125 fDebug = o.fDebug;
12fffad7 126 fList = o.fList;
127 fSumRings = o.fSumRings;
128 fCoverage = o.fCoverage;
77f97e3f 129 fSkipped = o.fSkipped;
e1f47419 130 fMergeMethod = o.fMergeMethod;
131 fFiducialMethod = o.fFiducialMethod;
ce731b9f 132 fSkipFMDRings = o.fSkipFMDRings;
133 fBgAndHitMaps = o.fBgAndHitMaps;
8449e3e0 134 fVtxList = o.fVtxList;
135 fByCent = o.fByCent;
136 fDoByCent = o.fDoByCent;
7e4038b5 137 return *this;
138}
139
140//____________________________________________________________________
141void
5934a3e3 142AliFMDHistCollector::SetupForData(const TAxis& vtxAxis,
8449e3e0 143 const TAxis& etaAxis)
7e4038b5 144{
7984e5f7 145 //
146 // Intialise
147 //
148 // Parameters:
149 // vtxAxis Vertex axis
150 //
6ab100ec 151 DGUARD(fDebug, 1, "Initialization of AliFMDHistCollector");
7984e5f7 152
8449e3e0 153 // AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
7e4038b5 154
12fffad7 155 fSumRings = new TH2D("sumRings", "Sum in individual rings",
156 etaAxis.GetNbins(), etaAxis.GetXmin(), etaAxis.GetXmax(),
157 5, 1, 6);
158 fSumRings->Sumw2();
159 fSumRings->SetDirectory(0);
160 fSumRings->SetXTitle("#eta");
161 fSumRings->GetYaxis()->SetBinLabel(1,"FMD1i");
162 fSumRings->GetYaxis()->SetBinLabel(2,"FMD2i");
163 fSumRings->GetYaxis()->SetBinLabel(3,"FMD2o");
164 fSumRings->GetYaxis()->SetBinLabel(4,"FMD3i");
165 fSumRings->GetYaxis()->SetBinLabel(5,"FMD3o");
166 fList->Add(fSumRings);
167
168 fCoverage = new TH2D("coverage", "#eta coverage per v_{z}",
e1f47419 169 etaAxis.GetNbins(),etaAxis.GetXmin(),etaAxis.GetXmax(),
170 vtxAxis.GetNbins(),vtxAxis.GetXmin(),vtxAxis.GetXmax());
12fffad7 171 fCoverage->SetDirectory(0);
172 fCoverage->SetXTitle("#eta");
173 fCoverage->SetYTitle("v_{z} [cm]");
174 fCoverage->SetZTitle("n_{bins}");
175 fList->Add(fCoverage);
176
77f97e3f
CHC
177 fSkipped = new TH1D("skipped", "Rings skipped", 5, 1, 6);
178 fSkipped->SetDirectory(0);
179 fSkipped->SetFillColor(kRed+1);
180 fSkipped->SetFillStyle(3001);
181 fSkipped->SetYTitle("Events");
182 fSkipped->GetXaxis()->SetBinLabel(1,"FMD1i");
183 fSkipped->GetXaxis()->SetBinLabel(2,"FMD2i");
184 fSkipped->GetXaxis()->SetBinLabel(3,"FMD2o");
185 fSkipped->GetXaxis()->SetBinLabel(4,"FMD3i");
186 fSkipped->GetXaxis()->SetBinLabel(5,"FMD3o");
187 fList->Add(fSkipped);
7e4038b5 188
6af747ad 189 // --- Add parameters to output ------------------------------------
190 fList->Add(AliForwardUtil::MakeParameter("nCutBins",fNCutBins));
191 fList->Add(AliForwardUtil::MakeParameter("skipRings",fSkipFMDRings));
192 fList->Add(AliForwardUtil::MakeParameter("bgAndHits",fBgAndHitMaps));
193 fList->Add(AliForwardUtil::MakeParameter("fiducial",Int_t(fFiducialMethod)));
194 fList->Add(AliForwardUtil::MakeParameter("fiducialCut",fCorrectionCut));
195 fList->Add(AliForwardUtil::MakeParameter("merge",Int_t(fMergeMethod)));
196
8449e3e0 197 UShort_t nVz = vtxAxis.GetNbins();
198 fVtxList = new TObjArray(nVz, 1);
199 fVtxList->SetName("histCollectorVtxBins");
200 fVtxList->SetOwner();
201
7e4038b5 202 // Find the eta bin ranges
0bd4b00f 203 for (UShort_t iVz = 1; iVz <= nVz; iVz++) {
e1f47419 204 Double_t vMin = vtxAxis.GetBinLowEdge(iVz);
205 Double_t vMax = vtxAxis.GetBinUpEdge(iVz);
8449e3e0 206 VtxBin* bin = new VtxBin(iVz, vMin, vMax, fNCutBins);
207 fVtxList->AddAt(bin, iVz);
7e4038b5 208
8449e3e0 209 bin->SetupForData(fCoverage, fSkipFMDRings, fFiducialMethod,
210 fCorrectionCut, fList, etaAxis,
211 fBgAndHitMaps, fBgAndHitMaps);
212 }
7e4038b5 213
8449e3e0 214 if (!fDoByCent) return;
215
216 fByCent = new TList;
217 fByCent->SetName("byCentrality");
218 fByCent->SetOwner();
219 fList->Add(fByCent);
220
221 Int_t nCent = 101;
222 Double_t minCent = -.5;
223 Double_t maxCent = 100.5;
224 for (Int_t i = 0; i < 5; i++) {
225 UShort_t d;
226 Char_t r;
227 GetDetRing(i, d, r);
228
229 TH3* h = new TH3D(Form("FMD%d%c", d, r),
230 Form("dN/d#eta per centrality for FMD%d%c", d, r),
231 etaAxis.GetNbins(), etaAxis.GetXmin(), etaAxis.GetXmax(),
232 nCent, minCent, maxCent, 1, 0, 1);
233 h->SetXTitle("#eta");
234 h->SetYTitle("Centrality [%]");
235 h->SetZTitle("dN/d#eta");
236 h->SetDirectory(0);
237 h->SetMarkerColor(AliForwardUtil::RingColor(d, r));
238 h->SetMarkerStyle(20);
239 fByCent->Add(h);
7e4038b5 240 }
241}
e1f47419 242//____________________________________________________________________
243Bool_t
8449e3e0 244AliFMDHistCollector::CheckCorrection(FiducialMethod m,
245 Double_t cut,
246 const TH2D* bg,
247 Int_t ie,
248 Int_t ip)
e1f47419 249{
250 //
251 // Check if we should include the bin in the data range
252 //
253 // Parameters:
254 // bg Secondary map histogram
255 // ie Eta bin
256 // ip Phi bin
257 //
258 // Return:
259 // True if to be used
260 //
261 Double_t c = bg->GetBinContent(ie,ip);
8449e3e0 262 switch (m) {
e1f47419 263 case kByCut:
8449e3e0 264 return c >= cut;
e1f47419 265 case kDistance:
266 if (2 * c < bg->GetBinContent(ie+1,ip) ||
267 2 * c < bg->GetBinContent(ie-1,ip)) return false;
268 return true;
269 default:
8449e3e0 270 AliErrorClass("No fiducal cut method defined");
e1f47419 271 }
272 return false;
273}
274
12fffad7 275//____________________________________________________________________
276void
5934a3e3 277AliFMDHistCollector::CreateOutputObjects(TList* dir)
12fffad7 278{
279 //
280 // Output diagnostic histograms to directory
281 //
282 // Parameters:
283 // dir List to write in
284 //
6ab100ec 285 DGUARD(fDebug, 1, "Define output of AliFMDHistCollector");
12fffad7 286 fList = new TList;
287 fList->SetOwner();
288 fList->SetName(GetName());
289 dir->Add(fList);
5bb5d1f6 290
12fffad7 291}
292
8449e3e0 293//____________________________________________________________________
294Bool_t
295AliFMDHistCollector::CheckSkip(UShort_t d, Char_t r, UShort_t skips)
296{
8449e3e0 297 UShort_t q = (r == 'I' || r == 'i' ? 0 : 1);
bfab35d9 298 UShort_t c = 1 << (d-1);
299 UShort_t t = 1 << (c+q-1);
300
8449e3e0 301 return (t & skips) == t;
302}
5bb5d1f6 303
7e4038b5 304//____________________________________________________________________
305Int_t
8449e3e0 306AliFMDHistCollector::GetIdx(UShort_t d, Char_t r)
7e4038b5 307{
7984e5f7 308 //
309 // Get the ring index from detector number and ring identifier
310 //
311 // Parameters:
312 // d Detector
313 // r Ring identifier
314 //
315 // Return:
316 // ring index or -1 in case of problems
317 //
7e4038b5 318 Int_t idx = -1;
319 switch (d) {
320 case 1: idx = 0; break;
321 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
322 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
323 }
324 return idx;
325}
326//____________________________________________________________________
327void
8449e3e0 328AliFMDHistCollector::GetDetRing(Int_t idx, UShort_t& d, Char_t& r)
7e4038b5 329{
7984e5f7 330 //
331 // Get the detector and ring from the ring index
332 //
333 // Parameters:
334 // idx Ring index
335 // d On return, the detector or 0 in case of errors
336 // r On return, the ring id or '0' in case of errors
337 //
7e4038b5 338 d = 0;
339 r = '\0';
340 switch (idx) {
341 case 0: d = 1; r = 'I'; break;
342 case 1: d = 2; r = 'I'; break;
343 case 2: d = 2; r = 'O'; break;
344 case 3: d = 3; r = 'I'; break;
345 case 4: d = 3; r = 'O'; break;
346 }
347}
348
349//____________________________________________________________________
8449e3e0 350AliFMDHistCollector::VtxBin*
351AliFMDHistCollector::GetVtxBin(Int_t ivtx)
7e4038b5 352{
7984e5f7 353 // Parameters:
7984e5f7 354 // vtxBin Vertex bin (1 based)
8449e3e0 355 if (!fVtxList) return 0;
356 if (ivtx < 1 || ivtx > fVtxList->GetEntriesFast()) return 0;
357 VtxBin* bin = static_cast<VtxBin*>(fVtxList->At(ivtx));
358 return bin;
7e4038b5 359}
7e4038b5 360//____________________________________________________________________
8449e3e0 361const AliFMDHistCollector::VtxBin*
362AliFMDHistCollector::GetVtxBin(Int_t ivtx) const
7e4038b5 363{
7984e5f7 364 // Parameters:
8449e3e0 365 // vtxBin Vertex bin (1 based)
366 if (!fVtxList) return 0;
367 if (ivtx < 1 || ivtx > fVtxList->GetEntriesFast()) return 0;
368 VtxBin* bin = static_cast<VtxBin*>(fVtxList->At(ivtx));
369 return bin;
7e4038b5 370}
7e4038b5 371
e1f47419 372//____________________________________________________________________
373void
8449e3e0 374AliFMDHistCollector::MergeBins(MergeMethod m,
375 Double_t c, Double_t e,
e1f47419 376 Double_t oc, Double_t oe,
8449e3e0 377 Double_t& rc, Double_t& re)
e1f47419 378{
379 //
380 // Merge bins accoring to set method
381 //
382 // Parameters:
383 // c Current content
384 // e Current error
385 // oc Old content
386 // oe Old error
387 // rc On return, the new content
388 // re On return, tne new error
389 //
390 rc = re = 0;
8449e3e0 391 switch (m) {
e1f47419 392 case kStraightMean:
bfab35d9 393 case kPreferInner: // We only get these two when there's an overlap
394 case kPreferOuter: // between like rings, and we should do a straight mean
e1f47419 395 // calculate the average of old value (half the original),
396 // and this value, as well as the summed squared errors
397 // of the existing content (sqrt((e_1/2)^2=sqrt(e_1^2/4)=e_1/2)
398 // and half the error of this.
399 //
400 // So, on the first overlapping histogram we get
401 //
402 // c = c_1 / 2
403 // e = sqrt((e_1 / 2)^2) = e_1/2
404 //
405 // On the second we get
406 //
407 // c' = c_2 / 2 + c = c_2 / 2 + c_1 / 2 = (c_1+c_2)/2
408 // e' = sqrt(e^2 + (e_2/2)^2)
409 // = sqrt(e_1^2/4 + e_2^2/4)
410 // = sqrt(1/4 * (e_1^2+e_2^2))
411 // = 1/2 * sqrt(e_1^2 + e_2^2)
412 rc = oc + c/2;
413 re = TMath::Sqrt(oe*oe+(e*e)/4);
414 break;
415 case kStraightMeanNoZero:
416 // If there's data in the overlapping histogram,
417 // calculate the average and add the errors in
418 // quadrature.
419 //
420 // If there's no data in the overlapping histogram,
421 // then just fill in the data
422 if (oe > 0) {
423 rc = (oc + c)/2;
424 re = TMath::Sqrt(oe*oe + e*e)/2;
425 }
426 else {
427 rc = c;
428 re = e;
429 }
430 break;
431 case kWeightedMean: {
432 // Calculate the weighted mean
433 Double_t w = 1/(e*e);
434 Double_t sc = w * c;
435 Double_t sw = w;
436 if (oe > 0) {
437 Double_t ow = 1/(oe*oe);
438 sc += ow * oc;
439 sw += ow;
440 }
441 rc = sc / sw;
442 re = TMath::Sqrt(1 / sw);
443 }
444 break;
445 case kLeastError:
446 if (e < oe) {
447 rc = c;
448 re = e;
449 }
450 else {
451 rc = oc;
452 re = oe;
453 }
454 break;
5ca83fee 455 case kSum:
456 rc = c + oc;
457 re = TMath::Sqrt(oe * oe + e * e);//Add in quadarature
458 break;
e1f47419 459 default:
8449e3e0 460 AliErrorClass("No method for defining content of overlapping bins defined");
e1f47419 461 return;
462 }
463}
464
7e4038b5 465//____________________________________________________________________
466Bool_t
5bb5d1f6 467AliFMDHistCollector::Collect(const AliForwardUtil::Histos& hists,
468 AliForwardUtil::Histos& sums,
0bd4b00f 469 UShort_t vtxbin,
4f9319f3 470 TH2D& out,
c8b1a7db 471 Double_t cent,
472 Bool_t eta2phi)
7e4038b5 473{
7984e5f7 474 //
475 // Do the calculations
476 //
477 // Parameters:
478 // hists Cache of histograms
479 // vtxBin Vertex bin (1 based)
480 // out Output histogram
481 //
482 // Return:
483 // true on successs
484 //
6ab100ec 485 DGUARD(fDebug, 1, "Collect final histogram of AliFMDHistCollector");
8449e3e0 486 // AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
487 // const TAxis* vtxAxis = fcm.GetVertexAxis();
488 // Double_t vMin = vtxAxis->GetBinLowEdge(vtxbin);
489 // Double_t vMax = vtxAxis->GetBinUpEdge(vtxbin);
490 VtxBin* bin = GetVtxBin(vtxbin);
717a4c2c 491 if (!bin) return false;
77f97e3f 492 Bool_t ret = bin->Collect(hists, sums, out, fSumRings, fSkipped, cent,
8449e3e0 493 fMergeMethod, fSkipFMDRings,
c8b1a7db 494 fByCent, eta2phi);
8449e3e0 495
496 return ret;
497}
498
c8b1a7db 499#define PF(N,V,...) \
500 AliForwardUtil::PrintField(N,V, ## __VA_ARGS__)
501#define PFB(N,FLAG) \
502 do { \
503 AliForwardUtil::PrintName(N); \
504 std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \
505 } while(false)
506#define PFV(N,VALUE) \
507 do { \
508 AliForwardUtil::PrintName(N); \
509 std::cout << (VALUE) << std::endl; } while(false)
510
8449e3e0 511//____________________________________________________________________
512void
513AliFMDHistCollector::Print(Option_t* /* option */) const
514{
515 //
516 // Print information
517 //
518 // Parameters:
519 // option Not used
520 //
c8b1a7db 521 TString merge("unknown");
8449e3e0 522 switch (fMergeMethod) {
c8b1a7db 523 case kStraightMean: merge = "straight mean"; break;
524 case kStraightMeanNoZero: merge = "straight mean (no zeros)"; break;
525 case kWeightedMean: merge = "weighted mean"; break;
526 case kLeastError: merge = "least error"; break;
527 case kSum: merge = "straight sum"; break;
528 case kPreferInner: merge = "prefer inners"; break;
529 case kPreferOuter: merge = "prefer outers"; break;
8449e3e0 530 }
c8b1a7db 531
532 AliForwardUtil::PrintTask(*this);
533 gROOT->IncreaseDirLevel();
534 PFV("# of cut bins", fNCutBins );
535 PFV("Fiducal method", (fFiducialMethod == kByCut ? "cut" : "distance"));
536 PFV("Fiducial cut", fCorrectionCut );
537 PFV("Merge method", merge);
8449e3e0 538
c8b1a7db 539 if (!fVtxList) {
540 gROOT->DecreaseDirLevel();
541 return;
542 }
543 char ind[64];
544 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
545 ind[gROOT->GetDirLevel()] = '\0';
8449e3e0 546
c8b1a7db 547 std::cout << ind << "Bin ranges:\n" << ind << " rings | Range ";
8449e3e0 548 Int_t nVz = fVtxList->GetEntriesFast();
549 for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
550 UShort_t d = 0;
551 Char_t r = 0;
552 GetDetRing(iIdx, d, r);
553 std::cout << ind << " | FMD" << d << r << " ";
554 }
555 std::cout << '\n' << ind << " /vz_bin |-----------";
556 for (Int_t iIdx = 0; iIdx < 5; iIdx++)
557 std::cout << "-+--------";
558 std::cout << std::endl;
559
560 for (UShort_t iVz = 1; iVz <= nVz; iVz++) {
561 const VtxBin* bin = GetVtxBin(iVz);
562 if (!bin) continue;
563 std::cout << " " << std::right << std::setw(6) << iVz << " | "
564 << std::setw(3) << bin->fLow << " - " << std::left
565 << std::setw(3) << bin->fHigh << " ";
566 for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
567 Int_t first, last;
568 bin->GetFirstAndLast(iIdx, first, last);
569 std::cout << " | " << std::setw(3) << first << "-"
570 << std::setw(3) << last;
571 }
572 std::cout << std::endl;
573 }
c8b1a7db 574 gROOT->DecreaseDirLevel();
8449e3e0 575}
576
577//____________________________________________________________________
578AliFMDHistCollector::VtxBin::VtxBin(Int_t idx, Double_t minIpZ, Double_t maxIpZ,
579 Int_t nCutBins)
580 : fIndex(idx),
581 fLow(minIpZ),
582 fHigh(maxIpZ),
583 fHitMap(0),
584 fFirstBin(1),
585 fLastBin(1),
586 fNCutBins(nCutBins)
587{
588}
589//____________________________________________________________________
590AliFMDHistCollector::VtxBin::VtxBin(const VtxBin& o)
591 : TObject(o),
592 fIndex(o.fIndex),
593 fLow(o.fLow),
594 fHigh(o.fHigh),
595 fHitMap(o.fHitMap),
596 fFirstBin(o.fFirstBin),
597 fLastBin(o.fLastBin),
598 fNCutBins(o.fNCutBins)
599{
600}
601//____________________________________________________________________
602AliFMDHistCollector::VtxBin&
603AliFMDHistCollector::VtxBin::operator=(const VtxBin& o)
604{
605 if (&o == this) return *this;
606 fIndex = o.fIndex;
607 fLow = o.fLow;
608 fHigh = o.fHigh;
609 fHitMap = o.fHitMap;
610 fFirstBin = o.fFirstBin;
611 fLastBin = o.fLastBin;
612 fNCutBins = o.fNCutBins;
613 return *this;
614}
615//____________________________________________________________________
616const Char_t*
617AliFMDHistCollector::VtxBin::GetName() const
618{
619 return Form("%c%03d_%c%03d",
620 (fLow >= 0 ? 'p' : 'm'), Int_t(TMath::Abs(fLow)),
621 (fHigh >= 0 ? 'p' : 'm'), Int_t(TMath::Abs(fHigh)));
622}
623//____________________________________________________________________
624void
625AliFMDHistCollector::VtxBin::SetupForData(TH2* coverage,
626 UShort_t skips,
627 FiducialMethod fiducial,
628 Double_t cut,
629 TList* l,
630 const TAxis& etaAxis,
631 Bool_t doHitMaps,
632 Bool_t storeSecMap)
633{
634 TList* out = 0;
635 if (doHitMaps || storeSecMap) {
636 out = new TList;
637 out->SetName(GetName());
638 out->SetOwner();
639 l->Add(out);
640 }
641 if (doHitMaps) {
642 fHitMap = new AliForwardUtil::Histos();
643 fHitMap->Init(etaAxis);
644 }
645 fFirstBin.Set(5);
646 fLastBin.Set(5);
647
73e536c6 648 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
73e536c6 649
8449e3e0 650 for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
651 UShort_t d = 0;
652 Char_t r = 0;
653 GetDetRing(iIdx, d, r);
654
655 // Skipping selected FMD rings
656 if (CheckSkip(d, r, skips)) continue;
657
658 // Get the background object
659 TH2D* bg = fcm.GetSecondaryMap()->GetCorrection(d,r,UShort_t(fIndex));
660 Int_t nEta = bg->GetNbinsX();
661 Int_t first = nEta+1;
662 Int_t last = 0;
663
664 // Loop over the eta bins
665 for (Int_t ie = 1; ie <= nEta; ie++) {
666 // Loop over the phi bins to make sure that we
667 // do not have holes in the coverage
668 bool ok = true;
669 for (Int_t ip = 1; ip <= bg->GetNbinsY(); ip++) {
670 if (!CheckCorrection(fiducial, cut, bg, ie, ip)) {
671 ok = false;
672 continue;
673 }
674 }
675 if (!ok) continue;
676
677 first = TMath::Min(ie, first);
678 last = TMath::Max(ie, last);
679 }
680 // Store result of first/last bin for this ring
681 fFirstBin[iIdx] = first;
682 fLastBin[iIdx] = last;
683
684 if (fHitMap) {
685 TH2* h = fHitMap->Get(d, r);
686 h->SetDirectory(0);
687 h->SetName(Form("hitMapFMD%d%c", d, r));
688 // if (r == 'O') h->RebinY(2);
689 out->Add(h);
690 }
691
692 TH2D* obg=0;
693 if(storeSecMap) {
694 obg = static_cast<TH2D*>(bg->Clone(Form("secMapFMD%d%c", d, r)));
695 obg->SetDirectory(0);
696 obg->Reset();
697 out->Add(obg);
698 }
699 // Fill diagnostics histograms
700 for (Int_t ie = first+fNCutBins; ie <= last-fNCutBins; ie++) {
701 Double_t old = coverage->GetBinContent(ie, fIndex);
702 coverage->SetBinContent(ie, fIndex, old+1);
703 if(obg) {
704 for (Int_t ip = 1; ip <= bg->GetNbinsY(); ip++) {
705 obg->SetBinContent(ie, ip, bg->GetBinContent(ie, ip));
706 obg->SetBinError(ie, ip, bg->GetBinError(ie, ip));
707 } // for (ip)
708 } // if (doSecHits)
709 } // for (ie)
710 } // for (iIdx)
711}
712
713//____________________________________________________________________
714void
715AliFMDHistCollector::VtxBin::GetFirstAndLast(Int_t idx,
716 Int_t& first,
717 Int_t& last) const
718{
719 // Get the first and last eta bin to use for a given ring and vertex
720 //
721 // Parameters:
722 // idx Ring index as given by GetIdx
723 // first On return, the first eta bin to use
724 // last On return, the last eta bin to use
725 //
726 first = 0;
727 last = 0;
728
729 if (idx < 0 || idx >= fFirstBin.GetSize()) return;
730
731 first = fFirstBin.At(idx)+fNCutBins;
732 last = fLastBin.At(idx)-fNCutBins;
733}
734//____________________________________________________________________
735Int_t
736AliFMDHistCollector::VtxBin::GetFirst(Int_t idx) const
737{
738 Int_t first, last;
739 GetFirstAndLast(idx, first , last);
740 return first;
741}
742//____________________________________________________________________
743Int_t
744AliFMDHistCollector::VtxBin::GetLast(Int_t idx) const
745{
746 Int_t first, last;
747 GetFirstAndLast(idx, first , last);
748 return last;
749}
750
6b7e379a 751#define PRINT_OVERFLOW(D,R,T,H) do { \
752 printf("Content of FMD%d%c overflow %s rebinning", D, R, T); \
753 Int_t i = 0; \
754 for (Int_t ix = 1; ix <= t->GetNbinsX(); ix++) { \
755 Double_t c = t->GetBinContent(ix, t->GetNbinsY()+1); \
756 if (c <= 1e-9) continue; \
757 if ((i % 10) == 0) printf("\n "); \
758 printf("%3d: %5.2f ", ix, c); \
759 i++; \
760 } \
761 printf("\n"); \
762 } while (false)
763
8449e3e0 764//____________________________________________________________________
765Bool_t
766AliFMDHistCollector::VtxBin::Collect(const AliForwardUtil::Histos& hists,
767 AliForwardUtil::Histos& sums,
768 TH2D& out,
769 TH2D* sumRings,
77f97e3f 770 TH1D* skipped,
8449e3e0 771 Double_t cent,
772 MergeMethod m,
773 UShort_t skips,
c8b1a7db 774 TList* byCent,
775 Bool_t eta2phi)
8449e3e0 776{
7e4038b5 777 for (UShort_t d=1; d<=3; d++) {
778 UShort_t nr = (d == 1 ? 1 : 2);
779 for (UShort_t q=0; q<nr; q++) {
780 Char_t r = (q == 0 ? 'I' : 'O');
77f97e3f 781 Int_t i = (d == 1 ? 1 : 2*d + (q == 0 ? -2 : -1));
7e4038b5 782 TH2D* h = hists.Get(d,r);
77f97e3f
CHC
783 if (CheckSkip(d, r, skips) || !h ||
784 h->TestBit(AliForwardUtil::kSkipRing)) {
785 // Skipping a ring - either because disable, not there, or
786 // because of flagged (too many outliers, ...)
787 skipped->Fill(i);
788 continue;
789 }
8449e3e0 790 TH2D* o = sums.Get(d, r);
7e4038b5 791 TH2D* t = static_cast<TH2D*>(h->Clone(Form("FMD%d%c_tmp",d,r)));
8449e3e0 792
5bb5d1f6 793 // Get valid range
7e4038b5 794 Int_t first = 0;
795 Int_t last = 0;
8449e3e0 796 GetFirstAndLast(d, r, first, last);
5bb5d1f6 797
798 // Zero outside valid range
5ca83fee 799 Int_t nY = t->GetNbinsY();
8449e3e0 800 Int_t nX = t->GetNbinsX();
5ca83fee 801 for (Int_t iPhi = 0; iPhi <= nY+1; iPhi++) {
5bb5d1f6 802 // Lower range
803 for (Int_t iEta = 1; iEta < first; iEta++) {
804 t->SetBinContent(iEta,iPhi,0);
805 t->SetBinError(iEta,iPhi,0);
806 }
8449e3e0 807 for (Int_t iEta = last+1; iEta <= nX; iEta++) {
5bb5d1f6 808 t->SetBinContent(iEta,iPhi,0);
809 t->SetBinError(iEta,iPhi,0);
810 }
811 }
bfab35d9 812 // Fill under-flow bins with eta coverage
813 for (Int_t iEta = first; iEta <= last; iEta++)
5bb5d1f6 814 t->SetBinContent(iEta,0,1);
c8b1a7db 815 if (eta2phi) {
816 for (Int_t iEta = first; iEta <= last; iEta++)
817 t->SetBinContent(iEta,nY+1,1);
818 }
bfab35d9 819
5bb5d1f6 820 // Add to our per-ring sum
821 o->Add(t);
bfab35d9 822
8449e3e0 823 // If we store hit maps, update here
824 if (fHitMap) fHitMap->Get(d, r)->Add(t);
4f9319f3 825
8449e3e0 826 if (byCent) {
827 TH3* dNdetaCent = static_cast<TH3*>(byCent->At(i-1));
828 if (cent >= 0 && dNdetaCent) {
829 Int_t iCent = dNdetaCent->GetYaxis()->FindBin(cent);
830
831 if (iCent > 0 && iCent <= dNdetaCent->GetNbinsY()) {
832 // Make a projection of data
833 TH1* proj = static_cast<TH1*>(t->ProjectionX("tmp", 1, nY));
834 proj->SetDirectory(0);
835 for (Int_t iEta = 1; iEta <= nX; iEta++) {
836 Double_t v1 = proj->GetBinContent(iEta);
837 Double_t e1 = proj->GetBinError(iEta);
838 Double_t v2 = dNdetaCent->GetBinContent(iEta, iCent, 1);
839 Double_t e2 = dNdetaCent->GetBinError(iEta, iCent, 1);
840 dNdetaCent->SetBinContent(iEta,iCent,1, v1+v2);
841 dNdetaCent->SetBinError(iEta,iCent,1, TMath::Sqrt(e1*e1+e2*e2));
842
843 // Check under-/overflow bins
844 Double_t uF = t->GetBinContent(iEta, 0);
845 Double_t oF = t->GetBinContent(iEta, nY+1);
846 if (uF > 0) {
847 Double_t old = dNdetaCent->GetBinContent(iEta, iCent, 0);
848 dNdetaCent->SetBinContent(iEta, iCent, 0, old + uF);
849 }
850 if (oF > 0) {
851 Double_t old = dNdetaCent->GetBinContent(iEta, iCent, 2);
852 dNdetaCent->SetBinContent(iEta, iCent, 2, old + oF);
853 }
854 } // for(iEta)
855 delete proj;
856 } // if(iCent)
857 } // if (cent)
858 } // if (byCent)
4f9319f3 859
5bb5d1f6 860 // Outer rings have better phi segmentation - rebin to same as inner.
6b7e379a 861 if (q == 1) {
862 // PRINT_OVERFLOW(d, r, "before", t);
863 t->RebinY(2);
864 // PRINT_OVERFLOW(d, r, "after", t);
865 }
7e4038b5 866
5ca83fee 867 nY = t->GetNbinsY();
bfab35d9 868
7e4038b5 869 // Now update profile output
870 for (Int_t iEta = first; iEta <= last; iEta++) {
871
872 // Get the possibly overlapping histogram
8449e3e0 873 Int_t overlap = GetOverlap(d,r,iEta);
7e4038b5 874
5ca83fee 875 // Get factor
bfab35d9 876 MergeMethod mm = m; // Possibly override method locally
877 Float_t fac = 1;
878 if (m != kSum && overlap >= 0) {
879 // Default is to average
880 fac = 0.5;
881 if (m == kPreferInner) {
882 // Current one is an outer overlapping an inner
883 if ((r == 'o' || r == 'O') &&
884 (overlap == 0 || overlap == 1 || overlap == 3))
885 // Do not use this signal
886 fac = 0;
887 // Current one is inner overlapping an outer
888 else if ((r == 'i' || r == 'I') && (overlap == 2 || overlap == 4))
889 // Prefer this one
890 fac = 1;
891 else
892 // In case of two overlapping inners
893 mm = kStraightMean;
894 }
895 else if (m == kPreferOuter) {
896 // Current one is an inner overlapping an outer
897 if ((r == 'i' || r == 'I') && (overlap == 2 || overlap == 4))
898 // Do not use this signal
899 fac = 0;
900 else if ((r == 'O' || r == 'o') &&
901 (overlap == 0 || overlap == 1 || overlap == 3))
902 fac = 1;
903 else
904 // In case of two overlapping outers
905 mm = kStraightMean;
906 }
907 }
5ca83fee 908
909 // Fill eta acceptance for this event into the phi underflow bin
7e4038b5 910 Float_t ooc = out.GetBinContent(iEta,0);
5ca83fee 911 out.SetBinContent(iEta, 0, ooc + fac);
912
913 // Fill phi acceptance for this event into the phi overflow bin
914 Float_t oop = out.GetBinContent(iEta,nY+1);
915 Float_t nop = t->GetBinContent(iEta,nY+1);
916#if 0
917 Info("", "etaBin=%3d Setting phi acceptance to %f(%f+%f)=%f",
918 iEta, fac, oop, nop, fac*(oop+nop));
919#endif
920 out.SetBinContent(iEta, nY+1, fac * nop + oop);
7e4038b5 921
5bb5d1f6 922 // Should we loop over h or t Y bins - I think it's t
5ca83fee 923 for (Int_t iPhi = 1; iPhi <= nY; iPhi++) {
12fffad7 924 Double_t c = t->GetBinContent(iEta,iPhi);
925 Double_t e = t->GetBinError(iEta,iPhi);
926 Double_t ee = t->GetXaxis()->GetBinCenter(iEta);
8449e3e0 927 sumRings->Fill(ee, i, c);
7e4038b5 928
bfab35d9 929 // If there's no signal or the signal was ignored because we
930 // prefer the inners/outers, continue if (e <= 0) continue;
931 if (fac <= 0 || c <= 0 || e <= 0) continue;
7e4038b5 932
bfab35d9 933 // If there's no overlapping histogram (ring) or if we
934 // prefer inner/outer, then fill in data and continue to the
935 // next phi bin
936 if (overlap < 0 || fac >= 1) {
7e4038b5 937 out.SetBinContent(iEta,iPhi,c);
938 out.SetBinError(iEta,iPhi,e);
939 continue;
940 }
941
942 // Get the current bin content and error
943 Double_t oc = out.GetBinContent(iEta,iPhi);
944 Double_t oe = out.GetBinError(iEta,iPhi);
945
e1f47419 946 Double_t rc, re;
bfab35d9 947 MergeBins(mm, c, e, oc, oe, rc, re);
e1f47419 948 out.SetBinContent(iEta,iPhi, rc);
949 out.SetBinError(iEta,iPhi, re);
7e4038b5 950 }
951 }
36ffcf83 952 // Remove temporary histogram
7e4038b5 953 delete t;
954 } // for r
955 } // for d
8449e3e0 956 return true;
7e4038b5 957}
0bd4b00f 958//____________________________________________________________________
8449e3e0 959Int_t
960AliFMDHistCollector::VtxBin::GetOverlap(UShort_t d, Char_t r,
961 Int_t bin) const
0bd4b00f 962{
7984e5f7 963 //
8449e3e0 964 // Get the possibly overlapping histogram of eta bin @a e in
965 // detector and ring
7984e5f7 966 //
967 // Parameters:
8449e3e0 968 // d Detector
969 // r Ring
970 // e Eta bin
971 // v Vertex bin (1 based)
7984e5f7 972 //
8449e3e0 973 // Return:
974 // Overlapping histogram index or -1
975 //
976
977 Int_t other = -1;
978 if (d == 1) {
979 if (bin <= GetLast(2,'I')) other = GetIdx(2,'I');
e1f47419 980 }
8449e3e0 981 else if (d == 2 && r == 'I') {
982 if (bin <= GetLast(2, 'O')) other = GetIdx(2, 'O');
983 else if (bin >= GetFirst(1, 'I')) other = GetIdx(1, 'I');
5bb5d1f6 984 }
8449e3e0 985 else if (d == 2 && r == 'O') {
986 if (bin >= GetFirst(2, 'I')) other = GetIdx(2,'I');
0bd4b00f 987 }
8449e3e0 988 else if (d == 3 && r == 'O') {
989 if (bin <= GetLast(3, 'I')) other = GetIdx(3, 'I');
990 }
991 else if (d == 3 && r == 'I') {
992 if (bin >= GetFirst(3, 'O')) other = GetIdx(3, 'O');
993 }
994 // AliInfo(Form("FMD%d%c (%d) -> %d", d, r, GetIdx(d,r), other));
995 return other;
0bd4b00f 996}
8449e3e0 997
7e4038b5 998
999//____________________________________________________________________
1000//
1001// EOF
1002//
1003
1004
1005