1 // Calculate the total energy loss
2 #include "AliFMDHistCollector.h"
7 // #include "AliFMDAnaParameters.h"
8 #include "AliForwardCorrectionManager.h"
13 #include <TProfile2D.h>
19 ClassImp(AliFMDHistCollector)
25 //____________________________________________________________________
27 AliFMDHistCollector::operator=(const AliFMDHistCollector& o)
31 fNCutBins = o.fNCutBins;
32 fCorrectionCut = o.fCorrectionCut;
33 fFirstBins = o.fFirstBins;
34 fLastBins = o.fLastBins;
40 //____________________________________________________________________
42 AliFMDHistCollector::Init(const TAxis& vtxAxis)
44 // AliFMDAnaParameters* pars = AliFMDAnaParameters::Instance();
45 AliForwardCorrectionManager& fcm = AliForwardCorrectionManager::Instance();
47 UShort_t nVz = vtxAxis.GetNbins();
48 fFirstBins.Set(5*nVz);
51 // Find the eta bin ranges
52 for (UShort_t iVz = 1; iVz <= nVz; iVz++) {
53 // Find the first and last eta bin to use for each ring for
54 // each vertex bin. This is instead of using the methods
55 // provided by AliFMDAnaParameters
56 for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
59 GetDetRing(iIdx, d, r);
61 // Get the background object
62 // TH2F* bg = pars->GetBackgroundCorrection(d,r,iVz);
63 TH2D* bg = fcm.GetSecondaryMap()->GetCorrection(d,r,iVz);
64 Int_t nEta = bg->GetNbinsX();
68 // Loop over the eta bins
69 for (Int_t ie = 1; ie <= nEta; ie++) {
70 if (bg->GetBinContent(ie,1) < fCorrectionCut) continue;
72 // Loop over the phi bins to make sure that we
73 // do not have holes in the coverage
75 for (Int_t ip = 1; ip <= bg->GetNbinsY(); ip++) {
76 if (bg->GetBinContent(ie,ip) < 0.001) {
83 first = TMath::Min(ie, first);
84 last = TMath::Max(ie, last);
87 // Store the result for later use
88 fFirstBins[(iVz-1)*5+iIdx] = first;
89 fLastBins[(iVz-1)*5+iIdx] = last;
94 //____________________________________________________________________
96 AliFMDHistCollector::GetIdx(UShort_t d, Char_t r) const
100 case 1: idx = 0; break;
101 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
102 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
106 //____________________________________________________________________
108 AliFMDHistCollector::GetDetRing(Int_t idx, UShort_t& d, Char_t& r) const
113 case 0: d = 1; r = 'I'; break;
114 case 1: d = 2; r = 'I'; break;
115 case 2: d = 2; r = 'O'; break;
116 case 3: d = 3; r = 'I'; break;
117 case 4: d = 3; r = 'O'; break;
121 //____________________________________________________________________
123 AliFMDHistCollector::GetFirstAndLast(Int_t idx, UShort_t vtxbin,
124 Int_t& first, Int_t& last) const
130 if (vtxbin <= 0) return;
131 idx += (vtxbin-1) * 5;
133 if (idx < 0 || idx >= fFirstBins.GetSize()) return;
135 first = fFirstBins.At(idx)+fNCutBins;
136 last = fLastBins.At(idx)-fNCutBins;
139 //____________________________________________________________________
141 AliFMDHistCollector::GetFirst(Int_t idx, UShort_t v) const
144 GetFirstAndLast(idx,v,f,l);
149 //____________________________________________________________________
151 AliFMDHistCollector::GetLast(Int_t idx, UShort_t v) const
154 GetFirstAndLast(idx,v,f,l);
158 //____________________________________________________________________
160 AliFMDHistCollector::GetOverlap(UShort_t d, Char_t r,
161 Int_t bin, UShort_t vtxbin) const
163 // Get the possibly overlapping histogram
166 if (bin <= GetLast(2,'I',vtxbin)) other = GetIdx(2,'I');
168 else if (d == 2 && r == 'I') {
169 if (bin <= GetLast(2, 'O', vtxbin)) other = GetIdx(2, 'O');
170 else if (bin >= GetFirst(1, 'I', vtxbin)) other = GetIdx(1, 'I');
172 else if (d == 2 && r == 'O') {
173 if (bin >= GetFirst(2, 'I', vtxbin)) other = GetIdx(2,'I');
175 else if (d == 3 && r == 'O') {
176 if (bin <= GetLast(3, 'I', vtxbin)) other = GetIdx(3, 'I');
178 else if (d == 3 && r == 'I') {
179 if (bin >= GetFirst(3, 'O', vtxbin)) other = GetIdx(3, 'O');
181 // AliInfo(Form("FMD%d%c (%d) -> %d", d, r, GetIdx(d,r), other));
184 //____________________________________________________________________
186 AliFMDHistCollector::GetOverlap(Int_t idx, Int_t bin, UShort_t vtxbin) const
190 GetDetRing(idx, d, r);
191 if (d == 0 || r == '\0') return 0;
193 return GetOverlap(d, r, bin, vtxbin);
197 //____________________________________________________________________
199 AliFMDHistCollector::Collect(AliForwardUtil::Histos& hists,
203 for (UShort_t d=1; d<=3; d++) {
204 UShort_t nr = (d == 1 ? 1 : 2);
205 for (UShort_t q=0; q<nr; q++) {
206 Char_t r = (q == 0 ? 'I' : 'O');
207 TH2D* h = hists.Get(d,r);
208 TH2D* t = static_cast<TH2D*>(h->Clone(Form("FMD%d%c_tmp",d,r)));
210 // Outer rings have better phi segmentation - rebin to same as inner.
211 if (q == 1) t->RebinY(2);
215 GetFirstAndLast(d, r, vtxbin, first, last);
217 // Now update profile output
218 for (Int_t iEta = first; iEta <= last; iEta++) {
220 // Get the possibly overlapping histogram
221 Int_t overlap = GetOverlap(d,r,iEta,vtxbin);
223 // Fill eta acceptance for this event into the phi underlow bin
224 Float_t ooc = out.GetBinContent(iEta,0);
225 Float_t noc = overlap >= 0? 0.5 : 1;
226 out.SetBinContent(iEta, 0, ooc + noc);
228 for (Int_t iPhi = 1; iPhi <= h->GetNbinsY(); iPhi++) {
229 Double_t c = t->GetBinContent(iEta,iPhi);
230 Double_t e = t->GetBinError(iEta,iPhi);
232 // If there's no signal, continue
233 // if (e <= 0) continue;
234 if (c <= 0 || e <= 0) continue;
236 // If there's no overlapping histogram (ring), then
237 // fill in data and continue to the next phi bin
239 out.SetBinContent(iEta,iPhi,c);
240 out.SetBinError(iEta,iPhi,e);
244 // Get the current bin content and error
245 Double_t oc = out.GetBinContent(iEta,iPhi);
246 Double_t oe = out.GetBinError(iEta,iPhi);
248 #define USE_STRAIGHT_MEAN
249 // #define USE_STRAIGHT_MEAN_NONZERO
250 // #define USE_WEIGHTED_MEAN
251 // #define USE_MOST_CERTAIN
252 #if defined(USE_STRAIGHT_MEAN)
253 // calculate the average of old value (half the original),
254 // and this value, as well as the summed squared errors
255 // of the existing content (sqrt((e_1/2)^2=sqrt(e_1^2/4)=e_1/2)
256 // and half the error of this.
258 // So, on the first overlapping histogram we get
261 // e = sqrt((e_1 / 2)^2) = e_1/2
263 // On the second we get
265 // c' = c_2 / 2 + c = c_2 / 2 + c_1 / 2 = (c_1+c_2)/2
266 // e' = sqrt(e^2 + (e_2/2)^2)
267 // = sqrt(e_1^2/4 + e_2^2/4)
268 // = sqrt(1/4 * (e_1^2+e_2^2))
269 // = 1/2 * sqrt(e_1^2 + e_2^2)
270 out.SetBinContent(iEta,iPhi,oc + c/2);
271 out.SetBinError(iEta,iPhi,TMath::Sqrt(oe*oe+(e*e)/4));
272 #elif defined(USE_STRAIGHT_MEAN_NONZERO)
274 // If there's data in the overlapping histogram,
275 // calculate the average and add the errors in
278 // If there's no data in the overlapping histogram,
279 // then just fill in the data
281 out.SetBinContent(iEta,iPhi,(oc + c)/2);
282 out.SetBinError(iEta,iPhi,TMath::Sqrt(oe*oe + e*e)/2);
285 out.SetBinContent(iEta,iPhi,c);
286 out.SetBinError(iEta,iPhi,e);
288 #elif defined(USE_WEIGHTED_MEAN)
289 // Calculate the weighted mean
290 Double_t w = 1/(e*e);
294 Double_t ow = 1/(oe*oe);
298 Double_t nc = sc / sw;
299 Double_t ne = TMath::Sqrt(1 / sw);
300 out.SetBinContent(iEta,iPhi,nc,ne);
301 #elif defined(USE_MOST_CERTAIN)
304 out.SetBinContent(iEta,iPhi,c);
305 out.SetBinError(iEta,iPhi,e);
308 out.SetBinContent(iEta,iPhi,oc);
309 out.SetBinError(iEta,iPhi,oe);
312 # error No method for defining content of overlapping bins defined
314 #if defined(ZERO_OTHER)
315 // Get the content of the overlapping histogram,
316 // and zero the content so that we won't use it
318 UShort_t od; Char_t oR;
319 GetDetRing(overlap, od, oR);
320 TH2D* other = hists.Get(od,oR);
321 other->SetBinContent(iEta,iPhi,0);
322 other->SetBinError(iEta,iPhi,0);
326 // Remove temporary histogram
333 //____________________________________________________________________
335 AliFMDHistCollector::Print(Option_t* /* option */) const
337 char ind[gROOT->GetDirLevel()+1];
338 for (Int_t i = 0; i < gROOT->GetDirLevel(); i++) ind[i] = ' ';
339 ind[gROOT->GetDirLevel()] = '\0';
340 std::cout << ind << "AliFMDHistCollector: " << GetName() << '\n'
341 << ind << " # of cut bins: " << fNCutBins << '\n'
342 << ind << " Correction cut: " << fCorrectionCut << '\n'
343 << ind << " Bin ranges:\n" << ind << " v_z bin";
344 Int_t nVz = fFirstBins.fN / 5;
345 for (UShort_t iVz = 1; iVz <= nVz; iVz++)
346 std::cout << " | " << std::setw(7) << iVz;
347 std::cout << '\n' << ind << " / ring ";
348 for (UShort_t iVz = 1; iVz <= nVz; iVz++)
349 std::cout << "-+--------";
350 std::cout << std::endl;
352 for (Int_t iIdx = 0; iIdx < 5; iIdx++) {
355 GetDetRing(iIdx, d, r);
357 std::cout << ind << " FMD" << d << r << " ";
358 for (UShort_t iVz = 1; iVz <= nVz; iVz++) {
360 GetFirstAndLast(iIdx, iVz, first, last);
361 std::cout << " | " << std::setw(3) << first << "-"
362 << std::setw(3) << last;
364 std::cout << std::endl;
368 //____________________________________________________________________