2 // This class contains the acceptance correction due to dead channels
5 #include "AliFMDCorrAcceptance.h"
9 #include <AliForwardUtil.h>
18 //____________________________________________________________________
19 AliFMDCorrAcceptance::AliFMDCorrAcceptance()
26 // Default constructor
28 fRingArray.SetOwner(kTRUE);
29 fRingArray.SetName("rings");
30 fVertexAxis.SetName("vtxAxis");
31 fVertexAxis.SetTitle("v_{z} [cm]");
34 //____________________________________________________________________
35 AliFMDCorrAcceptance::AliFMDCorrAcceptance(const
36 AliFMDCorrAcceptance& o)
38 fRingArray(o.fRingArray),
40 fVertexAxis(o.fVertexAxis.GetNbins(), o.fVertexAxis.GetXmin(),
41 o.fVertexAxis.GetXmax()),
42 fHasOverflow(o.fHasOverflow)
48 // o Object to copy from
50 fVertexAxis.SetName("vtxAxis");
51 fVertexAxis.SetTitle("v_{z} [cm]");
53 //____________________________________________________________________
54 AliFMDCorrAcceptance::~AliFMDCorrAcceptance()
61 if (fCache) fCache->Clear();
63 //____________________________________________________________________
65 AliFMDCorrAcceptance::operator=(const AliFMDCorrAcceptance& o)
68 // Assignment operator
71 // o Object to assign from
74 // Reference to this object
76 if (&o == this) return *this;
78 fRingArray = o.fRingArray;
80 fHasOverflow = o.fHasOverflow;
81 SetVertexAxis(o.fVertexAxis);
85 //____________________________________________________________________
87 AliFMDCorrAcceptance::GetCorrection(UShort_t d, Char_t r, Double_t v) const
90 // Get the acceptance correction @f$ a_{r,v}@f$
93 // d Detector number (1-3)
94 // r Ring identifier (I or O)
95 // v Primary interaction point @f$z@f$ coordinate
98 // The correction @f$ a_{r,v}@f$
100 Int_t b = FindVertexBin(v);
101 if (b <= 0) return 0;
102 return GetCorrection(d, r, UShort_t(b));
104 //____________________________________________________________________
106 AliFMDCorrAcceptance::GetCorrection(UShort_t d, Char_t r, UShort_t b) const
109 // Get the acceptance correction @f$ a_{r,v}@f$
112 // d Detector number (1-3)
113 // r Ring identifier (I or O)
114 // b Bin corresponding to the primary interaction point
115 // @f$z@f$ coordinate (1 based)
118 // The correction @f$ a_{r,v}@f$
120 return static_cast<TH2D*>(GetObject(fRingArray, d, r, b));
122 //____________________________________________________________________
124 AliFMDCorrAcceptance::GetPhiAcceptance(UShort_t d, Char_t r, Double_t v) const
127 // Get the acceptance correction @f$ a_{r,v}@f$
130 // d Detector number (1-3)
131 // r Ring identifier (I or O)
132 // v Primary interaction point @f$z@f$ coordinate
135 // The correction @f$ a_{r,v}@f$
137 Int_t b = FindVertexBin(v);
138 if (b <= 0) return 0;
139 return GetPhiAcceptance(d, r, UShort_t(b));
141 //____________________________________________________________________
143 AliFMDCorrAcceptance::GetPhiAcceptance(UShort_t d, Char_t r, UShort_t b) const
146 // Get the acceptance correction @f$ a_{r,v}@f$
149 // d Detector number (1-3)
150 // r Ring identifier (I or O)
151 // b Bin corresponding to the primary interaction point
152 // @f$z@f$ coordinate (1 based)
155 // The correction @f$ a_{r,v}@f$
157 if (!fHasOverflow) return 0;
158 if (!fCache) FillCache();
159 return static_cast<TH1D*>(GetObject(*fCache, d, r, b));
162 //____________________________________________________________________
164 AliFMDCorrAcceptance::FindVertexBin(Double_t v) const
167 // Find the vertex bin that corresponds to the passed vertex
170 // vertex The interaction points @f$z@f$-coordinate
173 // Vertex bin in @f$[1,N_{\mbox{vertex}}]@f$ or negative if
176 if (fVertexAxis.GetNbins() <= 0) {
177 AliWarning("No vertex array defined");
180 Int_t bin = const_cast<TAxis&>(fVertexAxis).FindBin(v);
181 if (bin <= 0 || bin > fVertexAxis.GetNbins()) {
182 AliWarning(Form("vertex %+8.4f out of range [%+8.4f,%+8.4f]",
183 v, fVertexAxis.GetXmin(), fVertexAxis.GetXmax()));
188 //____________________________________________________________________
190 AliFMDCorrAcceptance::GetRingIndex(UShort_t d, Char_t r) const
192 // Get the index corresponding to the given ring
199 // Index (0 based) or negative in case of errors
203 case 2: return (r == 'I' || r == 'i' ? 1 : 2); break;
204 case 3: return (r == 'I' || r == 'i' ? 3 : 4); break;
207 AliWarning(Form("Index for FMD%d%c not found", d, r));
210 //____________________________________________________________________
212 AliFMDCorrAcceptance::GetObject(const TObjArray& m, UShort_t d,
213 Char_t r, UShort_t b) const
216 // Get the object @f$ a_{r,v}@f$
220 // d Detector number (1-3)
221 // r Ring identifier (I or O)
222 // b Bin corresponding to the primary interaction point
223 // @f$z@f$ coordinate (1 based)
226 // The correction @f$ a_{r,v}@f$
228 TObjArray* ringArray = GetRingArray(m, d, r);
229 if (!ringArray) return 0;
231 if (b <= 0 || b > ringArray->GetEntriesFast()) {
232 AliWarning(Form("vertex bin %d out of range [1,%d]",
233 b, ringArray->GetEntriesFast()));
237 TObject* o = ringArray->At(b-1);
240 AliWarning(Form("No dead channels map found for FMD%d%c in vertex bin %d",
244 //____________________________________________________________________
246 AliFMDCorrAcceptance::GetRingArray(const TObjArray& m,
247 UShort_t d, Char_t r) const
250 // Get the ring array corresponding to the specified ring
257 // Pointer to ring array, or null in case of problems
259 Int_t idx = GetRingIndex(d,r);
260 if (idx < 0) return 0;
262 TObject* o = m.At(idx);
264 AliWarning(Form("No array found for FMD%d%c", d, r));
268 return static_cast<TObjArray*>(o);
270 //____________________________________________________________________
272 AliFMDCorrAcceptance::GetOrMakeRingArray(TObjArray& m,
273 UShort_t d, Char_t r) const
276 // Get the ring array corresponding to the specified ring
283 // Pointer to ring array, or newly created container
285 Int_t idx = GetRingIndex(d,r);
286 if (idx < 0) return 0;
288 TObject* o = m.At(idx);
290 TObjArray* a = new TObjArray(fVertexAxis.GetNbins());
291 a->SetName(Form("FMD%d%c", d, r));
293 m.AddAtAndExpand(a, idx);
297 return static_cast<TObjArray*>(m.At(idx));
300 //____________________________________________________________________
302 AliFMDCorrAcceptance::SetCorrection(UShort_t d, Char_t r,
306 // Set the acceptance correction @f$ a_{r,v}(\eta)@f$
307 // Note, that the object takes ownership of the passed pointer.
310 // d Detector number (1-3)
311 // r Ring identifier (I or O)
312 // b Bin corresponding to the primary interaction point
313 // @f$z@f$ coordinate (1 based)
314 // h @f$ a_{r,v}(\eta)@f$
317 // true if operation succeeded
319 TObjArray* ringArray = GetOrMakeRingArray(fRingArray, d, r);
320 if (!ringArray) return false;
322 if (b <= 0 || b > fVertexAxis.GetNbins()) {
323 AliWarning(Form("Vertex bin %3d out of range [1,%3d]",
324 b, fVertexAxis.GetNbins()));
327 h->SetName(Form("FMD%d%c_vtxbin%03d", d, r, b));
328 h->SetTitle(Form("Acceptance correction for FMD%d%c "
329 "in vertex bin %d [%+8.4f,%+8.4f]",
330 d, r, b, fVertexAxis.GetBinLowEdge(b),
331 fVertexAxis.GetBinUpEdge(b)));
332 h->SetXTitle("#eta");
333 h->SetYTitle("N_{strips,OK}/N_{strips}");
334 h->SetFillStyle(3001);
337 ringArray->AddAtAndExpand(h, b-1);
340 //____________________________________________________________________
342 AliFMDCorrAcceptance::SetCorrection(UShort_t d, Char_t r,
346 // Set the acceptance correction @f$ a_{r,v}(\eta)@f$.
347 // Note, that the object takes ownership of the passed pointer.
350 // d Detector number (1-3)
351 // r Ring identifier (I or O)
352 // v Primary interaction point @f$z@f$ coordinate
353 // h @f$ a_{r,v}(\eta)@f$
356 // true if operation succeeded
358 Int_t b = FindVertexBin(v);
359 if (b <= 0 || b > fVertexAxis.GetNbins()) {
360 AliWarning(Form("Vertex %+8.4f out of range [%+8.4f,%+8.4f]",
361 v, fVertexAxis.GetXmin(), fVertexAxis.GetXmax()));
364 return SetCorrection(d, r, UShort_t(b), h);
367 //____________________________________________________________________
369 AliFMDCorrAcceptance::FillCache() const
373 fCache = new TObjArray;
374 fCache->SetOwner(kTRUE);
375 fCache->SetName("cache");
377 Int_t nV = fVertexAxis.GetNbins();
378 for (UShort_t v = 1; v <= nV; v++) {
379 for(UShort_t d = 1; d <= 3;d++) {
380 UShort_t nR = (d == 1 ? 1 : 2);
381 for (UShort_t q = 0; q < nR; q++) {
382 Char_t r = (q == 0 ? 'I' : 'O');
384 TObjArray* a = GetOrMakeRingArray(*fCache, d, r);
386 TH2D* corr = GetCorrection(d, r, v);
389 Int_t nY = corr->GetNbinsY();
390 TH1D* h = corr->ProjectionX("tmp", nY+1, nY+1, "");
391 h->SetName(Form("FMD%d%c_vtxbin%03d", d, r, v));
392 h->SetTitle(Form("#phi acceptance correction for FMD%d%c "
393 "in vertex bin %d [%+8.4f,%+8.4f]",
394 d, r, v, fVertexAxis.GetBinLowEdge(v),
395 fVertexAxis.GetBinUpEdge(v)));
396 h->SetXTitle("#eta");
397 h->SetYTitle("N_{strips}/N_{strips,OK}");
398 h->SetFillStyle(3001);
401 a->AddAtAndExpand(h,v-1);
403 if (fHasOverflow) continue;
405 // Construct the overflow bin from
406 Int_t nX = corr->GetNbinsX();
407 for (Int_t eta = 1; eta <= nX; eta++) {
409 for (Int_t phi = 1; phi <= nY; phi++)
410 sum += corr->GetBinContent(eta, phi);
411 if (nY <= 0) continue;
412 h->SetBinContent(eta, nY/sum);
418 //____________________________________________________________________
420 AliFMDCorrAcceptance::Browse(TBrowser* b)
423 // Browse this object in the browser
429 if (fCache) b->Add(fCache);
430 b->Add(&fVertexAxis);
432 //____________________________________________________________________
434 AliFMDCorrAcceptance::Print(Option_t* option) const
442 std::cout << "Acceptance correction due to dead channels" << std::endl;
443 fRingArray.Print(option);
444 fVertexAxis.Print(option);
446 //____________________________________________________________________
448 AliFMDCorrAcceptance::ls(Option_t* option) const
457 gROOT->IncreaseDirLevel();
458 fVertexAxis.ls(option);
459 fRingArray.ls(option);
460 gROOT->DecreaseDirLevel();
465 void ClearCanvas(TVirtualPad* c)
467 c->SetLeftMargin(.1);
468 c->SetRightMargin(.05);
469 c->SetBottomMargin(.1);
470 c->SetTopMargin(.05);
475 //____________________________________________________________________
477 AliFMDCorrAcceptance::SaveAs(const Char_t* filename, Option_t* option) const
480 // Override to allow saving to a PDF
482 TString fileName(filename);
483 if (!fileName.EndsWith(".pdf")) {
484 TObject::SaveAs(fileName, option);
488 TVirtualPad* c = new TCanvas(filename, GetTitle(), 800/TMath::Sqrt(2), 800);
492 c->Print(Form("%s[", filename));
494 //__________________________________________________________________
495 // Create a title page
496 TLatex* ll = new TLatex(.5,.8, filename);
497 ll->SetTextAlign(22);
498 ll->SetTextSize(0.03);
502 TLatex* l = new TLatex(.5,.8, filename);
504 l->SetTextSize(0.03);
507 l->DrawLatex(0.2, 0.70, "Acceptance due to dead channels");
509 l->DrawLatex(0.5, 0.60, "c_{v,r}(#eta,#phi)=#frac{"
510 "#sum active strips#in(#eta,#phi)}{"
511 "#sum strips#in(#eta,#phi)}");
513 c->Print(filename, "Title:Title page");
515 //__________________________________________________________________
516 // Draw all corrections
517 const TAxis& vtxAxis = GetVertexAxis();
518 Int_t nVtx = vtxAxis.GetNbins();
520 // --- Loop over detectors -----------------------------------------
521 for (UShort_t d = 1; d <= 3; d++) {
522 UShort_t nQ = (d == 1 ? 1 : 2);
523 for (UShort_t q = 0; q < nQ; q++) {
524 Char_t r = (q == 0 ? 'I' : 'O');
527 c->Divide(2, (nVtx+1)/2);
528 for (UShort_t v=1; v <= nVtx; v++) {
529 TVirtualPad* p = c->cd(v);
530 p->SetFillColor(kWhite);
532 TH2* h2 = GetCorrection(d, r, v);
534 Warning("DrawCorrAcc", "No correction for r=%c, v=%d", r, v);
539 c->Print(filename, Form("Title:FMD%d%c", d, r));
543 const_cast<AliFMDCorrAcceptance*>(this)->Draw(Form("%s phi", option));
544 c->Print(filename, "Title:Phi Acceptance");
546 const_cast<AliFMDCorrAcceptance*>(this)->Draw(option);
547 c->Print(filename, "Title:Summary");
548 c->Print(Form("%s]", filename));
550 //____________________________________________________________________
552 AliFMDCorrAcceptance::Draw(Option_t* option)
562 Bool_t over = opt.Contains("phi");
563 opt.ReplaceAll("phi", "");
565 TVirtualPad* c = gPad;
566 if (!c) c = new TCanvas(GetName(), GetTitle());
568 const TAxis& vtxAxis = fVertexAxis;
569 Int_t nVtx = vtxAxis.GetNbins();
571 c->SetLeftMargin(.1);
572 c->SetRightMargin(.05);
573 c->SetBottomMargin(.1);
574 c->SetTopMargin(.05);
576 c->Divide((nVtx+2)/3, 3, 0, 0);
578 // Draw all corrections
579 for (UShort_t v = 1; v <= nVtx; v++) {
581 if (ipad == 1 || ipad == 12) ipad++;
583 TVirtualPad* p = c->cd(ipad);
584 p->SetFillColor(kWhite);
586 THStack* stack = new THStack(Form("vtx%02d", v),
587 Form("%+5.1f<v_{z}<%+5.1f",
588 vtxAxis.GetBinLowEdge(v),
589 vtxAxis.GetBinUpEdge(v)));
590 for (UShort_t d = 1; d <= 3; d++) {
591 UShort_t nQ = (d == 1 ? 1 : 2);
592 for (UShort_t q = 0; q < nQ; q++) {
593 Char_t r = (q == 0 ? 'I' : 'O');
596 TH1* hp = GetPhiAcceptance(d, r, v);
598 Error("", "No phi acceptance at v=%d", v-1);
602 hp->SetMarkerColor(AliForwardUtil::RingColor(d, r));
603 hp->SetLineColor(AliForwardUtil::RingColor(d, r));
604 hp->SetFillColor(AliForwardUtil::RingColor(d, r));
605 hp->SetFillStyle(3001);
606 // Info("", "Adding phi acceptance plot %d", int(hp->GetEntries()));
611 TH2* h1 = GetCorrection(d, r, v);
613 Warning("Draw", "No correction for r=%c, v=%d", r, v);
616 Int_t nY = h1->GetNbinsY();
617 TH1* hh = h1->ProjectionX(Form("FMD%d%c", d, r), 1, nY);
620 hh->SetMarkerColor(AliForwardUtil::RingColor(d, r));
621 hh->SetLineColor(AliForwardUtil::RingColor(d, r));
622 hh->SetFillColor(AliForwardUtil::RingColor(d, r));
623 hh->SetFillStyle(3004);
628 stack->SetMaximum(1.2);
629 stack->Draw(Form("nostack %s", opt.Data()));
634 //____________________________________________________________________