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