]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONTriggerChamberEff.cxx
- Adding *.C *.txt *.sh to FILE_PATTERNS
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerChamberEff.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 /* $Id$ */
17
18 /// \class AliMUONTriggerChamberEff
19 /// implementation of the trigger chamber efficiency determination from
20 /// data, and returns the
21 /// efficiencyCells.dat with the calculated efficiencies
22 ///
23 /// \author Diego Stocco (Torino)
24
25 #include "AliMUONTriggerChamberEff.h"
26 #include "AliMUONVDigit.h"
27 #include "AliMUONConstants.h"
28 #include "AliMUONTriggerTrack.h"
29 #include "AliMUONDigitMaker.h"
30 #include "AliMUONLocalTrigger.h"
31 #include "AliMUONGeometryTransformer.h"
32
33 #include "AliMUONTrack.h"
34 #include "AliMUONTrackParam.h"
35 #include "AliMUONTrackExtrap.h"
36
37 #include "AliMUONDigitStoreV1.h"
38 #include "AliMUONVDigitStore.h"
39 #include "AliMUONVTriggerStore.h"
40 #include "AliMUONVTriggerTrackStore.h"
41 #include "AliMUONVTrackStore.h"
42
43 #include "AliMpVSegmentation.h"
44 #include "AliMpSegmentation.h"
45 #include "AliMpPad.h"
46 #include "AliMpDEIterator.h"
47 #include "AliMpPlaneType.h"
48 #include "AliMpDEManager.h"
49 #include "AliMpConstants.h"
50
51 #include "AliMpDDLStore.h"
52 #include "AliMpDDL.h"
53 #include "AliMpTriggerCrate.h"
54 #include "AliMpLocalBoard.h"
55
56 #include "AliLog.h"
57
58 #include <Riostream.h>
59 #include <TFile.h>
60 #include <TH1F.h>
61 #include <TMath.h>
62
63 #include <TSeqCollection.h>
64 #include <TTree.h>
65 #include <TROOT.h>
66
67 #include <TStyle.h>
68 #include <TCanvas.h>
69 #include <TH2.h>
70 #include <TSystem.h>
71 #include <TPaveLabel.h>
72
73 #include <cassert>
74
75 /// \cond CLASSIMP
76 ClassImp(AliMUONTriggerChamberEff)
77 /// \endcond
78
79 //_____________________________________________________________________________
80 AliMUONTriggerChamberEff::AliMUONTriggerChamberEff()
81 : TObject(),
82   fTransformer(0x0),
83   fDigitMaker(0x0),
84   fReproduceTrigResponse(kFALSE),
85   fPrintInfo(kFALSE),
86   fWriteOnESD(kFALSE),
87   fDebugLevel(0),
88   fkMaxDistance(99999.)
89 {
90 /// Default constructor
91
92     CheckConstants();
93     ResetArrays();
94 }
95
96
97 //_____________________________________________________________________________
98 AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(const AliMUONGeometryTransformer* transformer,
99                                                    const AliMUONDigitMaker* digitMaker,
100                                                    Bool_t writeOnESD)
101 : TObject(),
102   fTransformer(transformer),
103   fDigitMaker(digitMaker),
104   fReproduceTrigResponse(kFALSE),
105   fPrintInfo(kFALSE),
106   fWriteOnESD(writeOnESD),
107   fDebugLevel(0),
108   fkMaxDistance(99999.)
109 {
110 /// Standard constructor
111
112     CheckConstants();
113     ResetArrays();
114 }
115
116
117 //_____________________________________________________________________________
118 AliMUONTriggerChamberEff::~AliMUONTriggerChamberEff()
119 {
120 /// Destructor
121     Bool_t writeOnESD=fWriteOnESD;
122     fWriteOnESD=kFALSE;
123     if(writeOnESD) SaveInESDFile();
124 }
125
126
127 //_____________________________________________________________________________
128 AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(const AliMUONTriggerChamberEff& other)
129     :TObject(other),
130      fTransformer(0x0),
131      fDigitMaker(0x0),
132      fReproduceTrigResponse(other.fReproduceTrigResponse),
133      fPrintInfo(other.fPrintInfo),
134      fWriteOnESD(other.fWriteOnESD),
135      fDebugLevel(other.fDebugLevel),
136      fkMaxDistance(other.fkMaxDistance),
137      fTrigger44(other.fTrigger44),
138      fTrigger34(other.fTrigger34)
139 {
140 /// Copy constructor
141
142     for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
143         fInefficientSlat[chCath] = other.fInefficientSlat[chCath];
144         fHitPerSlat[chCath] = other.fHitPerSlat[chCath];
145         fInefficientBoard[chCath] = other.fInefficientBoard[chCath];
146         fHitPerBoard[chCath] = other.fHitPerBoard[chCath];
147     }
148 }
149
150
151 //_____________________________________________________________________________
152 AliMUONTriggerChamberEff& AliMUONTriggerChamberEff::operator=(const AliMUONTriggerChamberEff& other)
153 {
154     /// Asignment operator
155     // check assignement to self
156     if (this == &other)
157         return *this;
158
159     // base class assignement
160     TObject::operator=(other);
161
162     fTransformer = 0x0;
163     fDigitMaker = 0x0;
164     fReproduceTrigResponse = other.fReproduceTrigResponse;
165     fPrintInfo = other.fPrintInfo;
166     fWriteOnESD = other.fWriteOnESD;
167     fDebugLevel = other.fDebugLevel;
168
169     fTrigger44 = other.fTrigger44;
170     fTrigger34 = other.fTrigger34;
171
172     for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
173         fInefficientSlat[chCath] = other.fInefficientSlat[chCath];
174         fHitPerSlat[chCath] = other.fHitPerSlat[chCath];
175         fInefficientBoard[chCath] = other.fInefficientBoard[chCath];
176         fHitPerBoard[chCath] = other.fHitPerBoard[chCath];
177     }
178     return *this;
179 }
180
181
182 //_____________________________________________________________________________
183 void AliMUONTriggerChamberEff::ResetArrays()
184 {
185     //
186     /// Sets the data member counters to 0.
187     //
188
189     fTrigger44.Set(fgkNcathodes);
190     fTrigger34.Set(fgkNplanes);
191
192     for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
193         fInefficientSlat[chCath].Set(fgkNslats);
194         fHitPerSlat[chCath].Set(fgkNslats);
195         fInefficientBoard[chCath].Set(AliMpConstants::NofLocalBoards());
196         fHitPerBoard[chCath].Set(AliMpConstants::NofLocalBoards());
197     }
198
199     fTrigger44.Reset();
200     fTrigger34.Reset();
201
202     for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
203         fInefficientSlat[chCath].Reset();
204         fHitPerSlat[chCath].Reset();
205         fInefficientBoard[chCath].Reset();
206         fHitPerBoard[chCath].Reset();
207     }
208 }
209
210
211 //______________________________________________________________________________
212 Bool_t 
213 AliMUONTriggerChamberEff::TriggerDigits(const AliMUONVTriggerStore& triggerStore,
214                                         AliMUONVDigitStore& digitStore) const
215 {
216     //
217     /// make (S)Digit for trigger
218     //
219     digitStore.Clear();
220
221     AliMUONLocalTrigger* locTrg;
222     TIter next(triggerStore.CreateLocalIterator());
223   
224     while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) ) 
225     {
226         if (locTrg->IsNull()) continue;
227    
228         TArrayS xyPattern[fgkNcathodes];
229         locTrg->GetXPattern(xyPattern[0]);
230         locTrg->GetYPattern(xyPattern[1]);
231     
232         Int_t nBoard = locTrg->LoCircuit();
233         fDigitMaker->TriggerDigits(nBoard, xyPattern, digitStore);
234     }
235     return kTRUE;
236 }
237
238
239 //_____________________________________________________________________________
240 void AliMUONTriggerChamberEff::InfoDigit(AliMUONVDigitStore& digitStore)
241 {
242     //
243     /// Prints information on digits (for debugging)
244     //
245     TIter next(digitStore.CreateIterator());
246     AliMUONVDigit* mDigit=0x0;
247     
248     while ( ( mDigit = static_cast<AliMUONVDigit*>(next()) ) )
249     {
250         mDigit->Print();
251     } // end digit loop
252     printf("\n");
253 }
254
255
256 //_____________________________________________________________________________
257 Int_t AliMUONTriggerChamberEff::MatchingPad(AliMUONVDigitStore& digitStore, Int_t &detElemId,
258                                             Float_t coor[2], Bool_t isMatch[2],
259                                             TArrayI nboard[2], TArrayF &zRealMatch, Float_t y11)
260 {
261     //
262     /// Check slat and board number of digit matching track
263     //
264
265     enum {kBending, kNonBending};
266
267     Float_t minMatchDist[fgkNcathodes];
268     Int_t padsInCheckArea[fgkNcathodes];
269
270     for(Int_t cath=0; cath<fgkNcathodes; cath++){
271         isMatch[cath] = kFALSE;
272         minMatchDist[cath] = fkMaxDistance/10.;
273         padsInCheckArea[cath] = 0;
274     }
275     Int_t iChamber = AliMpDEManager::GetChamberId(detElemId);
276     Int_t ch = iChamber-10;
277     Float_t oldDeltaZ = AliMUONConstants::DefaultChamberZ(iChamber) - AliMUONConstants::DefaultChamberZ(10);
278     Float_t y = coor[1];
279     Int_t iSlat = detElemId%100;
280     Int_t trigDigitBendPlane = -1;
281     Int_t foundDetElemId = detElemId;
282     Float_t foundZmatch=999.;
283     Float_t yCoorAtPadZ=999.;
284
285     TIter next(digitStore.CreateIterator());
286     AliMUONVDigit* mDigit;
287     Int_t idigit=0;
288     
289     while ( ( mDigit = static_cast<AliMUONVDigit*>(next()) ) )
290     {
291         idigit++;
292         Int_t currDetElemId = mDigit->DetElemId();
293         Int_t currCh = AliMpDEManager::GetChamberId(currDetElemId);
294         if(currCh!=iChamber) continue;
295         Int_t currSlat = currDetElemId%100;
296         Int_t slatDiff = TMath::Abs(currSlat-iSlat);
297         if(slatDiff>1 && slatDiff<17) continue; // Check neighbour slats
298         Int_t cathode = mDigit->Cathode();
299         Int_t ix = mDigit->PadX();
300         Int_t iy = mDigit->PadY();
301         Float_t xpad, ypad, zpad;
302         const AliMpVSegmentation* seg = AliMpSegmentation::Instance()
303             ->GetMpSegmentation(currDetElemId,AliMp::GetCathodType(cathode));
304
305         AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
306         Float_t xlocal1 = pad.Position().X();
307         Float_t ylocal1 = pad.Position().Y();
308         Float_t dpx = pad.Dimensions().X();
309         Float_t dpy = pad.Dimensions().Y();
310         fTransformer->Local2Global(currDetElemId, xlocal1, ylocal1, 0, xpad, ypad, zpad);
311         if(fDebugLevel>2)printf("DetElemId = %i\tCathode = %i\t(x,y) Pad = (%i,%i) = (%.2f,%.2f)\tDim = (%.2f,%.2f)\tTrack = (%.2f,%.2f)\n",currDetElemId,cathode,ix,iy,xpad,ypad,dpx,dpy,coor[0],coor[1]);
312         // searching track intersection with chambers (second approximation)
313         if(ch%2==1){
314             //if(iChamber%2==1){
315             Float_t deltaZ = zpad - zRealMatch[0];
316             y = (coor[1]-y11)*deltaZ/oldDeltaZ + y11;
317             if(fDebugLevel>=3 && TMath::Abs(y-coor[1])>0.1)printf("oldDeltaZ = %7.2f   newDeltaZ = %7.2f\toldY = %7.2f   new y = %7.2f\n",oldDeltaZ,deltaZ,coor[1],y);
318         }
319         Float_t matchDist = PadMatchTrack(xpad, ypad, dpx, dpy, coor[0], y, ch);
320         if(matchDist<fkMaxDistance/2.) padsInCheckArea[cathode]++;
321         if(matchDist>minMatchDist[cathode])continue;
322         isMatch[cathode] = kTRUE;
323         minMatchDist[cathode] = matchDist;
324         foundDetElemId = currDetElemId;
325         foundZmatch=zpad;
326         yCoorAtPadZ=y;
327         if(cathode==kBending) trigDigitBendPlane = idigit;
328         for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){
329             AliMpIntPair location = pad.GetLocation(loc);
330             nboard[cathode][loc] = location.GetFirst();
331         }
332         for(Int_t loc=pad.GetNofLocations(); loc<fgkNlocations; loc++){
333             nboard[cathode][loc]=-1;
334         }
335     }
336
337     for(Int_t cath=0; cath<fgkNcathodes; cath++){
338         if(padsInCheckArea[cath]>2) {
339             if(fDebugLevel>=1) printf("padsInCheckArea[%i] = %i\n",cath,padsInCheckArea[cath]);
340             return -500;
341         }
342     }
343
344     if(isMatch[kBending] || isMatch[kNonBending]){
345         detElemId = foundDetElemId;
346         zRealMatch[ch] = foundZmatch;
347         coor[1] = yCoorAtPadZ;
348         if(fDebugLevel>2){
349             Int_t whichCathode=kBending;
350             if(!isMatch[kBending])whichCathode=kNonBending;
351         }
352     }
353     return trigDigitBendPlane;
354 }
355
356 //_____________________________________________________________________________
357 Float_t AliMUONTriggerChamberEff::PadMatchTrack(Float_t xPad, Float_t yPad,
358                                                 Float_t dpx, Float_t dpy, 
359                                                 Float_t xTrackAtPad, Float_t yTrackAtPad,
360                                                 Int_t chamber)
361 {
362     //
363     /// Decides if the digit belongs to the trigger track.
364     //
365
366     Float_t maxDist = 2.;//3. // cm
367     Float_t maxDistCheckArea = 6.; // cm
368
369     Float_t matchDist = fkMaxDistance;
370
371     Float_t deltaX = TMath::Abs(xPad-xTrackAtPad)-dpx;
372     Float_t deltaY = TMath::Abs(yPad-yTrackAtPad)-dpy;
373     Float_t maxDistX = maxDist;
374     Float_t maxDistY = maxDist;
375     
376     if(fReproduceTrigResponse){
377         maxDistX = dpx;
378         maxDistY = dpy;
379         deltaX = TMath::Abs(xPad-xTrackAtPad);
380         deltaY = TMath::Abs(yPad-yTrackAtPad);
381         if(dpx<dpy && chamber>=2) maxDistX = 3.*dpx;// Non-bending plane: check the +- 1 strip between stations
382         if(dpy<dpx && chamber%2) maxDistY = 3.*dpy;// bending plane: check the +- 1 strip between planes in the same station
383     }
384
385     if(deltaX<=maxDistX && deltaY<=maxDistY) matchDist = TMath::Max(deltaX, deltaY);
386     else if(deltaX<=maxDistCheckArea && deltaY<=maxDistCheckArea) matchDist = fkMaxDistance/5.;
387     return matchDist;
388 }
389
390
391 //_____________________________________________________________________________
392 void AliMUONTriggerChamberEff::CalculateEfficiency(Int_t trigger44, Int_t trigger34,
393                                                    Float_t &efficiency, Float_t &error,
394                                                    Bool_t failuresAsInput)
395 {
396     //
397     /// Returns the efficiency.
398     //
399
400     efficiency=-9.;
401     error=0.;
402     if(trigger34>0){
403         efficiency=(Double_t)trigger44/((Double_t)trigger34);
404         if(failuresAsInput)efficiency=1.-(Double_t)trigger44/((Double_t)trigger34);
405     }
406     Double_t q = TMath::Abs(1-efficiency);
407     if(efficiency<0)error=0.0;
408     else error = TMath::Sqrt(efficiency*q/((Double_t)trigger34));
409 }
410
411
412 //_____________________________________________________________________________
413 Int_t AliMUONTriggerChamberEff::DetElemIdFromPos(Float_t x, Float_t y, 
414                                                  Int_t chamber, Int_t cathode)
415 {
416     //
417     /// Given the (x,y) position in the chamber,
418     /// it returns the corresponding slat
419     //
420
421     Int_t resultingDetElemId = -1;
422     AliMpDEIterator it;
423     Float_t minDist = 999.;
424     for ( it.First(chamber-1); ! it.IsDone(); it.Next() ){
425         Int_t detElemId = it.CurrentDEId();
426         Int_t ich = detElemId/100-10;
427         Float_t tolerance=0.2*((Float_t)ich);
428         Float_t currDist=9999.;
429
430         const AliMpVSegmentation* seg = 
431             AliMpSegmentation::Instance()
432             ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
433         if (!seg) continue;
434
435         Float_t deltax = seg->Dimensions().X();
436         Float_t deltay = seg->Dimensions().Y();
437         Float_t xlocal1 =  -deltax;
438         Float_t ylocal1 =  -deltay;
439         Float_t xlocal2 =  +deltax;
440         Float_t ylocal2 =  +deltay;
441         Float_t xg01, yg01, zg1, xg02, yg02, zg2;
442         fTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg01, yg01, zg1);
443         fTransformer->Local2Global(detElemId, xlocal2, ylocal2, 0, xg02, yg02, zg2);
444
445         Float_t xg1 = xg01, xg2 = xg02, yg1 = yg01, yg2 = yg02;
446
447         if(xg01>xg02){
448             xg1 = xg02;
449             xg2 = xg01;
450         }
451         if(yg01>yg02){
452             yg1 = yg02;
453             yg2 = yg01;
454         }
455
456         if(x>=xg1-tolerance && x<=xg2+tolerance && y>=yg1-tolerance && y<=yg2+tolerance){ // takes into account errors in extrapolation
457             if(y<yg1) currDist = yg1-y;
458             else if(y>yg2) currDist = y-yg2;
459             if(currDist<minDist) {
460                 resultingDetElemId = detElemId;
461                 minDist=currDist;
462                 continue;
463             }
464             resultingDetElemId = detElemId;
465             break;
466         }
467     } // loop on detElemId
468     return resultingDetElemId;
469 }
470
471
472 //_____________________________________________________________________________
473 void AliMUONTriggerChamberEff::LocalBoardFromPos(Float_t x, Float_t y,
474                                                  Int_t detElemId, Int_t cathode,
475                                                  Int_t localBoard[4])
476 {
477     //
478     /// Given the (x,y) position in the chamber,
479     /// it returns the corresponding local board
480     //
481
482     for(Int_t loc=0; loc<fgkNlocations; loc++){
483         localBoard[loc]=-1;
484     }
485     Float_t xl, yl, zl;
486     fTransformer->Global2Local(detElemId, x, y, 0, xl, yl, zl);
487     TVector2 pos(xl,yl);
488     const AliMpVSegmentation* seg = 
489         AliMpSegmentation::Instance()
490           ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
491     if (seg){
492         AliMpPad pad = seg->PadByPosition(pos,kFALSE);
493         for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){
494             AliMpIntPair location = pad.GetLocation(loc);
495             localBoard[loc] = location.GetFirst();
496         }
497     }
498 }
499
500
501 //_____________________________________________________________________________
502 void AliMUONTriggerChamberEff::EventChamberEff(const AliMUONVTriggerStore& triggerStore,
503                                                const AliMUONVTriggerTrackStore& trigTrackStore,
504                                                const AliMUONVTrackStore& trackStore)
505 {
506     //
507     /// Main method.
508     /// It loops over the the trigger rec. tracks in the event.
509     /// Then it search for matching digits around the track.
510     /// Finally it calculates the efficiency for each trigger board.
511     /// Files with calculated efficiency are placed in the user defined outputDir.
512     //
513
514     if(!fTransformer || ! fDigitMaker) {
515         AliError(Form("AliMUONGeometryTransformer or AliMUONDigitMaker not properly initialized!!"));
516         return;
517     }
518
519     enum {kBending, kNonBending};
520     Float_t rad2deg = 180./TMath::Pi();
521
522     Int_t chOrder[fgkNchambers] = {0,2,1,3};
523
524     TArrayF zRealMatch(fgkNchambers);
525     TArrayF correctFactor(fgkNcathodes);
526
527     Bool_t match[fgkNchambers][fgkNcathodes];
528     Bool_t matchPad[fgkNcathodes];
529     for(Int_t cath=0; cath<fgkNcathodes; cath++){
530         matchPad[cath] = kFALSE;
531     }
532
533     TArrayF zMeanChamber(fgkNchambers);
534     for(Int_t ch=0; ch<fgkNchambers; ch++){
535         zMeanChamber[ch] = AliMUONConstants::DefaultChamberZ(10+ch);
536     }
537
538     TArrayI digitPerTrack(fgkNcathodes);
539
540     Float_t trackIntersectCh[fgkNchambers][fgkNcathodes];
541
542     TArrayI triggeredDigits[2];
543     for(Int_t itrack=0; itrack<2; itrack++){
544         triggeredDigits[itrack].Set(fgkNchambers);
545         triggeredDigits[itrack].Reset(-1);
546     }
547
548     TArrayI trigScheme[fgkNcathodes];
549     TArrayI slatThatTriggered[fgkNcathodes];
550     for(Int_t cath=0; cath<fgkNcathodes; cath++){
551         trigScheme[cath].Set(fgkNchambers);
552         slatThatTriggered[cath].Set(fgkNchambers);
553     }
554
555     Int_t boardThatTriggered[fgkNchambers][fgkNcathodes][fgkNlocations];
556     TArrayI nboard[fgkNcathodes];
557     for(Int_t cath=0; cath<fgkNcathodes; cath++){
558         nboard[cath].Set(fgkNlocations);
559     }
560     Int_t ineffBoard[fgkNlocations];
561     for(Int_t loc=0; loc<fgkNlocations; loc++){
562         ineffBoard[loc] = -1;
563     }
564
565     AliMUONDigitStoreV1 digitStore;   
566     TriggerDigits(triggerStore,digitStore);
567
568     AliMUONTriggerTrack *recTrigTrack = 0x0;
569
570     TIter next(trigTrackStore.CreateIterator());
571     
572     while ( ( recTrigTrack = static_cast<AliMUONTriggerTrack*>(next()) ) )
573     {
574         if(!IsCleanTrack(recTrigTrack, trackStore)) {
575             if(fDebugLevel>=1) printf("\tTrack %p (%f, %f) don't match tracker track: rejected!\n",(void *)recTrigTrack,recTrigTrack->GetX11(),recTrigTrack->GetY11());
576             continue;
577         }
578
579         digitPerTrack.Reset();
580         for(Int_t ch=0; ch<fgkNchambers; ch++){
581             zRealMatch[ch] = zMeanChamber[ch];
582             for(Int_t cath=0; cath<fgkNcathodes; cath++){
583                 match[ch][cath]=kFALSE;
584                 //slatThatTriggered[ch][cath]=-1;
585                 //trigScheme[ch][cath] = 0;
586                 for(Int_t loc=0; loc<fgkNlocations; loc++){
587                     boardThatTriggered[ch][cath][loc]=-1;
588                 }
589             }
590         }
591
592         for(Int_t cath=0; cath<fgkNcathodes; cath++){
593             slatThatTriggered[cath].Reset(-1);
594             trigScheme[cath].Reset();
595         }
596
597         Bool_t isClearEvent = kTRUE;
598         Bool_t doubleCountTrack = kFALSE;
599
600         Float_t x11 = recTrigTrack->GetX11();// x position (info from non-bending plane)
601         Float_t y11 = recTrigTrack->GetY11();// y position (info from bending plane)
602         Float_t thetaX = recTrigTrack->GetThetax();
603         Float_t thetaY = recTrigTrack->GetThetay();
604
605         if(fDebugLevel>=3) printf("\tTrack = %p\npos from track: (x,y) = (%f, %f), (thetaX, thetaY) = (%f, %f)\n",(void *)recTrigTrack,x11,y11,thetaX*rad2deg,thetaY*rad2deg);
606
607         for(Int_t ch=0; ch<fgkNchambers; ch++) { // chamber loop
608             Int_t currCh = chOrder[ch];
609             if(fDebugLevel>=2)
610                 printf("zMeanChamber[%i] = %.2f\tzRealMatch[0] = %.2f\n",currCh,zMeanChamber[currCh],zRealMatch[0]);
611
612             for(Int_t cath=0; cath<fgkNcathodes; cath++){
613                 correctFactor[cath]=1.;
614             }
615             // calculate corrections to trigger track theta
616             if(ch>=1)correctFactor[kNonBending] = zMeanChamber[0]/zRealMatch[0];// corrects x position
617             if(ch>=2)correctFactor[kBending] = (zMeanChamber[2] - zMeanChamber[0]) / (zRealMatch[2] - zRealMatch[0]);// corrects y position
618
619             // searching track intersection with chambers (first approximation)
620             Float_t deltaZ = zMeanChamber[currCh] - zMeanChamber[0];
621             trackIntersectCh[currCh][0] = zMeanChamber[currCh] * TMath::Tan(thetaX) * correctFactor[kNonBending];// x position (info from non-bending plane) 
622             trackIntersectCh[currCh][1] = y11 + deltaZ * TMath::Tan(thetaY) * correctFactor[kBending];// y position (info from bending plane)
623             Int_t detElemIdFromTrack = DetElemIdFromPos(trackIntersectCh[currCh][0], trackIntersectCh[currCh][1], 11+currCh, 0);
624             if(detElemIdFromTrack<0) {
625                 if(fDebugLevel>1) printf("Warning: trigger track outside trigger chamber\n");
626                 continue;
627             }
628                 
629             triggeredDigits[1][currCh] = MatchingPad(digitStore, detElemIdFromTrack, trackIntersectCh[currCh], matchPad, nboard, zRealMatch, y11);
630
631             // if MatchingPad = -500 => too many digits matching pad =>
632             //                       => Event not clear => Reject track
633             if(triggeredDigits[1][currCh]<-100){
634                 isClearEvent = kFALSE;
635                 if(fDebugLevel>=1) printf("Warning: track = %p (%i) matches many pads. Rejected!\n",(void *)recTrigTrack, detElemIdFromTrack);
636                 break;
637             }
638
639             // deciding if digit matches track
640             Bool_t isDiffLocBoard = kFALSE;
641             if(fReproduceTrigResponse && ch>2){
642                 for(Int_t cath=0; cath<fgkNcathodes; cath++){
643                     if(boardThatTriggered[currCh][cath][0]>=0){
644                         if(boardThatTriggered[currCh][cath][0]!=boardThatTriggered[currCh-1][cath][0]) isDiffLocBoard = kTRUE;
645                     }
646                 }
647             }
648
649             if(isDiffLocBoard && fDebugLevel>=1)printf("\tDifferent local board\n");
650
651             for(Int_t cath=0; cath<fgkNcathodes; cath++){
652                 match[currCh][cath] = (matchPad[cath] && !isDiffLocBoard);
653                 if(!match[currCh][cath]) continue;
654                 digitPerTrack[cath]++;
655                 trigScheme[cath][currCh]++;
656                 slatThatTriggered[cath][currCh] = detElemIdFromTrack;
657                 for(Int_t loc=0; loc<fgkNlocations; loc++){
658                     boardThatTriggered[currCh][cath][loc] = nboard[cath][loc];
659                 }
660             }
661         } // end chamber loop
662
663         for(Int_t cath=0; cath<fgkNcathodes; cath++){
664             if(digitPerTrack[cath]<3)isClearEvent = kFALSE;
665             if(fDebugLevel>=1 && !isClearEvent)printf("Warning: found %i digits for trigger track cathode %i.\nRejecting event\n", digitPerTrack[cath],cath);
666         }
667
668         if(!isClearEvent && !fReproduceTrigResponse) continue;
669
670         Int_t commonDigits = 0;
671         for(Int_t ch=0; ch<fgkNchambers; ch++){
672             if(triggeredDigits[1][ch]==triggeredDigits[0][ch]) commonDigits++; // Compare with previous track
673             triggeredDigits[0][ch] = triggeredDigits[1][ch]; // Store this track parameters for comparison with next one
674         }
675         if(commonDigits>=2){
676             doubleCountTrack=kTRUE;
677         }
678
679         if(!doubleCountTrack || fReproduceTrigResponse){
680             for(Int_t cath=0; cath<fgkNcathodes; cath++){
681                 Int_t is44 = 1;
682                 Bool_t goodForSlatEff = kTRUE;
683                 Bool_t goodForBoardEff = kTRUE;
684                 Int_t ineffSlat = -1;
685                 Int_t ineffDetElId = -1;
686                 Int_t firstSlat = slatThatTriggered[cath][0]%100;
687                 if(firstSlat<0) firstSlat=slatThatTriggered[cath][1]%100;
688                 Int_t firstBoard = boardThatTriggered[0][kBending][0];
689                 if(firstBoard<0) firstBoard=boardThatTriggered[1][kBending][0];
690                 for(Int_t ch=0; ch<fgkNchambers; ch++){
691                     Bool_t isCurrChIneff = kFALSE;
692                     is44 *= trigScheme[cath][ch];
693                     Int_t currSlat = slatThatTriggered[cath][ch]%100;
694                     if(currSlat<0){
695                         ineffDetElId = DetElemIdFromPos(trackIntersectCh[ch][0], trackIntersectCh[ch][1], 11+ch, cath);
696                         currSlat = ineffDetElId%100;
697                         ineffSlat = currSlat;
698                         isCurrChIneff = kTRUE;
699                     }
700                     if(currSlat!=firstSlat)goodForSlatEff=kFALSE;
701                     Bool_t atLeastOneLoc=kFALSE;
702                     if(isCurrChIneff) LocalBoardFromPos(trackIntersectCh[ch][0], trackIntersectCh[ch][1], ineffDetElId, cath, ineffBoard);
703                     for(Int_t loc=0; loc<fgkNlocations; loc++){
704                         Int_t currBoard = boardThatTriggered[ch][cath][loc];
705                         if(isCurrChIneff) currBoard = ineffBoard[loc];
706                         if(currBoard==firstBoard){
707                             atLeastOneLoc=kTRUE;
708                             break;
709                         }
710                     }
711                     if(!atLeastOneLoc)goodForBoardEff=kFALSE;
712                 } // end chamber loop
713
714                 // Trigger 4/4
715                 if(is44==1){
716                     fTrigger44[cath]++;
717                     if(fDebugLevel>=1)printf("Trigger44[%i] = %i\n",cath,fTrigger44[cath]);
718                     if(goodForSlatEff){
719                         for(Int_t ch=0; ch<fgkNchambers; ch++){
720                             Int_t chCath = fgkNchambers*cath + ch;
721                             fHitPerSlat[chCath][firstSlat]++;
722                             if(fDebugLevel>=1)printf("Slat that triggered = %i\n",slatThatTriggered[cath][ch]);
723                             if(goodForBoardEff && firstBoard>0){
724                                 fHitPerBoard[chCath][firstBoard-1]++;
725                                 if(fDebugLevel>=1)printf("Board that triggered = %i\n",firstBoard);
726                             }
727                             else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different boards: rejected!\n",(void *)recTrigTrack);
728                         }
729                     }
730                     else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different slats: rejected!\n",(void *)recTrigTrack);
731                 }
732
733                 // Trigger 3/4
734                 if(ineffDetElId>0){
735                     Int_t ineffCh = ineffDetElId/100-11;
736                     Int_t chCath = fgkNchambers*cath + ineffCh;
737                     fTrigger34[chCath]++;
738                     if(fDebugLevel>=1) printf("Trigger34[%i] = %i\n",chCath,fTrigger34[chCath]);
739                     if(goodForSlatEff){
740                         if(fDebugLevel>=1) printf("Slat non efficient = %i\n",ineffDetElId);
741                         fInefficientSlat[chCath][ineffSlat]++;
742
743                         if(goodForBoardEff && firstBoard>0){
744                             if(fDebugLevel>=1) printf("Board non efficient = %i\n",firstBoard);
745                             fInefficientBoard[chCath][firstBoard-1]++;
746                         }
747                         else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different boards: rejected!\n",(void *)recTrigTrack);
748                     }
749                     else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different slats: rejected!\n",(void *)recTrigTrack);
750                 }
751             } // end loop on cathodes
752         }
753         else if(doubleCountTrack){
754             if(fDebugLevel>=1)
755                 printf("\n\tTrack = %p: \nDouble Count Track: Track rejected!\n",(void *)recTrigTrack);
756         }
757     } // end trigger tracks loop
758
759     if(fPrintInfo) InfoDigit(digitStore);
760 }
761
762 //_____________________________________________________________________________
763 void AliMUONTriggerChamberEff::WriteEfficiencyMap(const char* outputDir)
764 {
765     //
766     /// Writes information on calculated efficiency.
767     /// It writes: triggerChamberEff.root file containing efficiency histograms.
768     //
769
770     char *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
771
772     char outFileName[100];
773
774     sprintf(outFileName, "%s/MUON.TriggerEfficiencyMap.root",outputDir);
775     TFile *outputHistoFile = new TFile(outFileName,"RECREATE");
776     TDirectory *dir = gDirectory;
777
778     char *yAxisTitle = "trigger efficiency (a.u.)";
779     char *xAxisTitle = "chamber";
780
781     const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards();
782
783     TH1F *histoChamber[fgkNcathodes];
784     TH1F *histoSlat[8];
785     TH1F *histoBoard[8];
786
787     // ADDED for check
788     enum {kAllChEff, kChNonEff, kNumOfHistoTypes};
789     char *histoTypeName[kNumOfHistoTypes] = {"CountInCh", "NonCountInCh"};
790     char *histoTypeTitle[kNumOfHistoTypes] = {"counted", "non counted"};
791     TH1F *histoCheckSlat[8][kNumOfHistoTypes];
792     TH1F *histoCheckBoard[8][kNumOfHistoTypes];
793     // end ADDED for check
794
795     char histoName[40];
796     char histoTitle[90];
797
798     for(Int_t cath=0; cath<fgkNcathodes; cath++){
799         sprintf(histoName, "%sChamberEff", cathCode[cath]);
800         sprintf(histoTitle, "Chamber efficiency %s", cathCode[cath]);
801         histoChamber[cath] = new TH1F(histoName, histoTitle, fgkNchambers, 11-0.5, 15-0.5);
802         histoChamber[cath]->SetXTitle(xAxisTitle);
803         histoChamber[cath]->SetYTitle(yAxisTitle);
804         histoChamber[cath]->GetXaxis()->SetNdivisions(fgkNchambers);
805         for(Int_t ch=0; ch<fgkNchambers; ch++){
806             Int_t chCath = fgkNchambers*cath + ch;
807             sprintf(histoName, "%sSlatEffChamber%i", cathCode[cath], 11+ch);
808             sprintf(histoTitle, "Chamber %i: slat efficiency %s", 11+ch, cathCode[cath]);
809             histoSlat[chCath] = new TH1F(histoName, histoTitle, fgkNslats, 0-0.5, fgkNslats-0.5);
810             histoSlat[chCath]->SetXTitle("slat");
811             histoSlat[chCath]->SetYTitle(yAxisTitle);
812             histoSlat[chCath]->GetXaxis()->SetNdivisions(fgkNslats);
813                 
814             sprintf(histoName, "%sBoardEffChamber%i", cathCode[cath], 11+ch);
815             sprintf(histoTitle, "Chamber %i: board efficiency %s", 11+ch, cathCode[cath]);
816             histoBoard[chCath] = new TH1F(histoName, histoTitle, kNumOfBoards, 1-0.5, kNumOfBoards+1.-0.5);
817             histoBoard[chCath]->SetXTitle("boards");
818             histoBoard[chCath]->SetYTitle(yAxisTitle);
819             histoBoard[chCath]->GetXaxis()->SetNdivisions(kNumOfBoards);
820
821             // ADDED for check
822             for(Int_t hType=0; hType<kNumOfHistoTypes; hType++){
823                 sprintf(histoName, "%sSlat%s%i", cathCode[cath], histoTypeName[hType], 11+ch);
824                 sprintf(histoTitle, "Chamber %i: slat %s %s", 11+ch, histoTypeTitle[hType], cathCode[cath]);
825                 histoCheckSlat[chCath][hType] = new TH1F(histoName, histoTitle, fgkNslats, 0-0.5, fgkNslats-0.5);
826                 histoCheckSlat[chCath][hType]->SetXTitle("slat");
827                 histoCheckSlat[chCath][hType]->SetYTitle(yAxisTitle);
828                 histoCheckSlat[chCath][hType]->GetXaxis()->SetNdivisions(fgkNslats);
829
830                 sprintf(histoName, "%sBoard%s%i", cathCode[cath], histoTypeName[hType], 11+ch);
831                 sprintf(histoTitle, "Chamber %i: board %s %s", 11+ch, histoTypeTitle[hType], cathCode[cath]);
832                 histoCheckBoard[chCath][hType] = new TH1F(histoName, histoTitle, kNumOfBoards, 1-0.5, kNumOfBoards+1.-0.5);
833                 histoCheckBoard[chCath][hType]->SetXTitle("boards");
834                 histoCheckBoard[chCath][hType]->SetYTitle(yAxisTitle);
835                 histoCheckBoard[chCath][hType]->GetXaxis()->SetNdivisions(kNumOfBoards);
836             }
837             // end ADDED for check
838         }
839     }
840
841     Float_t efficiency, efficiencyError;
842     Int_t bin;
843
844     for(Int_t cath=0; cath<fgkNcathodes; cath++){
845         for(Int_t ch=0; ch<fgkNchambers; ch++){
846             Int_t chCath = fgkNchambers*cath + ch;
847             for(Int_t slat=0; slat<fgkNslats; slat++){
848                 CalculateEfficiency(fHitPerSlat[chCath][slat], fHitPerSlat[chCath][slat]+fInefficientSlat[chCath][slat], efficiency, efficiencyError, kFALSE);
849                 bin = histoSlat[chCath]->FindBin(slat);
850                 histoSlat[chCath]->SetBinContent(bin, efficiency);
851                 histoSlat[chCath]->SetBinError(bin, efficiencyError);
852
853                 // ADDED for check
854                 histoCheckSlat[chCath][kAllChEff]->SetBinContent(bin, fHitPerSlat[chCath][slat]);
855                 histoCheckSlat[chCath][kChNonEff]->SetBinContent(bin, fInefficientSlat[chCath][slat]);
856             }
857             CalculateEfficiency(fTrigger44[cath], fTrigger34[chCath]+fTrigger44[cath], efficiency, efficiencyError, kFALSE);
858             bin = histoChamber[cath]->FindBin(11+ch);
859             histoChamber[cath]->SetBinContent(bin, efficiency);
860             histoChamber[cath]->SetBinError(bin, efficiencyError);
861
862             for(Int_t board=0; board<kNumOfBoards; board++){
863                 CalculateEfficiency(fHitPerBoard[chCath][board], fHitPerBoard[chCath][board]+fInefficientBoard[chCath][board], efficiency, efficiencyError, kFALSE);
864                 bin = histoBoard[chCath]->FindBin(board+1);
865                 histoBoard[chCath]->SetBinContent(bin, efficiency);
866                 histoBoard[chCath]->SetBinError(bin, efficiencyError);
867
868                 // ADDED for check
869                 histoCheckBoard[chCath][kAllChEff]->SetBinContent(bin, fHitPerBoard[chCath][board]);
870                 histoCheckBoard[chCath][kChNonEff]->SetBinContent(bin, fInefficientBoard[chCath][board]);
871             }
872         }
873     }
874
875 // write all histos
876     outputHistoFile->cd();
877     dir->GetList()->Write();
878     outputHistoFile->Close();
879 }
880
881
882 //_____________________________________________________________________________
883 void AliMUONTriggerChamberEff::WriteEfficiencyMapTxt(const char* outputDir)
884 {
885     //
886     /// Writes the calculated efficiency in the text file efficiencyCells.dat
887     ///
888     /// The file can be further put in $ALICE_ROOT/MUON/data
889     /// and used to run simulations with measured trigger chamber efficiencies.
890     //
891
892     Int_t effOutWidth=4;
893
894     Float_t efficiency, efficiencyError;
895
896     Int_t aCapo[] = {16, 38, 60, 76, 92, 108, 117, 133, 155, 177, 193, 209, 225, 234};
897
898     char filename[70];
899     sprintf(filename, "%s/efficiencyCells.dat", outputDir);
900     ofstream outFile(filename);
901     outFile << "localBoards" << endl;
902     for(Int_t ch=0; ch<fgkNchambers; ch++){
903         //Print information
904         outFile << "\n\ndetElemId:\t" << 11+ch;
905         outFile << "00";
906         for(Int_t cath=0; cath<fgkNcathodes; cath++){
907             outFile << "\n cathode:\t" << cath << endl;
908             Int_t chCath = fgkNchambers*cath + ch;
909             Int_t currLine=0;
910             for(Int_t board=0; board<AliMpConstants::NofLocalBoards(); board++){
911
912                 if(board==aCapo[currLine]){
913                     outFile << endl;
914                     currLine++;
915                 }
916                 CalculateEfficiency(fHitPerBoard[chCath][board], fHitPerBoard[chCath][board]+fInefficientBoard[chCath][board], efficiency, efficiencyError, kFALSE);
917                 outFile << " " << setw(effOutWidth) << efficiency;
918             }// loop on boards
919             outFile << endl;
920         }// loop on cathodes
921     }// loop on chambers    
922 }
923
924
925 //_____________________________________________________________________________
926 Bool_t AliMUONTriggerChamberEff::IsCleanTrack(AliMUONTriggerTrack *triggerTrack,
927                                               const AliMUONVTrackStore& trackStore)
928 {
929     //
930     /// Try to match track from tracking system with trigger track
931     //
932     const Double_t kDistSigma[3]={1,1,0.02}; // sigma of distributions (trigger-track) X,Y,slopeY
933     const Double_t kMaxChi2MatchTrigger = 16.0;
934   
935     AliMUONTrackParam trackParam; 
936
937     Double_t distTriggerTrack[3];
938     Double_t xTrack, yTrack, ySlopeTrack, chi2;
939   
940     AliMUONTrack* track;
941     TIter next(trackStore.CreateIterator());
942     
943     while ( ( track = static_cast<AliMUONTrack*>(next()) ) )
944     {
945         trackParam = *((AliMUONTrackParam*) (track->GetTrackParamAtHit()->Last()));
946         AliMUONTrackExtrap::ExtrapToZ(&trackParam, AliMUONConstants::DefaultChamberZ(10)); // extrap to 1st trigger chamber
947     
948         xTrack = trackParam.GetNonBendingCoor();
949         yTrack = trackParam.GetBendingCoor();
950         ySlopeTrack = trackParam.GetBendingSlope();
951   
952         distTriggerTrack[0] = (triggerTrack->GetX11()-xTrack)/kDistSigma[0];
953         distTriggerTrack[1] = (triggerTrack->GetY11()-yTrack)/kDistSigma[1];
954         distTriggerTrack[2] = (TMath::Tan(triggerTrack->GetThetay())-ySlopeTrack)/kDistSigma[2];
955         chi2 = 0.;
956         for (Int_t iVar = 0; iVar < 3; iVar++) chi2 += distTriggerTrack[iVar]*distTriggerTrack[iVar];
957         chi2 /= 3.; // Normalized Chi2: 3 degrees of freedom (X,Y,slopeY)
958         if (chi2 < kMaxChi2MatchTrigger) return kTRUE;
959     }
960
961     return kFALSE;
962 }
963
964
965 //_____________________________________________________________________________
966 void AliMUONTriggerChamberEff::SaveInESDFile()
967 {
968     //
969     /// Store AliMUONTriggerChamberEff in esd file
970     //
971     TDirectory *dir = gDirectory;
972     TFile *logFile = 0x0;
973     TSeqCollection *list = gROOT->GetListOfFiles();
974     Int_t n = list->GetEntries();
975     for(Int_t i=0; i<n; i++) {
976         logFile = (TFile*)list->At(i);
977         if (strstr(logFile->GetName(), "AliESDs.root")) break;
978     }
979     if(logFile){
980         TTree *esdTree = (TTree*)logFile->Get("esdTree");
981         if(esdTree){
982             if(!esdTree->GetUserInfo()->FindObject("AliMUONTriggerChamberEff")){
983                 AliInfo(Form("Adding AliMUONTrigChamberEff in %s",logFile->GetName()));
984                 esdTree->GetUserInfo()->Add(this->Clone());
985                 esdTree->Write("",TObject::kOverwrite);
986             }
987         }
988     }
989     dir->cd();
990 }
991
992
993 //_____________________________________________________________________________
994 void AliMUONTriggerChamberEff::DisplayEfficiency(Bool_t perSlat)
995 {
996     //
997     /// Display calculated efficiency.
998     //
999
1000     const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards();
1001
1002     Int_t side, col, line, nbx, slat;
1003     Float_t xCenter, yCenter, zCenter, xWidth, yWidth;
1004     Int_t x1, y1, x2, y2, board=0;
1005     char name[8], text[200];
1006
1007     gStyle->SetPalette(1);
1008
1009     TString boardName[234];
1010
1011     // instanciate the elec. mapping class
1012     AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1013
1014     // loop over the trigger DDL (Right: 20, Left: 21)
1015     for (Int_t iDDL = 20; iDDL <= 21; ++iDDL) {
1016
1017       // get ddl object
1018       AliMpDDL* ddl = ddlStore->GetDDL(iDDL);
1019
1020       Int_t nCrate = ddl->GetNofTriggerCrates();
1021     
1022       // loop over the number of crate in DDL
1023       for (Int_t index = 0; index < nCrate; ++index) {
1024
1025         // get crate object
1026         AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(iDDL, index);
1027
1028         Int_t nLocal = crate->GetNofLocalBoards();
1029
1030         for (Int_t iLocal = 0; iLocal  < nLocal; ++iLocal) {
1031
1032           // get local board Id from crate object
1033           board = crate->GetLocalBoardId(iLocal);
1034           if(board>kNumOfBoards || board<=0) continue;
1035
1036           AliMpLocalBoard* localBoard = ddlStore->GetLocalBoard(board);
1037           boardName[board-1] = localBoard->GetName();
1038         }
1039       }
1040     }
1041
1042     char *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
1043
1044     Float_t boardsX = 257.00;  // cm
1045     Float_t boardsY = 307.00;  // cm
1046
1047     TH2F *histo[8];
1048     TPaveLabel *boardLabel[8][234];
1049
1050     char histoName[40];
1051     char histoTitle[90];
1052
1053     Float_t efficiency, efficiencyError;
1054
1055     for(Int_t cath=0; cath<fgkNcathodes; cath++){
1056         for(Int_t ch=0; ch<fgkNchambers; ch++){
1057             Int_t chCath = fgkNchambers*cath + ch;
1058             sprintf(histoName, "%sChamber%i", cathCode[cath], 11+ch);
1059             sprintf(histoTitle, "Chamber %i: efficiency %s", 11+ch, cathCode[cath]);
1060             histo[chCath] = new TH2F(histoName, histoTitle, (Int_t)boardsX, -boardsX, boardsX, (Int_t)boardsY, -boardsY, boardsY);
1061             histo[chCath]->SetXTitle("X (cm)");
1062             histo[chCath]->SetYTitle("Y (cm)");
1063         }
1064     }
1065
1066     TString mapspath = gSystem->Getenv("ALICE_ROOT");
1067     mapspath.Append("/MUON/data");
1068
1069     sprintf(text,"%s/guimapp11.txt",mapspath.Data());
1070     FILE *fmap = fopen(text,"r");
1071
1072     for (Int_t ib = 0; ib < kNumOfBoards; ib++) {
1073         fscanf(fmap,"%d   %d   %d   %d   %f   %f   %f   %f   %f   %s   \n",&side,&col,&line,&nbx,&xCenter,&yCenter,&xWidth,&yWidth,&zCenter,&name[0]);
1074
1075         slat = (line-5)%fgkNslats;
1076         for(Int_t iBoard=0; iBoard<kNumOfBoards; iBoard++){
1077             if(!boardName[iBoard].Contains(name)) continue;
1078             board = iBoard;
1079             break;
1080         }
1081
1082         for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
1083             x1 = histo[chCath]->GetXaxis()->FindBin(xCenter-xWidth/2.)+1;
1084             y1 = histo[chCath]->GetYaxis()->FindBin(yCenter-yWidth/2.)+1;
1085             x2 = histo[chCath]->GetXaxis()->FindBin(xCenter+xWidth/2.)-1;
1086             y2 = histo[chCath]->GetYaxis()->FindBin(yCenter+yWidth/2.)-1;
1087             
1088             boardLabel[chCath][board] = new TPaveLabel(xCenter-xWidth/2., yCenter-yWidth/2., xCenter+xWidth/2., yCenter+yWidth/2., Form("%3d",board+1));
1089             boardLabel[chCath][board]->SetFillStyle(0);
1090             boardLabel[chCath][board]->SetBorderSize(0);
1091
1092             if(!perSlat){
1093                 CalculateEfficiency(fHitPerBoard[chCath][board], fHitPerBoard[chCath][board]+fInefficientBoard[chCath][board], efficiency, efficiencyError, kFALSE);
1094             }
1095             else{
1096                 CalculateEfficiency(fHitPerSlat[chCath][slat], fHitPerSlat[chCath][slat]+fInefficientSlat[chCath][slat], efficiency, efficiencyError, kFALSE);
1097             }
1098             
1099             for(Int_t binX=x1; binX<=x2; binX++){
1100                 for(Int_t binY=y1; binY<=y2; binY++){
1101                     histo[chCath]->SetBinContent(binX, binY, efficiency);
1102                     histo[chCath]->SetBinError(binX, binY, efficiencyError);
1103                 }
1104             }
1105         }
1106     }
1107
1108     TCanvas *can[8];
1109     for(Int_t chCath=0; chCath<fgkNplanes; chCath++){
1110         sprintf(histoName, "%sCan", histo[chCath]->GetName());
1111         sprintf(histoTitle, "%s", histo[chCath]->GetTitle());
1112         can[chCath] = new TCanvas(histoName, histoTitle, 100+10*chCath, 10*chCath, 700, 700);
1113         can[chCath]->SetRightMargin(0.14);
1114         can[chCath]->SetLeftMargin(0.12);
1115         histo[chCath]->GetZaxis()->SetRangeUser(0.,1.);
1116         histo[chCath]->GetYaxis()->SetTitleOffset(1.4);
1117         histo[chCath]->SetStats(kFALSE);
1118         histo[chCath]->Draw("COLZ");
1119         for (Int_t board = 0; board < kNumOfBoards; board++) {
1120             boardLabel[chCath][board]->Draw("same");
1121         }
1122     }
1123 }
1124
1125 //_____________________________________________________________________________
1126 void AliMUONTriggerChamberEff::CheckConstants() const
1127 {
1128 /// Check consistence of redefined constants 
1129
1130   assert(fgkNcathodes == AliMpConstants::NofCathodes());    
1131   assert(fgkNchambers == AliMpConstants::NofTriggerChambers());    
1132   assert(fgkNplanes == AliMpConstants::NofTriggerChambers() * fgkNcathodes);    
1133 }