]>
Commit | Line | Data |
---|---|---|
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 | |
34 | ClassImp(AliFMDHistCollector) | |
35 | #if 0 | |
36 | ; // For Emacs | |
37 | #endif | |
38 | ||
5bb5d1f6 | 39 | //____________________________________________________________________ |
40 | AliFMDHistCollector::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 | //____________________________________________________________________ | |
60 | AliFMDHistCollector::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 | //____________________________________________________________________ | |
80 | AliFMDHistCollector::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 | //____________________________________________________________________ |
101 | AliFMDHistCollector::~AliFMDHistCollector() | |
102 | { | |
6ab100ec | 103 | DGUARD(fDebug, 3, "DTOR of AliFMDHistCollector"); |
b7ab8a2c | 104 | // if (fList) delete fList; |
12fffad7 | 105 | } |
7e4038b5 | 106 | //____________________________________________________________________ |
107 | AliFMDHistCollector& | |
108 | AliFMDHistCollector::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 | //____________________________________________________________________ | |
141 | void | |
5934a3e3 | 142 | AliFMDHistCollector::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 | //____________________________________________________________________ |
243 | Bool_t | |
8449e3e0 | 244 | AliFMDHistCollector::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 | //____________________________________________________________________ |
276 | void | |
5934a3e3 | 277 | AliFMDHistCollector::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 | //____________________________________________________________________ |
294 | Bool_t | |
295 | AliFMDHistCollector::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 | //____________________________________________________________________ |
305 | Int_t | |
8449e3e0 | 306 | AliFMDHistCollector::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 | //____________________________________________________________________ | |
327 | void | |
8449e3e0 | 328 | AliFMDHistCollector::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 | 350 | AliFMDHistCollector::VtxBin* |
351 | AliFMDHistCollector::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 | 361 | const AliFMDHistCollector::VtxBin* |
362 | AliFMDHistCollector::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 | //____________________________________________________________________ |
373 | void | |
8449e3e0 | 374 | AliFMDHistCollector::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 | //____________________________________________________________________ |
466 | Bool_t | |
5bb5d1f6 | 467 | AliFMDHistCollector::Collect(const AliForwardUtil::Histos& hists, |
468 | AliForwardUtil::Histos& sums, | |
0bd4b00f | 469 | UShort_t vtxbin, |
4f9319f3 | 470 | TH2D& out, |
c8b1a7db | 471 | Double_t cent, |
45533148 | 472 | Bool_t eta2phi, |
473 | Bool_t add) | |
7e4038b5 | 474 | { |
7984e5f7 | 475 | // |
476 | // Do the calculations | |
477 | // | |
478 | // Parameters: | |
479 | // hists Cache of histograms | |
480 | // vtxBin Vertex bin (1 based) | |
481 | // out Output histogram | |
482 | // | |
483 | // Return: | |
484 | // true on successs | |
485 | // | |
6ab100ec | 486 | DGUARD(fDebug, 1, "Collect final histogram of AliFMDHistCollector"); |
8449e3e0 | 487 | // AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance(); |
488 | // const TAxis* vtxAxis = fcm.GetVertexAxis(); | |
489 | // Double_t vMin = vtxAxis->GetBinLowEdge(vtxbin); | |
490 | // Double_t vMax = vtxAxis->GetBinUpEdge(vtxbin); | |
491 | VtxBin* bin = GetVtxBin(vtxbin); | |
717a4c2c | 492 | if (!bin) return false; |
77f97e3f | 493 | Bool_t ret = bin->Collect(hists, sums, out, fSumRings, fSkipped, cent, |
8449e3e0 | 494 | fMergeMethod, fSkipFMDRings, |
45533148 | 495 | fByCent, eta2phi, add); |
8449e3e0 | 496 | |
497 | return ret; | |
498 | } | |
499 | ||
c8b1a7db | 500 | #define PF(N,V,...) \ |
501 | AliForwardUtil::PrintField(N,V, ## __VA_ARGS__) | |
502 | #define PFB(N,FLAG) \ | |
503 | do { \ | |
504 | AliForwardUtil::PrintName(N); \ | |
505 | std::cout << std::boolalpha << (FLAG) << std::noboolalpha << std::endl; \ | |
506 | } while(false) | |
507 | #define PFV(N,VALUE) \ | |
508 | do { \ | |
509 | AliForwardUtil::PrintName(N); \ | |
510 | std::cout << (VALUE) << std::endl; } while(false) | |
511 | ||
8449e3e0 | 512 | //____________________________________________________________________ |
513 | void | |
514 | AliFMDHistCollector::Print(Option_t* /* option */) const | |
515 | { | |
516 | // | |
517 | // Print information | |
518 | // | |
519 | // Parameters: | |
520 | // option Not used | |
521 | // | |
c8b1a7db | 522 | TString merge("unknown"); |
8449e3e0 | 523 | switch (fMergeMethod) { |
c8b1a7db | 524 | case kStraightMean: merge = "straight mean"; break; |
525 | case kStraightMeanNoZero: merge = "straight mean (no zeros)"; break; | |
526 | case kWeightedMean: merge = "weighted mean"; break; | |
527 | case kLeastError: merge = "least error"; break; | |
528 | case kSum: merge = "straight sum"; break; | |
529 | case kPreferInner: merge = "prefer inners"; break; | |
530 | case kPreferOuter: merge = "prefer outers"; break; | |
8449e3e0 | 531 | } |
c8b1a7db | 532 | |
533 | AliForwardUtil::PrintTask(*this); | |
534 | gROOT->IncreaseDirLevel(); | |
535 | PFV("# of cut bins", fNCutBins ); | |
536 | PFV("Fiducal method", (fFiducialMethod == kByCut ? "cut" : "distance")); | |
537 | PFV("Fiducial cut", fCorrectionCut ); | |
538 | PFV("Merge method", merge); | |
8449e3e0 | 539 | |
c8b1a7db | 540 | if (!fVtxList) { |
541 | gROOT->DecreaseDirLevel(); | |
542 | return; | |
543 | } | |
544 | char ind[64]; | |
545 | for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' '; | |
546 | ind[gROOT->GetDirLevel()] = '\0'; | |
8449e3e0 | 547 | |
c8b1a7db | 548 | std::cout << ind << "Bin ranges:\n" << ind << " rings | Range "; |
8449e3e0 | 549 | Int_t nVz = fVtxList->GetEntriesFast(); |
550 | for (Int_t iIdx = 0; iIdx < 5; iIdx++) { | |
551 | UShort_t d = 0; | |
552 | Char_t r = 0; | |
553 | GetDetRing(iIdx, d, r); | |
554 | std::cout << ind << " | FMD" << d << r << " "; | |
555 | } | |
556 | std::cout << '\n' << ind << " /vz_bin |-----------"; | |
557 | for (Int_t iIdx = 0; iIdx < 5; iIdx++) | |
558 | std::cout << "-+--------"; | |
559 | std::cout << std::endl; | |
560 | ||
561 | for (UShort_t iVz = 1; iVz <= nVz; iVz++) { | |
562 | const VtxBin* bin = GetVtxBin(iVz); | |
563 | if (!bin) continue; | |
564 | std::cout << " " << std::right << std::setw(6) << iVz << " | " | |
565 | << std::setw(3) << bin->fLow << " - " << std::left | |
566 | << std::setw(3) << bin->fHigh << " "; | |
567 | for (Int_t iIdx = 0; iIdx < 5; iIdx++) { | |
568 | Int_t first, last; | |
569 | bin->GetFirstAndLast(iIdx, first, last); | |
570 | std::cout << " | " << std::setw(3) << first << "-" | |
571 | << std::setw(3) << last; | |
572 | } | |
573 | std::cout << std::endl; | |
574 | } | |
c8b1a7db | 575 | gROOT->DecreaseDirLevel(); |
8449e3e0 | 576 | } |
577 | ||
578 | //____________________________________________________________________ | |
579 | AliFMDHistCollector::VtxBin::VtxBin(Int_t idx, Double_t minIpZ, Double_t maxIpZ, | |
580 | Int_t nCutBins) | |
581 | : fIndex(idx), | |
582 | fLow(minIpZ), | |
583 | fHigh(maxIpZ), | |
584 | fHitMap(0), | |
585 | fFirstBin(1), | |
586 | fLastBin(1), | |
587 | fNCutBins(nCutBins) | |
588 | { | |
589 | } | |
590 | //____________________________________________________________________ | |
591 | AliFMDHistCollector::VtxBin::VtxBin(const VtxBin& o) | |
592 | : TObject(o), | |
593 | fIndex(o.fIndex), | |
594 | fLow(o.fLow), | |
595 | fHigh(o.fHigh), | |
596 | fHitMap(o.fHitMap), | |
597 | fFirstBin(o.fFirstBin), | |
598 | fLastBin(o.fLastBin), | |
599 | fNCutBins(o.fNCutBins) | |
600 | { | |
601 | } | |
602 | //____________________________________________________________________ | |
603 | AliFMDHistCollector::VtxBin& | |
604 | AliFMDHistCollector::VtxBin::operator=(const VtxBin& o) | |
605 | { | |
606 | if (&o == this) return *this; | |
607 | fIndex = o.fIndex; | |
608 | fLow = o.fLow; | |
609 | fHigh = o.fHigh; | |
610 | fHitMap = o.fHitMap; | |
611 | fFirstBin = o.fFirstBin; | |
612 | fLastBin = o.fLastBin; | |
613 | fNCutBins = o.fNCutBins; | |
614 | return *this; | |
615 | } | |
616 | //____________________________________________________________________ | |
617 | const Char_t* | |
618 | AliFMDHistCollector::VtxBin::GetName() const | |
619 | { | |
620 | return Form("%c%03d_%c%03d", | |
621 | (fLow >= 0 ? 'p' : 'm'), Int_t(TMath::Abs(fLow)), | |
622 | (fHigh >= 0 ? 'p' : 'm'), Int_t(TMath::Abs(fHigh))); | |
623 | } | |
624 | //____________________________________________________________________ | |
625 | void | |
626 | AliFMDHistCollector::VtxBin::SetupForData(TH2* coverage, | |
627 | UShort_t skips, | |
628 | FiducialMethod fiducial, | |
629 | Double_t cut, | |
630 | TList* l, | |
631 | const TAxis& etaAxis, | |
632 | Bool_t doHitMaps, | |
633 | Bool_t storeSecMap) | |
634 | { | |
635 | TList* out = 0; | |
636 | if (doHitMaps || storeSecMap) { | |
637 | out = new TList; | |
638 | out->SetName(GetName()); | |
639 | out->SetOwner(); | |
640 | l->Add(out); | |
641 | } | |
642 | if (doHitMaps) { | |
643 | fHitMap = new AliForwardUtil::Histos(); | |
644 | fHitMap->Init(etaAxis); | |
645 | } | |
646 | fFirstBin.Set(5); | |
647 | fLastBin.Set(5); | |
648 | ||
73e536c6 | 649 | AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance(); |
73e536c6 | 650 | |
8449e3e0 | 651 | for (Int_t iIdx = 0; iIdx < 5; iIdx++) { |
652 | UShort_t d = 0; | |
653 | Char_t r = 0; | |
654 | GetDetRing(iIdx, d, r); | |
655 | ||
656 | // Skipping selected FMD rings | |
657 | if (CheckSkip(d, r, skips)) continue; | |
658 | ||
659 | // Get the background object | |
660 | TH2D* bg = fcm.GetSecondaryMap()->GetCorrection(d,r,UShort_t(fIndex)); | |
661 | Int_t nEta = bg->GetNbinsX(); | |
662 | Int_t first = nEta+1; | |
663 | Int_t last = 0; | |
664 | ||
665 | // Loop over the eta bins | |
666 | for (Int_t ie = 1; ie <= nEta; ie++) { | |
667 | // Loop over the phi bins to make sure that we | |
668 | // do not have holes in the coverage | |
669 | bool ok = true; | |
670 | for (Int_t ip = 1; ip <= bg->GetNbinsY(); ip++) { | |
671 | if (!CheckCorrection(fiducial, cut, bg, ie, ip)) { | |
672 | ok = false; | |
673 | continue; | |
674 | } | |
675 | } | |
676 | if (!ok) continue; | |
677 | ||
678 | first = TMath::Min(ie, first); | |
679 | last = TMath::Max(ie, last); | |
680 | } | |
681 | // Store result of first/last bin for this ring | |
682 | fFirstBin[iIdx] = first; | |
683 | fLastBin[iIdx] = last; | |
684 | ||
a26aa8b2 | 685 | if (doHitMaps) { |
8449e3e0 | 686 | TH2* h = fHitMap->Get(d, r); |
687 | h->SetDirectory(0); | |
688 | h->SetName(Form("hitMapFMD%d%c", d, r)); | |
689 | // if (r == 'O') h->RebinY(2); | |
690 | out->Add(h); | |
691 | } | |
692 | ||
693 | TH2D* obg=0; | |
694 | if(storeSecMap) { | |
695 | obg = static_cast<TH2D*>(bg->Clone(Form("secMapFMD%d%c", d, r))); | |
696 | obg->SetDirectory(0); | |
697 | obg->Reset(); | |
698 | out->Add(obg); | |
699 | } | |
700 | // Fill diagnostics histograms | |
701 | for (Int_t ie = first+fNCutBins; ie <= last-fNCutBins; ie++) { | |
702 | Double_t old = coverage->GetBinContent(ie, fIndex); | |
703 | coverage->SetBinContent(ie, fIndex, old+1); | |
704 | if(obg) { | |
705 | for (Int_t ip = 1; ip <= bg->GetNbinsY(); ip++) { | |
706 | obg->SetBinContent(ie, ip, bg->GetBinContent(ie, ip)); | |
707 | obg->SetBinError(ie, ip, bg->GetBinError(ie, ip)); | |
708 | } // for (ip) | |
709 | } // if (doSecHits) | |
710 | } // for (ie) | |
711 | } // for (iIdx) | |
712 | } | |
713 | ||
714 | //____________________________________________________________________ | |
715 | void | |
716 | AliFMDHistCollector::VtxBin::GetFirstAndLast(Int_t idx, | |
717 | Int_t& first, | |
718 | Int_t& last) const | |
719 | { | |
720 | // Get the first and last eta bin to use for a given ring and vertex | |
721 | // | |
722 | // Parameters: | |
723 | // idx Ring index as given by GetIdx | |
724 | // first On return, the first eta bin to use | |
725 | // last On return, the last eta bin to use | |
726 | // | |
727 | first = 0; | |
728 | last = 0; | |
729 | ||
730 | if (idx < 0 || idx >= fFirstBin.GetSize()) return; | |
731 | ||
732 | first = fFirstBin.At(idx)+fNCutBins; | |
733 | last = fLastBin.At(idx)-fNCutBins; | |
734 | } | |
735 | //____________________________________________________________________ | |
736 | Int_t | |
737 | AliFMDHistCollector::VtxBin::GetFirst(Int_t idx) const | |
738 | { | |
739 | Int_t first, last; | |
740 | GetFirstAndLast(idx, first , last); | |
741 | return first; | |
742 | } | |
743 | //____________________________________________________________________ | |
744 | Int_t | |
745 | AliFMDHistCollector::VtxBin::GetLast(Int_t idx) const | |
746 | { | |
747 | Int_t first, last; | |
748 | GetFirstAndLast(idx, first , last); | |
749 | return last; | |
750 | } | |
751 | ||
6b7e379a | 752 | #define PRINT_OVERFLOW(D,R,T,H) do { \ |
753 | printf("Content of FMD%d%c overflow %s rebinning", D, R, T); \ | |
754 | Int_t i = 0; \ | |
755 | for (Int_t ix = 1; ix <= t->GetNbinsX(); ix++) { \ | |
756 | Double_t c = t->GetBinContent(ix, t->GetNbinsY()+1); \ | |
757 | if (c <= 1e-9) continue; \ | |
758 | if ((i % 10) == 0) printf("\n "); \ | |
759 | printf("%3d: %5.2f ", ix, c); \ | |
760 | i++; \ | |
761 | } \ | |
762 | printf("\n"); \ | |
763 | } while (false) | |
764 | ||
8449e3e0 | 765 | //____________________________________________________________________ |
766 | Bool_t | |
767 | AliFMDHistCollector::VtxBin::Collect(const AliForwardUtil::Histos& hists, | |
768 | AliForwardUtil::Histos& sums, | |
769 | TH2D& out, | |
770 | TH2D* sumRings, | |
77f97e3f | 771 | TH1D* skipped, |
8449e3e0 | 772 | Double_t cent, |
773 | MergeMethod m, | |
774 | UShort_t skips, | |
c8b1a7db | 775 | TList* byCent, |
45533148 | 776 | Bool_t eta2phi, |
777 | Bool_t add) | |
8449e3e0 | 778 | { |
7e4038b5 | 779 | for (UShort_t d=1; d<=3; d++) { |
780 | UShort_t nr = (d == 1 ? 1 : 2); | |
781 | for (UShort_t q=0; q<nr; q++) { | |
782 | Char_t r = (q == 0 ? 'I' : 'O'); | |
77f97e3f | 783 | Int_t i = (d == 1 ? 1 : 2*d + (q == 0 ? -2 : -1)); |
7e4038b5 | 784 | TH2D* h = hists.Get(d,r); |
77f97e3f CHC |
785 | if (CheckSkip(d, r, skips) || !h || |
786 | h->TestBit(AliForwardUtil::kSkipRing)) { | |
787 | // Skipping a ring - either because disable, not there, or | |
788 | // because of flagged (too many outliers, ...) | |
789 | skipped->Fill(i); | |
790 | continue; | |
791 | } | |
8449e3e0 | 792 | TH2D* o = sums.Get(d, r); |
7e4038b5 | 793 | TH2D* t = static_cast<TH2D*>(h->Clone(Form("FMD%d%c_tmp",d,r))); |
8449e3e0 | 794 | |
5bb5d1f6 | 795 | // Get valid range |
7e4038b5 | 796 | Int_t first = 0; |
797 | Int_t last = 0; | |
8449e3e0 | 798 | GetFirstAndLast(d, r, first, last); |
5bb5d1f6 | 799 | |
800 | // Zero outside valid range | |
5ca83fee | 801 | Int_t nY = t->GetNbinsY(); |
8449e3e0 | 802 | Int_t nX = t->GetNbinsX(); |
5ca83fee | 803 | for (Int_t iPhi = 0; iPhi <= nY+1; iPhi++) { |
5bb5d1f6 | 804 | // Lower range |
805 | for (Int_t iEta = 1; iEta < first; iEta++) { | |
806 | t->SetBinContent(iEta,iPhi,0); | |
807 | t->SetBinError(iEta,iPhi,0); | |
808 | } | |
8449e3e0 | 809 | for (Int_t iEta = last+1; iEta <= nX; iEta++) { |
5bb5d1f6 | 810 | t->SetBinContent(iEta,iPhi,0); |
811 | t->SetBinError(iEta,iPhi,0); | |
812 | } | |
813 | } | |
bfab35d9 | 814 | // Fill under-flow bins with eta coverage |
815 | for (Int_t iEta = first; iEta <= last; iEta++) | |
5bb5d1f6 | 816 | t->SetBinContent(iEta,0,1); |
c8b1a7db | 817 | if (eta2phi) { |
818 | for (Int_t iEta = first; iEta <= last; iEta++) | |
819 | t->SetBinContent(iEta,nY+1,1); | |
820 | } | |
bfab35d9 | 821 | |
45533148 | 822 | if (add) { |
823 | // Add to our per-ring sum | |
824 | o->Add(t); | |
bfab35d9 | 825 | |
3a2b980d | 826 | // If we store hit maps, update here If "eta2phi" is true, |
827 | // then we are here for MC, and so we do not update the hit | |
828 | // maps - ever! | |
829 | if (fHitMap && !eta2phi) fHitMap->Get(d, r)->Add(t); | |
45533148 | 830 | |
4f9319f3 | 831 | |
45533148 | 832 | if (byCent) { |
833 | TH3* dNdetaCent = static_cast<TH3*>(byCent->At(i-1)); | |
834 | if (cent >= 0 && dNdetaCent) { | |
835 | Int_t iCent = dNdetaCent->GetYaxis()->FindBin(cent); | |
8449e3e0 | 836 | |
45533148 | 837 | if (iCent > 0 && iCent <= dNdetaCent->GetNbinsY()) { |
838 | // Make a projection of data | |
839 | TH1* proj = static_cast<TH1*>(t->ProjectionX("tmp", 1, nY)); | |
840 | proj->SetDirectory(0); | |
841 | for (Int_t iEta = 1; iEta <= nX; iEta++) { | |
842 | Double_t v1 = proj->GetBinContent(iEta); | |
843 | Double_t e1 = proj->GetBinError(iEta); | |
844 | Double_t v2 = dNdetaCent->GetBinContent(iEta, iCent, 1); | |
845 | Double_t e2 = dNdetaCent->GetBinError(iEta, iCent, 1); | |
846 | dNdetaCent->SetBinContent(iEta,iCent,1, v1+v2); | |
847 | dNdetaCent->SetBinError(iEta,iCent,1, TMath::Sqrt(e1*e1+e2*e2)); | |
8449e3e0 | 848 | |
45533148 | 849 | // Check under-/overflow bins |
850 | Double_t uF = t->GetBinContent(iEta, 0); | |
851 | Double_t oF = t->GetBinContent(iEta, nY+1); | |
852 | if (uF > 0) { | |
853 | Double_t old = dNdetaCent->GetBinContent(iEta, iCent, 0); | |
854 | dNdetaCent->SetBinContent(iEta, iCent, 0, old + uF); | |
855 | } | |
856 | if (oF > 0) { | |
857 | Double_t old = dNdetaCent->GetBinContent(iEta, iCent, 2); | |
858 | dNdetaCent->SetBinContent(iEta, iCent, 2, old + oF); | |
859 | } | |
860 | } // for(iEta) | |
861 | delete proj; | |
862 | } // if(iCent) | |
863 | } // if (cent) | |
864 | } // if (byCent) | |
865 | } // if (add) | |
4f9319f3 | 866 | |
5bb5d1f6 | 867 | // Outer rings have better phi segmentation - rebin to same as inner. |
6b7e379a | 868 | if (q == 1) { |
869 | // PRINT_OVERFLOW(d, r, "before", t); | |
870 | t->RebinY(2); | |
871 | // PRINT_OVERFLOW(d, r, "after", t); | |
872 | } | |
7e4038b5 | 873 | |
5ca83fee | 874 | nY = t->GetNbinsY(); |
bfab35d9 | 875 | |
7e4038b5 | 876 | // Now update profile output |
877 | for (Int_t iEta = first; iEta <= last; iEta++) { | |
878 | ||
879 | // Get the possibly overlapping histogram | |
8449e3e0 | 880 | Int_t overlap = GetOverlap(d,r,iEta); |
7e4038b5 | 881 | |
5ca83fee | 882 | // Get factor |
bfab35d9 | 883 | MergeMethod mm = m; // Possibly override method locally |
884 | Float_t fac = 1; | |
885 | if (m != kSum && overlap >= 0) { | |
886 | // Default is to average | |
887 | fac = 0.5; | |
888 | if (m == kPreferInner) { | |
889 | // Current one is an outer overlapping an inner | |
890 | if ((r == 'o' || r == 'O') && | |
891 | (overlap == 0 || overlap == 1 || overlap == 3)) | |
892 | // Do not use this signal | |
893 | fac = 0; | |
894 | // Current one is inner overlapping an outer | |
895 | else if ((r == 'i' || r == 'I') && (overlap == 2 || overlap == 4)) | |
896 | // Prefer this one | |
897 | fac = 1; | |
898 | else | |
899 | // In case of two overlapping inners | |
900 | mm = kStraightMean; | |
901 | } | |
902 | else if (m == kPreferOuter) { | |
903 | // Current one is an inner overlapping an outer | |
904 | if ((r == 'i' || r == 'I') && (overlap == 2 || overlap == 4)) | |
905 | // Do not use this signal | |
906 | fac = 0; | |
907 | else if ((r == 'O' || r == 'o') && | |
908 | (overlap == 0 || overlap == 1 || overlap == 3)) | |
909 | fac = 1; | |
910 | else | |
911 | // In case of two overlapping outers | |
912 | mm = kStraightMean; | |
913 | } | |
914 | } | |
5ca83fee | 915 | |
916 | // Fill eta acceptance for this event into the phi underflow bin | |
7e4038b5 | 917 | Float_t ooc = out.GetBinContent(iEta,0); |
5ca83fee | 918 | out.SetBinContent(iEta, 0, ooc + fac); |
919 | ||
920 | // Fill phi acceptance for this event into the phi overflow bin | |
921 | Float_t oop = out.GetBinContent(iEta,nY+1); | |
922 | Float_t nop = t->GetBinContent(iEta,nY+1); | |
923 | #if 0 | |
924 | Info("", "etaBin=%3d Setting phi acceptance to %f(%f+%f)=%f", | |
925 | iEta, fac, oop, nop, fac*(oop+nop)); | |
926 | #endif | |
927 | out.SetBinContent(iEta, nY+1, fac * nop + oop); | |
7e4038b5 | 928 | |
5bb5d1f6 | 929 | // Should we loop over h or t Y bins - I think it's t |
5ca83fee | 930 | for (Int_t iPhi = 1; iPhi <= nY; iPhi++) { |
12fffad7 | 931 | Double_t c = t->GetBinContent(iEta,iPhi); |
932 | Double_t e = t->GetBinError(iEta,iPhi); | |
933 | Double_t ee = t->GetXaxis()->GetBinCenter(iEta); | |
8449e3e0 | 934 | sumRings->Fill(ee, i, c); |
7e4038b5 | 935 | |
bfab35d9 | 936 | // If there's no signal or the signal was ignored because we |
937 | // prefer the inners/outers, continue if (e <= 0) continue; | |
938 | if (fac <= 0 || c <= 0 || e <= 0) continue; | |
7e4038b5 | 939 | |
bfab35d9 | 940 | // If there's no overlapping histogram (ring) or if we |
941 | // prefer inner/outer, then fill in data and continue to the | |
942 | // next phi bin | |
943 | if (overlap < 0 || fac >= 1) { | |
7e4038b5 | 944 | out.SetBinContent(iEta,iPhi,c); |
945 | out.SetBinError(iEta,iPhi,e); | |
946 | continue; | |
947 | } | |
948 | ||
949 | // Get the current bin content and error | |
950 | Double_t oc = out.GetBinContent(iEta,iPhi); | |
951 | Double_t oe = out.GetBinError(iEta,iPhi); | |
952 | ||
e1f47419 | 953 | Double_t rc, re; |
bfab35d9 | 954 | MergeBins(mm, c, e, oc, oe, rc, re); |
e1f47419 | 955 | out.SetBinContent(iEta,iPhi, rc); |
956 | out.SetBinError(iEta,iPhi, re); | |
7e4038b5 | 957 | } |
958 | } | |
36ffcf83 | 959 | // Remove temporary histogram |
7e4038b5 | 960 | delete t; |
961 | } // for r | |
962 | } // for d | |
8449e3e0 | 963 | return true; |
7e4038b5 | 964 | } |
0bd4b00f | 965 | //____________________________________________________________________ |
8449e3e0 | 966 | Int_t |
967 | AliFMDHistCollector::VtxBin::GetOverlap(UShort_t d, Char_t r, | |
968 | Int_t bin) const | |
0bd4b00f | 969 | { |
7984e5f7 | 970 | // |
8449e3e0 | 971 | // Get the possibly overlapping histogram of eta bin @a e in |
972 | // detector and ring | |
7984e5f7 | 973 | // |
974 | // Parameters: | |
8449e3e0 | 975 | // d Detector |
976 | // r Ring | |
977 | // e Eta bin | |
978 | // v Vertex bin (1 based) | |
7984e5f7 | 979 | // |
8449e3e0 | 980 | // Return: |
981 | // Overlapping histogram index or -1 | |
982 | // | |
983 | ||
984 | Int_t other = -1; | |
985 | if (d == 1) { | |
986 | if (bin <= GetLast(2,'I')) other = GetIdx(2,'I'); | |
e1f47419 | 987 | } |
8449e3e0 | 988 | else if (d == 2 && r == 'I') { |
989 | if (bin <= GetLast(2, 'O')) other = GetIdx(2, 'O'); | |
990 | else if (bin >= GetFirst(1, 'I')) other = GetIdx(1, 'I'); | |
5bb5d1f6 | 991 | } |
8449e3e0 | 992 | else if (d == 2 && r == 'O') { |
993 | if (bin >= GetFirst(2, 'I')) other = GetIdx(2,'I'); | |
0bd4b00f | 994 | } |
8449e3e0 | 995 | else if (d == 3 && r == 'O') { |
996 | if (bin <= GetLast(3, 'I')) other = GetIdx(3, 'I'); | |
997 | } | |
998 | else if (d == 3 && r == 'I') { | |
999 | if (bin >= GetFirst(3, 'O')) other = GetIdx(3, 'O'); | |
1000 | } | |
1001 | // AliInfo(Form("FMD%d%c (%d) -> %d", d, r, GetIdx(d,r), other)); | |
1002 | return other; | |
0bd4b00f | 1003 | } |
8449e3e0 | 1004 | |
7e4038b5 | 1005 | |
1006 | //____________________________________________________________________ | |
1007 | // | |
1008 | // EOF | |
1009 | // | |
1010 | ||
1011 | ||
1012 |