]>
Commit | Line | Data |
---|---|---|
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" | |
311d0691 | 44 | #include "AliMUONTriggerEfficiencyCells.h" |
2227e936 | 45 | |
f165a2d2 | 46 | #include "AliMpVSegmentation.h" |
47 | #include "AliMpSegmentation.h" | |
48 | #include "AliMpPad.h" | |
49 | #include "AliMpDEIterator.h" | |
2227e936 | 50 | #include "AliMpPlaneType.h" |
8c0b5e70 | 51 | #include "AliMpDEManager.h" |
8b1cdc26 | 52 | #include "AliMpConstants.h" |
53 | ||
8c0b5e70 | 54 | #include "AliLog.h" |
f165a2d2 | 55 | |
311d0691 | 56 | //#include "AliESDEvent.h" |
57 | ||
2227e936 | 58 | #include <Riostream.h> |
59 | #include <TFile.h> | |
60 | #include <TH1F.h> | |
96079e17 | 61 | #include <TH3F.h> |
2227e936 | 62 | #include <TMath.h> |
63 | ||
8c0b5e70 | 64 | #include <TSeqCollection.h> |
65 | #include <TTree.h> | |
66 | #include <TROOT.h> | |
67 | ||
8b1cdc26 | 68 | #include <cassert> |
8c0b5e70 | 69 | |
2227e936 | 70 | /// \cond CLASSIMP |
f165a2d2 | 71 | ClassImp(AliMUONTriggerChamberEff) |
2227e936 | 72 | /// \endcond |
f165a2d2 | 73 | |
74 | //_____________________________________________________________________________ | |
8c0b5e70 | 75 | AliMUONTriggerChamberEff::AliMUONTriggerChamberEff() |
f165a2d2 | 76 | : TObject(), |
8c0b5e70 | 77 | fTransformer(0x0), |
78 | fDigitMaker(0x0), | |
f165a2d2 | 79 | fReproduceTrigResponse(kFALSE), |
80 | fPrintInfo(kFALSE), | |
8c0b5e70 | 81 | fWriteOnESD(kFALSE), |
f165a2d2 | 82 | fDebugLevel(0), |
8c0b5e70 | 83 | fkMaxDistance(99999.) |
f165a2d2 | 84 | { |
8b1cdc26 | 85 | /// Default constructor |
86 | ||
87 | CheckConstants(); | |
f165a2d2 | 88 | ResetArrays(); |
96079e17 | 89 | InitHistos(); |
f165a2d2 | 90 | } |
91 | ||
8c0b5e70 | 92 | |
f165a2d2 | 93 | //_____________________________________________________________________________ |
8c0b5e70 | 94 | AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(const AliMUONGeometryTransformer* transformer, |
95 | const AliMUONDigitMaker* digitMaker, | |
96 | Bool_t writeOnESD) | |
f165a2d2 | 97 | : TObject(), |
8c0b5e70 | 98 | fTransformer(transformer), |
99 | fDigitMaker(digitMaker), | |
f165a2d2 | 100 | fReproduceTrigResponse(kFALSE), |
101 | fPrintInfo(kFALSE), | |
8c0b5e70 | 102 | fWriteOnESD(writeOnESD), |
f165a2d2 | 103 | fDebugLevel(0), |
8c0b5e70 | 104 | fkMaxDistance(99999.) |
f165a2d2 | 105 | { |
71a2d3aa | 106 | /// Standard constructor |
8b1cdc26 | 107 | |
108 | CheckConstants(); | |
f165a2d2 | 109 | ResetArrays(); |
96079e17 | 110 | InitHistos(); |
f165a2d2 | 111 | } |
112 | ||
8c0b5e70 | 113 | |
f165a2d2 | 114 | //_____________________________________________________________________________ |
115 | AliMUONTriggerChamberEff::~AliMUONTriggerChamberEff() | |
116 | { | |
117 | /// Destructor | |
527d5dcc | 118 | |
119 | // Bool_t writeOnESD=fWriteOnESD; | |
8c0b5e70 | 120 | fWriteOnESD=kFALSE; |
527d5dcc | 121 | // if(writeOnESD) SaveInESDFile(); |
f165a2d2 | 122 | } |
123 | ||
8c0b5e70 | 124 | |
f165a2d2 | 125 | //_____________________________________________________________________________ |
8c0b5e70 | 126 | AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(const AliMUONTriggerChamberEff& other) |
127 | :TObject(other), | |
128 | fTransformer(0x0), | |
129 | fDigitMaker(0x0), | |
130 | fReproduceTrigResponse(other.fReproduceTrigResponse), | |
131 | fPrintInfo(other.fPrintInfo), | |
132 | fWriteOnESD(other.fWriteOnESD), | |
133 | fDebugLevel(other.fDebugLevel), | |
8b1cdc26 | 134 | fkMaxDistance(other.fkMaxDistance), |
135 | fTrigger44(other.fTrigger44), | |
136 | fTrigger34(other.fTrigger34) | |
f165a2d2 | 137 | { |
8b1cdc26 | 138 | /// Copy constructor |
9f6be20d | 139 | |
8b1cdc26 | 140 | for(Int_t chCath=0; chCath<fgkNplanes; chCath++){ |
141 | fInefficientSlat[chCath] = other.fInefficientSlat[chCath]; | |
142 | fHitPerSlat[chCath] = other.fHitPerSlat[chCath]; | |
143 | fInefficientBoard[chCath] = other.fInefficientBoard[chCath]; | |
144 | fHitPerBoard[chCath] = other.fHitPerBoard[chCath]; | |
f165a2d2 | 145 | } |
146 | } | |
147 | ||
8c0b5e70 | 148 | |
f165a2d2 | 149 | //_____________________________________________________________________________ |
8c0b5e70 | 150 | AliMUONTriggerChamberEff& AliMUONTriggerChamberEff::operator=(const AliMUONTriggerChamberEff& other) |
f165a2d2 | 151 | { |
8c0b5e70 | 152 | /// Asignment operator |
153 | // check assignement to self | |
154 | if (this == &other) | |
155 | return *this; | |
156 | ||
157 | // base class assignement | |
158 | TObject::operator=(other); | |
159 | ||
160 | fTransformer = 0x0; | |
161 | fDigitMaker = 0x0; | |
162 | fReproduceTrigResponse = other.fReproduceTrigResponse; | |
163 | fPrintInfo = other.fPrintInfo; | |
164 | fWriteOnESD = other.fWriteOnESD; | |
165 | fDebugLevel = other.fDebugLevel; | |
8b1cdc26 | 166 | |
167 | fTrigger44 = other.fTrigger44; | |
168 | fTrigger34 = other.fTrigger34; | |
169 | ||
170 | for(Int_t chCath=0; chCath<fgkNplanes; chCath++){ | |
171 | fInefficientSlat[chCath] = other.fInefficientSlat[chCath]; | |
172 | fHitPerSlat[chCath] = other.fHitPerSlat[chCath]; | |
173 | fInefficientBoard[chCath] = other.fInefficientBoard[chCath]; | |
174 | fHitPerBoard[chCath] = other.fHitPerBoard[chCath]; | |
175 | } | |
8c0b5e70 | 176 | return *this; |
f165a2d2 | 177 | } |
178 | ||
8c0b5e70 | 179 | |
f165a2d2 | 180 | //_____________________________________________________________________________ |
181 | void AliMUONTriggerChamberEff::ResetArrays() | |
182 | { | |
2227e936 | 183 | // |
184 | /// Sets the data member counters to 0. | |
185 | // | |
186 | ||
8b1cdc26 | 187 | fTrigger44.Set(fgkNcathodes); |
188 | fTrigger34.Set(fgkNplanes); | |
189 | ||
190 | for(Int_t chCath=0; chCath<fgkNplanes; chCath++){ | |
191 | fInefficientSlat[chCath].Set(fgkNslats); | |
192 | fHitPerSlat[chCath].Set(fgkNslats); | |
193 | fInefficientBoard[chCath].Set(AliMpConstants::NofLocalBoards()); | |
194 | fHitPerBoard[chCath].Set(AliMpConstants::NofLocalBoards()); | |
195 | } | |
196 | ||
197 | fTrigger44.Reset(); | |
198 | fTrigger34.Reset(); | |
199 | ||
200 | for(Int_t chCath=0; chCath<fgkNplanes; chCath++){ | |
201 | fInefficientSlat[chCath].Reset(); | |
202 | fHitPerSlat[chCath].Reset(); | |
203 | fInefficientBoard[chCath].Reset(); | |
204 | fHitPerBoard[chCath].Reset(); | |
f165a2d2 | 205 | } |
206 | } | |
207 | ||
208 | ||
96079e17 | 209 | //_____________________________________________________________________________ |
210 | void AliMUONTriggerChamberEff::InitHistos() | |
211 | { | |
212 | // | |
213 | /// Initialize histogram for firef pads counting. | |
214 | // | |
215 | const Int_t kMaxNpads[fgkNcathodes] = {GetMaxX(0)*GetMaxY(0), GetMaxX(1)*GetMaxY(1)}; | |
216 | Char_t histoName[40]; | |
217 | Char_t *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"}; | |
218 | ||
219 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ | |
220 | sprintf(histoName, "fPadFired%s", cathCode[cath]); | |
221 | fPadFired[cath] = new TH3F(histoName, histoName, | |
222 | fgkNchambers, -0.5, (Float_t)fgkNchambers - 0.5, | |
223 | fgkNslats, -0.5, (Float_t)fgkNslats - 0.5, | |
224 | kMaxNpads[cath], -0.5, (Float_t)kMaxNpads[cath] - 0.5); | |
225 | } | |
226 | } | |
227 | ||
228 | ||
8c0b5e70 | 229 | //______________________________________________________________________________ |
230 | Bool_t | |
231 | AliMUONTriggerChamberEff::TriggerDigits(const AliMUONVTriggerStore& triggerStore, | |
232 | AliMUONVDigitStore& digitStore) const | |
233 | { | |
234 | // | |
235 | /// make (S)Digit for trigger | |
236 | // | |
237 | digitStore.Clear(); | |
238 | ||
239 | AliMUONLocalTrigger* locTrg; | |
240 | TIter next(triggerStore.CreateLocalIterator()); | |
241 | ||
242 | while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) ) | |
243 | { | |
244 | if (locTrg->IsNull()) continue; | |
245 | ||
8b1cdc26 | 246 | TArrayS xyPattern[fgkNcathodes]; |
8c0b5e70 | 247 | locTrg->GetXPattern(xyPattern[0]); |
248 | locTrg->GetYPattern(xyPattern[1]); | |
249 | ||
250 | Int_t nBoard = locTrg->LoCircuit(); | |
251 | fDigitMaker->TriggerDigits(nBoard, xyPattern, digitStore); | |
252 | } | |
253 | return kTRUE; | |
254 | } | |
255 | ||
256 | ||
f165a2d2 | 257 | //_____________________________________________________________________________ |
8c0b5e70 | 258 | void AliMUONTriggerChamberEff::InfoDigit(AliMUONVDigitStore& digitStore) |
f165a2d2 | 259 | { |
2227e936 | 260 | // |
261 | /// Prints information on digits (for debugging) | |
262 | // | |
8c0b5e70 | 263 | TIter next(digitStore.CreateIterator()); |
264 | AliMUONVDigit* mDigit=0x0; | |
f165a2d2 | 265 | |
8c0b5e70 | 266 | while ( ( mDigit = static_cast<AliMUONVDigit*>(next()) ) ) |
267 | { | |
268 | mDigit->Print(); | |
269 | } // end digit loop | |
270 | printf("\n"); | |
f165a2d2 | 271 | } |
272 | ||
273 | ||
274 | //_____________________________________________________________________________ | |
8c0b5e70 | 275 | Int_t AliMUONTriggerChamberEff::MatchingPad(AliMUONVDigitStore& digitStore, Int_t &detElemId, |
8b1cdc26 | 276 | Float_t coor[2], Bool_t isMatch[2], |
277 | TArrayI nboard[2], TArrayF &zRealMatch, Float_t y11) | |
f165a2d2 | 278 | { |
2227e936 | 279 | // |
a690d2f8 | 280 | /// Check slat and board number of digit matching track |
2227e936 | 281 | // |
282 | ||
a690d2f8 | 283 | enum {kBending, kNonBending}; |
284 | ||
285 | Float_t minMatchDist[fgkNcathodes]; | |
8c0b5e70 | 286 | Int_t padsInCheckArea[fgkNcathodes]; |
f165a2d2 | 287 | |
a690d2f8 | 288 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ |
8c0b5e70 | 289 | isMatch[cath] = kFALSE; |
290 | minMatchDist[cath] = fkMaxDistance/10.; | |
291 | padsInCheckArea[cath] = 0; | |
a690d2f8 | 292 | } |
8c0b5e70 | 293 | Int_t iChamber = AliMpDEManager::GetChamberId(detElemId); |
a690d2f8 | 294 | Int_t ch = iChamber-10; |
295 | Float_t oldDeltaZ = AliMUONConstants::DefaultChamberZ(iChamber) - AliMUONConstants::DefaultChamberZ(10); | |
296 | Float_t y = coor[1]; | |
297 | Int_t iSlat = detElemId%100; | |
298 | Int_t trigDigitBendPlane = -1; | |
a690d2f8 | 299 | Int_t foundDetElemId = detElemId; |
300 | Float_t foundZmatch=999.; | |
301 | Float_t yCoorAtPadZ=999.; | |
8c0b5e70 | 302 | |
303 | TIter next(digitStore.CreateIterator()); | |
304 | AliMUONVDigit* mDigit; | |
305 | Int_t idigit=0; | |
306 | ||
307 | while ( ( mDigit = static_cast<AliMUONVDigit*>(next()) ) ) | |
308 | { | |
309 | idigit++; | |
a690d2f8 | 310 | Int_t currDetElemId = mDigit->DetElemId(); |
8c0b5e70 | 311 | Int_t currCh = AliMpDEManager::GetChamberId(currDetElemId); |
312 | if(currCh!=iChamber) continue; | |
a690d2f8 | 313 | Int_t currSlat = currDetElemId%100; |
8c0b5e70 | 314 | Int_t slatDiff = TMath::Abs(currSlat-iSlat); |
315 | if(slatDiff>1 && slatDiff<17) continue; // Check neighbour slats | |
a690d2f8 | 316 | Int_t cathode = mDigit->Cathode(); |
317 | Int_t ix = mDigit->PadX(); | |
318 | Int_t iy = mDigit->PadY(); | |
319 | Float_t xpad, ypad, zpad; | |
320 | const AliMpVSegmentation* seg = AliMpSegmentation::Instance() | |
321 | ->GetMpSegmentation(currDetElemId,AliMp::GetCathodType(cathode)); | |
322 | ||
323 | AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy),kTRUE); | |
324 | Float_t xlocal1 = pad.Position().X(); | |
325 | Float_t ylocal1 = pad.Position().Y(); | |
326 | Float_t dpx = pad.Dimensions().X(); | |
327 | Float_t dpy = pad.Dimensions().Y(); | |
8c0b5e70 | 328 | fTransformer->Local2Global(currDetElemId, xlocal1, ylocal1, 0, xpad, ypad, zpad); |
a690d2f8 | 329 | 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]); |
330 | // searching track intersection with chambers (second approximation) | |
331 | if(ch%2==1){ | |
8c0b5e70 | 332 | //if(iChamber%2==1){ |
a690d2f8 | 333 | Float_t deltaZ = zpad - zRealMatch[0]; |
334 | y = (coor[1]-y11)*deltaZ/oldDeltaZ + y11; | |
335 | 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); | |
336 | } | |
337 | Float_t matchDist = PadMatchTrack(xpad, ypad, dpx, dpy, coor[0], y, ch); | |
8c0b5e70 | 338 | if(matchDist<fkMaxDistance/2.) padsInCheckArea[cathode]++; |
a690d2f8 | 339 | if(matchDist>minMatchDist[cathode])continue; |
340 | isMatch[cathode] = kTRUE; | |
341 | minMatchDist[cathode] = matchDist; | |
342 | foundDetElemId = currDetElemId; | |
343 | foundZmatch=zpad; | |
344 | yCoorAtPadZ=y; | |
8c0b5e70 | 345 | if(cathode==kBending) trigDigitBendPlane = idigit; |
a690d2f8 | 346 | for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){ |
347 | AliMpIntPair location = pad.GetLocation(loc); | |
348 | nboard[cathode][loc] = location.GetFirst(); | |
349 | } | |
8b1cdc26 | 350 | for(Int_t loc=pad.GetNofLocations(); loc<fgkNlocations; loc++){ |
a690d2f8 | 351 | nboard[cathode][loc]=-1; |
352 | } | |
96079e17 | 353 | |
354 | // Fired pads info | |
355 | Int_t currPair = ix*GetMaxY(cathode) + iy; | |
356 | fPadFired[cathode]->Fill(ch, currSlat, currPair); | |
a690d2f8 | 357 | } |
8c0b5e70 | 358 | |
359 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ | |
360 | if(padsInCheckArea[cath]>2) { | |
361 | if(fDebugLevel>=1) printf("padsInCheckArea[%i] = %i\n",cath,padsInCheckArea[cath]); | |
362 | return -500; | |
363 | } | |
364 | } | |
365 | ||
a690d2f8 | 366 | if(isMatch[kBending] || isMatch[kNonBending]){ |
367 | detElemId = foundDetElemId; | |
368 | zRealMatch[ch] = foundZmatch; | |
369 | coor[1] = yCoorAtPadZ; | |
370 | if(fDebugLevel>2){ | |
371 | Int_t whichCathode=kBending; | |
372 | if(!isMatch[kBending])whichCathode=kNonBending; | |
373 | } | |
374 | } | |
375 | return trigDigitBendPlane; | |
376 | } | |
f165a2d2 | 377 | |
378 | //_____________________________________________________________________________ | |
8c0b5e70 | 379 | Float_t AliMUONTriggerChamberEff::PadMatchTrack(Float_t xPad, Float_t yPad, |
380 | Float_t dpx, Float_t dpy, | |
381 | Float_t xTrackAtPad, Float_t yTrackAtPad, | |
382 | Int_t chamber) | |
f165a2d2 | 383 | { |
2227e936 | 384 | // |
a690d2f8 | 385 | /// Decides if the digit belongs to the trigger track. |
2227e936 | 386 | // |
387 | ||
8c0b5e70 | 388 | Float_t maxDist = 2.;//3. // cm |
389 | Float_t maxDistCheckArea = 6.; // cm | |
a690d2f8 | 390 | |
8c0b5e70 | 391 | Float_t matchDist = fkMaxDistance; |
a690d2f8 | 392 | |
393 | Float_t deltaX = TMath::Abs(xPad-xTrackAtPad)-dpx; | |
394 | Float_t deltaY = TMath::Abs(yPad-yTrackAtPad)-dpy; | |
395 | Float_t maxDistX = maxDist; | |
396 | Float_t maxDistY = maxDist; | |
397 | ||
398 | if(fReproduceTrigResponse){ | |
399 | maxDistX = dpx; | |
400 | maxDistY = dpy; | |
401 | deltaX = TMath::Abs(xPad-xTrackAtPad); | |
402 | deltaY = TMath::Abs(yPad-yTrackAtPad); | |
403 | if(dpx<dpy && chamber>=2) maxDistX = 3.*dpx;// Non-bending plane: check the +- 1 strip between stations | |
404 | if(dpy<dpx && chamber%2) maxDistY = 3.*dpy;// bending plane: check the +- 1 strip between planes in the same station | |
405 | } | |
406 | ||
8c0b5e70 | 407 | if(deltaX<=maxDistX && deltaY<=maxDistY) matchDist = TMath::Max(deltaX, deltaY); |
408 | else if(deltaX<=maxDistCheckArea && deltaY<=maxDistCheckArea) matchDist = fkMaxDistance/5.; | |
a690d2f8 | 409 | return matchDist; |
f165a2d2 | 410 | } |
411 | ||
412 | ||
413 | //_____________________________________________________________________________ | |
414 | void AliMUONTriggerChamberEff::CalculateEfficiency(Int_t trigger44, Int_t trigger34, | |
8c0b5e70 | 415 | Float_t &efficiency, Float_t &error, |
416 | Bool_t failuresAsInput) | |
f165a2d2 | 417 | { |
2227e936 | 418 | // |
419 | /// Returns the efficiency. | |
420 | // | |
421 | ||
f165a2d2 | 422 | efficiency=-9.; |
423 | error=0.; | |
424 | if(trigger34>0){ | |
425 | efficiency=(Double_t)trigger44/((Double_t)trigger34); | |
426 | if(failuresAsInput)efficiency=1.-(Double_t)trigger44/((Double_t)trigger34); | |
427 | } | |
428 | Double_t q = TMath::Abs(1-efficiency); | |
429 | if(efficiency<0)error=0.0; | |
430 | else error = TMath::Sqrt(efficiency*q/((Double_t)trigger34)); | |
431 | } | |
432 | ||
433 | ||
434 | //_____________________________________________________________________________ | |
8c0b5e70 | 435 | Int_t AliMUONTriggerChamberEff::DetElemIdFromPos(Float_t x, Float_t y, |
436 | Int_t chamber, Int_t cathode) | |
f165a2d2 | 437 | { |
2227e936 | 438 | // |
439 | /// Given the (x,y) position in the chamber, | |
440 | /// it returns the corresponding slat | |
441 | // | |
442 | ||
f165a2d2 | 443 | Int_t resultingDetElemId = -1; |
444 | AliMpDEIterator it; | |
a690d2f8 | 445 | Float_t minDist = 999.; |
f165a2d2 | 446 | for ( it.First(chamber-1); ! it.IsDone(); it.Next() ){ |
866c3232 | 447 | Int_t detElemId = it.CurrentDEId(); |
a690d2f8 | 448 | Int_t ich = detElemId/100-10; |
449 | Float_t tolerance=0.2*((Float_t)ich); | |
450 | Float_t currDist=9999.; | |
f165a2d2 | 451 | |
8c0b5e70 | 452 | const AliMpVSegmentation* seg = |
453 | AliMpSegmentation::Instance() | |
454 | ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode)); | |
455 | if (!seg) continue; | |
456 | ||
457 | Float_t deltax = seg->Dimensions().X(); | |
458 | Float_t deltay = seg->Dimensions().Y(); | |
459 | Float_t xlocal1 = -deltax; | |
460 | Float_t ylocal1 = -deltay; | |
461 | Float_t xlocal2 = +deltax; | |
462 | Float_t ylocal2 = +deltay; | |
463 | Float_t xg01, yg01, zg1, xg02, yg02, zg2; | |
464 | fTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg01, yg01, zg1); | |
465 | fTransformer->Local2Global(detElemId, xlocal2, ylocal2, 0, xg02, yg02, zg2); | |
466 | ||
467 | Float_t xg1 = xg01, xg2 = xg02, yg1 = yg01, yg2 = yg02; | |
468 | ||
469 | if(xg01>xg02){ | |
470 | xg1 = xg02; | |
471 | xg2 = xg01; | |
472 | } | |
473 | if(yg01>yg02){ | |
474 | yg1 = yg02; | |
475 | yg2 = yg01; | |
476 | } | |
f165a2d2 | 477 | |
8c0b5e70 | 478 | if(x>=xg1-tolerance && x<=xg2+tolerance && y>=yg1-tolerance && y<=yg2+tolerance){ // takes into account errors in extrapolation |
479 | if(y<yg1) currDist = yg1-y; | |
480 | else if(y>yg2) currDist = y-yg2; | |
481 | if(currDist<minDist) { | |
482 | resultingDetElemId = detElemId; | |
483 | minDist=currDist; | |
484 | continue; | |
f165a2d2 | 485 | } |
8c0b5e70 | 486 | resultingDetElemId = detElemId; |
487 | break; | |
f165a2d2 | 488 | } |
8c0b5e70 | 489 | } // loop on detElemId |
f165a2d2 | 490 | return resultingDetElemId; |
491 | } | |
492 | ||
493 | ||
494 | //_____________________________________________________________________________ | |
8c0b5e70 | 495 | void AliMUONTriggerChamberEff::LocalBoardFromPos(Float_t x, Float_t y, |
496 | Int_t detElemId, Int_t cathode, | |
497 | Int_t localBoard[4]) | |
f165a2d2 | 498 | { |
2227e936 | 499 | // |
500 | /// Given the (x,y) position in the chamber, | |
501 | /// it returns the corresponding local board | |
502 | // | |
503 | ||
8b1cdc26 | 504 | for(Int_t loc=0; loc<fgkNlocations; loc++){ |
f165a2d2 | 505 | localBoard[loc]=-1; |
506 | } | |
f165a2d2 | 507 | Float_t xl, yl, zl; |
8c0b5e70 | 508 | fTransformer->Global2Local(detElemId, x, y, 0, xl, yl, zl); |
f165a2d2 | 509 | TVector2 pos(xl,yl); |
510 | const AliMpVSegmentation* seg = | |
866c3232 | 511 | AliMpSegmentation::Instance() |
512 | ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode)); | |
f165a2d2 | 513 | if (seg){ |
514 | AliMpPad pad = seg->PadByPosition(pos,kFALSE); | |
515 | for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){ | |
516 | AliMpIntPair location = pad.GetLocation(loc); | |
517 | localBoard[loc] = location.GetFirst(); | |
518 | } | |
519 | } | |
520 | } | |
521 | ||
522 | ||
523 | //_____________________________________________________________________________ | |
8c0b5e70 | 524 | void AliMUONTriggerChamberEff::EventChamberEff(const AliMUONVTriggerStore& triggerStore, |
525 | const AliMUONVTriggerTrackStore& trigTrackStore, | |
526 | const AliMUONVTrackStore& trackStore) | |
f165a2d2 | 527 | { |
2227e936 | 528 | // |
529 | /// Main method. | |
530 | /// It loops over the the trigger rec. tracks in the event. | |
531 | /// Then it search for matching digits around the track. | |
532 | /// Finally it calculates the efficiency for each trigger board. | |
533 | /// Files with calculated efficiency are placed in the user defined outputDir. | |
534 | // | |
535 | ||
8c0b5e70 | 536 | if(!fTransformer || ! fDigitMaker) { |
537 | AliError(Form("AliMUONGeometryTransformer or AliMUONDigitMaker not properly initialized!!")); | |
538 | return; | |
539 | } | |
540 | ||
2227e936 | 541 | enum {kBending, kNonBending}; |
f165a2d2 | 542 | Float_t rad2deg = 180./TMath::Pi(); |
543 | ||
a690d2f8 | 544 | Int_t chOrder[fgkNchambers] = {0,2,1,3}; |
f165a2d2 | 545 | |
8b1cdc26 | 546 | TArrayF zRealMatch(fgkNchambers); |
547 | TArrayF correctFactor(fgkNcathodes); | |
f165a2d2 | 548 | |
8b1cdc26 | 549 | Bool_t match[fgkNchambers][fgkNcathodes]; |
550 | Bool_t matchPad[fgkNcathodes]; | |
551 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ | |
552 | matchPad[cath] = kFALSE; | |
553 | } | |
f165a2d2 | 554 | |
8b1cdc26 | 555 | TArrayF zMeanChamber(fgkNchambers); |
f165a2d2 | 556 | for(Int_t ch=0; ch<fgkNchambers; ch++){ |
557 | zMeanChamber[ch] = AliMUONConstants::DefaultChamberZ(10+ch); | |
558 | } | |
559 | ||
8b1cdc26 | 560 | TArrayI digitPerTrack(fgkNcathodes); |
f165a2d2 | 561 | |
8b1cdc26 | 562 | Float_t trackIntersectCh[fgkNchambers][fgkNcathodes]; |
f165a2d2 | 563 | |
8b1cdc26 | 564 | TArrayI triggeredDigits[2]; |
565 | for(Int_t itrack=0; itrack<2; itrack++){ | |
566 | triggeredDigits[itrack].Set(fgkNchambers); | |
567 | triggeredDigits[itrack].Reset(-1); | |
568 | } | |
569 | ||
570 | TArrayI trigScheme[fgkNcathodes]; | |
571 | TArrayI slatThatTriggered[fgkNcathodes]; | |
572 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ | |
573 | trigScheme[cath].Set(fgkNchambers); | |
574 | slatThatTriggered[cath].Set(fgkNchambers); | |
575 | } | |
f165a2d2 | 576 | |
8b1cdc26 | 577 | Int_t boardThatTriggered[fgkNchambers][fgkNcathodes][fgkNlocations]; |
578 | TArrayI nboard[fgkNcathodes]; | |
579 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ | |
580 | nboard[cath].Set(fgkNlocations); | |
581 | } | |
582 | Int_t ineffBoard[fgkNlocations]; | |
583 | for(Int_t loc=0; loc<fgkNlocations; loc++){ | |
584 | ineffBoard[loc] = -1; | |
585 | } | |
f165a2d2 | 586 | |
8c0b5e70 | 587 | AliMUONDigitStoreV1 digitStore; |
588 | TriggerDigits(triggerStore,digitStore); | |
f165a2d2 | 589 | |
8c0b5e70 | 590 | AliMUONTriggerTrack *recTrigTrack = 0x0; |
a690d2f8 | 591 | |
8c0b5e70 | 592 | TIter next(trigTrackStore.CreateIterator()); |
593 | ||
594 | while ( ( recTrigTrack = static_cast<AliMUONTriggerTrack*>(next()) ) ) | |
595 | { | |
8b1cdc26 | 596 | if(!IsCleanTrack(recTrigTrack, trackStore)) { |
597 | if(fDebugLevel>=1) printf("\tTrack %p (%f, %f) don't match tracker track: rejected!\n",(void *)recTrigTrack,recTrigTrack->GetX11(),recTrigTrack->GetY11()); | |
598 | continue; | |
8c0b5e70 | 599 | } |
8b1cdc26 | 600 | |
601 | digitPerTrack.Reset(); | |
f165a2d2 | 602 | for(Int_t ch=0; ch<fgkNchambers; ch++){ |
8b1cdc26 | 603 | zRealMatch[ch] = zMeanChamber[ch]; |
f165a2d2 | 604 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ |
8c0b5e70 | 605 | match[ch][cath]=kFALSE; |
8b1cdc26 | 606 | //slatThatTriggered[ch][cath]=-1; |
607 | //trigScheme[ch][cath] = 0; | |
608 | for(Int_t loc=0; loc<fgkNlocations; loc++){ | |
8c0b5e70 | 609 | boardThatTriggered[ch][cath][loc]=-1; |
610 | } | |
f165a2d2 | 611 | } |
612 | } | |
613 | ||
8b1cdc26 | 614 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ |
615 | slatThatTriggered[cath].Reset(-1); | |
616 | trigScheme[cath].Reset(); | |
617 | } | |
618 | ||
8c0b5e70 | 619 | Bool_t isClearEvent = kTRUE; |
620 | Bool_t doubleCountTrack = kFALSE; | |
a690d2f8 | 621 | |
8c0b5e70 | 622 | Float_t x11 = recTrigTrack->GetX11();// x position (info from non-bending plane) |
623 | Float_t y11 = recTrigTrack->GetY11();// y position (info from bending plane) | |
624 | Float_t thetaX = recTrigTrack->GetThetax(); | |
625 | Float_t thetaY = recTrigTrack->GetThetay(); | |
f165a2d2 | 626 | |
8b1cdc26 | 627 | 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 | 628 | |
8c0b5e70 | 629 | for(Int_t ch=0; ch<fgkNchambers; ch++) { // chamber loop |
630 | Int_t currCh = chOrder[ch]; | |
631 | if(fDebugLevel>=2) | |
632 | printf("zMeanChamber[%i] = %.2f\tzRealMatch[0] = %.2f\n",currCh,zMeanChamber[currCh],zRealMatch[0]); | |
f165a2d2 | 633 | |
8c0b5e70 | 634 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ |
635 | correctFactor[cath]=1.; | |
636 | } | |
637 | // calculate corrections to trigger track theta | |
638 | if(ch>=1)correctFactor[kNonBending] = zMeanChamber[0]/zRealMatch[0];// corrects x position | |
639 | if(ch>=2)correctFactor[kBending] = (zMeanChamber[2] - zMeanChamber[0]) / (zRealMatch[2] - zRealMatch[0]);// corrects y position | |
640 | ||
641 | // searching track intersection with chambers (first approximation) | |
642 | Float_t deltaZ = zMeanChamber[currCh] - zMeanChamber[0]; | |
643 | trackIntersectCh[currCh][0] = zMeanChamber[currCh] * TMath::Tan(thetaX) * correctFactor[kNonBending];// x position (info from non-bending plane) | |
644 | trackIntersectCh[currCh][1] = y11 + deltaZ * TMath::Tan(thetaY) * correctFactor[kBending];// y position (info from bending plane) | |
645 | Int_t detElemIdFromTrack = DetElemIdFromPos(trackIntersectCh[currCh][0], trackIntersectCh[currCh][1], 11+currCh, 0); | |
646 | if(detElemIdFromTrack<0) { | |
647 | if(fDebugLevel>1) printf("Warning: trigger track outside trigger chamber\n"); | |
648 | continue; | |
f165a2d2 | 649 | } |
a690d2f8 | 650 | |
8c0b5e70 | 651 | triggeredDigits[1][currCh] = MatchingPad(digitStore, detElemIdFromTrack, trackIntersectCh[currCh], matchPad, nboard, zRealMatch, y11); |
652 | ||
653 | // if MatchingPad = -500 => too many digits matching pad => | |
654 | // => Event not clear => Reject track | |
655 | if(triggeredDigits[1][currCh]<-100){ | |
656 | isClearEvent = kFALSE; | |
8b1cdc26 | 657 | if(fDebugLevel>=1) printf("Warning: track = %p (%i) matches many pads. Rejected!\n",(void *)recTrigTrack, detElemIdFromTrack); |
8c0b5e70 | 658 | break; |
659 | } | |
f165a2d2 | 660 | |
8c0b5e70 | 661 | // deciding if digit matches track |
662 | Bool_t isDiffLocBoard = kFALSE; | |
663 | if(fReproduceTrigResponse && ch>2){ | |
a690d2f8 | 664 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ |
8c0b5e70 | 665 | if(boardThatTriggered[currCh][cath][0]>=0){ |
666 | if(boardThatTriggered[currCh][cath][0]!=boardThatTriggered[currCh-1][cath][0]) isDiffLocBoard = kTRUE; | |
a690d2f8 | 667 | } |
668 | } | |
8c0b5e70 | 669 | } |
670 | ||
671 | if(isDiffLocBoard && fDebugLevel>=1)printf("\tDifferent local board\n"); | |
f165a2d2 | 672 | |
673 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ | |
8c0b5e70 | 674 | match[currCh][cath] = (matchPad[cath] && !isDiffLocBoard); |
675 | if(!match[currCh][cath]) continue; | |
676 | digitPerTrack[cath]++; | |
8b1cdc26 | 677 | trigScheme[cath][currCh]++; |
678 | slatThatTriggered[cath][currCh] = detElemIdFromTrack; | |
679 | for(Int_t loc=0; loc<fgkNlocations; loc++){ | |
8c0b5e70 | 680 | boardThatTriggered[currCh][cath][loc] = nboard[cath][loc]; |
681 | } | |
f165a2d2 | 682 | } |
8c0b5e70 | 683 | } // end chamber loop |
f165a2d2 | 684 | |
8c0b5e70 | 685 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ |
686 | if(digitPerTrack[cath]<3)isClearEvent = kFALSE; | |
687 | if(fDebugLevel>=1 && !isClearEvent)printf("Warning: found %i digits for trigger track cathode %i.\nRejecting event\n", digitPerTrack[cath],cath); | |
688 | } | |
f165a2d2 | 689 | |
8c0b5e70 | 690 | if(!isClearEvent && !fReproduceTrigResponse) continue; |
f165a2d2 | 691 | |
8c0b5e70 | 692 | Int_t commonDigits = 0; |
693 | for(Int_t ch=0; ch<fgkNchambers; ch++){ | |
694 | if(triggeredDigits[1][ch]==triggeredDigits[0][ch]) commonDigits++; // Compare with previous track | |
695 | triggeredDigits[0][ch] = triggeredDigits[1][ch]; // Store this track parameters for comparison with next one | |
696 | } | |
697 | if(commonDigits>=2){ | |
698 | doubleCountTrack=kTRUE; | |
699 | } | |
a690d2f8 | 700 | |
8c0b5e70 | 701 | if(!doubleCountTrack || fReproduceTrigResponse){ |
702 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ | |
703 | Int_t is44 = 1; | |
704 | Bool_t goodForSlatEff = kTRUE; | |
705 | Bool_t goodForBoardEff = kTRUE; | |
706 | Int_t ineffSlat = -1; | |
707 | Int_t ineffDetElId = -1; | |
8b1cdc26 | 708 | Int_t firstSlat = slatThatTriggered[cath][0]%100; |
709 | if(firstSlat<0) firstSlat=slatThatTriggered[cath][1]%100; | |
8c0b5e70 | 710 | Int_t firstBoard = boardThatTriggered[0][kBending][0]; |
711 | if(firstBoard<0) firstBoard=boardThatTriggered[1][kBending][0]; | |
712 | for(Int_t ch=0; ch<fgkNchambers; ch++){ | |
713 | Bool_t isCurrChIneff = kFALSE; | |
8b1cdc26 | 714 | is44 *= trigScheme[cath][ch]; |
715 | Int_t currSlat = slatThatTriggered[cath][ch]%100; | |
8c0b5e70 | 716 | if(currSlat<0){ |
717 | ineffDetElId = DetElemIdFromPos(trackIntersectCh[ch][0], trackIntersectCh[ch][1], 11+ch, cath); | |
718 | currSlat = ineffDetElId%100; | |
719 | ineffSlat = currSlat; | |
720 | isCurrChIneff = kTRUE; | |
721 | } | |
722 | if(currSlat!=firstSlat)goodForSlatEff=kFALSE; | |
723 | Bool_t atLeastOneLoc=kFALSE; | |
724 | if(isCurrChIneff) LocalBoardFromPos(trackIntersectCh[ch][0], trackIntersectCh[ch][1], ineffDetElId, cath, ineffBoard); | |
8b1cdc26 | 725 | for(Int_t loc=0; loc<fgkNlocations; loc++){ |
8c0b5e70 | 726 | Int_t currBoard = boardThatTriggered[ch][cath][loc]; |
727 | if(isCurrChIneff) currBoard = ineffBoard[loc]; | |
728 | if(currBoard==firstBoard){ | |
729 | atLeastOneLoc=kTRUE; | |
730 | break; | |
f165a2d2 | 731 | } |
f165a2d2 | 732 | } |
8c0b5e70 | 733 | if(!atLeastOneLoc)goodForBoardEff=kFALSE; |
734 | } // end chamber loop | |
735 | ||
736 | // Trigger 4/4 | |
737 | if(is44==1){ | |
738 | fTrigger44[cath]++; | |
739 | if(fDebugLevel>=1)printf("Trigger44[%i] = %i\n",cath,fTrigger44[cath]); | |
740 | if(goodForSlatEff){ | |
741 | for(Int_t ch=0; ch<fgkNchambers; ch++){ | |
8b1cdc26 | 742 | Int_t chCath = fgkNchambers*cath + ch; |
743 | fHitPerSlat[chCath][firstSlat]++; | |
744 | if(fDebugLevel>=1)printf("Slat that triggered = %i\n",slatThatTriggered[cath][ch]); | |
a690d2f8 | 745 | if(goodForBoardEff && firstBoard>0){ |
8b1cdc26 | 746 | fHitPerBoard[chCath][firstBoard-1]++; |
8c0b5e70 | 747 | if(fDebugLevel>=1)printf("Board that triggered = %i\n",firstBoard); |
f165a2d2 | 748 | } |
8b1cdc26 | 749 | else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different boards: rejected!\n",(void *)recTrigTrack); |
f165a2d2 | 750 | } |
751 | } | |
8b1cdc26 | 752 | else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different slats: rejected!\n",(void *)recTrigTrack); |
8c0b5e70 | 753 | } |
a690d2f8 | 754 | |
8c0b5e70 | 755 | // Trigger 3/4 |
756 | if(ineffDetElId>0){ | |
757 | Int_t ineffCh = ineffDetElId/100-11; | |
8b1cdc26 | 758 | Int_t chCath = fgkNchambers*cath + ineffCh; |
759 | fTrigger34[chCath]++; | |
760 | if(fDebugLevel>=1) printf("Trigger34[%i] = %i\n",chCath,fTrigger34[chCath]); | |
8c0b5e70 | 761 | if(goodForSlatEff){ |
762 | if(fDebugLevel>=1) printf("Slat non efficient = %i\n",ineffDetElId); | |
8b1cdc26 | 763 | fInefficientSlat[chCath][ineffSlat]++; |
8c0b5e70 | 764 | |
765 | if(goodForBoardEff && firstBoard>0){ | |
766 | if(fDebugLevel>=1) printf("Board non efficient = %i\n",firstBoard); | |
8b1cdc26 | 767 | fInefficientBoard[chCath][firstBoard-1]++; |
8c0b5e70 | 768 | } |
8b1cdc26 | 769 | else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different boards: rejected!\n",(void *)recTrigTrack); |
8c0b5e70 | 770 | } |
8b1cdc26 | 771 | else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different slats: rejected!\n",(void *)recTrigTrack); |
8c0b5e70 | 772 | } |
773 | } // end loop on cathodes | |
f165a2d2 | 774 | } |
8c0b5e70 | 775 | else if(doubleCountTrack){ |
776 | if(fDebugLevel>=1) | |
8b1cdc26 | 777 | printf("\n\tTrack = %p: \nDouble Count Track: Track rejected!\n",(void *)recTrigTrack); |
f165a2d2 | 778 | } |
8c0b5e70 | 779 | } // end trigger tracks loop |
f165a2d2 | 780 | |
8c0b5e70 | 781 | if(fPrintInfo) InfoDigit(digitStore); |
f165a2d2 | 782 | } |
783 | ||
784 | //_____________________________________________________________________________ | |
311d0691 | 785 | void AliMUONTriggerChamberEff::GetEfficiencyHistos(TList &countList, TList &noCountList) |
f165a2d2 | 786 | { |
311d0691 | 787 | // |
788 | /// Gets lists of histograms containing number of 4/4 and 3/4 | |
789 | /// for further efficiency calculations. | |
790 | // | |
791 | ||
792 | char *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"}; | |
793 | ||
794 | char *yAxisTitle = "counts"; | |
795 | ||
796 | const Int_t kNumOfBoards = AliMpConstants::NofLocalBoards(); | |
797 | ||
798 | enum {kAllChEff, kChNonEff, kNumOfHistoTypes}; | |
799 | char *histoTypeName[kNumOfHistoTypes] = {"CountInCh", "NonCountInCh"}; | |
800 | char *histoTypeTitle[kNumOfHistoTypes] = {"counted", "non counted"}; | |
801 | TH1F *histoCheckChamber[fgkNcathodes][kNumOfHistoTypes]; | |
802 | TH1F *histoCheckSlat[fgkNplanes][kNumOfHistoTypes]; | |
803 | TH1F *histoCheckBoard[fgkNplanes][kNumOfHistoTypes]; | |
804 | ||
805 | char histoName[40]; | |
806 | char histoTitle[90]; | |
807 | ||
808 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ | |
809 | for(Int_t hType=0; hType<kNumOfHistoTypes; hType++){ | |
810 | sprintf(histoName, "%sChamber%s", cathCode[cath], histoTypeName[hType]); | |
811 | sprintf(histoTitle, "%s %s", histoTypeTitle[hType], cathCode[cath]); | |
812 | histoCheckChamber[cath][hType] = new TH1F(histoName, histoTitle, fgkNchambers, 11-0.5, 11+fgkNchambers-0.5); | |
813 | histoCheckChamber[cath][hType]->SetXTitle("chamber"); | |
814 | histoCheckChamber[cath][hType]->SetYTitle(yAxisTitle); | |
815 | histoCheckChamber[cath][hType]->GetXaxis()->SetNdivisions(fgkNchambers); | |
f165a2d2 | 816 | } |
311d0691 | 817 | |
818 | for(Int_t ch=0; ch<fgkNchambers; ch++){ | |
819 | Int_t chCath = fgkNchambers*cath + ch; | |
820 | for(Int_t hType=0; hType<kNumOfHistoTypes; hType++){ | |
821 | sprintf(histoName, "%sSlat%s%i", cathCode[cath], histoTypeName[hType], 11+ch); | |
822 | sprintf(histoTitle, "Chamber %i: slat %s %s", 11+ch, histoTypeTitle[hType], cathCode[cath]); | |
823 | histoCheckSlat[chCath][hType] = new TH1F(histoName, histoTitle, fgkNslats, 0-0.5, fgkNslats-0.5); | |
824 | histoCheckSlat[chCath][hType]->SetXTitle("slat"); | |
825 | histoCheckSlat[chCath][hType]->SetYTitle(yAxisTitle); | |
826 | histoCheckSlat[chCath][hType]->GetXaxis()->SetNdivisions(fgkNslats); | |
827 | ||
828 | sprintf(histoName, "%sBoard%s%i", cathCode[cath], histoTypeName[hType], 11+ch); | |
829 | sprintf(histoTitle, "Chamber %i: board %s %s", 11+ch, histoTypeTitle[hType], cathCode[cath]); | |
830 | histoCheckBoard[chCath][hType] = new TH1F(histoName, histoTitle, kNumOfBoards, 1-0.5, kNumOfBoards+1.-0.5); | |
831 | histoCheckBoard[chCath][hType]->SetXTitle("boards"); | |
832 | histoCheckBoard[chCath][hType]->SetYTitle(yAxisTitle); | |
833 | histoCheckBoard[chCath][hType]->GetXaxis()->SetNdivisions(kNumOfBoards); | |
834 | } | |
f165a2d2 | 835 | } |
311d0691 | 836 | } |
f165a2d2 | 837 | |
311d0691 | 838 | Int_t bin; |
f165a2d2 | 839 | |
311d0691 | 840 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ |
841 | for(Int_t ch=0; ch<fgkNchambers; ch++){ | |
842 | Int_t chCath = fgkNchambers*cath + ch; | |
843 | for(Int_t slat=0; slat<fgkNslats; slat++){ | |
844 | bin = histoCheckSlat[chCath][kAllChEff]->FindBin(slat); | |
845 | histoCheckSlat[chCath][kAllChEff]->SetBinContent(bin, fHitPerSlat[chCath][slat]); | |
846 | histoCheckSlat[chCath][kChNonEff]->SetBinContent(bin, fInefficientSlat[chCath][slat]); | |
847 | } | |
848 | bin = histoCheckChamber[cath][kAllChEff]->FindBin(11+ch); | |
849 | histoCheckChamber[cath][kAllChEff]->SetBinContent(bin, fTrigger44[cath]); | |
850 | histoCheckChamber[cath][kChNonEff]->SetBinContent(bin, fTrigger34[chCath]); | |
851 | ||
852 | for(Int_t board=0; board<kNumOfBoards; board++){ | |
853 | bin = histoCheckBoard[chCath][kAllChEff]->FindBin(board+1); | |
854 | histoCheckBoard[chCath][kAllChEff]->SetBinContent(bin, fHitPerBoard[chCath][board]); | |
855 | histoCheckBoard[chCath][kChNonEff]->SetBinContent(bin, fInefficientBoard[chCath][board]); | |
856 | } | |
857 | } | |
858 | } | |
f165a2d2 | 859 | |
311d0691 | 860 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ |
861 | countList.Add(histoCheckChamber[cath][kAllChEff]); | |
862 | noCountList.Add(histoCheckChamber[cath][kChNonEff]); | |
863 | } | |
f165a2d2 | 864 | |
311d0691 | 865 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ |
866 | for(Int_t ch=0; ch<fgkNchambers; ch++){ | |
867 | Int_t chCath = fgkNchambers*cath + ch; | |
868 | countList.Add(histoCheckSlat[chCath][kAllChEff]); | |
869 | noCountList.Add(histoCheckSlat[chCath][kChNonEff]); | |
870 | } | |
871 | } | |
f165a2d2 | 872 | |
311d0691 | 873 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ |
f165a2d2 | 874 | for(Int_t ch=0; ch<fgkNchambers; ch++){ |
311d0691 | 875 | Int_t chCath = fgkNchambers*cath + ch; |
876 | countList.Add(histoCheckBoard[chCath][kAllChEff]); | |
877 | noCountList.Add(histoCheckBoard[chCath][kChNonEff]); | |
878 | } | |
879 | } | |
f165a2d2 | 880 | } |
881 | ||
8c0b5e70 | 882 | |
883 | //_____________________________________________________________________________ | |
884 | Bool_t AliMUONTriggerChamberEff::IsCleanTrack(AliMUONTriggerTrack *triggerTrack, | |
885 | const AliMUONVTrackStore& trackStore) | |
886 | { | |
887 | // | |
888 | /// Try to match track from tracking system with trigger track | |
889 | // | |
890 | const Double_t kDistSigma[3]={1,1,0.02}; // sigma of distributions (trigger-track) X,Y,slopeY | |
891 | const Double_t kMaxChi2MatchTrigger = 16.0; | |
892 | ||
893 | AliMUONTrackParam trackParam; | |
894 | ||
895 | Double_t distTriggerTrack[3]; | |
896 | Double_t xTrack, yTrack, ySlopeTrack, chi2; | |
897 | ||
898 | AliMUONTrack* track; | |
899 | TIter next(trackStore.CreateIterator()); | |
900 | ||
901 | while ( ( track = static_cast<AliMUONTrack*>(next()) ) ) | |
902 | { | |
96ebe67e | 903 | trackParam = *((AliMUONTrackParam*) (track->GetTrackParamAtCluster()->Last())); |
8c0b5e70 | 904 | AliMUONTrackExtrap::ExtrapToZ(&trackParam, AliMUONConstants::DefaultChamberZ(10)); // extrap to 1st trigger chamber |
905 | ||
906 | xTrack = trackParam.GetNonBendingCoor(); | |
907 | yTrack = trackParam.GetBendingCoor(); | |
908 | ySlopeTrack = trackParam.GetBendingSlope(); | |
909 | ||
910 | distTriggerTrack[0] = (triggerTrack->GetX11()-xTrack)/kDistSigma[0]; | |
911 | distTriggerTrack[1] = (triggerTrack->GetY11()-yTrack)/kDistSigma[1]; | |
912 | distTriggerTrack[2] = (TMath::Tan(triggerTrack->GetThetay())-ySlopeTrack)/kDistSigma[2]; | |
913 | chi2 = 0.; | |
914 | for (Int_t iVar = 0; iVar < 3; iVar++) chi2 += distTriggerTrack[iVar]*distTriggerTrack[iVar]; | |
915 | chi2 /= 3.; // Normalized Chi2: 3 degrees of freedom (X,Y,slopeY) | |
916 | if (chi2 < kMaxChi2MatchTrigger) return kTRUE; | |
917 | } | |
918 | ||
919 | return kFALSE; | |
920 | } | |
921 | ||
922 | ||
923 | //_____________________________________________________________________________ | |
924 | void AliMUONTriggerChamberEff::SaveInESDFile() | |
925 | { | |
311d0691 | 926 | // |
927 | /// Store AliMUONTriggerChamberEff in esd file | |
928 | // | |
96079e17 | 929 | TList countHistoList, noCountHistoList, firedPads; |
930 | for(Int_t cath=0; cath<fgkNcathodes; cath++){ | |
931 | firedPads.Add(fPadFired[cath]->Clone()); | |
932 | } | |
933 | TFile *prova = new TFile("prova.root", "recreate"); | |
934 | prova->cd(); | |
935 | firedPads.Write(); | |
936 | prova->Close(); | |
937 | ||
311d0691 | 938 | GetEfficiencyHistos(countHistoList, noCountHistoList); |
939 | AliMUONTriggerEfficiencyCells *effMap = | |
940 | new AliMUONTriggerEfficiencyCells(&countHistoList, &noCountHistoList); | |
96079e17 | 941 | effMap->SetFiredStrips(&firedPads); |
311d0691 | 942 | |
943 | TDirectory *dir = gDirectory; | |
944 | ||
945 | TFile *logFile = 0x0; | |
96079e17 | 946 | Bool_t reopenFile = kFALSE; |
311d0691 | 947 | Char_t *esdFileName = "AliESDs.root"; |
96079e17 | 948 | |
311d0691 | 949 | TSeqCollection *list = gROOT->GetListOfFiles(); |
311d0691 | 950 | Int_t n = list->GetEntries(); |
951 | for(Int_t i=0; i<n; i++) { | |
952 | logFile = (TFile*)list->At(i); | |
953 | if (strstr(logFile->GetName(), esdFileName)) break; | |
954 | logFile = 0x0; | |
955 | } | |
96079e17 | 956 | |
311d0691 | 957 | if(!logFile) { |
958 | AliWarning(Form("%s already stored on disk. Re-opening in update mode.",esdFileName)); | |
959 | logFile = new TFile(esdFileName, "update"); | |
960 | reopenFile = kTRUE; | |
961 | } | |
8b1cdc26 | 962 | |
311d0691 | 963 | if(logFile){ |
96079e17 | 964 | logFile->cd(); |
965 | TTree *esdTree = (TTree*)logFile->Get("esdTree;1"); | |
311d0691 | 966 | if(esdTree){ |
967 | if(!esdTree->GetUserInfo()->FindObject("AliMUONTriggerEfficiencyCells")){ | |
968 | AliInfo(Form("Adding AliMUONTriggerEfficiencyCells in %s",esdTree->GetName())); | |
969 | esdTree->GetUserInfo()->Add(effMap); | |
96079e17 | 970 | esdTree->Write(esdTree->GetName(),TObject::kOverwrite); |
8b1cdc26 | 971 | } |
972 | } | |
311d0691 | 973 | if(reopenFile){ |
974 | logFile->Close(); | |
8b1cdc26 | 975 | } |
311d0691 | 976 | } |
977 | dir->cd(); | |
8b1cdc26 | 978 | } |
979 | ||
311d0691 | 980 | |
8b1cdc26 | 981 | //_____________________________________________________________________________ |
982 | void AliMUONTriggerChamberEff::CheckConstants() const | |
983 | { | |
984 | /// Check consistence of redefined constants | |
985 | ||
986 | assert(fgkNcathodes == AliMpConstants::NofCathodes()); | |
987 | assert(fgkNchambers == AliMpConstants::NofTriggerChambers()); | |
988 | assert(fgkNplanes == AliMpConstants::NofTriggerChambers() * fgkNcathodes); | |
989 | } |