]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONTriggerEfficiencyCells.cxx
Updated list of framework libraries
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerEfficiencyCells.cxx
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 #include "AliMUONTriggerEfficiencyCells.h"
17 #include "AliMpConstants.h"
18 #include "AliMpDEManager.h"
19
20 // Classes for display
21 #include "AliMUONGeometryTransformer.h"
22 #include "AliMpCDB.h"
23 #include "AliMpDDLStore.h"
24 #include "AliMpDDL.h"
25 #include "AliMpTriggerCrate.h"
26 #include "AliMpLocalBoard.h"
27 #include "AliMpPad.h"
28 #include "AliMpVSegmentation.h"
29 #include "AliMpSegmentation.h"
30
31 #include "AliLog.h"
32
33 #include "TRandom.h"
34 #include "Riostream.h"
35 #include "TSystem.h"
36 #include "TFile.h"
37 #include "TH1F.h"
38 #include "TMath.h"
39
40 #include "TH2F.h"
41 #include "TH3F.h"
42 #include "TF1.h"
43 #include "TStyle.h"
44 #include "TPaveLabel.h"
45 #include "TCanvas.h"
46
47 #include <fstream>
48 #include <cassert>
49
50 //-----------------------------------------------------------------------------
51 /// \class AliMUONTriggerEfficiencyCells
52 /// A class to store and give access to the trigger chamber efficiency.
53 ///
54 /// Efficiency is stored per cathode on local boards, or, alternatively,
55 /// on "cells" of a given size.
56 ///
57 /// The main method of this class is IsTriggered().
58 ///
59 /// $ALICE_ROOT/MUON/data/TriggerChamberefficiencyCells.dat contains efficiency 
60 /// for each chamber (i.e. DetElement). 
61 ///
62 /// In the case of local boards, efficiency is stored from left to right
63 /// per increasing board number (from 1 to 234)
64 ///
65 /// Otherwise, he efficiency cells goes from right to left and 
66 /// from bottom to top of the chamber, namely, the efficiencies tabulated in the 
67 /// file refers to the following reference frame:
68 ///
69 /// <pre>
70 /// x
71 /// <----------------------------------|
72 ///                                    |
73 ///    ---------------------------     |
74 ///   | 0.97 | 0.97 | 0.97 | 0.97 |    |
75 ///    ---------------------------     |
76 ///   | 0.97 | 0.97 | 0.97 | 0.97 |    |
77 ///    ---------------------------     |
78 ///   | 0.97 | 0.97 | 0.97 | 0.97 |    |
79 ///    ---------------------------     |
80 ///                                    |
81 ///                                   \/ y
82 /// </pre>
83 ///
84 ///  In both cases, the file can be edited in order to change efficiency
85 ///  in a chosen local board/region of the chamber.
86 ///
87 ///
88 /// But please note that this object is also available from the CDB 
89 /// (generated using the MUONCDB.C macro)
90 ///
91 /// \author Diego Stocco; INFN Torino
92 //-----------------------------------------------------------------------------
93
94 /// \cond CLASSIMP
95 ClassImp(AliMUONTriggerEfficiencyCells)
96 /// \endcond
97
98 //__________________________________________________________________________
99 AliMUONTriggerEfficiencyCells::AliMUONTriggerEfficiencyCells()
100 :
101 TObject(),
102 fCountHistoList(0x0),
103 fNoCountHistoList(0x0),
104 fFiredStrips(0x0),
105 fDisplayHistoList(0x0),
106 fBoardLabelList(0x0),
107 fFiredFitHistoList(0x0),
108 fFiredDisplayHistoList(0x0)
109 {
110 ///  Default constructor.
111   CheckConstants();
112   Reset();
113   InitHistos();
114 }
115
116 //__________________________________________________________________________
117 AliMUONTriggerEfficiencyCells::AliMUONTriggerEfficiencyCells(const Char_t* filename)
118 :
119 TObject(),
120 fCountHistoList(0x0),
121 fNoCountHistoList(0x0),
122 fFiredStrips(0x0),
123 fDisplayHistoList(0x0),
124 fBoardLabelList(0x0),
125 fFiredFitHistoList(0x0),
126 fFiredDisplayHistoList(0x0)
127 {
128 ///  Constructor using an ASCII file.
129   CheckConstants();
130   Reset();
131   ReadFile(filename);
132 }
133
134 AliMUONTriggerEfficiencyCells::AliMUONTriggerEfficiencyCells(TList *countHistoList,
135                                                              TList *noCountHistoList)
136 :
137 TObject(),
138 fCountHistoList(countHistoList),
139 fNoCountHistoList(noCountHistoList),
140 fFiredStrips(0x0),
141 fDisplayHistoList(0x0),
142 fBoardLabelList(0x0),
143 fFiredFitHistoList(0x0),
144 fFiredDisplayHistoList(0x0)
145 {
146 ///  Constructor using an ASCII file.
147   CheckConstants();
148   Reset();
149   InitHistos();
150   FillHistosFromList();
151 }
152
153 //_____________________________________________________________________________
154 AliMUONTriggerEfficiencyCells::AliMUONTriggerEfficiencyCells(const AliMUONTriggerEfficiencyCells& other)
155 :
156 TObject(other),
157 fCountHistoList(other.fCountHistoList),
158 fNoCountHistoList(other.fNoCountHistoList),
159 fFiredStrips(other.fFiredStrips),
160 fDisplayHistoList(other.fDisplayHistoList),
161 fBoardLabelList(other.fBoardLabelList),
162 fFiredFitHistoList(other.fFiredFitHistoList),
163 fFiredDisplayHistoList(other.fFiredDisplayHistoList)
164 {
165 /// Copy constructor
166
167   for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
168     for(Int_t slat=0; slat<fgkNslats; slat++){
169       fCellContent[chCath][slat] = other.fCellContent[chCath][slat];
170     }
171     fCellSize[chCath] = other.fCellSize[chCath];
172     fCellNumber[chCath] = other.fCellNumber[chCath];
173     fBoardEfficiency[chCath] = other.fBoardEfficiency[chCath];
174     fSlatEfficiency[chCath] = other.fSlatEfficiency[chCath];
175   }
176 }
177
178 //_____________________________________________________________________________
179 AliMUONTriggerEfficiencyCells& AliMUONTriggerEfficiencyCells::operator=(const AliMUONTriggerEfficiencyCells& other)
180 {
181   /// Asignment operator
182   // check assignement to self
183   if (this == &other)
184     return *this;
185
186   for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
187     for(Int_t slat=0; slat<fgkNslats; slat++){
188       fCellContent[chCath][slat] = other.fCellContent[chCath][slat];
189     }
190     fCellSize[chCath] = other.fCellSize[chCath];
191     fCellNumber[chCath] = other.fCellNumber[chCath];
192     fBoardEfficiency[chCath] = other.fBoardEfficiency[chCath];
193     fSlatEfficiency[chCath] = other.fSlatEfficiency[chCath];
194   }
195
196   fCountHistoList = other.fCountHistoList;
197   fNoCountHistoList = other.fNoCountHistoList;
198   fFiredStrips = other.fFiredStrips;
199
200   fDisplayHistoList = other.fDisplayHistoList;
201   fBoardLabelList = other.fBoardLabelList;
202   fFiredFitHistoList = other.fFiredFitHistoList;
203   fFiredDisplayHistoList = other.fFiredDisplayHistoList;
204     
205   return *this;
206 }
207
208 //__________________________________________________________________________
209 AliMUONTriggerEfficiencyCells::~AliMUONTriggerEfficiencyCells()
210 {
211 ///  Destructor.
212 }
213
214
215 //__________________________________________________________________________
216 void AliMUONTriggerEfficiencyCells::GetCellEfficiency(Int_t detElemId, Float_t x, Float_t y, Float_t &eff1, Float_t &eff2) const
217 {
218 ///  Get the efficiencies of the 2 cathodes at a given location (x,y)
219
220   Int_t chamber = FindChamberIndex(detElemId);
221   Int_t slat = FindSlatIndex(detElemId);
222   TArrayI cell = CellByCoord(detElemId,x,y);
223   eff1 = 0.0;
224   eff2 = 0.0;
225   if(cell.At(0)>=0 && cell.At(1)>=0)
226   {
227     eff1 = fCellContent[chamber][slat][cell.At(0)][cell.At(1)];
228     eff2 = fCellContent[fgkNchambers+chamber][slat][cell.At(0)][cell.At(1)];
229   }
230 }
231
232
233 //__________________________________________________________________________
234 void AliMUONTriggerEfficiencyCells::GetCellEfficiency(Int_t detElemId, Int_t localBoard, Float_t &eff1, Float_t &eff2) const
235 {
236 ///  Get the efficiencies of the 2 cathodes at a given local board
237
238   Int_t chamber = FindChamberIndex(detElemId);
239   Int_t bin = fBoardEfficiency[chamber]->FindBin(localBoard);
240   eff1 = fBoardEfficiency[chamber]->GetBinContent(bin);
241   eff2 = fBoardEfficiency[fgkNchambers+chamber]->GetBinContent(bin);
242 }
243
244
245 //__________________________________________________________________________
246 void 
247 AliMUONTriggerEfficiencyCells::IsTriggered(Int_t detElemId, Float_t x, Float_t y, Bool_t &trig1, Bool_t &trig2) const
248 {
249 ///  Whether or not a given location (x,y) has a chance to trig, on each cathode.
250
251   Float_t eff1 = 0.0;
252   Float_t eff2 = 0.0;
253   GetCellEfficiency(detElemId, x, y, eff1, eff2);
254   trig1 = kTRUE; 
255   trig2 = kTRUE;
256   if(gRandom->Rndm()>eff1)trig1 = kFALSE;
257   if(gRandom->Rndm()>eff2)trig2 = kFALSE;
258 }
259
260
261 //__________________________________________________________________________
262 void 
263 AliMUONTriggerEfficiencyCells::IsTriggered(Int_t detElemId, Int_t localBoard, Bool_t &trig1, Bool_t &trig2) const
264 {
265 ///  Whether or not a given local board has a chance to trig, on each cathode.
266
267   Float_t eff1 = 0.0;
268   Float_t eff2 = 0.0;
269   GetCellEfficiency(detElemId, localBoard, eff1, eff2);
270   trig1 = kTRUE; 
271   trig2 = kTRUE;
272   if(gRandom->Rndm()>eff1)trig1 = kFALSE;
273   if(gRandom->Rndm()>eff2)trig2 = kFALSE;
274 }
275
276 //__________________________________________________________________________
277 TArrayI AliMUONTriggerEfficiencyCells::CellByCoord(Int_t detElemId, Float_t x, Float_t y) const
278 {
279 ///  Get the efficiencies at a given location.
280
281   Int_t chamber = FindChamberIndex(detElemId);
282   Int_t slat = FindSlatIndex(detElemId);
283   Int_t cell[fgkNcathodes]={-1,-1};
284   Float_t maxX = fCellSize[chamber][slat]*((Float_t)fCellNumber[chamber][slat]);
285   Float_t maxY = fCellSize[fgkNchambers+chamber][slat]*((Float_t)fCellNumber[fgkNchambers+chamber][slat]);
286   if(x>=0 & x<maxX & y>=0 & y<maxY)
287   {
288     cell[0] = (Int_t)(x/fCellSize[chamber][slat]);
289     cell[1] = (Int_t)(y/fCellSize[fgkNchambers+chamber][slat]);
290   }
291   return TArrayI(fgkNcathodes,cell);
292 }
293
294 //__________________________________________________________________________
295 void AliMUONTriggerEfficiencyCells::ReadFile(const Char_t* filename)
296 {
297 ///  Reads a file containing the efficiency map.
298
299   TString fileName = gSystem->ExpandPathName(filename);
300   if(fileName.EndsWith(".root")){
301       ReadHistoBoards(fileName.Data());
302       return;
303   }
304
305   InitHistos();
306   ifstream file(fileName.Data());
307   Char_t dat[50];
308   if (file.good()){
309       file >> dat;
310       if(!strcmp(dat,"localBoards"))ReadFileBoards(file);
311       else ReadFileXY(file);
312       file.close();
313   } else {
314       AliWarning(Form("Can't read file %s",fileName.Data()));
315   }
316 }
317
318
319 //__________________________________________________________________________
320 void AliMUONTriggerEfficiencyCells::ReadFileXY(ifstream &file)
321 {
322 ///  Structure of file (.dat) containing geometrical efficency
323     Int_t datInt=0, detEl=0, chamber=0, rpc=0, chCath=0;
324     Float_t datFloat=0.0;
325     Char_t dat[50];
326
327     while (file >> dat) {
328         file >> detEl;
329         chamber = FindChamberIndex(detEl);
330         rpc = FindSlatIndex(detEl);
331         file >> dat;
332         for(Int_t i=0; i<fgkNcathodes; i++){
333             chCath = fgkNchambers*i + chamber;
334             file >> datInt;
335             fCellNumber[chCath][rpc] = datInt;
336             file >> dat;
337         }
338         for(Int_t i=0; i<fgkNcathodes; i++){
339             chCath = fgkNchambers*i + chamber;
340             file >> datFloat;
341             fCellSize[chCath][rpc] = datFloat;
342             if(i==0)file >> dat;
343         }
344         for(Int_t cath=0; cath<fgkNcathodes; cath++){
345             chCath = fgkNchambers*cath + chamber;
346             file >> dat;
347             file >> datInt;
348             for(Int_t iy=0; iy<fCellNumber[fgkNchambers+chamber][rpc]; iy++){
349                 for(Int_t ix=0; ix<fCellNumber[chamber][rpc]; ix++){
350                     file >> datFloat;
351                     fCellContent[chCath][rpc][ix][iy] = datFloat;
352                 }
353             }
354         }
355     }
356 }
357
358 //__________________________________________________________________________
359 void AliMUONTriggerEfficiencyCells::ReadFileBoards(ifstream &file)
360 {
361 ///  Structure of file (.dat) containing local board efficency
362   Int_t datInt=0, detEl=0, chamber=0, chCath=0, bin=0;
363     Float_t datFloat=0.0;
364     Char_t dat[50];
365
366     while (file >> dat) {
367             file >> detEl;
368             chamber = FindChamberIndex(detEl);
369             //rpc = FindSlatIndex(detEl);
370             for(Int_t cath=0; cath<fgkNcathodes; cath++){
371                 chCath = fgkNchambers*cath + chamber;
372                 file >> dat;
373                 file >> datInt;
374                 for(Int_t board=1; board<=AliMpConstants::NofLocalBoards(); board++){
375                     file >> datFloat;
376                     bin = fBoardEfficiency[chCath]->FindBin(board);
377                     fBoardEfficiency[chCath]->SetBinContent(bin, datFloat);
378                 }
379             }
380     }
381 }
382
383
384 //__________________________________________________________________________
385 void AliMUONTriggerEfficiencyCells::ReadHistoBoards(const Char_t *filename)
386 {
387 ///  Structure of file (.root) containing local board efficency
388     TFile *file = new TFile(filename, "read");
389     if(!file) {
390         AliWarning(Form("Can't read file %s",filename));
391         return;
392     }
393     Char_t histoName[30];
394     Char_t *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
395
396     for(Int_t ch=0; ch<fgkNchambers; ch++){
397         for(Int_t cath=0; cath<fgkNcathodes; cath++){
398             sprintf(histoName, "%sBoardEffChamber%i", cathCode[cath], 11+ch);
399             if(!(TH1F *)file->Get(histoName)) {
400                 AliWarning(Form("Can't find histo %s in file %s",histoName, filename));
401                 continue;
402             }
403             Int_t chCath = fgkNchambers*cath + ch;
404             fBoardEfficiency[chCath] = (TH1F *)file->Get(histoName);
405         }
406     }
407 }
408
409
410 //_____________________________________________________________________________
411 void AliMUONTriggerEfficiencyCells::CheckConstants() const
412 {
413 /// Check consistence of redefined constants 
414
415   assert(fgkNcathodes == AliMpConstants::NofCathodes());    
416   assert(fgkNchambers == AliMpConstants::NofTriggerChambers());    
417   assert(fgkNplanes == AliMpConstants::NofTriggerChambers() * fgkNcathodes);    
418 }
419
420
421 //__________________________________________________________________________
422 Int_t AliMUONTriggerEfficiencyCells::FindChamberIndex(Int_t detElemId) const
423 {
424 ///  From detElemId to chamber number
425   Int_t iChamber = AliMpDEManager::GetChamberId(detElemId);
426   Int_t chamber = iChamber-AliMpConstants::NofTrackingChambers();
427   return chamber;
428 }
429
430
431 //__________________________________________________________________________
432 Int_t AliMUONTriggerEfficiencyCells::FindSlatIndex(Int_t detElemId) const
433 {
434 ///  From detElemId to slat index.
435   Int_t slat = detElemId%100;
436   return slat;
437 }
438
439
440 //__________________________________________________________________________
441 TVector2 AliMUONTriggerEfficiencyCells::ChangeReferenceFrame(Float_t x, Float_t y, Float_t x0, Float_t y0)
442 {
443 /// (x0,y0) position of the local reference frame (center of the chamber)
444
445     Float_t x1 = x0-x;//reflection of axis
446     Float_t y1 = y+y0;
447     return TVector2(x1,y1);
448 }
449
450 //__________________________________________________________________________
451 void
452 AliMUONTriggerEfficiencyCells::Reset()
453 {
454 ///  Sets our internal array contents to zero.
455
456     for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
457         fCellSize[chCath].Set(fgkNslats);
458         fCellNumber[chCath].Set(fgkNslats);
459         for(Int_t slat=0; slat<fgkNslats; slat++){
460             fCellContent[chCath][slat].ResizeTo(fgkNcells,fgkNcells);
461         }
462     }
463
464     for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
465         fCellSize[chCath].Reset();
466         fCellNumber[chCath].Reset();
467         for(Int_t slat=0; slat<fgkNslats; slat++){
468             fCellContent[chCath][slat].Zero();
469         }
470     }
471
472     for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
473       fBoardEfficiency[chCath] = 0x0;
474       fSlatEfficiency[chCath] = 0x0;
475     }
476
477     if(!AliMpCDB::LoadDDLStore()) // Load DDL store from OCDB
478       AliFatal("Could not access mapping OCDB");
479 }
480
481
482 //__________________________________________________________________________
483 void
484 AliMUONTriggerEfficiencyCells::InitHistos()
485 {
486 ///  Sets our internal array contents to zero.
487
488   const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards();
489   Int_t chCath=0;
490   Char_t histoName[40];
491
492   Char_t *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
493
494   for(Int_t ch=0; ch<fgkNchambers; ch++){
495     for(Int_t cath=0; cath<fgkNcathodes; cath++){
496       chCath = fgkNchambers*cath + ch;
497       sprintf(histoName, "%sBoardEffChamber%i", cathCode[cath], 11+ch);
498       fBoardEfficiency[chCath] = new TH1F(histoName, histoName, kNumOfBoards, 1-0.5, kNumOfBoards+1.-0.5);
499       sprintf(histoName, "%sSlatEffChamber%i", cathCode[cath], 11+ch);
500       fSlatEfficiency[chCath] = new TH1F(histoName, histoName, fgkNslats, 0-0.5, fgkNslats-0.5);
501     }
502   }
503 }
504
505
506 //__________________________________________________________________________
507 void
508 AliMUONTriggerEfficiencyCells::FillHistosFromList()
509 {
510 ///  Fills internal histos from list.
511
512   Int_t nHistoBins=0;
513   TH1F *histoNum = 0x0, *histoDen=0x0, *currHisto = 0x0;
514   TString slatName = "Slat", boardName = "Board", histoName;
515   Int_t iHistoBoard = -1, iHistoSlat = -1;
516   Float_t efficiency, efficiencyError;
517
518   Int_t nentries = fCountHistoList->GetEntries();
519
520   for(Int_t iEntry=0; iEntry<nentries; iEntry++){
521     histoNum = (TH1F*)fCountHistoList->At(iEntry);
522     histoDen = (TH1F*)fNoCountHistoList->At(iEntry);
523
524     if(!histoNum) {
525       AliWarning("Histogram not found in fCountHistoList. Skip to next");
526       continue;
527     }
528     if(!histoDen) {
529       AliWarning("Histogram not found in fNoCountHistoList. Skip to next");
530       continue;
531     }
532
533     histoName = histoNum->GetName();
534     nHistoBins = histoNum->GetNbinsX();
535
536     if(histoName.Contains(boardName)){
537       iHistoBoard++;
538       currHisto = fBoardEfficiency[iHistoBoard];
539     }
540     else if(histoName.Contains(slatName)){
541       iHistoSlat++;
542       currHisto = fSlatEfficiency[iHistoSlat];
543     }
544     else continue;
545
546     for(Int_t iBin=1; iBin<=nHistoBins; iBin++){
547       CalculateEfficiency((Int_t)histoNum->GetBinContent(iBin), (Int_t)histoNum->GetBinContent(iBin) + (Int_t)histoDen->GetBinContent(iBin), efficiency, efficiencyError, kFALSE);
548
549       currHisto->SetBinContent(iBin, efficiency);
550       currHisto->SetBinError(iBin, efficiencyError);
551     }
552   }
553 }
554
555
556
557 //_____________________________________________________________________________
558 void AliMUONTriggerEfficiencyCells::CalculateEfficiency(Int_t trigger44, Int_t trigger34,
559                                                         Float_t &efficiency, Float_t &error,
560                                                         Bool_t failuresAsInput)
561 {
562     //
563     /// Returns the efficiency.
564     //
565
566     efficiency=-9.;
567     error=0.;
568     if(trigger34>0){
569         efficiency=(Double_t)trigger44/((Double_t)trigger34);
570         if(failuresAsInput)efficiency=1.-(Double_t)trigger44/((Double_t)trigger34);
571     }
572     Double_t q = TMath::Abs(1-efficiency);
573     if(efficiency<0)error=0.0;
574     else error = TMath::Sqrt(efficiency*q/((Double_t)trigger34));
575 }
576
577
578 //_____________________________________________________________________________
579 void AliMUONTriggerEfficiencyCells::CheckFiredStrips(const Char_t* geoFilename)
580 {
581   //
582   /// Check for fired strips participating to efficiency
583   /// calculation (when available).
584   /// Strips inside a local board should be quite homogeneously hit
585   /// If not, this could be a problem of electronics (i.e. ADULT board off).
586   //
587
588   if(!fFiredStrips) {
589     AliWarning("List of fired pads not present. Check not performable.");
590     return;
591   }
592
593   GetListsForCheck(geoFilename);
594
595   Char_t histoName[40], histoTitle[90];
596
597   // Check fired pads (when available)
598   if(fFiredFitHistoList){
599     TH1F *histo1D = 0x0;
600     TF1 *fitFunc = 0x0;
601     TCanvas *histoFiredCan[20];
602     Int_t nEntries = fFiredFitHistoList->GetEntries();
603     for(Int_t iEntry=0; iEntry<nEntries; iEntry++){
604       histo1D = (TH1F*)fFiredFitHistoList->At(iEntry);
605       printf("Problems found in %s\n", histo1D->GetTitle());
606     }
607     Int_t nPrintCan = nEntries;
608     if(nPrintCan>20) {
609       AliWarning("Too many boards with problems: only 20 will be shown");
610       nPrintCan = 20;
611     }
612     for(Int_t iCan=0; iCan<nPrintCan; iCan++){
613       histo1D = (TH1F*)fFiredFitHistoList->At(iCan);
614       histoFiredCan[iCan] = new TCanvas(histoName, histoTitle, 100+10*iCan, 10*iCan, 700, 700);
615       histoFiredCan[iCan]->SetRightMargin(0.14);
616       histoFiredCan[iCan]->SetLeftMargin(0.12);
617       histo1D->Draw("E");
618       fitFunc = histo1D->GetFunction("pol0");
619       fitFunc->SetLineColor(2);
620       fitFunc->Draw("same");
621     }
622     if(nEntries==0){
623       printf("\nAll local boards seem ok!!\n\n");
624     }
625   }
626 }
627
628
629 //_____________________________________________________________________________
630 void AliMUONTriggerEfficiencyCells::DisplayEfficiency(Bool_t perSlat, const Char_t* geoFilename)
631 {
632   //
633   /// Display calculated efficiency.
634   //
635
636   Bool_t isInitSlat = kFALSE, isInitBoard = kFALSE;
637   for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
638     if(fBoardEfficiency[chCath]->GetEntries()>0) isInitBoard = kTRUE;
639     if(fSlatEfficiency[chCath]->GetEntries()>0) isInitSlat = kTRUE;
640   }
641
642   if(!isInitBoard){
643     printf("Trigger efficiency not initialized per board.\nDisplay not yet implemented.\n");
644     return;
645   }
646   if(!isInitSlat && perSlat){
647     printf("Trigger efficiency not initialized for slat.\nPlease try option kFALSE.\n");
648     return;
649   }
650   
651   GetListsForCheck(geoFilename);
652
653   const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards();
654
655   TH2F *histo = 0x0;
656   Char_t histoName[40], histoTitle[90];
657   TPaveLabel *boardLabel = 0x0;
658
659   // Plot fired strips (when available)
660   if(fFiredDisplayHistoList){
661     TCanvas *displayFiredCan[fgkNplanes];
662     for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
663       histo = (TH2F*)fFiredDisplayHistoList->At(chCath);
664       sprintf(histoName, "%sCan", histo->GetName());
665       sprintf(histoTitle, "%s", histo->GetTitle());
666       displayFiredCan[chCath] = new TCanvas(histoName, histoTitle, 100+10*chCath, 10*chCath, 700, 700);
667       displayFiredCan[chCath]->SetRightMargin(0.14);
668       displayFiredCan[chCath]->SetLeftMargin(0.12);
669       histo->GetYaxis()->SetTitleOffset(1.4);
670       histo->SetStats(kFALSE);
671       histo->Draw("COLZ");
672       for (Int_t board = 0; board < kNumOfBoards; board++) {
673         Int_t currLabel = chCath * kNumOfBoards + board;
674         boardLabel = (TPaveLabel*)fBoardLabelList->At(currLabel);
675         boardLabel->Draw("same");
676       }
677     }
678   }
679
680   // Plot efficiency
681   if(fDisplayHistoList){
682     TCanvas *can[fgkNplanes];
683     for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
684       Int_t currChCath = chCath;
685       if(perSlat==kTRUE) currChCath += fgkNplanes;
686       histo = (TH2F*)fDisplayHistoList->At(currChCath);
687       sprintf(histoName, "%sCan", histo->GetName());
688       sprintf(histoTitle, "%s", histo->GetTitle());
689       can[chCath] = new TCanvas(histoName, histoTitle, 100+10*chCath, 10*chCath, 700, 700);
690       can[chCath]->SetRightMargin(0.14);
691       can[chCath]->SetLeftMargin(0.12);
692       histo->GetZaxis()->SetRangeUser(0.,1.);
693       histo->GetYaxis()->SetTitleOffset(1.4);
694       histo->SetStats(kFALSE);
695       histo->Draw("COLZ");
696       for (Int_t board = 0; board < kNumOfBoards; board++) {
697         Int_t currLabel = chCath * kNumOfBoards + board;
698         if(perSlat==kTRUE) currLabel += kNumOfBoards * fgkNplanes;
699         boardLabel = (TPaveLabel*)fBoardLabelList->At(currLabel);
700         boardLabel->Draw("same");
701       }
702     }
703   }
704 }
705
706
707 //__________________________________________________________________________
708 Bool_t AliMUONTriggerEfficiencyCells::GetListsForCheck(const Char_t* geoFilename)
709 {
710   //
711   /// Getting histograms for efficiency, 
712   /// map of fired strips entering efficiency calculations,
713   /// fits for checking switched-off elements in chambers.
714   //
715
716   const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards();
717   const Float_t kChi2RedMax = 1.5;
718   const Float_t kDummyFired = 1e-5;
719
720   if(fDisplayHistoList || fBoardLabelList || fFiredFitHistoList || fFiredDisplayHistoList) return kTRUE;
721
722   if(!fDisplayHistoList) fDisplayHistoList = new TList();
723   if(!fBoardLabelList) fBoardLabelList = new TList(); 
724   if(!fFiredFitHistoList && fFiredStrips) fFiredFitHistoList = new TList();
725   if(!fFiredDisplayHistoList && fFiredStrips) fFiredDisplayHistoList = new TList();
726
727   AliMUONGeometryTransformer *transform = new AliMUONGeometryTransformer();
728   transform->LoadGeometryData(geoFilename);
729
730   if(!AliMpCDB::LoadDDLStore()) // Load DDL store from OCDB
731     AliFatal("Could not access mapping OCDB");
732
733   AliMpDDLStore *ddlStore = AliMpDDLStore::Instance();
734   Int_t line, slat;
735   Float_t xLocal1=0., yLocal1=0., xLocal2=0., yLocal2=0.;
736   Float_t xg1, yg1, zg1, xg2, yg2, zg2;
737   Float_t xWidth=0., yWidth=0.;
738   Float_t x1Label=0., x2Label=0., y1Label=0., y2Label=0.;
739   Float_t x1LabelSlat=0., x2LabelSlat=0., y1LabelSlat=0., y2LabelSlat=0.;
740   Int_t x1=0, y1=0, x2=0, y2=0, localId;
741
742   gStyle->SetPalette(1);
743
744   Char_t *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
745
746   Float_t boardsX = 280.00;  // cm
747   Float_t boardsY = 335.00;  // cm
748
749   // Check fired pads (when available)  
750   Int_t maxY[fgkNcathodes] = {64,1};
751   TH3F *padFired[fgkNplanes];
752   TH1F *histoFired[fgkNplanes][234];
753   TH2F *histoFiredDisplay[fgkNplanes];
754   TF1 *fitFunc = 0x0;
755   Bool_t isStripOffInBoard[fgkNplanes][234];
756
757   TH2F *histo[fgkNplanes];
758   TH2F *histoSlat[fgkNplanes];
759   TPaveLabel *boardLabel[fgkNplanes][234];
760   TPaveLabel *boardLabelSlat[fgkNplanes][234];
761   assert(kNumOfBoards==234);
762
763   Char_t histoName[40], histoTitle[90], labelTxt[5], labelSlatTxt[5];
764
765   Float_t efficiency, efficiencyError, efficiencySlat, efficiencySlatError;
766
767   // Book histos
768   for(Int_t cath=0; cath<fgkNcathodes; cath++){
769     padFired[cath] = 0x0;
770     if(fFiredStrips) padFired[cath] = (TH3F*)fFiredStrips->At(cath);
771     for(Int_t ch=0; ch<fgkNchambers; ch++){
772       Int_t chCath = fgkNchambers*cath + ch;
773       sprintf(histoName, "%sChamber%i", cathCode[cath], 11+ch);
774       sprintf(histoTitle, "Chamber %i: efficiency %s", 11+ch, cathCode[cath]);
775       histo[chCath] = new TH2F(histoName, histoTitle, (Int_t)boardsX, -boardsX, boardsX, (Int_t)boardsY, -boardsY, boardsY);
776       histo[chCath]->SetXTitle("X (cm)");
777       histo[chCath]->SetYTitle("Y (cm)");
778       fDisplayHistoList->Add(histo[chCath]);
779
780       if(!fFiredStrips) continue;
781       sprintf(histoName, "firedPads%sChamber%i", cathCode[cath], 11+ch);
782       sprintf(histoTitle, "Chamber %i: Fired pads %s", 11+ch, cathCode[cath]);
783       histoFiredDisplay[chCath] = new TH2F(histoName, histoTitle, (Int_t)boardsX, -boardsX, boardsX, (Int_t)boardsY, -boardsY, boardsY);
784       histoFiredDisplay[chCath]->SetXTitle("X (cm)");
785       histoFiredDisplay[chCath]->SetYTitle("Y (cm)");
786       fFiredDisplayHistoList->Add(histoFiredDisplay[chCath]);
787       
788       for(Int_t ib=0; ib<kNumOfBoards; ib++){
789         sprintf(histoName, "%sChamber%iBoard%i", cathCode[cath], 11+ch, ib+1);
790         sprintf(histoTitle, "Chamber %i: fired pads %s board = %i", 11+ch, cathCode[cath], ib+1);
791         histoFired[chCath][ib] = new TH1F(histoName, histoTitle, 16, -0.5, 15.5);
792         histoFired[chCath][ib]->SetXTitle("board");
793         isStripOffInBoard[chCath][ib] = kFALSE;
794       } // loop on board
795     } // loop on chamber
796   } // loop on cathode
797
798   for(Int_t cath=0; cath<fgkNcathodes; cath++){
799     for(Int_t ch=0; ch<fgkNchambers; ch++){
800       Int_t chCath = fgkNchambers*cath + ch;
801       sprintf(histoName, "%sChamber%iSlatEff", cathCode[cath], 11+ch);
802       sprintf(histoTitle, "Chamber %i: efficiency %s per slat", 11+ch, cathCode[cath]);
803       histoSlat[chCath] = new TH2F(histoName, histoTitle, (Int_t)boardsX, -boardsX, boardsX, (Int_t)boardsY, -boardsY, boardsY);
804       histoSlat[chCath]->SetXTitle("X (cm)");
805       histoSlat[chCath]->SetYTitle("Y (cm)");
806       fDisplayHistoList->Add(histoSlat[chCath]);
807     }
808   }
809
810   // loop over the trigger DDL (Right: 20, Left: 21)
811   for (Int_t iDDL = 20; iDDL <= 21; ++iDDL) {
812     AliMpDDL* ddl = ddlStore->GetDDL(iDDL);
813     Int_t nCrate = ddl->GetNofTriggerCrates();
814     // loop over the number of crates in DDL
815     for (Int_t index = 0; index < nCrate; ++index) {
816       // get crate object
817       AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(iDDL, index);
818       Int_t nLocal = crate->GetNofLocalBoards();
819       for (Int_t iLocal = 0; iLocal < nLocal; ++iLocal) {
820         // get local board Id from crate object
821         localId = crate->GetLocalBoardId(iLocal);
822         // get local board object
823         AliMpLocalBoard* localBoard = ddlStore->GetLocalBoard(localId);
824
825         if (!localBoard->IsNotified()) continue;
826
827         // get detection element connected to this board
828         for (Int_t ch = 0; ch < fgkNchambers; ++ch) {
829           Int_t iCh = ch + AliMpConstants::NofTrackingChambers();
830           Int_t detElemId = ddlStore->GetDEfromLocalBoard(localId, iCh);
831
832           if (!detElemId) continue;
833
834           // get segmentation
835           for (Int_t cath = 0; cath < fgkNcathodes; ++cath) {
836             const AliMpVSegmentation* seg = AliMpSegmentation::Instance()
837               ->GetMpSegmentation(detElemId,
838                                   AliMp::GetCathodType(cath));
839
840             Int_t chCath = fgkNchambers*cath + ch;
841             slat = detElemId%100;
842             Int_t nStrips=0;
843
844             // loop over strips
845             for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
846               // get pad from electronics
847               AliMpPad pad = seg->PadByLocation(AliMpIntPair(localId,
848                                                                ibitxy),kFALSE);
849                 
850               if (!pad.IsValid()) continue;
851               if(cath==0){ // Geometry info from bending plane only
852                 if(ibitxy==0) {
853                   xLocal1 = pad.Position().X();
854                   yLocal1 = pad.Position().Y();
855                   xWidth = pad.Dimensions().X();
856                   yWidth = pad.Dimensions().Y();
857                 }
858                 xLocal2 = pad.Position().X();
859                 yLocal2 = pad.Position().Y();
860               }
861               
862               // Check fired pads (when available)
863               if(padFired[cath]) {
864                 Int_t padX = pad.GetIndices().GetFirst();
865                 Int_t padY = pad.GetIndices().GetSecond();
866                 Int_t currPair = padX*maxY[cath] + padY;
867                 nStrips++;
868                 //printf("cath %i board = %i  (%2i, %2i) -> %i\n",
869                 //cath, localId, padX, padY, currPair);
870                 Int_t chBin = padFired[cath]->GetXaxis()->FindBin(ch);
871                 Int_t slatBin = padFired[cath]->GetYaxis()->FindBin(slat);
872                 Int_t pairBin = padFired[cath]->GetZaxis()->FindBin(currPair);
873                 Float_t nFired = padFired[cath]->GetBinContent(chBin, slatBin, pairBin);;
874
875                 Float_t dimX = pad.Dimensions().X();
876                 Float_t dimY = pad.Dimensions().Y();
877
878                 Float_t stripX1 = pad.Position().X();
879                 Float_t stripY1 = pad.Position().Y();
880                 Float_t stripX2 = pad.Position().X();
881                 Float_t stripY2 = pad.Position().Y();
882
883                 transform->Local2Global(detElemId, stripX1, stripY1, 0, xg1, yg1, zg1);
884                 transform->Local2Global(detElemId, stripX2, stripY2, 0, xg2, yg2, zg2);
885
886                 Float_t x1Float = TMath::Min(xg1,xg2) - dimX;
887                 Float_t y1Float = TMath::Min(yg1,yg2) - dimY;
888                 Float_t x2Float = TMath::Max(xg1,xg2) + dimX;
889                 Float_t y2Float = TMath::Max(yg1,yg2) + dimY;  
890
891                 Int_t x1Int = histoFiredDisplay[chCath]->GetXaxis()->FindBin(x1Float)+1;
892                 Int_t y1Int = histoFiredDisplay[chCath]->GetYaxis()->FindBin(y1Float)+1;
893                 Int_t x2Int = histoFiredDisplay[chCath]->GetXaxis()->FindBin(x2Float)-1;
894                 Int_t y2Int = histoFiredDisplay[chCath]->GetYaxis()->FindBin(y2Float)-1;
895
896                 for(Int_t binX=x1Int; binX<=x2Int; binX++){
897                   for(Int_t binY=y1Int; binY<=y2Int; binY++){
898                     histoFiredDisplay[chCath]->SetBinContent(binX, binY, nFired);
899                   }
900                 }
901
902                 if(nFired==0.) nFired = kDummyFired;
903                 histoFired[chCath][localId-1]->Fill(ibitxy, nFired);
904               }
905             } // loop on strips
906
907             if(cath==0){ // Geometry info from bending plane only
908               transform->Local2Global(detElemId, xLocal1, yLocal1, 0, xg1, yg1, zg1);
909               transform->Local2Global(detElemId, xLocal2, yLocal2, 0, xg2, yg2, zg2);
910
911               // Per board
912               x1Label = TMath::Min(xg1,xg2) - xWidth;
913               y1Label = TMath::Min(yg1,yg2) - yWidth;
914               x2Label = TMath::Max(xg1,xg2) + xWidth;
915               y2Label = TMath::Max(yg1,yg2) + yWidth;
916
917               x1 = histo[ch]->GetXaxis()->FindBin(x1Label)+1;
918               y1 = histo[ch]->GetYaxis()->FindBin(y1Label)+1;
919               x2 = histo[ch]->GetXaxis()->FindBin(x2Label)-1;
920               y2 = histo[ch]->GetYaxis()->FindBin(y2Label)-1;
921
922               sprintf(labelTxt,"%3d", localId);
923
924               // Per slat
925               line = localBoard->GetPosition().GetFirst();
926               x1LabelSlat = 140.;
927               x2LabelSlat = x1LabelSlat + 40.;
928               y1LabelSlat = -285. + ((Float_t)(line - 1)) * 68;
929               y2LabelSlat = y1LabelSlat + 34.;
930               if(localId>kNumOfBoards/2){
931                 x1LabelSlat = -x2LabelSlat;
932                 x2LabelSlat = x1LabelSlat + 40.;
933               }
934               sprintf(labelSlatTxt,"%2d", slat);
935             }
936
937             boardLabel[chCath][localId-1] = new TPaveLabel(x1Label, y1Label, x2Label, y2Label, labelTxt);
938             boardLabel[chCath][localId-1]->SetFillStyle(0);
939             boardLabel[chCath][localId-1]->SetBorderSize(0);
940
941             boardLabelSlat[chCath][localId-1] = new TPaveLabel(x1LabelSlat, y1LabelSlat, x2LabelSlat, y2LabelSlat, labelSlatTxt);
942             boardLabelSlat[chCath][localId-1]->SetFillStyle(0);
943             boardLabelSlat[chCath][localId-1]->SetBorderSize(0);
944
945             Int_t histoBin = localId;
946             efficiency = fBoardEfficiency[chCath]->GetBinContent(histoBin);
947             efficiencyError = fBoardEfficiency[chCath]->GetBinError(histoBin);
948
949             histoBin = slat+1;
950             efficiencySlat = fSlatEfficiency[chCath]->GetBinContent(histoBin);
951             efficiencySlatError = fSlatEfficiency[chCath]->GetBinError(histoBin);
952
953             for(Int_t binX=x1; binX<=x2; binX++){
954               for(Int_t binY=y1; binY<=y2; binY++){
955                 histo[chCath]->SetBinContent(binX, binY, efficiency);
956                 histo[chCath]->SetBinError(binX, binY, efficiencyError);
957                 histoSlat[chCath]->SetBinContent(binX, binY, efficiencySlat);
958                 histoSlat[chCath]->SetBinError(binX, binY, efficiencySlatError);
959               }
960             }
961
962             // Check fired pads (when available)
963             if(padFired[cath]) {
964               histoFired[chCath][localId-1]->Fit("pol0","Q0R","",0., (Float_t)nStrips-1.);
965               fitFunc = histoFired[chCath][localId-1]->GetFunction("pol0");
966               Float_t chi2 = fitFunc->GetChisquare();
967               Float_t ndf = (Float_t)fitFunc->GetNDF();
968               Float_t reducedChi2 = chi2/ndf;
969               if(reducedChi2>kChi2RedMax) {
970                 isStripOffInBoard[chCath][localId-1] = kTRUE;
971                 //printf("Chamber = %i Cath = %i Board %i: chi2/NDF = %f\tparam = %f\n", ch, cath, localId, reducedChi2, fitFunc->GetParameter(0));
972                 fFiredFitHistoList->Add(histoFired[chCath][localId-1]);
973               }
974             }
975           } // loop on cathodes
976         } // loop on chambers
977       } // loop on boards
978     } // loop on crates
979   } // loop on DDL
980
981   for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
982     for(Int_t ib=0; ib<kNumOfBoards; ib++){
983       fBoardLabelList->Add(boardLabel[chCath][ib]);
984     }
985   }
986   for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
987     for(Int_t ib=0; ib<kNumOfBoards; ib++){
988       fBoardLabelList->Add(boardLabelSlat[chCath][ib]);
989     }
990   }
991
992   return kTRUE;
993 }
994
995
996 //__________________________________________________________________________
997 Bool_t AliMUONTriggerEfficiencyCells::SumRunEfficiency(const AliMUONTriggerEfficiencyCells &other)
998 {
999 ///  Sums results from different runs and gives the efficiency
1000   if(!fCountHistoList || !fNoCountHistoList) {
1001     AliWarning("Histograms for efficiency calculations not implemented in object");
1002     return kFALSE;
1003   }
1004   if(!other.fCountHistoList || !other.fNoCountHistoList) {
1005     AliWarning("Histograms for efficiency calculations not implemented in object passed as argument");
1006     return kFALSE;
1007   }
1008
1009   Int_t nentries = fCountHistoList->GetEntries();
1010   TH1F *currNum = 0x0, *currDen = 0x0, *otherNum = 0x0, *otherDen = 0x0;
1011
1012   for(Int_t iEntry=0; iEntry<nentries; iEntry++){
1013     currNum = (TH1F*)fCountHistoList->At(iEntry);
1014     currDen = (TH1F*)fNoCountHistoList->At(iEntry);
1015     otherNum = (TH1F*)other.fCountHistoList->At(iEntry);
1016     otherDen = (TH1F*)other.fNoCountHistoList->At(iEntry);
1017     currNum->Add(otherNum);
1018     currDen->Add(otherDen);
1019   }
1020
1021   FillHistosFromList();
1022
1023   if(!fFiredStrips) {
1024     AliWarning("Histograms for fired region check not implemented in object");
1025     return kFALSE;
1026   }
1027   if(!other.fFiredStrips) {
1028     AliWarning("Histograms for fired region check not implemented in object passed as argument");
1029     return kFALSE;
1030   }
1031   
1032   TH3F *currFired = 0x0, *otherFired = 0x0;
1033   nentries = fFiredStrips->GetEntries();
1034   for(Int_t iEntry=0; iEntry<nentries; iEntry++){
1035     currFired  = (TH3F*)fFiredStrips->At(iEntry);
1036     otherFired = (TH3F*)fFiredStrips->At(iEntry);
1037     currFired->Add(otherFired);
1038   }
1039     
1040   return kTRUE;
1041 }