Update of ACORDE-QA-Raw data histograms (now they go from -0.5 to 59.5)
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerDisplay.cxx
CommitLineData
aef183f7 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16// $Id$
17
18// --- MUON header files ---
19#include "AliMUONTriggerDisplay.h"
aef183f7 20
21#include "AliMpDDLStore.h"
22#include "AliMpVSegmentation.h"
23#include "AliMpSegmentation.h"
24#include "AliMpConstants.h"
25#include "AliMpPad.h"
26#include "AliMpLocalBoard.h"
27#include "AliMpCDB.h"
28
29// --- AliRoot header files ---
30#include "AliLog.h"
31
32// --- ROOT system ---
33#include <TH1.h>
34#include <TH2.h>
35
36//-----------------------------------------------------------------------------
37/// \class AliMUONTriggerDisplay
38///
39/// MUON base class for converting histos as a function of strip/board/slat number
40/// into display histos showing the detection element position in the
49e110ec 41/// trigger chamber.
42///
43/// Input histos can be given as:
44/// - TH2 with x -> board # [1-234] and y -> strip # in board [0-15]. Option: kDisplayStrips
45/// - TH1 with x -> board # [1-234] Option: kDisplayBoards
46/// - TH1 with x -> slat # [0-17] Option: kDisplaySlats
aef183f7 47///
48/// \author D. Stocco
49
50/// \cond CLASSIMP
51ClassImp(AliMUONTriggerDisplay)
52/// \endcond
53
54//____________________________________________________________________________
55AliMUONTriggerDisplay::AliMUONTriggerDisplay() :
56TObject()
57{
58 /// ctor
59}
60
61//__________________________________________________________________
62AliMUONTriggerDisplay::~AliMUONTriggerDisplay()
63{
64 /// dtor
65}
66
67
68//____________________________________________________________________________
69TH2* AliMUONTriggerDisplay::GetEmptyDisplayHisto(TString displayHistoName, EDisplayType displayType,
70 Int_t cathode, Int_t chamber,
71 TString displayHistoTitle)
72{
73 //
74 /// Return the display histogram with optimized binning
75 /// but do not fill it.
76 //
77 TH2F* displayHisto = new TH2F();
78
79 InitOrDisplayTriggerInfo(0x0, displayHisto, displayType,
80 cathode, chamber, displayHistoName, displayHistoTitle);
81
82 return displayHisto;
83}
84
85
86//____________________________________________________________________________
87TH2* AliMUONTriggerDisplay::GetBoardNumberHisto(TString displayHistoName,
88 Int_t chamber,
89 TString displayHistoTitle)
90{
91 //
92 /// Return the display histogram with optimized binning
93 /// and fill it with the board number
94 //
95
96 const Int_t kNboards = AliMpConstants::NofLocalBoards();
97 TH1F* inputHisto = new TH1F("boardNumbers","Board Numbers",kNboards,0.5,(Float_t)kNboards + 0.5);
98 for(Int_t ibin=1; ibin<=kNboards; ibin++){
99 inputHisto->Fill(ibin,ibin);
100 }
101
102 TH2F* displayHisto = (TH2F*)GetEmptyDisplayHisto(displayHistoName, kDisplayBoards, 0, chamber, displayHistoTitle);
103 FillDisplayHistogram(inputHisto,displayHisto,kDisplayBoards,0,chamber,kNumbered);
104
105 delete inputHisto;
106
107 displayHisto->SetStats(kFALSE);
108 return displayHisto;
109}
110
111
112//____________________________________________________________________________
113TH2* AliMUONTriggerDisplay::GetDisplayHistogram(TH1* inputHisto, TString displayHistoName,
114 EDisplayType displayType, Int_t cathode,
115 Int_t chamber, TString displayHistoTitle,
116 EDisplayOption displayOpt)
117{
118 //
119 /// Get histogram displaying the information contained in the input histogram
120 //
121 TH2* displayHisto = GetEmptyDisplayHisto(displayHistoName, displayType,
122 cathode, chamber, displayHistoTitle);
123
124 FillDisplayHistogram(inputHisto, displayHisto, displayType, cathode, chamber, displayOpt);
125
126 return displayHisto;
127}
128
129//____________________________________________________________________________
130Bool_t AliMUONTriggerDisplay::FillDisplayHistogram(TH1* inputHisto, TH2* displayHisto,
131 EDisplayType displayType, Int_t cathode,
132 Int_t chamber, EDisplayOption displayOpt)
133{
134 //
135 /// Fill a previously initialized display histogram
136 /// with the information contained in inputHisto.
137 /// To get initialized display, please use GetEmptyDisplayHisto method
138 //
139 return InitOrDisplayTriggerInfo(inputHisto, displayHisto, displayType,
140 cathode, chamber, "", "",displayOpt);
141}
142
143//____________________________________________________________________________
144Bool_t AliMUONTriggerDisplay::InitOrDisplayTriggerInfo(TH1* inputHisto, TH2* displayHisto,
145 EDisplayType displayType,
146 Int_t cathode, Int_t chamber,
147 TString displayHistoName, TString displayHistoTitle,
148 EDisplayOption displayOpt)
149{
150 //
151 /// Initialize trigger information display histograms using mapping
152 /// Trigger information is displayed in a user-friendly way:
153 /// from local board and strip numbers to their position on chambers.
154 //
155
156 // Load mapping
157 if ( ! AliMpSegmentation::Instance(kFALSE) ) {
158 /// Load mapping
159 if ( ! AliMpCDB::LoadDDLStore() ) {
160 AliError("Could not access mapping from OCDB !");
161 AliError("Histograms are not initialized !");
162 return kFALSE;
163 }
164 }
165
166 Int_t iCh = (chamber > AliMpConstants::NofTrackingChambers()) ? chamber - 11 : chamber;
167 Int_t iCath = cathode;
168
169 TArrayD xAxisStrip;
170 TArrayD yAxisStrip;
171 TArrayD xAxisBoard;
172 TArrayD yAxisBoard;
173
174 Float_t yOffsetLine, xOffsetLine = 0.;
175
176 const Float_t kResetValue=1234567.;
177
178 if(!inputHisto){
179 xAxisBoard.Set(55);
180 xAxisBoard.Reset(kResetValue);
181 yAxisBoard.Set(50);
182 yAxisBoard.Reset(kResetValue);
183
184 xAxisStrip.Set(420);
185 xAxisStrip.Reset(kResetValue);
186 yAxisStrip.Set(710);
187 yAxisStrip.Reset(kResetValue);
188 }
189 else if(!displayHisto){
190 AliWarning("Display histogram not initialized. Please initialize it first!");
191 return kFALSE;
192 }
719914e0 193 else if ( inputHisto->GetEntries() == 0 ) {
194 return kTRUE;
195 }
aef183f7 196
197 Float_t xWidth, yWidth, yWidthSlat=0., xWidthCol=0.;
198 Float_t x1,x2,y1,y2;
199 Float_t x1b=0., x2b=0., y1b=0., y2b=0.;
200 Float_t xcPad, ycPad;
201 Int_t line=0, slat;
202 Float_t sign = 1.;
203
204 const Float_t kShiftB = 0.5;
205 const Float_t kShiftS = 0.1;
206
207 const Float_t kShiftX = (iCath==0) ? kShiftB : kShiftS;
208 const Float_t kShiftY = (iCath==0) ? kShiftS : kShiftB;
209 const Float_t kShiftEl = (displayType==kDisplaySlats) ? 0.01 : kShiftB;
210
211 Int_t iChamber = iCh + AliMpConstants::NofTrackingChambers();
212 for(Int_t iLoc = 0; iLoc < AliMpConstants::NofLocalBoards(); iLoc++) {
213 Int_t iBoard = iLoc+1;
214 Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromLocalBoard(iBoard, iChamber);
215
216 if (!detElemId) continue;
217
218 AliMpLocalBoard* localBoard = AliMpDDLStore::Instance()->GetLocalBoard(iBoard, kFALSE);
219
220 // skip copy cards
221 if( !localBoard->IsNotified())
222 continue;
223
224 // get segmentation
225 const AliMpVSegmentation* seg[2] = {
226 AliMpSegmentation::Instance()->GetMpSegmentation(detElemId, AliMp::GetCathodType(0)),
227 AliMpSegmentation::Instance()->GetMpSegmentation(detElemId, AliMp::GetCathodType(1))};
228
229 if(iLoc==0){
168e9c4d 230 AliMpPad pad1 = seg[1]->PadByLocation(iBoard,0,kFALSE);
6e97fbb8 231 yWidthSlat = pad1.GetDimensionY();
168e9c4d 232 AliMpPad pad0 = seg[0]->PadByLocation(iBoard,0,kFALSE);
6e97fbb8 233 xOffsetLine = TMath::Abs(pad0.GetPositionX()) + pad0.GetDimensionX();
234 xWidthCol = 2.* pad0.GetDimensionX();
aef183f7 235 }
236
237 // Get ideal global position of DetElemId center
238 slat = detElemId%100;
239 line = (4 + slat)%18;
240 sign = 1.;
241 if(line>8) {
242 line = 17 - line;
243 sign = -1.;
244 }
245 yOffsetLine = (Float_t)(line - 4) * 2. * yWidthSlat;
246
247 for(Int_t cath=0; cath<AliMpConstants::NofCathodes(); cath++){
248 // Loop on cathodes:
249 // necessary because strip info is read for each cathode
250 // board info is read only from cathode 0
251
252 // loop over strips
253 for (Int_t iStrip = 0; iStrip < 16; ++iStrip) {
254 // get pad from electronics
32f0a7ea 255
256 Int_t offset = 0;
dc5d3949 257 if (cath && localBoard->GetSwitch(AliMpLocalBoard::kZeroAllYLSB)) offset = -8;
32f0a7ea 258
168e9c4d 259 AliMpPad pad = seg[cath]->PadByLocation(iBoard,iStrip+offset,kFALSE);
aef183f7 260
261 if (!pad.IsValid()) continue;
262
6e97fbb8 263 xWidth = pad.GetDimensionX();
264 yWidth = pad.GetDimensionY();
265 xcPad = sign * (pad.GetPositionX() + xOffsetLine);
aef183f7 266 if(line==4) xcPad += 0.75 * sign * xWidthCol;
6e97fbb8 267 ycPad = pad.GetPositionY() + yOffsetLine;
aef183f7 268
269 if(cath==iCath){
270 x1 = xcPad - xWidth + kShiftX;
271 y1 = ycPad - yWidth + kShiftY;
272 x2 = xcPad + xWidth - kShiftX;
273 y2 = ycPad + yWidth - kShiftY;
274
275 if(!inputHisto){
276 AddSortedPoint(x1, xAxisStrip, kResetValue);
277 AddSortedPoint(x2, xAxisStrip, kResetValue);
278
279 AddSortedPoint(y1, yAxisStrip, kResetValue);
280 AddSortedPoint(y2, yAxisStrip, kResetValue);
281 }
282 else if(displayType==kDisplayStrips)
283 FillBins(inputHisto, displayHisto, iBoard, iStrip, x1, x2, y1, y2, kShiftX, kShiftY, displayOpt);
284 }
285
286 if(cath==0){
32f0a7ea 287 if(iStrip+offset==0) {
aef183f7 288 x1b = xcPad - xWidth + kShiftEl;
289 y1b = ycPad - yWidth + kShiftEl;
290 }
291 x2b = xcPad + xWidth - kShiftEl;
292 y2b = ycPad + yWidth - kShiftEl;
293 }
294 } // loop on strips
295
296 // if iCath==0 strip info and board info are both filled -> break!
297 // if iCath==1 board info is filled at cath==0. Strip info to be filled at cath==1
298 if(iCath==0) break;
299 } // loop on cathodes
300
301 if(!inputHisto){
302 // Per board
303 AddSortedPoint(x1b, xAxisBoard, kResetValue);
304 AddSortedPoint(x2b, xAxisBoard, kResetValue);
305
306 AddSortedPoint(y1b, yAxisBoard, kResetValue);
307 AddSortedPoint(y2b, yAxisBoard, kResetValue);
308 }
309 else if(displayType==kDisplayBoards)
310 FillBins(inputHisto, displayHisto, iBoard, -1, x1b, x2b, y1b, y2b, kShiftEl, kShiftEl, displayOpt);
311 else if(displayType==kDisplaySlats)
312 FillBins(inputHisto, displayHisto, slat, -1, x1b, x2b, y1b, y2b, kShiftEl, kShiftEl, displayOpt);
313 } // loop on local boards
314
315 if(inputHisto) return kTRUE;
316
317 displayHisto->Reset();
318
319 // Book histos
320 const Float_t kMinDiff = 0.1;
321
322 TArrayD* currArray[4] = {&xAxisStrip, &yAxisStrip,
323 &xAxisBoard, &yAxisBoard};
324 for(Int_t iaxis=0; iaxis<4; iaxis++){
325 Int_t ipoint=0;
326 while(TMath::Abs((*currArray[iaxis])[ipoint]-kResetValue)>kMinDiff) {
327 ipoint++;
328 }
329 if(ipoint>currArray[iaxis]->GetSize()-2)
330 AliWarning(Form("Array size (%i) lower than the number of points!", currArray[iaxis]->GetSize()));
331 currArray[iaxis]->Set(ipoint);
332 }
333
334 switch(displayType){
335 case kDisplayStrips:
336 displayHisto->SetBins(xAxisStrip.GetSize()-1, xAxisStrip.GetArray(),
337 yAxisStrip.GetSize()-1, yAxisStrip.GetArray());
338 break;
339 case kDisplayBoards:
340 case kDisplaySlats:
341 displayHisto->SetBins(xAxisBoard.GetSize()-1, xAxisBoard.GetArray(),
342 yAxisBoard.GetSize()-1, yAxisBoard.GetArray());
343 break;
344 }
345
346 displayHisto->SetName(displayHistoName.Data());
347 displayHisto->SetTitle(displayHistoTitle.Data());
348 displayHisto->SetXTitle("X (cm)");
349 displayHisto->SetYTitle("Y (cm)");
350 //displayHisto->SetStats(kFALSE);
351
352 return kTRUE;
353}
354
355
356//____________________________________________________________________________
357Bool_t AliMUONTriggerDisplay::AddSortedPoint(Float_t currVal, TArrayD& position, const Float_t kResetValue)
358{
359 //
360 /// Add sorted point in array according to an increasing order.
361 /// Used to build display histograms axis.
362 //
363 Int_t nEntries = position.GetSize()-1;
364 Float_t tmp1, tmp2;
365 const Float_t kMinDiff = 0.1;
366 for(Int_t i=0; i<nEntries; i++){
367 if(TMath::Abs(position[i]-currVal)<kMinDiff) return kFALSE;
368 if(TMath::Abs(position[i]-kResetValue)<kMinDiff) {
369 position[i] = currVal;
370 return kTRUE;
371 }
372 if(currVal>position[i]) continue;
373 tmp1 = position[i];
374 position[i] = currVal;
375 for(Int_t j=i+1; j<nEntries; j++){
376 tmp2 = position[j];
377 position[j] = tmp1;
378 tmp1 = tmp2;
379 if(tmp1==kResetValue) break;
380 }
381 return kTRUE;
382 }
383 return kFALSE;
384}
385
386
387//____________________________________________________________________________
388void AliMUONTriggerDisplay::FillBins(TH1* inputHisto, TH2* displayHisto,
389 Int_t iElement1, Int_t iElement2,
390 Float_t x1, Float_t x2, Float_t y1, Float_t y2,
391 const Float_t kShiftX, const Float_t kShiftY,
392 EDisplayOption displayOpt)
393{
394 //
395 /// Given the bin in inputHisto, search the corresponding bins
396 /// in display histo and fill it.
397 //
398 TString className = inputHisto->ClassName();
399 Int_t binY=0;
400 Float_t binContent=0;
401 Int_t binX = inputHisto->GetXaxis()->FindBin(iElement1);
402 if(className.Contains("2")) {
403 binY = inputHisto->GetYaxis()->FindBin(iElement2);
404 binContent = inputHisto->GetBinContent(binX, binY);
405 }
406 else binContent = inputHisto->GetBinContent(binX);
407
408 if(binContent==0) {
409 if(displayOpt==kShowZeroes) binContent = 1e-5;
410 else return;
411 }
412
413 Int_t binX1 = displayHisto->GetXaxis()->FindBin(x1 + 0.01*kShiftX);
414 Int_t binX2 = displayHisto->GetXaxis()->FindBin(x2 - 0.01*kShiftX);
415 Int_t binY1 = displayHisto->GetYaxis()->FindBin(y1 + 0.01*kShiftY);
416 Int_t binY2 = displayHisto->GetYaxis()->FindBin(y2 - 0.01*kShiftY);
417
418 if(displayOpt==kNumbered) {
419 Int_t meanBin = (binX1+binX2)/2;
420 binX1 = meanBin;
421 binX2 = meanBin;
422
423 meanBin = (binY1+binY2)/2;
424 binY1 = meanBin;
425 binY2 = meanBin;
426 }
427
719914e0 428 Float_t elementArea = 1.;
429 if(displayOpt == kNormalizeToArea) {
430 elementArea = (x2 - x1 + 2*kShiftX) *
431 (y2 - y1 + 2*kShiftY); // In InitOrDisplayTriggerInfo:
432 // x2 = x_c + xHalfWidth - kShiftX
433 // x1 = x_c - xHalfWidth + kShiftX
434 // so x2 - x1 + 2*kShiftX returns the element width.
435
436 }
437
aef183f7 438 for(Int_t ibinx=binX1; ibinx<=binX2; ibinx++){
439 for(Int_t ibiny=binY1; ibiny<=binY2; ibiny++){
719914e0 440 displayHisto->SetBinContent(ibinx,ibiny,binContent/elementArea);
aef183f7 441 }
442 }
443}
444