]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONTriggerChamberEff.cxx
- Adding comment lines to class description needed for Root documentation
[u/mrichter/AliRoot.git] / MUON / AliMUONTriggerChamberEff.cxx
CommitLineData
f165a2d2 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
9edefa04 16/* $Id$ */
17
f165a2d2 18/// \class AliMUONTriggerChamberEff
19/// implementation of the trigger chamber efficiency determination from
20/// data, and returns the
21/// efficiencyCells.dat with the calculated efficiencies
78649106 22///
23/// \author Diego Stocco (Torino)
f165a2d2 24
25#include "AliMUONTriggerChamberEff.h"
86344f32 26#include "AliMUONVDigit.h"
f165a2d2 27#include "AliMUONConstants.h"
f165a2d2 28#include "AliMUONTriggerTrack.h"
8c0b5e70 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"
2227e936 42
f165a2d2 43#include "AliMpVSegmentation.h"
44#include "AliMpSegmentation.h"
45#include "AliMpPad.h"
46#include "AliMpDEIterator.h"
2227e936 47#include "AliMpPlaneType.h"
8c0b5e70 48#include "AliMpDEManager.h"
8b1cdc26 49#include "AliMpConstants.h"
50
51#include "AliMpDDLStore.h"
52#include "AliMpDDL.h"
53#include "AliMpTriggerCrate.h"
54#include "AliMpLocalBoard.h"
2227e936 55
8c0b5e70 56#include "AliLog.h"
f165a2d2 57
2227e936 58#include <Riostream.h>
59#include <TFile.h>
60#include <TH1F.h>
61#include <TMath.h>
62
8c0b5e70 63#include <TSeqCollection.h>
64#include <TTree.h>
65#include <TROOT.h>
66
8b1cdc26 67#include <TStyle.h>
68#include <TCanvas.h>
69#include <TH2.h>
70#include <TSystem.h>
71#include <TPaveLabel.h>
72
73#include <cassert>
8c0b5e70 74
2227e936 75/// \cond CLASSIMP
f165a2d2 76ClassImp(AliMUONTriggerChamberEff)
2227e936 77/// \endcond
f165a2d2 78
79//_____________________________________________________________________________
8c0b5e70 80AliMUONTriggerChamberEff::AliMUONTriggerChamberEff()
f165a2d2 81: TObject(),
8c0b5e70 82 fTransformer(0x0),
83 fDigitMaker(0x0),
f165a2d2 84 fReproduceTrigResponse(kFALSE),
85 fPrintInfo(kFALSE),
8c0b5e70 86 fWriteOnESD(kFALSE),
f165a2d2 87 fDebugLevel(0),
8c0b5e70 88 fkMaxDistance(99999.)
f165a2d2 89{
8b1cdc26 90/// Default constructor
91
92 CheckConstants();
f165a2d2 93 ResetArrays();
94}
95
8c0b5e70 96
f165a2d2 97//_____________________________________________________________________________
8c0b5e70 98AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(const AliMUONGeometryTransformer* transformer,
99 const AliMUONDigitMaker* digitMaker,
100 Bool_t writeOnESD)
f165a2d2 101: TObject(),
8c0b5e70 102 fTransformer(transformer),
103 fDigitMaker(digitMaker),
f165a2d2 104 fReproduceTrigResponse(kFALSE),
105 fPrintInfo(kFALSE),
8c0b5e70 106 fWriteOnESD(writeOnESD),
f165a2d2 107 fDebugLevel(0),
8c0b5e70 108 fkMaxDistance(99999.)
f165a2d2 109{
71a2d3aa 110/// Standard constructor
8b1cdc26 111
112 CheckConstants();
f165a2d2 113 ResetArrays();
f165a2d2 114}
115
8c0b5e70 116
f165a2d2 117//_____________________________________________________________________________
118AliMUONTriggerChamberEff::~AliMUONTriggerChamberEff()
119{
120/// Destructor
8c0b5e70 121 Bool_t writeOnESD=fWriteOnESD;
122 fWriteOnESD=kFALSE;
123 if(writeOnESD) SaveInESDFile();
f165a2d2 124}
125
8c0b5e70 126
f165a2d2 127//_____________________________________________________________________________
8c0b5e70 128AliMUONTriggerChamberEff::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),
8b1cdc26 136 fkMaxDistance(other.fkMaxDistance),
137 fTrigger44(other.fTrigger44),
138 fTrigger34(other.fTrigger34)
f165a2d2 139{
8b1cdc26 140/// Copy constructor
9f6be20d 141
8b1cdc26 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];
f165a2d2 147 }
148}
149
8c0b5e70 150
f165a2d2 151//_____________________________________________________________________________
8c0b5e70 152AliMUONTriggerChamberEff& AliMUONTriggerChamberEff::operator=(const AliMUONTriggerChamberEff& other)
f165a2d2 153{
8c0b5e70 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;
8b1cdc26 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 }
8c0b5e70 178 return *this;
f165a2d2 179}
180
8c0b5e70 181
f165a2d2 182//_____________________________________________________________________________
183void AliMUONTriggerChamberEff::ResetArrays()
184{
2227e936 185 //
186 /// Sets the data member counters to 0.
187 //
188
8b1cdc26 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();
f165a2d2 207 }
208}
209
210
8c0b5e70 211//______________________________________________________________________________
212Bool_t
213AliMUONTriggerChamberEff::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
8b1cdc26 228 TArrayS xyPattern[fgkNcathodes];
8c0b5e70 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
f165a2d2 239//_____________________________________________________________________________
8c0b5e70 240void AliMUONTriggerChamberEff::InfoDigit(AliMUONVDigitStore& digitStore)
f165a2d2 241{
2227e936 242 //
243 /// Prints information on digits (for debugging)
244 //
8c0b5e70 245 TIter next(digitStore.CreateIterator());
246 AliMUONVDigit* mDigit=0x0;
f165a2d2 247
8c0b5e70 248 while ( ( mDigit = static_cast<AliMUONVDigit*>(next()) ) )
249 {
250 mDigit->Print();
251 } // end digit loop
252 printf("\n");
f165a2d2 253}
254
255
256//_____________________________________________________________________________
8c0b5e70 257Int_t AliMUONTriggerChamberEff::MatchingPad(AliMUONVDigitStore& digitStore, Int_t &detElemId,
8b1cdc26 258 Float_t coor[2], Bool_t isMatch[2],
259 TArrayI nboard[2], TArrayF &zRealMatch, Float_t y11)
f165a2d2 260{
2227e936 261 //
a690d2f8 262 /// Check slat and board number of digit matching track
2227e936 263 //
264
a690d2f8 265 enum {kBending, kNonBending};
266
267 Float_t minMatchDist[fgkNcathodes];
8c0b5e70 268 Int_t padsInCheckArea[fgkNcathodes];
f165a2d2 269
a690d2f8 270 for(Int_t cath=0; cath<fgkNcathodes; cath++){
8c0b5e70 271 isMatch[cath] = kFALSE;
272 minMatchDist[cath] = fkMaxDistance/10.;
273 padsInCheckArea[cath] = 0;
a690d2f8 274 }
8c0b5e70 275 Int_t iChamber = AliMpDEManager::GetChamberId(detElemId);
a690d2f8 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;
a690d2f8 281 Int_t foundDetElemId = detElemId;
282 Float_t foundZmatch=999.;
283 Float_t yCoorAtPadZ=999.;
8c0b5e70 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++;
a690d2f8 292 Int_t currDetElemId = mDigit->DetElemId();
8c0b5e70 293 Int_t currCh = AliMpDEManager::GetChamberId(currDetElemId);
294 if(currCh!=iChamber) continue;
a690d2f8 295 Int_t currSlat = currDetElemId%100;
8c0b5e70 296 Int_t slatDiff = TMath::Abs(currSlat-iSlat);
297 if(slatDiff>1 && slatDiff<17) continue; // Check neighbour slats
a690d2f8 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();
8c0b5e70 310 fTransformer->Local2Global(currDetElemId, xlocal1, ylocal1, 0, xpad, ypad, zpad);
a690d2f8 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){
8c0b5e70 314 //if(iChamber%2==1){
a690d2f8 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);
8c0b5e70 320 if(matchDist<fkMaxDistance/2.) padsInCheckArea[cathode]++;
a690d2f8 321 if(matchDist>minMatchDist[cathode])continue;
322 isMatch[cathode] = kTRUE;
323 minMatchDist[cathode] = matchDist;
324 foundDetElemId = currDetElemId;
325 foundZmatch=zpad;
326 yCoorAtPadZ=y;
8c0b5e70 327 if(cathode==kBending) trigDigitBendPlane = idigit;
a690d2f8 328 for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){
329 AliMpIntPair location = pad.GetLocation(loc);
330 nboard[cathode][loc] = location.GetFirst();
331 }
8b1cdc26 332 for(Int_t loc=pad.GetNofLocations(); loc<fgkNlocations; loc++){
a690d2f8 333 nboard[cathode][loc]=-1;
334 }
335 }
8c0b5e70 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
a690d2f8 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}
f165a2d2 355
356//_____________________________________________________________________________
8c0b5e70 357Float_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)
f165a2d2 361{
2227e936 362 //
a690d2f8 363 /// Decides if the digit belongs to the trigger track.
2227e936 364 //
365
8c0b5e70 366 Float_t maxDist = 2.;//3. // cm
367 Float_t maxDistCheckArea = 6.; // cm
a690d2f8 368
8c0b5e70 369 Float_t matchDist = fkMaxDistance;
a690d2f8 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
8c0b5e70 385 if(deltaX<=maxDistX && deltaY<=maxDistY) matchDist = TMath::Max(deltaX, deltaY);
386 else if(deltaX<=maxDistCheckArea && deltaY<=maxDistCheckArea) matchDist = fkMaxDistance/5.;
a690d2f8 387 return matchDist;
f165a2d2 388}
389
390
391//_____________________________________________________________________________
392void AliMUONTriggerChamberEff::CalculateEfficiency(Int_t trigger44, Int_t trigger34,
8c0b5e70 393 Float_t &efficiency, Float_t &error,
394 Bool_t failuresAsInput)
f165a2d2 395{
2227e936 396 //
397 /// Returns the efficiency.
398 //
399
f165a2d2 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//_____________________________________________________________________________
8c0b5e70 413Int_t AliMUONTriggerChamberEff::DetElemIdFromPos(Float_t x, Float_t y,
414 Int_t chamber, Int_t cathode)
f165a2d2 415{
2227e936 416 //
417 /// Given the (x,y) position in the chamber,
418 /// it returns the corresponding slat
419 //
420
f165a2d2 421 Int_t resultingDetElemId = -1;
422 AliMpDEIterator it;
a690d2f8 423 Float_t minDist = 999.;
f165a2d2 424 for ( it.First(chamber-1); ! it.IsDone(); it.Next() ){
866c3232 425 Int_t detElemId = it.CurrentDEId();
a690d2f8 426 Int_t ich = detElemId/100-10;
427 Float_t tolerance=0.2*((Float_t)ich);
428 Float_t currDist=9999.;
f165a2d2 429
8c0b5e70 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 }
f165a2d2 455
8c0b5e70 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;
f165a2d2 463 }
8c0b5e70 464 resultingDetElemId = detElemId;
465 break;
f165a2d2 466 }
8c0b5e70 467 } // loop on detElemId
f165a2d2 468 return resultingDetElemId;
469}
470
471
472//_____________________________________________________________________________
8c0b5e70 473void AliMUONTriggerChamberEff::LocalBoardFromPos(Float_t x, Float_t y,
474 Int_t detElemId, Int_t cathode,
475 Int_t localBoard[4])
f165a2d2 476{
2227e936 477 //
478 /// Given the (x,y) position in the chamber,
479 /// it returns the corresponding local board
480 //
481
8b1cdc26 482 for(Int_t loc=0; loc<fgkNlocations; loc++){
f165a2d2 483 localBoard[loc]=-1;
484 }
f165a2d2 485 Float_t xl, yl, zl;
8c0b5e70 486 fTransformer->Global2Local(detElemId, x, y, 0, xl, yl, zl);
f165a2d2 487 TVector2 pos(xl,yl);
488 const AliMpVSegmentation* seg =
866c3232 489 AliMpSegmentation::Instance()
490 ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
f165a2d2 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//_____________________________________________________________________________
8c0b5e70 502void AliMUONTriggerChamberEff::EventChamberEff(const AliMUONVTriggerStore& triggerStore,
503 const AliMUONVTriggerTrackStore& trigTrackStore,
504 const AliMUONVTrackStore& trackStore)
f165a2d2 505{
2227e936 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
8c0b5e70 514 if(!fTransformer || ! fDigitMaker) {
515 AliError(Form("AliMUONGeometryTransformer or AliMUONDigitMaker not properly initialized!!"));
516 return;
517 }
518
2227e936 519 enum {kBending, kNonBending};
f165a2d2 520 Float_t rad2deg = 180./TMath::Pi();
521
a690d2f8 522 Int_t chOrder[fgkNchambers] = {0,2,1,3};
f165a2d2 523
8b1cdc26 524 TArrayF zRealMatch(fgkNchambers);
525 TArrayF correctFactor(fgkNcathodes);
f165a2d2 526
8b1cdc26 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 }
f165a2d2 532
8b1cdc26 533 TArrayF zMeanChamber(fgkNchambers);
f165a2d2 534 for(Int_t ch=0; ch<fgkNchambers; ch++){
535 zMeanChamber[ch] = AliMUONConstants::DefaultChamberZ(10+ch);
536 }
537
8b1cdc26 538 TArrayI digitPerTrack(fgkNcathodes);
f165a2d2 539
8b1cdc26 540 Float_t trackIntersectCh[fgkNchambers][fgkNcathodes];
f165a2d2 541
8b1cdc26 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 }
f165a2d2 554
8b1cdc26 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 }
f165a2d2 564
8c0b5e70 565 AliMUONDigitStoreV1 digitStore;
566 TriggerDigits(triggerStore,digitStore);
f165a2d2 567
8c0b5e70 568 AliMUONTriggerTrack *recTrigTrack = 0x0;
a690d2f8 569
8c0b5e70 570 TIter next(trigTrackStore.CreateIterator());
571
572 while ( ( recTrigTrack = static_cast<AliMUONTriggerTrack*>(next()) ) )
573 {
8b1cdc26 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;
8c0b5e70 577 }
8b1cdc26 578
579 digitPerTrack.Reset();
f165a2d2 580 for(Int_t ch=0; ch<fgkNchambers; ch++){
8b1cdc26 581 zRealMatch[ch] = zMeanChamber[ch];
f165a2d2 582 for(Int_t cath=0; cath<fgkNcathodes; cath++){
8c0b5e70 583 match[ch][cath]=kFALSE;
8b1cdc26 584 //slatThatTriggered[ch][cath]=-1;
585 //trigScheme[ch][cath] = 0;
586 for(Int_t loc=0; loc<fgkNlocations; loc++){
8c0b5e70 587 boardThatTriggered[ch][cath][loc]=-1;
588 }
f165a2d2 589 }
590 }
591
8b1cdc26 592 for(Int_t cath=0; cath<fgkNcathodes; cath++){
593 slatThatTriggered[cath].Reset(-1);
594 trigScheme[cath].Reset();
595 }
596
8c0b5e70 597 Bool_t isClearEvent = kTRUE;
598 Bool_t doubleCountTrack = kFALSE;
a690d2f8 599
8c0b5e70 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();
f165a2d2 604
8b1cdc26 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);
f165a2d2 606
8c0b5e70 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]);
f165a2d2 611
8c0b5e70 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;
f165a2d2 627 }
a690d2f8 628
8c0b5e70 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;
8b1cdc26 635 if(fDebugLevel>=1) printf("Warning: track = %p (%i) matches many pads. Rejected!\n",(void *)recTrigTrack, detElemIdFromTrack);
8c0b5e70 636 break;
637 }
f165a2d2 638
8c0b5e70 639 // deciding if digit matches track
640 Bool_t isDiffLocBoard = kFALSE;
641 if(fReproduceTrigResponse && ch>2){
a690d2f8 642 for(Int_t cath=0; cath<fgkNcathodes; cath++){
8c0b5e70 643 if(boardThatTriggered[currCh][cath][0]>=0){
644 if(boardThatTriggered[currCh][cath][0]!=boardThatTriggered[currCh-1][cath][0]) isDiffLocBoard = kTRUE;
a690d2f8 645 }
646 }
8c0b5e70 647 }
648
649 if(isDiffLocBoard && fDebugLevel>=1)printf("\tDifferent local board\n");
f165a2d2 650
651 for(Int_t cath=0; cath<fgkNcathodes; cath++){
8c0b5e70 652 match[currCh][cath] = (matchPad[cath] && !isDiffLocBoard);
653 if(!match[currCh][cath]) continue;
654 digitPerTrack[cath]++;
8b1cdc26 655 trigScheme[cath][currCh]++;
656 slatThatTriggered[cath][currCh] = detElemIdFromTrack;
657 for(Int_t loc=0; loc<fgkNlocations; loc++){
8c0b5e70 658 boardThatTriggered[currCh][cath][loc] = nboard[cath][loc];
659 }
f165a2d2 660 }
8c0b5e70 661 } // end chamber loop
f165a2d2 662
8c0b5e70 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 }
f165a2d2 667
8c0b5e70 668 if(!isClearEvent && !fReproduceTrigResponse) continue;
f165a2d2 669
8c0b5e70 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 }
a690d2f8 678
8c0b5e70 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;
8b1cdc26 686 Int_t firstSlat = slatThatTriggered[cath][0]%100;
687 if(firstSlat<0) firstSlat=slatThatTriggered[cath][1]%100;
8c0b5e70 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;
8b1cdc26 692 is44 *= trigScheme[cath][ch];
693 Int_t currSlat = slatThatTriggered[cath][ch]%100;
8c0b5e70 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);
8b1cdc26 703 for(Int_t loc=0; loc<fgkNlocations; loc++){
8c0b5e70 704 Int_t currBoard = boardThatTriggered[ch][cath][loc];
705 if(isCurrChIneff) currBoard = ineffBoard[loc];
706 if(currBoard==firstBoard){
707 atLeastOneLoc=kTRUE;
708 break;
f165a2d2 709 }
f165a2d2 710 }
8c0b5e70 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++){
8b1cdc26 720 Int_t chCath = fgkNchambers*cath + ch;
721 fHitPerSlat[chCath][firstSlat]++;
722 if(fDebugLevel>=1)printf("Slat that triggered = %i\n",slatThatTriggered[cath][ch]);
a690d2f8 723 if(goodForBoardEff && firstBoard>0){
8b1cdc26 724 fHitPerBoard[chCath][firstBoard-1]++;
8c0b5e70 725 if(fDebugLevel>=1)printf("Board that triggered = %i\n",firstBoard);
f165a2d2 726 }
8b1cdc26 727 else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different boards: rejected!\n",(void *)recTrigTrack);
f165a2d2 728 }
729 }
8b1cdc26 730 else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different slats: rejected!\n",(void *)recTrigTrack);
8c0b5e70 731 }
a690d2f8 732
8c0b5e70 733 // Trigger 3/4
734 if(ineffDetElId>0){
735 Int_t ineffCh = ineffDetElId/100-11;
8b1cdc26 736 Int_t chCath = fgkNchambers*cath + ineffCh;
737 fTrigger34[chCath]++;
738 if(fDebugLevel>=1) printf("Trigger34[%i] = %i\n",chCath,fTrigger34[chCath]);
8c0b5e70 739 if(goodForSlatEff){
740 if(fDebugLevel>=1) printf("Slat non efficient = %i\n",ineffDetElId);
8b1cdc26 741 fInefficientSlat[chCath][ineffSlat]++;
8c0b5e70 742
743 if(goodForBoardEff && firstBoard>0){
744 if(fDebugLevel>=1) printf("Board non efficient = %i\n",firstBoard);
8b1cdc26 745 fInefficientBoard[chCath][firstBoard-1]++;
8c0b5e70 746 }
8b1cdc26 747 else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different boards: rejected!\n",(void *)recTrigTrack);
8c0b5e70 748 }
8b1cdc26 749 else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different slats: rejected!\n",(void *)recTrigTrack);
8c0b5e70 750 }
751 } // end loop on cathodes
f165a2d2 752 }
8c0b5e70 753 else if(doubleCountTrack){
754 if(fDebugLevel>=1)
8b1cdc26 755 printf("\n\tTrack = %p: \nDouble Count Track: Track rejected!\n",(void *)recTrigTrack);
f165a2d2 756 }
8c0b5e70 757 } // end trigger tracks loop
f165a2d2 758
8c0b5e70 759 if(fPrintInfo) InfoDigit(digitStore);
f165a2d2 760}
761
762//_____________________________________________________________________________
8c0b5e70 763void AliMUONTriggerChamberEff::WriteEfficiencyMap(const char* outputDir)
f165a2d2 764{
2227e936 765 //
766 /// Writes information on calculated efficiency.
767 /// It writes: triggerChamberEff.root file containing efficiency histograms.
2227e936 768 //
769
f165a2d2 770 char *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
771
772 char outFileName[100];
f165a2d2 773
8c0b5e70 774 sprintf(outFileName, "%s/MUON.TriggerEfficiencyMap.root",outputDir);
f165a2d2 775 TFile *outputHistoFile = new TFile(outFileName,"RECREATE");
776 TDirectory *dir = gDirectory;
777
f165a2d2 778 char *yAxisTitle = "trigger efficiency (a.u.)";
779 char *xAxisTitle = "chamber";
780
8b1cdc26 781 const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards();
782
783 TH1F *histoChamber[fgkNcathodes];
784 TH1F *histoSlat[8];
785 TH1F *histoBoard[8];
f165a2d2 786
8c0b5e70 787 // ADDED for check
8b1cdc26 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];
8c0b5e70 793 // end ADDED for check
794
795 char histoName[40];
f165a2d2 796 char histoTitle[90];
797
798 for(Int_t cath=0; cath<fgkNcathodes; cath++){
8b1cdc26 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);
f165a2d2 813
8b1cdc26 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);
f165a2d2 836 }
8b1cdc26 837 // end ADDED for check
f165a2d2 838 }
839 }
840
841 Float_t efficiency, efficiencyError;
8c0b5e70 842 Int_t bin;
f165a2d2 843
844 for(Int_t cath=0; cath<fgkNcathodes; cath++){
845 for(Int_t ch=0; ch<fgkNchambers; ch++){
8b1cdc26 846 Int_t chCath = fgkNchambers*cath + ch;
f165a2d2 847 for(Int_t slat=0; slat<fgkNslats; slat++){
8b1cdc26 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);
8c0b5e70 852
853 // ADDED for check
8b1cdc26 854 histoCheckSlat[chCath][kAllChEff]->SetBinContent(bin, fHitPerSlat[chCath][slat]);
855 histoCheckSlat[chCath][kChNonEff]->SetBinContent(bin, fInefficientSlat[chCath][slat]);
f165a2d2 856 }
8b1cdc26 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);
f165a2d2 861
8b1cdc26 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);
8c0b5e70 867
868 // ADDED for check
8b1cdc26 869 histoCheckBoard[chCath][kAllChEff]->SetBinContent(bin, fHitPerBoard[chCath][board]);
870 histoCheckBoard[chCath][kChNonEff]->SetBinContent(bin, fInefficientBoard[chCath][board]);
f165a2d2 871 }
872 }
873 }
874
875// write all histos
876 outputHistoFile->cd();
877 dir->GetList()->Write();
878 outputHistoFile->Close();
879}
880
881
882//_____________________________________________________________________________
8c0b5e70 883void AliMUONTriggerChamberEff::WriteEfficiencyMapTxt(const char* outputDir)
f165a2d2 884{
2227e936 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
f165a2d2 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;
8b1cdc26 908 Int_t chCath = fgkNchambers*cath + ch;
f165a2d2 909 Int_t currLine=0;
8b1cdc26 910 for(Int_t board=0; board<AliMpConstants::NofLocalBoards(); board++){
f165a2d2 911
912 if(board==aCapo[currLine]){
913 outFile << endl;
914 currLine++;
915 }
8b1cdc26 916 CalculateEfficiency(fHitPerBoard[chCath][board], fHitPerBoard[chCath][board]+fInefficientBoard[chCath][board], efficiency, efficiencyError, kFALSE);
f165a2d2 917 outFile << " " << setw(effOutWidth) << efficiency;
918 }// loop on boards
919 outFile << endl;
920 }// loop on cathodes
921 }// loop on chambers
922}
923
8c0b5e70 924
925//_____________________________________________________________________________
926Bool_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//_____________________________________________________________________________
966void 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}
8b1cdc26 991
992
993//_____________________________________________________________________________
994void 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//_____________________________________________________________________________
1126void 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}