]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONTriggerChamberEff.cxx
Adding CreateIterator(void) and GetNeighbours() pure virtual methods,
[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
22/// Author: Diego Stocco (Torino)
23
24#include "AliMUONTriggerChamberEff.h"
25#include "AliMUONDigit.h"
26#include "AliMUONConstants.h"
27#include "AliMUONGlobalTrigger.h"
28#include "AliMUONGeometryTransformer.h"
29#include "AliMUONSegmentation.h"
30#include "AliMUON.h"
31#include "AliMUONData.h"
32#include "AliMUONTriggerTrack.h"
2227e936 33
f165a2d2 34#include "AliMpVSegmentation.h"
35#include "AliMpSegmentation.h"
36#include "AliMpPad.h"
37#include "AliMpDEIterator.h"
2227e936 38#include "AliMpPlaneType.h"
39
f165a2d2 40#include "AliRunLoader.h"
41#include "AliRun.h"
42
2227e936 43#include <Riostream.h>
44#include <TFile.h>
45#include <TH1F.h>
46#include <TMath.h>
47
48/// \cond CLASSIMP
f165a2d2 49ClassImp(AliMUONTriggerChamberEff)
2227e936 50/// \endcond
f165a2d2 51
52//_____________________________________________________________________________
53AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(const char* galiceFile,
54 Int_t firstEvent, Int_t lastEvent)
55: TObject(),
56 fFirstEvent(firstEvent),
57 fLastEvent(lastEvent),
58 fFirstRun(-1),
59 fLastRun(-1),
60 fRunLoader(0x0),
61 fData(0x0),
62 fReproduceTrigResponse(kFALSE),
63 fPrintInfo(kFALSE),
64 fMUON(0x0),
65 fDebugLevel(0),
66 fGaliceDir(0x0)
67{
68/// Standard constructor
69 SetGaliceFile(galiceFile);
70 ResetArrays();
71}
72
73//_____________________________________________________________________________
74AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(Int_t firstRun, Int_t lastRun,
75 const char* galiceRunDir,
76 Int_t firstEvent, Int_t lastEvent)
77: TObject(),
78 fFirstEvent(firstEvent),
79 fLastEvent(lastEvent),
80 fFirstRun(firstRun),
81 fLastRun(lastRun),
82 fRunLoader(0x0),
83 fData(0x0),
84 fReproduceTrigResponse(kFALSE),
85 fPrintInfo(kFALSE),
86 fMUON(0x0),
87 fDebugLevel(0),
88 fGaliceDir(galiceRunDir)
89{
90 ResetArrays();
91 delete gAlice;
92}
93
94//_____________________________________________________________________________
95AliMUONTriggerChamberEff::~AliMUONTriggerChamberEff()
96{
97/// Destructor
98 fRunLoader->UnloadAll();
99 delete fRunLoader;
100 delete fData;
101}
102
103//_____________________________________________________________________________
104void AliMUONTriggerChamberEff::SetGaliceFile(const char *galiceFile)
105{
2227e936 106 //
107 /// Opens the galice.root and loads tracks and digits.
108 //
109
f165a2d2 110 fRunLoader = AliRunLoader::Open(galiceFile,"MUONFolder","READ");
111 if (!fRunLoader)
112 {
113 AliError(Form("Error opening %s file \n",galiceFile));
114 }
115 else
116 {
117 fRunLoader->LoadgAlice();
118 gAlice = fRunLoader->GetAliRun();
119 fMUON = (AliMUON*)gAlice->GetModule("MUON");
120
121 if(fLastEvent<=0 || fLastEvent>fRunLoader->GetNumberOfEvents())fLastEvent = fRunLoader->GetNumberOfEvents()-1;
122 if(fFirstEvent<0)fFirstEvent=0;
123
124
125 AliLoader* loader = fRunLoader->GetLoader("MUONLoader");
126 if ( loader )
127 {
128 fData = new AliMUONData(loader,"MUON","MUON");
129 loader->LoadTracks("READ");
130 loader->LoadDigits("READ");
131 }
132 else
133 {
134 AliError(Form("Could get MUONLoader"));
135 }
136 }
137}
138
139//_____________________________________________________________________________
140void AliMUONTriggerChamberEff::CleanGalice()
141{
2227e936 142 //
143 /// Unload all loaded data
144 //
145
f165a2d2 146 fRunLoader->UnloadAll();
147 delete fRunLoader;
2227e936 148 fRunLoader = 0;
f165a2d2 149}
150
151//_____________________________________________________________________________
152void AliMUONTriggerChamberEff::ResetArrays()
153{
2227e936 154 //
155 /// Sets the data member counters to 0.
156 //
157
f165a2d2 158 for(Int_t ch=0; ch<fgkNchambers; ch++){
159 for(Int_t cath=0; cath<fgkNcathodes; cath++){
160 fTrigger34[ch][cath] = 0;
161 fTrigger44[cath] = 0;
162 for(Int_t slat=0; slat<fgkNslats; slat++){
163 fInefficientSlat[ch][cath][slat] = 0;
164 fHitPerSlat[ch][cath][slat] = 0;
165 }
166 }
167 }
168}
169
170
171//_____________________________________________________________________________
172void AliMUONTriggerChamberEff::InfoDigit()
173{
2227e936 174 //
175 /// Prints information on digits (for debugging)
176 //
177
f165a2d2 178 AliMUONDigit * mDigit=0x0;
179 Int_t firstTrigCh = AliMUONConstants::NTrackingCh();
180 // Addressing
181 Int_t nchambers = AliMUONConstants::NCh();
182 fData->SetTreeAddress("D,GLT");
183
184 fData->GetDigits();
185 // Loop on chambers
186 for(Int_t ichamber=firstTrigCh; ichamber<nchambers; ichamber++) {
187 TClonesArray* digits = fData->Digits(ichamber);
188 digits->Sort();
189 Int_t ndigits = (Int_t)digits->GetEntriesFast();
190 for(Int_t idigit=0; idigit<ndigits; idigit++) {
191 mDigit = (AliMUONDigit*)digits->At(idigit);
192 mDigit->Print();
193 } // end digit loop
194 } // end chamber loop
195 fData->ResetDigits();
196}
197
198
199//_____________________________________________________________________________
200Bool_t AliMUONTriggerChamberEff::PadMatchTrack(Float_t xPad, Float_t yPad, Float_t dpx, Float_t dpy,
201 Float_t xTrackAtPad, Float_t yTrackAtPad, Int_t chamber)
202{
2227e936 203 //
204 /// Decides if the digit belongs to the trigger track.
205 //
206
f165a2d2 207 Float_t numOfHalfWidth = 5.;
208 Bool_t match = kFALSE;
209 Float_t maxDistX = dpx;
210 if(fReproduceTrigResponse && chamber>=2) maxDistX = 3.*dpx;// Non-bending plane: check the +- 1 strip between stations
211 if(!fReproduceTrigResponse)maxDistX = numOfHalfWidth*dpx;
212 Float_t maxDistY = dpy;
213 if(fReproduceTrigResponse && chamber%2) maxDistY = 3*dpy;// bending plane: check the +- 1 strip between planes in the same station
214 if(!fReproduceTrigResponse) maxDistY = numOfHalfWidth*dpy;
215 Float_t deltaX = TMath::Abs(xPad-xTrackAtPad);
216 Float_t deltaY = TMath::Abs(yPad-yTrackAtPad);
217 if(deltaX<=maxDistX && deltaY<=maxDistY)match = kTRUE;
218 return match;
219}
220
221
222//_____________________________________________________________________________
2227e936 223Bool_t AliMUONTriggerChamberEff::IsDiffLocalBoard(Int_t currDetElemId, Int_t iy, Int_t detElemIdP1, Int_t iyDigitP1) const
f165a2d2 224{
2227e936 225 //
226 /// Determins if the digits belong to the same local board.
227 /// Used only if one wants to reproduce the trigger algorithm result.
228 /// (fReproduceTrigResponse = kTRUE).
229 //
230
f165a2d2 231 Bool_t isDiff = kTRUE;
232 if(detElemIdP1<0 || iyDigitP1<0)return kFALSE;
233 Int_t currSlat = currDetElemId%100;
234 Int_t slatP1 = detElemIdP1%100;
235 Int_t currLoc = iy/16;
236 Int_t locP1 = iyDigitP1/16;
237 if(currSlat==slatP1 && currLoc==locP1)isDiff = kFALSE;
238 return isDiff;
239}
240
241
242//_____________________________________________________________________________
243void AliMUONTriggerChamberEff::CalculateEfficiency(Int_t trigger44, Int_t trigger34,
244 Float_t &efficiency, Float_t &error, Bool_t failuresAsInput)
245{
2227e936 246 //
247 /// Returns the efficiency.
248 //
249
f165a2d2 250 efficiency=-9.;
251 error=0.;
252 if(trigger34>0){
253 efficiency=(Double_t)trigger44/((Double_t)trigger34);
254 if(failuresAsInput)efficiency=1.-(Double_t)trigger44/((Double_t)trigger34);
255 }
256 Double_t q = TMath::Abs(1-efficiency);
257 if(efficiency<0)error=0.0;
258 else error = TMath::Sqrt(efficiency*q/((Double_t)trigger34));
259}
260
261
262//_____________________________________________________________________________
263Int_t AliMUONTriggerChamberEff::DetElemIdFromPos(Float_t x, Float_t y, Int_t chamber, Int_t cathode)
264{
2227e936 265 //
266 /// Given the (x,y) position in the chamber,
267 /// it returns the corresponding slat
268 //
269
f165a2d2 270 Int_t resultingDetElemId = -1;
271 AliMpDEIterator it;
272 const AliMUONGeometryTransformer *kGeomTransformer = fMUON->GetGeometryTransformer();
273 AliMUONSegmentation *segmentation = fMUON->GetSegmentation();
274 for ( it.First(chamber-1); ! it.IsDone(); it.Next() ){
866c3232 275 Int_t detElemId = it.CurrentDEId();
f165a2d2 276
277 if ( segmentation->HasDE(detElemId) ){
278 const AliMpVSegmentation* seg =
866c3232 279 AliMpSegmentation::Instance()
280 ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
f165a2d2 281 if (seg){
282 Float_t deltax = seg->Dimensions().X();
283 Float_t deltay = seg->Dimensions().Y();
284 Float_t xlocal1 = -deltax;
285 Float_t ylocal1 = -deltay;
286 Float_t xlocal2 = +deltax;
287 Float_t ylocal2 = +deltay;
288 Float_t xg01, yg01, zg1, xg02, yg02, zg2;
289 kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg01, yg01, zg1);
290 kGeomTransformer->Local2Global(detElemId, xlocal2, ylocal2, 0, xg02, yg02, zg2);
291
292 Float_t xg1 = xg01, xg2 = xg02, yg1 = yg01, yg2 = yg02;
293
294 if(xg01>xg02){
295 xg1 = xg02;
296 xg2 = xg01;
297 }
298 if(yg01>yg02){
299 yg1 = yg02;
300 yg2 = yg01;
301 }
302
303 if(x>=xg1 && x<=xg2 && y>=yg1 && y<=yg2){
304 resultingDetElemId = detElemId;
305 break;
306 }
307 }
308 }
309 }
310 return resultingDetElemId;
311}
312
313
314//_____________________________________________________________________________
315void AliMUONTriggerChamberEff::LocalBoardFromPos(Float_t x, Float_t y, Int_t detElemId, Int_t cathode, Int_t localBoard[4])
316{
2227e936 317 //
318 /// Given the (x,y) position in the chamber,
319 /// it returns the corresponding local board
320 //
321
f165a2d2 322 for(Int_t loc=0; loc<4; loc++){
323 localBoard[loc]=-1;
324 }
325 const AliMUONGeometryTransformer *kGeomTransformer = fMUON->GetGeometryTransformer();
326 Float_t xl, yl, zl;
327 kGeomTransformer->Global2Local(detElemId, x, y, 0, xl, yl, zl);
328 TVector2 pos(xl,yl);
329 const AliMpVSegmentation* seg =
866c3232 330 AliMpSegmentation::Instance()
331 ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
f165a2d2 332 if (seg){
333 AliMpPad pad = seg->PadByPosition(pos,kFALSE);
334 for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){
335 AliMpIntPair location = pad.GetLocation(loc);
336 localBoard[loc] = location.GetFirst();
337 }
338 }
339}
340
341
342//_____________________________________________________________________________
343void AliMUONTriggerChamberEff::PrintTrigger(AliMUONGlobalTrigger *globalTrig)
344{
2227e936 345 //
346 /// Print trigger response.
347 //
f165a2d2 348
349 printf("===================================================\n");
350 printf(" Global Trigger output\t \tLow pt\tHigh pt\n");
351
352 printf(" number of Single:\t \t");
353 printf("%i\t",globalTrig->SingleLpt());
354 printf("%i\t",globalTrig->SingleHpt());
355 printf("\n");
356
357 printf(" number of UnlikeSign pair:\t");
358 printf("%i\t",globalTrig->PairUnlikeLpt());
359 printf("%i\t",globalTrig->PairUnlikeHpt());
360 printf("\n");
361
362 printf(" number of LikeSign pair:\t");
363 printf("%i\t",globalTrig->PairLikeLpt());
364 printf("%i\t",globalTrig->PairLikeHpt());
365 printf("\n");
366 printf("===================================================\n");
367 printf("\n");
368}
369
370void AliMUONTriggerChamberEff::PerformTriggerChamberEff(const char* outputDir)
371{
2227e936 372 //
373 /// Main method.
374 /// It loops over the the trigger rec. tracks in the event.
375 /// Then it search for matching digits around the track.
376 /// Finally it calculates the efficiency for each trigger board.
377 /// Files with calculated efficiency are placed in the user defined outputDir.
378 //
379
380 enum {kBending, kNonBending};
f165a2d2 381 Int_t evtBeforePrint = 1000;
382 Float_t rad2deg = 180./TMath::Pi();
383
384 Int_t chOrder[] = {0,2,1,3};
385 Int_t station[] = {0,0,1,1};
386 Float_t zRealMatch[fgkNchambers] = {0.0};
387 Float_t correctFactor[fgkNcathodes] = {1.};
388
389 Bool_t match[fgkNchambers][fgkNcathodes] = {{kFALSE}};
390
2227e936 391 TClonesArray *recTrigTracksArray = 0x0;
f165a2d2 392 AliMUONTriggerTrack *recTrigTrack = 0x0;
393 AliMUONDigit * mDigit = 0x0;
394
395 Float_t zMeanChamber[fgkNchambers];
396 for(Int_t ch=0; ch<fgkNchambers; ch++){
397 zMeanChamber[ch] = AliMUONConstants::DefaultChamberZ(10+ch);
398 }
399
400 TClonesArray * globalTrigger = 0x0;
401 AliMUONGlobalTrigger * gloTrg = 0x0;
402
403 Int_t partNumOfTrig[fgkNchambers][fgkNcathodes] = {{0}};
404 Int_t totNumOfTrig[fgkNchambers][fgkNcathodes] = {{0}};
405 Int_t atLeast1MuPerEv[fgkNchambers][fgkNcathodes] = {{0}};
406 Int_t digitPerTrack[fgkNcathodes] = {0};
407
408 Float_t trackIntersectCh[2][fgkNchambers]={{0.0}};
409
410 Int_t slatInPlane1[2][fgkNcathodes];
411 Int_t iyDigitInPlane1[2][fgkNcathodes];
412
2227e936 413 const Int_t kMaxNumOfTracks = 10;
414 Int_t trigScheme[kMaxNumOfTracks][fgkNchambers][fgkNcathodes]={{{0}}};
415 Int_t triggeredDigits[kMaxNumOfTracks][fgkNchambers][fgkNcathodes] = {{{-1}}};
416 Int_t slatThatTriggered[kMaxNumOfTracks][fgkNchambers][fgkNcathodes]={{{-1}}};
417 Int_t boardThatTriggered[kMaxNumOfTracks][fgkNchambers][fgkNcathodes][4]={{{{-1}}}};
f165a2d2 418 Int_t nboard[4]={-1};
419 Int_t ineffBoard[4]={-1};
420
2227e936 421 const Int_t kMaxNumOfDigits = 20;
422 Int_t detElOfDigitsInData[kMaxNumOfDigits][fgkNchambers][fgkNcathodes] = {{{-1}}};
f165a2d2 423
424 char filename[150];
425 FileStat_t fs;
426
427 if(fFirstRun<0)fFirstRun=fLastRun=-1;
428
429 for(Int_t iRun = fFirstRun; iRun <= fLastRun; iRun++){// Loop over runs
430 // open run loader and load gAlice
431 if(fFirstRun>=0){
432 cout<<"\n\nRun = "<<iRun<<endl;
433 sprintf(filename, "%s/run%i/galice.root", fGaliceDir.Data(), iRun);
434 if(gSystem->GetPathInfo(filename,fs)){
435 cout<<"Warning: "<<filename<<" not found. Skip to next one"<<endl;
436 continue;
437 }
438 cout<<"Opening file "<<filename<<endl;
439 SetGaliceFile(filename);
440 }
441
442 for (Int_t ievent=fFirstEvent; ievent<=fLastEvent; ievent++) { // event loop
443 Bool_t isClearEvent = kTRUE;
444
445 for(Int_t ch=0; ch<fgkNchambers; ch++){
446 for(Int_t cath=0; cath<fgkNcathodes; cath++){
447 partNumOfTrig[ch][cath]=0;
448 match[ch][cath]=kFALSE;
2227e936 449 for(Int_t itrack=0; itrack<kMaxNumOfTracks; itrack++){
f165a2d2 450 triggeredDigits[itrack][ch][cath]=-1;
451 slatThatTriggered[itrack][ch][cath]=-1;
452 for(Int_t loc=0; loc<4; loc++){
453 boardThatTriggered[itrack][ch][cath][loc]=-1;
454 }
455 }
2227e936 456 for(Int_t idig=0; idig<kMaxNumOfDigits; idig++){
f165a2d2 457 detElOfDigitsInData[idig][ch][cath]=-1;
458 }
459 }
460 }
461
462 fRunLoader->GetEvent(ievent);
463 if (ievent%evtBeforePrint==0) printf("\t Event = %d\n",ievent);
464
465 fData->SetTreeAddress("RL");
466 fData->GetRecTriggerTracks();
2227e936 467 recTrigTracksArray = fData->RecTriggerTracks();
468 Int_t nRecTrigTracks = (Int_t) recTrigTracksArray->GetEntriesFast();
f165a2d2 469
470 fData->SetTreeAddress("D,GLT");
471 fData->GetDigits();
472
473 const AliMUONGeometryTransformer* kGeomTransformer = fMUON->GetGeometryTransformer();
474
475 for (Int_t iRecTrigTrack=0; iRecTrigTrack<nRecTrigTracks; iRecTrigTrack++) {
476 for(Int_t cath=0; cath<fgkNcathodes; cath++){
477 digitPerTrack[cath]=0;
478 for(Int_t sta=0; sta<2; sta++){
479 slatInPlane1[sta][cath] = -9999;
480 iyDigitInPlane1[sta][cath] = -9999;
481 }
482 }
483
484 Bool_t doubleCountTrack = kFALSE;
485
486 // reading info from tracks
2227e936 487 recTrigTrack = (AliMUONTriggerTrack *)recTrigTracksArray->At(iRecTrigTrack);
f165a2d2 488 Float_t x11 = recTrigTrack->GetX11();// x position (info from non-bending plane)
489 Float_t y11 = recTrigTrack->GetY11();// y position (info from bending plane)
490 Float_t thetaX = recTrigTrack->GetThetax();
491 Float_t thetaY = recTrigTrack->GetThetay();
492
493 if(fDebugLevel>=3)printf("\tEvent = %i, Track = %i\npos from track: (x,y) = (%f, %f), (thetaX, thetaY) = (%f, %f)\n",ievent,iRecTrigTrack,x11,y11,thetaX*rad2deg,thetaY*rad2deg);
494
495 for(Int_t ch=0; ch<fgkNchambers; ch++) {
496 zRealMatch[ch] = zMeanChamber[ch];
497 for(Int_t cath=0; cath<fgkNcathodes; cath++){
498 trigScheme[iRecTrigTrack][ch][cath] = 0;
499 }
500 }
501
502 for(Int_t ch=0; ch<fgkNchambers; ch++) { // chamber loop
503 Int_t currCh = chOrder[ch];
504 Int_t ichamber = 10+currCh;
505 Int_t currStation = station[currCh];
506 TClonesArray* digits = fData->Digits(ichamber);
507 digits->Sort();
508 Int_t ndigits = (Int_t)digits->GetEntriesFast();
509 if(fDebugLevel>=2){
510 if(fDebugLevel<3)printf("\tEvent = %i, Track = %i\n", ievent, iRecTrigTrack);
511 printf("DigitNum: %i digits detected\n",ndigits);
512 }
513
514 for(Int_t cath=0; cath<fgkNcathodes; cath++){
515 correctFactor[cath]=1.;
516 }
517 // calculate corrections to trigger track theta
2227e936 518 if(ch>=1)correctFactor[kNonBending] = zMeanChamber[0]/zRealMatch[0];// corrects x position
519 if(ch>=2)correctFactor[kBending] = (zMeanChamber[2] - zMeanChamber[0]) / (zRealMatch[2] - zRealMatch[0]);// corrects y position
f165a2d2 520
521 // searching track intersection with chambers (first approximation)
522 Float_t deltaZ = zMeanChamber[currCh] - zMeanChamber[0];
2227e936 523 trackIntersectCh[0][currCh] = zMeanChamber[currCh] * TMath::Tan(thetaX) * correctFactor[kNonBending];// x position (info from non-bending plane)
524 trackIntersectCh[1][currCh] = y11 + deltaZ * TMath::Tan(thetaY) * correctFactor[kBending];// y position (info from bending plane)
f165a2d2 525
526 for(Int_t idigit=0; idigit<ndigits; idigit++) { // digit loop
527 mDigit = (AliMUONDigit*)digits->At(idigit);
528 for(Int_t loc=0; loc<4; loc++){
529 nboard[loc]=-1;
530 }
531
532 // searching loaded digit global position and dimension
533 Int_t detElemId = mDigit->DetElemId();
534 Int_t cathode = mDigit->Cathode();
535 Int_t ix = mDigit->PadX();
536 Int_t iy = mDigit->PadY();
537 Float_t xpad, ypad, zpad;
538 if(detElOfDigitsInData[idigit][ch][cathode]==-1)detElOfDigitsInData[idigit][ch][cathode] = detElemId;
539
540 if(fDebugLevel>=2)printf("cathode = %i\n",cathode);
866c3232 541 const AliMpVSegmentation* seg = AliMpSegmentation::Instance()
542 ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
f165a2d2 543
544 AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
545 for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){
546 AliMpIntPair location = pad.GetLocation(loc);
547 nboard[loc] = location.GetFirst();
548 }
549
550 // get the pad position and dimensions
551 Float_t xlocal1 = pad.Position().X();
552 Float_t ylocal1 = pad.Position().Y();
553 Float_t dpx = pad.Dimensions().X();
554 Float_t dpy = pad.Dimensions().Y();
555
556 kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xpad, ypad, zpad);
557
558 if(fDebugLevel>=3)printf("ch = %i\t cath = %i\tpad = (%4.1f, %4.1f, %4.1f)\tsize = (%3.1f, %3.1f)\n",currCh,cathode,xpad,ypad,zpad,dpx,dpy);
559
560 // searching track intersection with chambers (second approximation)
561 if(ch>=2){
562 deltaZ = zpad - zRealMatch[0];
2227e936 563 trackIntersectCh[1][currCh] = y11 + deltaZ * TMath::Tan(thetaY) * correctFactor[kBending];// y position (info from bending plane)
f165a2d2 564 }
565
566 // deciding if digit matches track
567 Bool_t isDiffLocBoard = kFALSE;
568 if(fReproduceTrigResponse)isDiffLocBoard = IsDiffLocalBoard(detElemId, iy, slatInPlane1[currStation][cathode], iyDigitInPlane1[currStation][cathode]);
569 Bool_t matchPad = PadMatchTrack(xpad, ypad, dpx, dpy, trackIntersectCh[0][currCh], trackIntersectCh[1][currCh], currCh);
570
571 if(matchPad && ch<2){
572 slatInPlane1[currStation][cathode] = detElemId;
573 iyDigitInPlane1[currStation][cathode] = iy;
574 if(fDebugLevel>=3)printf("slatInPlane1[%i][%i] = %i\tiyDigitInPlane1[%i][%i] = %i\n",currStation,cathode,slatInPlane1[currStation][cathode],currStation,cathode,iyDigitInPlane1[currStation][cathode]);
575 }
576
577 if(isDiffLocBoard && fDebugLevel>=1)printf("\tDifferent local board\n");
578
579 match[currCh][cathode] = (matchPad && !isDiffLocBoard);
580
581 if(match[currCh][cathode]){
582 digitPerTrack[cathode]++;
583 trigScheme[iRecTrigTrack][currCh][cathode]++;
584 triggeredDigits[iRecTrigTrack][currCh][cathode] = idigit;
585 slatThatTriggered[iRecTrigTrack][currCh][cathode] = detElemId;
586 for(Int_t loc=0; loc<4; loc++){
587 boardThatTriggered[iRecTrigTrack][currCh][cathode][loc] = nboard[loc];
588 }
589 if(digitPerTrack[cathode]>4 && !fReproduceTrigResponse)isClearEvent = kFALSE;
590 }
591
592 // in case of match, store real z position of the chamber
593 if(matchPad)zRealMatch[currCh] = zpad;
594
595 } // end digit loop
596 } // end chamber loop
597
598 for(Int_t cath=0; cath<fgkNcathodes; cath++){
599 if(digitPerTrack[cath]<3 && !fReproduceTrigResponse)isClearEvent = kFALSE;
600 }
601
602 if(!isClearEvent && !fReproduceTrigResponse){
603 fData->ResetDigits();
604 continue;
605 }
606
607 Int_t commonDigits = 0;
608 Int_t doubleTrack = -1;
609 for(Int_t itrack=0; itrack<iRecTrigTrack; itrack++){
610 for(Int_t ch=0; ch<fgkNchambers; ch++){
2227e936 611 if(triggeredDigits[itrack][ch][kBending]==triggeredDigits[iRecTrigTrack][ch][kBending])commonDigits++;
f165a2d2 612 }
613 if(commonDigits>=2){
614 doubleCountTrack=kTRUE;
615 doubleTrack = itrack;
616 break;
617 }
618 }
619
620 for(Int_t cath=0; cath<fgkNcathodes; cath++){
621 if(!doubleCountTrack || fReproduceTrigResponse){
622 Int_t is44 = 1;
623 Bool_t goodForSlatEff=kTRUE;
624 Bool_t goodForBoardEff=kTRUE;
625 Int_t firstSlat=slatThatTriggered[iRecTrigTrack][0][cath]%100;
626 if(firstSlat<0)firstSlat=slatThatTriggered[iRecTrigTrack][1][cath]%100;
627 Int_t firstBoard=boardThatTriggered[iRecTrigTrack][0][0][0];
628 if(firstBoard<0)firstBoard=boardThatTriggered[iRecTrigTrack][1][0][0];
629 for(Int_t ch=0; ch<fgkNchambers; ch++){
630 is44 *= trigScheme[iRecTrigTrack][ch][cath];
631 Int_t currSlat=slatThatTriggered[iRecTrigTrack][ch][cath]%100;
632 if(currSlat<0)continue;
633 if(currSlat!=firstSlat)goodForSlatEff=kFALSE;
634 Bool_t atLeastOneLoc=kFALSE;
635 for(Int_t loc=0; loc<4; loc++){
636 Int_t currBoard = boardThatTriggered[iRecTrigTrack][ch][cath][loc];
637 if(currBoard==firstBoard){
638 atLeastOneLoc=kTRUE;
639 break;
640 }
641 }
642 if(!atLeastOneLoc)goodForBoardEff=kFALSE;
643 }
644 if(fDebugLevel==1)printf("\tEvent = %i, Track = %i\n", ievent, iRecTrigTrack);
645 if(is44==1){
646 fTrigger44[cath]++;
647 if(fDebugLevel>=1)printf("Trigger44[%i] = %i\n",cath,fTrigger44[cath]);
648 if(goodForSlatEff){
649 for(Int_t ch=0; ch<fgkNchambers; ch++){
650 for(Int_t slat=0; slat<fgkNslats; slat++){
651 Int_t corrDetEl = (ch+11)*100 + slat;
652 if(corrDetEl==slatThatTriggered[iRecTrigTrack][ch][cath]){
653 fHitPerSlat[ch][cath][slat]++;
654 if(fDebugLevel>=1)printf("Slat that triggered = %i\n",corrDetEl);
655 if(goodForBoardEff && firstBoard>0){
656 fHitPerBoard[ch][cath][firstBoard-1]++;
657 if(fDebugLevel>=1)printf("Board that triggered = %i\n",firstBoard);
658 }
659 else if(fDebugLevel>=1)printf("Event = %i, Track = %i: Particle crossed different boards: rejected!\n",ievent,iRecTrigTrack);
660 }
661 }
662 }
663 }
664 else printf("Event = %i, Track = %i: Particle crossed different slats: rejected!\n",ievent,iRecTrigTrack);
665 }
666 if(digitPerTrack[cath]==3){
667 for(Int_t ch=0; ch<fgkNchambers; ch++){
668 if(match[ch][cath])partNumOfTrig[ch][cath]++;
669 if(trigScheme[iRecTrigTrack][ch][cath]==0){
670 fTrigger34[ch][cath]++;
671 if(fDebugLevel>=1)printf("Trigger34[%i][%i] = %i\n",ch,cath,fTrigger34[ch][cath]);
672 if(!goodForSlatEff){
673 printf("Event %i, Track = %i: Particle crossed different slats: rejected!\n",ievent,iRecTrigTrack);
674 continue;
675 }
676 Int_t ineffSlat = DetElemIdFromPos(trackIntersectCh[0][ch], trackIntersectCh[1][ch], 11+ch, cath);
677 if(fDebugLevel>=1)printf("Slat non efficient = %i\n",ineffSlat);
678 if(ineffSlat>0){
679 Int_t slatInCh = ineffSlat%100;
680 fInefficientSlat[ch][cath][slatInCh]++;
2227e936 681 for(Int_t idig=0; idig<kMaxNumOfDigits; idig++){
f165a2d2 682 if(ineffSlat==detElOfDigitsInData[idig][ch][cath])cout<<"Warning: "<<ineffSlat<<" is not inefficient!!!"<<endl;
683 }
684 LocalBoardFromPos(trackIntersectCh[0][ch], trackIntersectCh[1][ch], ineffSlat, cath, ineffBoard);
685 Int_t boardNonEff=-1;
686 for(Int_t loc=0; loc<4; loc++){
687 if(ineffBoard[loc]==firstBoard){
688 boardNonEff=ineffBoard[loc];
689 break;
690 }
691 }
692 if(fDebugLevel>=1)printf("Board non efficient = %i\n",boardNonEff);
693 if(boardNonEff>0)fInefficientBoard[ch][cath][boardNonEff-1]++;
694 else if(fDebugLevel>=1){
695 printf("Inefficient board should be %i.\tBoards found:\n", firstBoard);
696 for(Int_t loc=0; loc<4; loc++){
697 printf("%i\t",ineffBoard[loc]);
698 }
699 printf("\n");
700 }
701
702 }
703 }
704 }
705 }
706 }
707 else if(doubleCountTrack){
708 if(fDebugLevel<=1)printf("\n\tEvent = %i, Track = %i: ", ievent,iRecTrigTrack);
709 printf("Double Count Track: %i similar to %i. Track rejected!\n",iRecTrigTrack, doubleTrack);
710 }
711 }
712 }// end trigger tracks loop
713 if(nRecTrigTracks<=0){
714 fData->ResetDigits();
715 continue;
716 }
717 for(Int_t ch=0; ch<fgkNchambers; ch++){
718 for(Int_t cath=0; cath<fgkNcathodes; cath++){
719 totNumOfTrig[ch][cath] += partNumOfTrig[ch][cath];
720 if(partNumOfTrig[ch][cath]>0)atLeast1MuPerEv[ch][cath]++;
721 }
722 }
723
724 if(fPrintInfo){
725 //Global trigger
726 globalTrigger = fData->GlobalTrigger();
727 Int_t nglobals = (Int_t) globalTrigger->GetEntriesFast(); // should be 1
728
729 for (Int_t iglobal=0; iglobal<nglobals; iglobal++) { // Global Trigger
730 gloTrg = (AliMUONGlobalTrigger*)globalTrigger->At(iglobal);
731 }
732 PrintTrigger(gloTrg);
733 InfoDigit();
734 cout<<"\n"<<endl;
735 }
736
737 fData->ResetDigits();
738 }// end event loop
739 if(fFirstRun>=0)CleanGalice();
740 } //end loop over run
741
742 // Write output data
743 WriteEfficiencyMap(outputDir);
744
745 WriteOutput(outputDir, totNumOfTrig, atLeast1MuPerEv);
746}
747
748//_____________________________________________________________________________
749void AliMUONTriggerChamberEff::WriteOutput(const char* outputDir, Int_t totNumOfTrig[4][2], Int_t atLeast1MuPerEv[4][2])
750{
2227e936 751 //
752 /// Writes information on calculated efficiency.
753 /// It writes: triggerChamberEff.root file containing efficiency histograms.
754 ///
755 /// In addition a text file triggerChamberEff.out is created,
756 /// with further informations on efficiencies.
757 //
758
f165a2d2 759 char *cathodeName[fgkNcathodes]={"Bending plane", "Non-Bending plane"};
760 char *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
761
762 char outFileName[100];
763 sprintf(outFileName, "%s/triggerChamberEff.out",outputDir);
764 FILE *outfile = fopen(outFileName, "w");
765 for(Int_t cath=0; cath<fgkNcathodes; cath++){
766 fprintf(outfile,"%s:\n",cathodeName[cath]);
767 for(Int_t ch=0; ch<fgkNchambers; ch++){
768 fprintf(outfile,"Total number of muon triggers chamber 1%i = %i\n",ch+1,totNumOfTrig[ch][cath]);
769 }
770 fprintf(outfile,"\n");
771 }
772 fprintf(outfile,"\n");
773 for(Int_t cath=0; cath<fgkNcathodes; cath++){
774 fprintf(outfile,"%s:\n",cathodeName[cath]);
775 for(Int_t ch=0; ch<fgkNchambers; ch++){
776 fprintf(outfile,"At least 1 muon triggered chamber 1%i = %i\n",ch+1, atLeast1MuPerEv[ch][cath]);
777 }
778 fprintf(outfile,"\n");
779 }
780 fprintf(outfile,"\n\n");
781 for(Int_t cath=0; cath<fgkNcathodes; cath++){
782 fprintf(outfile,"%s:\n",cathodeName[cath]);
783 fprintf(outfile,"Number of triggers where all chambers counted = %i\n",fTrigger44[cath]);
784 fprintf(outfile,"\n");
785 }
786 fprintf(outfile,"\n");
787 for(Int_t cath=0; cath<fgkNcathodes; cath++){
788 fprintf(outfile,"%s:\n",cathodeName[cath]);
789 for(Int_t ch=0; ch<fgkNchambers; ch++){
790 fprintf(outfile,"Number of triggers where chamber 1%i did not count = %i\n",ch+1,fTrigger34[ch][cath]);
791 }
792 fprintf(outfile,"\n");
793 }
794
795 fprintf(outfile,"\n");
796 for(Int_t cath=0; cath<fgkNcathodes; cath++){
797 fprintf(outfile,"%s:\n",cathodeName[cath]);
798 for(Int_t ch=0; ch<fgkNchambers; ch++){
799 Int_t sumIneff = 0, sumHits = 0;
800 fprintf(outfile,"\n Chamber %1i\n", ch+1);
801 for(Int_t slat=0; slat<fgkNslats; slat++){
802 fprintf(outfile,"Number of triggers where slat %2i - did not count = %5i - was hit (hit%sCh%iSlat%i) = %5i\n",slat,fInefficientSlat[ch][cath][slat],cathCode[cath],11+ch,slat,fHitPerSlat[ch][cath][slat]);
803 sumIneff += fInefficientSlat[ch][cath][slat];
804 sumHits += fHitPerSlat[ch][cath][slat];
805 }
806 fprintf(outfile,"Number of triggers where chamber %1i - did not count = %5i - was hit (hit%sCh%i) = %5i\n",ch+1,sumIneff,cathCode[cath],11+ch,sumHits);
807 }
808 fprintf(outfile,"\n");
809 }
810 fclose(outfile);
811
812 sprintf(outFileName, "%s/triggerChamberEff.root",outputDir);
813 TFile *outputHistoFile = new TFile(outFileName,"RECREATE");
814 TDirectory *dir = gDirectory;
815
2227e936 816 enum {kSlatIn11, kSlatIn12, kSlatIn13, kSlatIn14, kChamberEff};
f165a2d2 817 char *yAxisTitle = "trigger efficiency (a.u.)";
818 char *xAxisTitle = "chamber";
819
820 TH1F *histo[fgkNcathodes][fgkNchambers+1];
821 TH1F *histoBoard[fgkNcathodes][fgkNchambers];
822
823 char histoName[30];
824 char histoTitle[90];
825
826 for(Int_t cath=0; cath<fgkNcathodes; cath++){
827 for(Int_t ch=0; ch<fgkNchambers+1; ch++){
2227e936 828 if(ch==kChamberEff){
f165a2d2 829 sprintf(histoName, "%sChamberEff", cathCode[cath]);
830 sprintf(histoTitle, "Chamber efficiency %s", cathCode[cath]);
831 histo[cath][ch] = new TH1F(histoName, histoTitle, fgkNchambers, 11-0.5, 15-0.5);
832 histo[cath][ch]->SetXTitle(xAxisTitle);
833 histo[cath][ch]->SetYTitle(yAxisTitle);
834 histo[cath][ch]->GetXaxis()->SetNdivisions(fgkNchambers);
835 }
836 else {
837 sprintf(histoName, "%sSlatEffChamber%i", cathCode[cath], 11+ch);
838 sprintf(histoTitle, "Chamber %i: slat efficiency %s", 11+ch, cathCode[cath]);
839 histo[cath][ch] = new TH1F(histoName, histoTitle, fgkNslats, 0-0.5, fgkNslats-0.5);
840 histo[cath][ch]->SetXTitle("slat");
841 histo[cath][ch]->SetYTitle(yAxisTitle);
842 histo[cath][ch]->GetXaxis()->SetNdivisions(fgkNslats);
843
844 sprintf(histoName, "%sBoardEffChamber%i", cathCode[cath], 11+ch);
845 sprintf(histoTitle, "Chamber %i: board efficiency %s", 11+ch, cathCode[cath]);
846 histoBoard[cath][ch] = new TH1F(histoName, histoTitle, fgkNboards, 1-0.5, fgkNboards+1.-0.5);
847 histoBoard[cath][ch]->SetXTitle("boards");
848 histoBoard[cath][ch]->SetYTitle(yAxisTitle);
849 histoBoard[cath][ch]->GetXaxis()->SetNdivisions(fgkNboards);
850 }
851 }
852 }
853
854 Float_t efficiency, efficiencyError;
855
856 for(Int_t cath=0; cath<fgkNcathodes; cath++){
857 for(Int_t ch=0; ch<fgkNchambers; ch++){
858 for(Int_t slat=0; slat<fgkNslats; slat++){
859 CalculateEfficiency(fHitPerSlat[ch][cath][slat], fHitPerSlat[ch][cath][slat]+fInefficientSlat[ch][cath][slat], efficiency, efficiencyError, kFALSE);
860 histo[cath][ch]->SetBinContent(slat+1, efficiency);
861 histo[cath][ch]->SetBinError(slat+1, efficiencyError);
862 }
863 CalculateEfficiency(fTrigger44[cath], fTrigger34[ch][cath]+fTrigger44[cath], efficiency, efficiencyError, kFALSE);
2227e936 864 histo[cath][kChamberEff]->SetBinContent(ch+1, efficiency);
865 histo[cath][kChamberEff]->SetBinError(ch+1, efficiencyError);
f165a2d2 866
867 for(Int_t board=0; board<fgkNboards; board++){
868 CalculateEfficiency(fHitPerBoard[ch][cath][board], fHitPerBoard[ch][cath][board]+fInefficientBoard[ch][cath][board], efficiency, efficiencyError, kFALSE);
869 histoBoard[cath][ch]->SetBinContent(board+1, efficiency);
870 histoBoard[cath][ch]->SetBinError(board+1, efficiencyError);
871 }
872 }
873 }
874
875// write all histos
876 outputHistoFile->cd();
877 dir->GetList()->Write();
878 outputHistoFile->Close();
879}
880
881
882//_____________________________________________________________________________
883void AliMUONTriggerChamberEff::WriteEfficiencyMap(const char* outputDir)
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;
908 Int_t currLine=0;
909 for(Int_t board=0; board<fgkNboards; board++){
910
911 if(board==aCapo[currLine]){
912 outFile << endl;
913 currLine++;
914 }
915 CalculateEfficiency(fHitPerBoard[ch][cath][board], fHitPerBoard[ch][cath][board]+fInefficientBoard[ch][cath][board], efficiency, efficiencyError, kFALSE);
916 outFile << " " << setw(effOutWidth) << efficiency;
917 }// loop on boards
918 outFile << endl;
919 }// loop on cathodes
920 }// loop on chambers
921}
922