]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONTriggerEfficiencyCells.cxx
Calibration object splitted in: pedestal + E calib + reco parameters
[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   const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards();
711   const Float_t kChi2RedMax = 1.5;
712   const Float_t kDummyFired = 1e-5;
713
714   if(fDisplayHistoList || fBoardLabelList || fFiredFitHistoList || fFiredDisplayHistoList) return kTRUE;
715
716   if(!fDisplayHistoList) fDisplayHistoList = new TList();
717   if(!fBoardLabelList) fBoardLabelList = new TList(); 
718   if(!fFiredFitHistoList && fFiredStrips) fFiredFitHistoList = new TList();
719   if(!fFiredDisplayHistoList && fFiredStrips) fFiredDisplayHistoList = new TList();
720
721   AliMUONGeometryTransformer *transform = new AliMUONGeometryTransformer();
722   transform->LoadGeometryData(geoFilename);
723
724   if(!AliMpCDB::LoadDDLStore()) // Load DDL store from OCDB
725     AliFatal("Could not access mapping OCDB");
726
727   AliMpDDLStore *ddlStore = AliMpDDLStore::Instance();
728   Int_t line, slat;
729   Float_t xLocal1=0., yLocal1=0., xLocal2=0., yLocal2=0.;
730   Float_t xg1, yg1, zg1, xg2, yg2, zg2;
731   Float_t xWidth=0., yWidth=0.;
732   Float_t x1Label=0., x2Label=0., y1Label=0., y2Label=0.;
733   Float_t x1LabelSlat=0., x2LabelSlat=0., y1LabelSlat=0., y2LabelSlat=0.;
734   Int_t x1=0, y1=0, x2=0, y2=0, localId;
735
736   gStyle->SetPalette(1);
737
738   Char_t *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
739
740   Float_t boardsX = 280.00;  // cm
741   Float_t boardsY = 335.00;  // cm
742
743   // Check fired pads (when available)  
744   Int_t maxY[fgkNcathodes] = {64,1};
745   TH3F *padFired[fgkNplanes];
746   TH1F *histoFired[fgkNplanes][234];
747   TH2F *histoFiredDisplay[fgkNplanes];
748   TF1 *fitFunc = 0x0;
749   Bool_t isStripOffInBoard[fgkNplanes][234];
750
751   TH2F *histo[fgkNplanes];
752   TH2F *histoSlat[fgkNplanes];
753   TPaveLabel *boardLabel[fgkNplanes][234];
754   TPaveLabel *boardLabelSlat[fgkNplanes][234];
755   assert(kNumOfBoards==234);
756
757   Char_t histoName[40], histoTitle[90], labelTxt[5], labelSlatTxt[5];
758
759   Float_t efficiency, efficiencyError, efficiencySlat, efficiencySlatError;
760
761   // Book histos
762   for(Int_t cath=0; cath<fgkNcathodes; cath++){
763     padFired[cath] = 0x0;
764     if(fFiredStrips) padFired[cath] = (TH3F*)fFiredStrips->At(cath);
765     for(Int_t ch=0; ch<fgkNchambers; ch++){
766       Int_t chCath = fgkNchambers*cath + ch;
767       sprintf(histoName, "%sChamber%i", cathCode[cath], 11+ch);
768       sprintf(histoTitle, "Chamber %i: efficiency %s", 11+ch, cathCode[cath]);
769       histo[chCath] = new TH2F(histoName, histoTitle, (Int_t)boardsX, -boardsX, boardsX, (Int_t)boardsY, -boardsY, boardsY);
770       histo[chCath]->SetXTitle("X (cm)");
771       histo[chCath]->SetYTitle("Y (cm)");
772       fDisplayHistoList->Add(histo[chCath]);
773
774       if(!fFiredStrips) continue;
775       sprintf(histoName, "firedPads%sChamber%i", cathCode[cath], 11+ch);
776       sprintf(histoTitle, "Chamber %i: Fired pads %s", 11+ch, cathCode[cath]);
777       histoFiredDisplay[chCath] = new TH2F(histoName, histoTitle, (Int_t)boardsX, -boardsX, boardsX, (Int_t)boardsY, -boardsY, boardsY);
778       histoFiredDisplay[chCath]->SetXTitle("X (cm)");
779       histoFiredDisplay[chCath]->SetYTitle("Y (cm)");
780       fFiredDisplayHistoList->Add(histoFiredDisplay[chCath]);
781       
782       for(Int_t ib=0; ib<kNumOfBoards; ib++){
783         sprintf(histoName, "%sChamber%iBoard%i", cathCode[cath], 11+ch, ib+1);
784         sprintf(histoTitle, "Chamber %i: fired pads %s board = %i", 11+ch, cathCode[cath], ib+1);
785         histoFired[chCath][ib] = new TH1F(histoName, histoTitle, 16, -0.5, 15.5);
786         histoFired[chCath][ib]->SetXTitle("board");
787         isStripOffInBoard[chCath][ib] = kFALSE;
788       } // loop on board
789     } // loop on chamber
790   } // loop on cathode
791
792   for(Int_t cath=0; cath<fgkNcathodes; cath++){
793     for(Int_t ch=0; ch<fgkNchambers; ch++){
794       Int_t chCath = fgkNchambers*cath + ch;
795       sprintf(histoName, "%sChamber%iSlatEff", cathCode[cath], 11+ch);
796       sprintf(histoTitle, "Chamber %i: efficiency %s per slat", 11+ch, cathCode[cath]);
797       histoSlat[chCath] = new TH2F(histoName, histoTitle, (Int_t)boardsX, -boardsX, boardsX, (Int_t)boardsY, -boardsY, boardsY);
798       histoSlat[chCath]->SetXTitle("X (cm)");
799       histoSlat[chCath]->SetYTitle("Y (cm)");
800       fDisplayHistoList->Add(histoSlat[chCath]);
801     }
802   }
803
804   // loop over the trigger DDL (Right: 20, Left: 21)
805   for (Int_t iDDL = 20; iDDL <= 21; ++iDDL) {
806     AliMpDDL* ddl = ddlStore->GetDDL(iDDL);
807     Int_t nCrate = ddl->GetNofTriggerCrates();
808     // loop over the number of crates in DDL
809     for (Int_t index = 0; index < nCrate; ++index) {
810       // get crate object
811       AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(iDDL, index);
812       Int_t nLocal = crate->GetNofLocalBoards();
813       for (Int_t iLocal = 0; iLocal < nLocal; ++iLocal) {
814         // get local board Id from crate object
815         localId = crate->GetLocalBoardId(iLocal);
816         // get local board object
817         AliMpLocalBoard* localBoard = ddlStore->GetLocalBoard(localId);
818
819         if (!localBoard->IsNotified()) continue;
820
821         // get detection element connected to this board
822         for (Int_t ch = 0; ch < fgkNchambers; ++ch) {
823           Int_t iCh = ch + AliMpConstants::NofTrackingChambers();
824           Int_t detElemId = ddlStore->GetDEfromLocalBoard(localId, iCh);
825
826           if (!detElemId) continue;
827
828           // get segmentation
829           for (Int_t cath = 0; cath < fgkNcathodes; ++cath) {
830             const AliMpVSegmentation* seg = AliMpSegmentation::Instance()
831               ->GetMpSegmentation(detElemId,
832                                   AliMp::GetCathodType(cath));
833
834             Int_t chCath = fgkNchambers*cath + ch;
835             slat = detElemId%100;
836             Int_t nStrips=0;
837
838             // loop over strips
839             for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
840               // get pad from electronics
841               AliMpPad pad = seg->PadByLocation(AliMpIntPair(localId,
842                                                                ibitxy),kFALSE);
843                 
844               if (!pad.IsValid()) continue;
845               if(cath==0){ // Geometry info from bending plane only
846                 if(ibitxy==0) {
847                   xLocal1 = pad.Position().X();
848                   yLocal1 = pad.Position().Y();
849                   xWidth = pad.Dimensions().X();
850                   yWidth = pad.Dimensions().Y();
851                 }
852                 xLocal2 = pad.Position().X();
853                 yLocal2 = pad.Position().Y();
854               }
855               
856               // Check fired pads (when available)
857               if(padFired[cath]) {
858                 Int_t padX = pad.GetIndices().GetFirst();
859                 Int_t padY = pad.GetIndices().GetSecond();
860                 Int_t currPair = padX*maxY[cath] + padY;
861                 nStrips++;
862                 //printf("cath %i board = %i  (%2i, %2i) -> %i\n",
863                 //cath, localId, padX, padY, currPair);
864                 Int_t chBin = padFired[cath]->GetXaxis()->FindBin(ch);
865                 Int_t slatBin = padFired[cath]->GetYaxis()->FindBin(slat);
866                 Int_t pairBin = padFired[cath]->GetZaxis()->FindBin(currPair);
867                 Float_t nFired = padFired[cath]->GetBinContent(chBin, slatBin, pairBin);;
868
869                 Float_t dimX = pad.Dimensions().X();
870                 Float_t dimY = pad.Dimensions().Y();
871
872                 Float_t stripX1 = pad.Position().X();
873                 Float_t stripY1 = pad.Position().Y();
874                 Float_t stripX2 = pad.Position().X();
875                 Float_t stripY2 = pad.Position().Y();
876
877                 transform->Local2Global(detElemId, stripX1, stripY1, 0, xg1, yg1, zg1);
878                 transform->Local2Global(detElemId, stripX2, stripY2, 0, xg2, yg2, zg2);
879
880                 Float_t x1Float = TMath::Min(xg1,xg2) - dimX;
881                 Float_t y1Float = TMath::Min(yg1,yg2) - dimY;
882                 Float_t x2Float = TMath::Max(xg1,xg2) + dimX;
883                 Float_t y2Float = TMath::Max(yg1,yg2) + dimY;  
884
885                 Int_t x1Int = histoFiredDisplay[chCath]->GetXaxis()->FindBin(x1Float)+1;
886                 Int_t y1Int = histoFiredDisplay[chCath]->GetYaxis()->FindBin(y1Float)+1;
887                 Int_t x2Int = histoFiredDisplay[chCath]->GetXaxis()->FindBin(x2Float)-1;
888                 Int_t y2Int = histoFiredDisplay[chCath]->GetYaxis()->FindBin(y2Float)-1;
889
890                 for(Int_t binX=x1Int; binX<=x2Int; binX++){
891                   for(Int_t binY=y1Int; binY<=y2Int; binY++){
892                     histoFiredDisplay[chCath]->SetBinContent(binX, binY, nFired);
893                   }
894                 }
895
896                 if(nFired==0.) nFired = kDummyFired;
897                 histoFired[chCath][localId-1]->Fill(ibitxy, nFired);
898               }
899             } // loop on strips
900
901             if(cath==0){ // Geometry info from bending plane only
902               transform->Local2Global(detElemId, xLocal1, yLocal1, 0, xg1, yg1, zg1);
903               transform->Local2Global(detElemId, xLocal2, yLocal2, 0, xg2, yg2, zg2);
904
905               // Per board
906               x1Label = TMath::Min(xg1,xg2) - xWidth;
907               y1Label = TMath::Min(yg1,yg2) - yWidth;
908               x2Label = TMath::Max(xg1,xg2) + xWidth;
909               y2Label = TMath::Max(yg1,yg2) + yWidth;
910
911               x1 = histo[ch]->GetXaxis()->FindBin(x1Label)+1;
912               y1 = histo[ch]->GetYaxis()->FindBin(y1Label)+1;
913               x2 = histo[ch]->GetXaxis()->FindBin(x2Label)-1;
914               y2 = histo[ch]->GetYaxis()->FindBin(y2Label)-1;
915
916               sprintf(labelTxt,"%3d", localId);
917
918               // Per slat
919               line = localBoard->GetPosition().GetFirst();
920               x1LabelSlat = 140.;
921               x2LabelSlat = x1LabelSlat + 40.;
922               y1LabelSlat = -285. + ((Float_t)(line - 1)) * 68;
923               y2LabelSlat = y1LabelSlat + 34.;
924               if(localId>kNumOfBoards/2){
925                 x1LabelSlat = -x2LabelSlat;
926                 x2LabelSlat = x1LabelSlat + 40.;
927               }
928               sprintf(labelSlatTxt,"%2d", slat);
929             }
930
931             boardLabel[chCath][localId-1] = new TPaveLabel(x1Label, y1Label, x2Label, y2Label, labelTxt);
932             boardLabel[chCath][localId-1]->SetFillStyle(0);
933             boardLabel[chCath][localId-1]->SetBorderSize(0);
934
935             boardLabelSlat[chCath][localId-1] = new TPaveLabel(x1LabelSlat, y1LabelSlat, x2LabelSlat, y2LabelSlat, labelSlatTxt);
936             boardLabelSlat[chCath][localId-1]->SetFillStyle(0);
937             boardLabelSlat[chCath][localId-1]->SetBorderSize(0);
938
939             Int_t histoBin = localId;
940             efficiency = fBoardEfficiency[chCath]->GetBinContent(histoBin);
941             efficiencyError = fBoardEfficiency[chCath]->GetBinError(histoBin);
942
943             histoBin = slat+1;
944             efficiencySlat = fSlatEfficiency[chCath]->GetBinContent(histoBin);
945             efficiencySlatError = fSlatEfficiency[chCath]->GetBinError(histoBin);
946
947             for(Int_t binX=x1; binX<=x2; binX++){
948               for(Int_t binY=y1; binY<=y2; binY++){
949                 histo[chCath]->SetBinContent(binX, binY, efficiency);
950                 histo[chCath]->SetBinError(binX, binY, efficiencyError);
951                 histoSlat[chCath]->SetBinContent(binX, binY, efficiencySlat);
952                 histoSlat[chCath]->SetBinError(binX, binY, efficiencySlatError);
953               }
954             }
955
956             // Check fired pads (when available)
957             if(padFired[cath]) {
958               histoFired[chCath][localId-1]->Fit("pol0","Q0R","",0., (Float_t)nStrips-1.);
959               fitFunc = histoFired[chCath][localId-1]->GetFunction("pol0");
960               Float_t chi2 = fitFunc->GetChisquare();
961               Float_t ndf = (Float_t)fitFunc->GetNDF();
962               Float_t reducedChi2 = chi2/ndf;
963               if(reducedChi2>kChi2RedMax) {
964                 isStripOffInBoard[chCath][localId-1] = kTRUE;
965                 //printf("Chamber = %i Cath = %i Board %i: chi2/NDF = %f\tparam = %f\n", ch, cath, localId, reducedChi2, fitFunc->GetParameter(0));
966                 fFiredFitHistoList->Add(histoFired[chCath][localId-1]);
967               }
968             }
969           } // loop on cathodes
970         } // loop on chambers
971       } // loop on boards
972     } // loop on crates
973   } // loop on DDL
974
975   for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
976     for(Int_t ib=0; ib<kNumOfBoards; ib++){
977       fBoardLabelList->Add(boardLabel[chCath][ib]);
978     }
979   }
980   for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
981     for(Int_t ib=0; ib<kNumOfBoards; ib++){
982       fBoardLabelList->Add(boardLabelSlat[chCath][ib]);
983     }
984   }
985
986   return kTRUE;
987 }
988
989
990 //__________________________________________________________________________
991 Bool_t AliMUONTriggerEfficiencyCells::SumRunEfficiency(const AliMUONTriggerEfficiencyCells &other)
992 {
993 ///  Sums results from different runs and gives the efficiency
994   if(!fCountHistoList || !fNoCountHistoList) {
995     AliWarning("Histograms for efficiency calculations not implemented in object");
996     return kFALSE;
997   }
998   if(!other.fCountHistoList || !other.fNoCountHistoList) {
999     AliWarning("Histograms for efficiency calculations not implemented in object passed as argument");
1000     return kFALSE;
1001   }
1002
1003   Int_t nentries = fCountHistoList->GetEntries();
1004   TH1F *currNum = 0x0, *currDen = 0x0, *otherNum = 0x0, *otherDen = 0x0;
1005
1006   for(Int_t iEntry=0; iEntry<nentries; iEntry++){
1007     currNum = (TH1F*)fCountHistoList->At(iEntry);
1008     currDen = (TH1F*)fNoCountHistoList->At(iEntry);
1009     otherNum = (TH1F*)other.fCountHistoList->At(iEntry);
1010     otherDen = (TH1F*)other.fNoCountHistoList->At(iEntry);
1011     currNum->Add(otherNum);
1012     currDen->Add(otherDen);
1013   }
1014
1015   FillHistosFromList();
1016
1017   if(!fFiredStrips) {
1018     AliWarning("Histograms for fired region check not implemented in object");
1019     return kFALSE;
1020   }
1021   if(!other.fFiredStrips) {
1022     AliWarning("Histograms for fired region check not implemented in object passed as argument");
1023     return kFALSE;
1024   }
1025   
1026   TH3F *currFired = 0x0, *otherFired = 0x0;
1027   nentries = fFiredStrips->GetEntries();
1028   for(Int_t iEntry=0; iEntry<nentries; iEntry++){
1029     currFired  = (TH3F*)fFiredStrips->At(iEntry);
1030     otherFired = (TH3F*)fFiredStrips->At(iEntry);
1031     currFired->Add(otherFired);
1032   }
1033     
1034   return kTRUE;
1035 }