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