]>
Commit | Line | Data |
---|---|---|
115179c6 | 1 | |
2 | ||
3 | ||
4 | ||
5 | ||
6 | ||
7 | ||
8 | ||
9 | ||
10 | ||
11 | ||
12 | ||
13 | ||
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ||
20 | ||
21 | ||
22 | ||
23 | ||
24 | ||
25 | ||
26 | ||
27 | ||
28 | ||
29 | ||
30 | ||
31 | ||
32 | ||
33 | ||
34 | ||
35 | ||
36 | ||
37 | ||
38 | ||
39 | ||
40 | ||
41 | ||
42 | ||
43 | /************************************************************************** | |
44 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
45 | * * | |
46 | * Author: The ALICE Off-line Project. * | |
47 | * Contributors are mentioned in the code where appropriate. * | |
48 | * * | |
49 | * Permission to use, copy, modify and distribute this software and its * | |
50 | * documentation strictly for non-commercial purposes is hereby granted * | |
51 | * without fee, provided that the above copyright notice appears in all * | |
52 | * copies and that both the copyright notice and this permission notice * | |
53 | * appear in the supporting documentation. The authors make no claims * | |
54 | * about the suitability of this software for any purpose. It is * | |
55 | * provided "as is" without express or implied warranty. * | |
56 | **************************************************************************/ | |
57 | ||
58 | //--------------------------------------------------------------------// | |
59 | // // | |
60 | // AliTOFtrackerV2 Class // | |
61 | // Task: Perform association of the ESD tracks to TOF Clusters // | |
62 | // and Update ESD track with associated TOF Cluster parameters // | |
63 | // // | |
64 | // -- Authors : S. Arcelli, C. Zampolli (Bologna University and INFN) // | |
65 | // -- Contacts: Annalisa.De.Caro@cern.ch // | |
66 | // -- : Chiara.Zampolli@bo.infn.it // | |
67 | // -- : Silvia.Arcelli@bo.infn.it // | |
68 | // // | |
69 | //--------------------------------------------------------------------// | |
70 | ||
71 | #include <Rtypes.h> | |
72 | #include <TROOT.h> | |
73 | ||
74 | #include <TClonesArray.h> | |
75 | #include <TObjArray.h> | |
76 | #include <TGeoManager.h> | |
77 | #include <TTree.h> | |
78 | ||
79 | #include "AliGeomManager.h" | |
80 | #include "AliESDtrack.h" | |
81 | #include "AliESDEvent.h" | |
82 | #include "AliESDpid.h" | |
83 | #include "AliESDTOFcluster.h" | |
84 | #include "AliLog.h" | |
85 | #include "AliTrackPointArray.h" | |
86 | #include "AliCDBManager.h" | |
87 | ||
88 | #include "AliTOFRecoParam.h" | |
89 | #include "AliTOFReconstructor.h" | |
90 | #include "AliTOFcluster.h" | |
91 | #include "AliTOFGeometry.h" | |
92 | #include "AliTOFtrackerV2.h" | |
93 | #include "AliTOFtrack.h" | |
94 | ||
95 | extern TGeoManager *gGeoManager; | |
96 | ||
97 | ClassImp(AliTOFtrackerV2) | |
98 | ||
99 | //_____________________________________________________________________________ | |
100 | AliTOFtrackerV2::AliTOFtrackerV2(): | |
101 | fkRecoParam(0x0), | |
102 | fGeom(0x0), | |
103 | fN(0), | |
104 | fNseeds(0), | |
105 | fNseedsTOF(0), | |
106 | fnunmatch(0), | |
107 | fnmatch(0), | |
108 | fTracks(new TClonesArray("AliTOFtrack")), | |
109 | fSeeds(new TObjArray(100)), | |
110 | fClusters(0x0) | |
111 | { | |
112 | //AliTOFtrackerV2 main Ctor | |
113 | ||
114 | // Getting the geometry | |
115 | fGeom = new AliTOFGeometry(); | |
116 | ||
117 | } | |
118 | //_____________________________________________________________________________ | |
119 | AliTOFtrackerV2::~AliTOFtrackerV2() { | |
120 | // | |
121 | // Dtor | |
122 | // | |
123 | ||
124 | if(!(AliCDBManager::Instance()->GetCacheFlag())){ | |
125 | delete fkRecoParam; | |
126 | } | |
127 | delete fGeom; | |
128 | if (fTracks){ | |
129 | fTracks->Delete(); | |
130 | delete fTracks; | |
131 | fTracks=0x0; | |
132 | } | |
133 | if (fSeeds){ | |
134 | fSeeds->Delete(); | |
135 | delete fSeeds; | |
136 | fSeeds=0x0; | |
137 | } | |
138 | ||
139 | if(fClusters){ | |
140 | delete[] fClusters; | |
141 | fClusters = NULL; | |
142 | } | |
143 | ||
144 | } | |
145 | //_____________________________________________________________________________ | |
146 | void AliTOFtrackerV2::GetPidSettings(AliESDpid *esdPID) { | |
147 | // | |
148 | // Sets TOF resolution from RecoParams | |
149 | // | |
150 | if (fkRecoParam) | |
151 | esdPID->GetTOFResponse().SetTimeResolution(fkRecoParam->GetTimeResolution()); | |
152 | else | |
153 | AliWarning("fkRecoParam not yet set; cannot set PID settings"); | |
154 | } | |
155 | //_____________________________________________________________________________ | |
156 | Int_t AliTOFtrackerV2::PropagateBack(AliESDEvent * const event) { | |
157 | // | |
158 | // Gets seeds from ESD event and Match with TOF Clusters | |
159 | // | |
160 | ||
161 | //Update the matched ESD tracks | |
162 | // needed in case of call of TOF info before of the selection of matching and in case of no clusters available at all | |
163 | if(fN==0) | |
164 | event->SetTOFcluster(1,fClusters); | |
165 | else | |
166 | event->SetTOFcluster(fN,fClusters); | |
167 | ||
168 | if (fN==0) { | |
169 | AliInfo("No TOF recPoints to be matched with reconstructed tracks"); | |
170 | return 0; | |
171 | } | |
172 | ||
173 | // initialize RecoParam for current event | |
174 | AliDebug(1,"Initializing params for TOF"); | |
175 | ||
176 | fkRecoParam = AliTOFReconstructor::GetRecoParam(); // instantiate reco param from STEER... | |
177 | ||
178 | if (fkRecoParam == 0x0) { | |
179 | AliFatal("No Reco Param found for TOF!!!"); | |
180 | } | |
181 | ||
182 | //Initialise some counters | |
183 | ||
184 | fNseeds=0; | |
185 | fNseedsTOF=0; | |
186 | fnunmatch=0; | |
187 | fnmatch=0; | |
188 | ||
189 | Int_t ntrk=event->GetNumberOfTracks(); | |
190 | fNseeds = ntrk; | |
191 | ||
192 | //Load ESD tracks into a local Array of ESD Seeds | |
193 | for (Int_t i=0; i<fNseeds; i++) | |
194 | fSeeds->AddLast(event->GetTrack(i)); | |
195 | ||
196 | //Prepare ESD tracks candidates for TOF Matching | |
197 | CollectESD(); | |
198 | ||
199 | if (fNseeds==0 || fNseedsTOF==0) { | |
200 | AliInfo("No seeds to try TOF match"); | |
201 | return 0; | |
202 | } | |
203 | ||
204 | // clusterize before of matching | |
205 | Clusterize(); | |
206 | ||
207 | //Second Step with Looser Matching Criterion | |
208 | MatchTracks(); | |
209 | ||
210 | AliInfo(Form("Number of matched tracks = %d",fnmatch)); | |
211 | ||
212 | for (Int_t i=0; i<ntrk; i++) { | |
213 | AliESDtrack *t=event->GetTrack(i); | |
214 | //t->SetESDEvent(event); | |
215 | AliESDtrack *seed =(AliESDtrack*)fSeeds->At(i); | |
216 | ||
217 | if ( (seed->GetStatus()&AliESDtrack::kTOFin)!=0 ) { | |
218 | t->SetStatus(AliESDtrack::kTOFin); | |
219 | if ( (seed->GetStatus()&AliESDtrack::kTOFout)!=0 ) { | |
220 | t->SetStatus(AliESDtrack::kTOFout); | |
221 | //t->SetTOFclusterArray(seed->GetNTOFclusters(),seed->GetTOFclusterArray()); | |
222 | t->SortTOFcluster(); | |
223 | ||
224 | // Make attention, please: | |
225 | // AliESDtrack::fTOFInfo array does not be stored in the AliESDs.root file | |
226 | // it is there only for a check during the reconstruction step. | |
227 | Float_t info[10]; seed->GetTOFInfo(info); | |
228 | t->SetTOFInfo(info); | |
229 | AliDebug(3,Form(" distance=%f; residual in the pad reference frame: dX=%f, dZ=%f", info[0],info[1],info[2])); | |
230 | ||
231 | /* | |
232 | Double_t alphaA = (Double_t)t->GetAlpha(); | |
233 | Double_t xA = (Double_t)t->GetX(); | |
234 | Double_t yA = (Double_t)t->GetY(); | |
235 | Double_t zA = (Double_t)t->GetZ(); | |
236 | Double_t p1A = (Double_t)t->GetSnp(); | |
237 | Double_t p2A = (Double_t)t->GetTgl(); | |
238 | Double_t p3A = (Double_t)t->GetSigned1Pt(); | |
239 | const Double_t *covA = (Double_t*)t->GetCovariance(); | |
240 | ||
241 | // Check done: | |
242 | // by calling the AliESDtrack::UpdateTrackParams, | |
243 | // the current track parameters are changed | |
244 | // and it could cause refit problems. | |
245 | // We need to update only the following track parameters: | |
246 | // the track length and expected times. | |
247 | // Removed AliESDtrack::UpdateTrackParams call | |
248 | // Called AliESDtrack::SetIntegratedTimes(...) and | |
249 | // AliESDtrack::SetIntegratedLength() routines. | |
250 | ||
251 | AliTOFtrack *track = new AliTOFtrack(*seed); | |
252 | t->UpdateTrackParams(track,AliESDtrack::kTOFout); // to be checked - AdC | |
253 | delete track; | |
254 | Double_t time[AliPID::kSPECIESC]; t->GetIntegratedTimes(time); | |
255 | Double_t alphaB = (Double_t)t->GetAlpha(); | |
256 | Double_t xB = (Double_t)t->GetX(); | |
257 | Double_t yB = (Double_t)t->GetY(); | |
258 | Double_t zB = (Double_t)t->GetZ(); | |
259 | Double_t p1B = (Double_t)t->GetSnp(); | |
260 | Double_t p2B = (Double_t)t->GetTgl(); | |
261 | Double_t p3B = (Double_t)t->GetSigned1Pt(); | |
262 | const Double_t *covB = (Double_t*)t->GetCovariance(); | |
263 | AliDebug(2,"Track params -now(before)-:"); | |
264 | AliDebug(2,Form(" X: %f(%f), Y: %f(%f), Z: %f(%f) --- alpha: %f(%f)", | |
265 | xB,xA, | |
266 | yB,yA, | |
267 | zB,zA, | |
268 | alphaB,alphaA)); | |
269 | AliDebug(2,Form(" p1: %f(%f), p2: %f(%f), p3: %f(%f)", | |
270 | p1B,p1A, | |
271 | p2B,p2A, | |
272 | p3B,p3A)); | |
273 | AliDebug(2,Form(" cov1: %f(%f), cov2: %f(%f), cov3: %f(%f)" | |
274 | " cov4: %f(%f), cov5: %f(%f), cov6: %f(%f)" | |
275 | " cov7: %f(%f), cov8: %f(%f), cov9: %f(%f)" | |
276 | " cov10: %f(%f), cov11: %f(%f), cov12: %f(%f)" | |
277 | " cov13: %f(%f), cov14: %f(%f), cov15: %f(%f)", | |
278 | covB[0],covA[0], | |
279 | covB[1],covA[1], | |
280 | covB[2],covA[2], | |
281 | covB[3],covA[3], | |
282 | covB[4],covA[4], | |
283 | covB[5],covA[5], | |
284 | covB[6],covA[6], | |
285 | covB[7],covA[7], | |
286 | covB[8],covA[8], | |
287 | covB[9],covA[9], | |
288 | covB[10],covA[10], | |
289 | covB[11],covA[11], | |
290 | covB[12],covA[12], | |
291 | covB[13],covA[13], | |
292 | covB[14],covA[14] | |
293 | )); | |
294 | */ | |
295 | Double_t time[AliPID::kSPECIESC]; t->GetIntegratedTimes(time); | |
296 | AliDebug(2,Form(" TOF params: %6d %f %f %f %f %f %6d %3d %f", | |
297 | i, | |
298 | t->GetTOFsignalRaw(),t->GetTOFsignal(),t->GetTOFsignalToT(), | |
299 | t->GetTOFsignalDz(),t->GetTOFsignalDx(),t->GetTOFCalChannel(), | |
300 | t->GetTOFcluster(),t->GetIntegratedLength())); | |
301 | AliDebug(2,Form(" %f %f %f %f %f %f %f %f %f", | |
302 | time[0], time[1], time[2], time[3], time[4], time[5], time[6], time[7], time[8])); | |
303 | } | |
304 | } | |
305 | } | |
306 | ||
307 | fSeeds->Clear(); | |
308 | fTracks->Clear(); | |
309 | ||
310 | AliInfo(Form("Number of cluster to be checked = %d",fN)); | |
311 | if(fN){ | |
312 | Int_t *matchmap = new Int_t[fN]; | |
313 | event->SetTOFcluster(fN,fClusters,matchmap); | |
314 | for (Int_t i=0; i<ntrk; i++) { // remapping after TOF matching selection | |
315 | AliESDtrack *t=event->GetTrack(i); | |
316 | t->ReMapTOFcluster(fN,matchmap); | |
317 | } | |
318 | ||
319 | delete[] matchmap; | |
320 | } | |
321 | ||
322 | ||
323 | ||
324 | return 0; | |
325 | ||
326 | } | |
327 | //_________________________________________________________________________ | |
328 | void AliTOFtrackerV2::CollectESD() { | |
329 | //prepare the set of ESD tracks to be matched to clusters in TOF | |
330 | ||
331 | Int_t seedsTOF1=0; | |
332 | Int_t seedsTOF3=0; | |
333 | Int_t seedsTOF2=0; | |
334 | ||
335 | TClonesArray &aTOFTrack = *fTracks; | |
336 | for (Int_t i=0; i<fNseeds; i++) { | |
337 | ||
338 | AliESDtrack *t =(AliESDtrack*)fSeeds->At(i); | |
339 | if ((t->GetStatus()&AliESDtrack::kTPCout)==0)continue; | |
340 | ||
341 | AliTOFtrack *track = new AliTOFtrack(*t); // New | |
342 | Float_t x = (Float_t)track->GetX(); //New | |
343 | ||
344 | // TRD 'good' tracks | |
345 | if ( ( (t->GetStatus()&AliESDtrack::kTRDout)!=0 ) ) { | |
346 | ||
347 | AliDebug(1,Form(" Before propagation till inner TOF radius, ESDtrackLength=%f, TOFtrackLength=%f",t->GetIntegratedLength(),track->GetIntegratedLength())); | |
348 | ||
349 | // TRD 'good' tracks, already propagated at 371 cm | |
350 | if ( x >= AliTOFGeometry::Rmin() ) { | |
351 | ||
352 | if ( track->PropagateToInnerTOF() ) { | |
353 | ||
354 | AliDebug(1,Form(" TRD propagated track till rho = %fcm." | |
355 | " And then the track has been propagated till rho = %fcm.", | |
356 | x, (Float_t)track->GetX())); | |
357 | ||
358 | track->SetSeedIndex(i); | |
359 | t->UpdateTrackParams(track,AliESDtrack::kTOFin); | |
360 | new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track); | |
361 | fNseedsTOF++; | |
362 | seedsTOF1++; | |
363 | ||
364 | AliDebug(1,Form(" After propagation till inner TOF radius, ESDtrackLength=%f, TOFtrackLength=%f",t->GetIntegratedLength(),track->GetIntegratedLength())); | |
365 | } | |
366 | delete track; | |
367 | ||
368 | } | |
369 | else { // TRD 'good' tracks, propagated rho<371cm | |
370 | ||
371 | if ( track->PropagateToInnerTOF() ) { | |
372 | ||
373 | AliDebug(1,Form(" TRD propagated track till rho = %fcm." | |
374 | " And then the track has been propagated till rho = %fcm.", | |
375 | x, (Float_t)track->GetX())); | |
376 | ||
377 | track->SetSeedIndex(i); | |
378 | t->UpdateTrackParams(track,AliESDtrack::kTOFin); | |
379 | new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track); | |
380 | fNseedsTOF++; | |
381 | seedsTOF3++; | |
382 | ||
383 | AliDebug(1,Form(" After propagation till inner TOF radius, ESDtrackLength=%f, TOFtrackLength=%f",t->GetIntegratedLength(),track->GetIntegratedLength())); | |
384 | } | |
385 | delete track; | |
386 | ||
387 | } | |
388 | //delete track; | |
389 | } | |
390 | ||
391 | else { // Propagate the rest of TPCbp | |
392 | ||
393 | AliDebug(1,Form(" Before propagation till inner TOF radius, ESDtrackLength=%f, TOFtrackLength=%f",t->GetIntegratedLength(),track->GetIntegratedLength())); | |
394 | ||
395 | if ( track->PropagateToInnerTOF() ) { | |
396 | ||
397 | AliDebug(1,Form(" TPC propagated track till rho = %fcm." | |
398 | " And then the track has been propagated till rho = %fcm.", | |
399 | x, (Float_t)track->GetX())); | |
400 | ||
401 | track->SetSeedIndex(i); | |
402 | t->UpdateTrackParams(track,AliESDtrack::kTOFin); | |
403 | new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track); | |
404 | fNseedsTOF++; | |
405 | seedsTOF2++; | |
406 | ||
407 | AliDebug(1,Form(" After propagation till inner TOF radius, ESDtrackLength=%f, TOFtrackLength=%f",t->GetIntegratedLength(),track->GetIntegratedLength())); | |
408 | } | |
409 | delete track; | |
410 | } | |
411 | } | |
412 | ||
413 | AliInfo(Form("Number of TOF seeds = %d (kTRDout371 = %d, kTRDoutLess371 = %d, !kTRDout = %d)",fNseedsTOF,seedsTOF1,seedsTOF3,seedsTOF2)); | |
414 | ||
415 | // Sort according uncertainties on track position | |
416 | fTracks->Sort(); | |
417 | ||
418 | } | |
419 | ||
420 | //_________________________________________________________________________ | |
421 | void AliTOFtrackerV2::MatchTracks() { | |
422 | // | |
423 | //Match ESD tracks to clusters in TOF | |
424 | // | |
425 | ||
426 | // Parameters used/regulating the reconstruction | |
427 | static Float_t detDepth=18.; | |
428 | static Float_t padDepth=0.5; | |
429 | ||
430 | const Float_t kSpeedOfLight= 2.99792458e-2; // speed of light [cm/ps] | |
431 | ||
432 | Float_t dY=AliTOFGeometry::XPad(); | |
433 | Float_t dZ=AliTOFGeometry::ZPad(); | |
434 | ||
435 | Float_t sensRadius = fkRecoParam->GetSensRadius(); | |
436 | Float_t stepSize = fkRecoParam->GetStepSize(); | |
437 | Float_t scaleFact = fkRecoParam->GetWindowScaleFact(); | |
438 | Float_t dyMax=fkRecoParam->GetWindowSizeMaxY(); | |
439 | Float_t dzMax=fkRecoParam->GetWindowSizeMaxZ(); | |
440 | Float_t dCut=10.;//fkRecoParam->GetDistanceCut(); // This is to be loaded by OCDB. It should be 10cm always. | |
441 | Double_t maxChi2=fkRecoParam->GetMaxChi2TRD(); | |
442 | Bool_t timeWalkCorr = fkRecoParam->GetTimeWalkCorr(); | |
443 | AliDebug(1,"++++++++++++++TOF Reconstruction Parameters:++++++++++++++"); | |
444 | AliDebug(1,Form("TOF sens radius: %f",sensRadius)); | |
445 | AliDebug(1,Form("TOF step size: %f",stepSize)); | |
446 | AliDebug(1,Form("TOF Window scale factor: %f",scaleFact)); | |
447 | AliDebug(1,Form("TOF Window max dy: %f",dyMax)); | |
448 | AliDebug(1,Form("TOF Window max dz: %f",dzMax)); | |
449 | AliDebug(1,Form("TOF distance Cut: %f",dCut)); | |
450 | AliDebug(1,Form("TOF Max Chi2: %f",maxChi2)); | |
451 | AliDebug(1,Form("Time Walk Correction? : %d",timeWalkCorr)); | |
452 | ||
453 | //Match ESD tracks to clusters in TOF | |
454 | ||
455 | // Get the number of propagation steps | |
456 | Int_t nSteps=(Int_t)(detDepth/stepSize); | |
457 | AliDebug(1,Form(" Number of steps to be done %d",nSteps)); | |
458 | ||
459 | AliDebug(1,"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); | |
460 | ||
461 | //PH Arrays (moved outside of the loop) | |
462 | Float_t * trackPos[4]; | |
463 | for (Int_t ii=0; ii<4; ii++) trackPos[ii] = new Float_t[nSteps]; | |
464 | Int_t * clind = new Int_t[fN]; | |
465 | ||
466 | // Some init | |
467 | const Int_t kNclusterMax = 1000; // related to fN value | |
468 | TGeoHMatrix global[kNclusterMax]; | |
469 | ||
470 | //The matching loop | |
471 | for (Int_t iseed=0; iseed<fNseedsTOF; iseed++) { | |
472 | ||
473 | for (Int_t ii=0; ii<fN; ii++) clind[ii]=-1; | |
474 | for (Int_t ii=0; ii<kNclusterMax; ii++) global[ii] = 0x0; | |
475 | for (Int_t ii=0; ii<4; ii++) | |
476 | for (Int_t jj=0; jj<nSteps; jj++) trackPos[ii][jj]=0.; | |
477 | ||
478 | AliTOFtrack *track =(AliTOFtrack*)fTracks->UncheckedAt(iseed); | |
479 | AliESDtrack *t =(AliESDtrack*)fSeeds->At(track->GetSeedIndex()); | |
480 | AliTOFtrack *trackTOFin = new AliTOFtrack(*track); | |
481 | ||
482 | Double_t timesOr[AliPID::kSPECIESC]; t->GetIntegratedTimes(timesOr); // in ps | |
483 | ||
484 | // Determine a window around the track | |
485 | Double_t x,par[5]; | |
486 | trackTOFin->GetExternalParameters(x,par); | |
487 | Double_t cov[15]; | |
488 | trackTOFin->GetExternalCovariance(cov); | |
489 | ||
490 | if (cov[0]<0. || cov[2]<0.) { | |
491 | AliWarning(Form("Very strange track (%d)! At least one of its covariance matrix diagonal elements is negative!",iseed)); | |
492 | delete trackTOFin; | |
493 | continue; | |
494 | } | |
495 | ||
496 | Double_t dphi= | |
497 | scaleFact* | |
498 | ((5*TMath::Sqrt(TMath::Abs(cov[0])) + 0.5*dY + 2.5*TMath::Abs(par[2]))/sensRadius); | |
499 | Double_t dz= | |
500 | scaleFact* | |
501 | (5*TMath::Sqrt(TMath::Abs(cov[2])) + 0.5*dZ + 2.5*TMath::Abs(par[3])); | |
502 | ||
503 | Double_t phi=TMath::ATan2(par[0],x) + trackTOFin->GetAlpha(); | |
504 | if (phi<-TMath::Pi())phi+=2*TMath::Pi(); | |
505 | if (phi>=TMath::Pi())phi-=2*TMath::Pi(); | |
506 | Double_t z=par[1]; | |
507 | ||
508 | //upper limit on window's size. | |
509 | if (dz> dzMax) dz=dzMax; | |
510 | if (dphi*sensRadius> dyMax) dphi=dyMax/sensRadius; | |
511 | ||
512 | ||
513 | // find the clusters in the window of the track | |
514 | Int_t nc=0; | |
515 | for (Int_t k=FindClusterIndex(z-dz); k<fN; k++) { | |
516 | ||
517 | if (nc>=kNclusterMax) { | |
518 | AliWarning("No more matchable clusters can be stored! Please, increase the corresponding vectors size."); | |
519 | break; | |
520 | } | |
521 | ||
522 | AliESDTOFcluster *c=&(fClusters[k]); | |
523 | if (c->GetZ() > z+dz) break; | |
524 | if (!c->GetStatus()) { | |
525 | AliDebug(1,"Cluster in channel declared bad!"); | |
526 | continue; // skip bad channels as declared in OCDB | |
527 | } | |
528 | ||
529 | Double_t dph=TMath::Abs(c->GetPhi()-phi); | |
530 | if (dph>TMath::Pi()) dph-=2.*TMath::Pi(); | |
531 | if (TMath::Abs(dph)>dphi) continue; | |
532 | ||
533 | Double_t yc=(c->GetPhi() - trackTOFin->GetAlpha())*c->GetR(); | |
534 | Double_t p[2]={yc, c->GetZ()}; | |
535 | Double_t cov2[3]= {dY*dY/12., 0., dZ*dZ/12.}; | |
536 | if (trackTOFin->AliExternalTrackParam::GetPredictedChi2(p,cov2) > maxChi2)continue; | |
537 | ||
538 | clind[nc] = k; | |
539 | Char_t path[200]; | |
540 | Int_t ind[5]; fGeom->GetVolumeIndices(c->GetTOFchannel(),ind); | |
541 | fGeom->GetVolumePath(ind,path); | |
542 | gGeoManager->cd(path); | |
543 | global[nc] = *gGeoManager->GetCurrentMatrix(); | |
544 | nc++; | |
545 | } | |
546 | ||
547 | if (nc == 0 ) { | |
548 | AliDebug(1,Form("No available clusters for the track number %d",iseed)); | |
549 | fnunmatch++; | |
550 | delete trackTOFin; | |
551 | continue; | |
552 | } | |
553 | ||
554 | AliDebug(1,Form(" Number of available TOF clusters for the track number %d: %d",iseed,nc)); | |
555 | ||
556 | //start fine propagation | |
557 | ||
558 | Double_t *times[AliPID::kSPECIESC]; | |
559 | for(Int_t isp=0;isp < AliPID::kSPECIESC;isp++){ | |
560 | times[isp] = new Double_t[nSteps]; | |
561 | } | |
562 | ||
563 | Int_t nStepsDone = 0; | |
564 | for( Int_t istep=0; istep<nSteps; istep++){ | |
565 | ||
566 | // First of all, propagate the track... | |
567 | Float_t xs = AliTOFGeometry::RinTOF()+istep*stepSize; | |
568 | if (!(trackTOFin->PropagateTo(xs))) break; | |
569 | ||
570 | // ...and then, if necessary, rotate the track | |
571 | Double_t ymax = xs*TMath::Tan(0.5*AliTOFGeometry::GetAlpha()); | |
572 | Double_t ysect = trackTOFin->GetY(); | |
573 | if (ysect > ymax) { | |
574 | if (!(trackTOFin->Rotate(AliTOFGeometry::GetAlpha()))) break; | |
575 | } else if (ysect <-ymax) { | |
576 | if (!(trackTOFin->Rotate(-AliTOFGeometry::GetAlpha()))) break; | |
577 | } | |
578 | ||
579 | Double_t mom = trackTOFin->P(); | |
580 | ||
581 | if(istep == 0){ | |
582 | for(Int_t isp=0;isp<AliPID::kSPECIESC;isp++){ | |
583 | Double_t mass=AliPID::ParticleMass(isp); | |
584 | Double_t momz = mom*AliPID::ParticleCharge(isp); | |
585 | times[isp][nStepsDone] = stepSize/kSpeedOfLight*TMath::Sqrt(momz*momz+mass*mass)/momz; | |
586 | } | |
587 | } | |
588 | else{ | |
589 | for(Int_t isp=0;isp<AliPID::kSPECIESC;isp++){ | |
590 | Double_t mass=AliPID::ParticleMass(isp); | |
591 | Double_t momz = mom*AliPID::ParticleCharge(isp); | |
592 | times[isp][nStepsDone] = times[isp][nStepsDone-1] + (trackTOFin->GetIntegratedLength()-trackPos[3][nStepsDone-1])/kSpeedOfLight*TMath::Sqrt(momz*momz+mass*mass)/momz; | |
593 | } | |
594 | } | |
595 | ||
596 | // store the running point (Globalrf) - fine propagation | |
597 | ||
598 | Double_t r[3]; trackTOFin->GetXYZ(r); | |
599 | trackPos[0][nStepsDone]= (Float_t) r[0]; | |
600 | trackPos[1][nStepsDone]= (Float_t) r[1]; | |
601 | trackPos[2][nStepsDone]= (Float_t) r[2]; | |
602 | trackPos[3][nStepsDone]= trackTOFin->GetIntegratedLength(); | |
603 | ||
604 | nStepsDone++; | |
605 | AliDebug(3,Form(" current step %d (%d) - nStepsDone=%d",istep,nSteps,nStepsDone)); | |
606 | } | |
607 | ||
608 | if ( nStepsDone == 0 ) { | |
609 | AliDebug(1,Form(" No track points for track number %d",iseed)); | |
610 | fnunmatch++; | |
611 | delete trackTOFin; | |
612 | continue; | |
613 | } | |
614 | ||
615 | AliDebug(3,Form(" Number of steps done for the track number %d: %d",iseed,nStepsDone)); | |
616 | ||
617 | Int_t *isClusterMatchable = NULL; | |
618 | if(nc){ | |
619 | isClusterMatchable = new Int_t[nc]; | |
620 | for (Int_t i=0; i<nc; i++) isClusterMatchable[i] = kFALSE; | |
621 | } | |
622 | ||
623 | Int_t nfound = 0; | |
624 | Bool_t accept = kFALSE; | |
625 | Bool_t isInside = kFALSE; | |
626 | for (Int_t istep=0; istep<nStepsDone; istep++) { | |
627 | ||
628 | Bool_t gotInsideCluster = kFALSE; | |
629 | Int_t trackInsideCluster = -1; | |
630 | ||
631 | Float_t ctrackPos[3]; | |
632 | ctrackPos[0] = trackPos[0][istep]; | |
633 | ctrackPos[1] = trackPos[1][istep]; | |
634 | ctrackPos[2] = trackPos[2][istep]; | |
635 | ||
636 | //now see whether the track matches any of the TOF clusters | |
637 | ||
638 | Float_t dist3d[3]={0.,0.,0.}; | |
639 | accept = kFALSE; | |
640 | ||
641 | for (Int_t i=0; i<nc; i++) { | |
642 | ||
643 | // ***** NEW ***** | |
644 | /* check whether track was inside another cluster | |
645 | * and in case inhibit this cluster. | |
646 | * this will allow to only go on and add track points for | |
647 | * that cluster where the track got inside first */ | |
648 | if (gotInsideCluster && trackInsideCluster != i) { | |
649 | AliDebug(3,Form(" A - istep=%d ~ %d %d ~ nfound=%d",istep,trackInsideCluster,i,nfound)); | |
650 | continue; | |
651 | } | |
652 | AliDebug(3,Form(" B - istep=%d ~ %d %d ~ nfound=%d",istep,trackInsideCluster,i,nfound)); | |
653 | ||
654 | /* check whether track is inside this cluster */ | |
655 | for (Int_t hh=0; hh<3; hh++) dist3d[hh]=0.; | |
656 | isInside = fGeom->IsInsideThePad((TGeoHMatrix*)(&global[i]),ctrackPos,dist3d); | |
657 | ||
658 | // ***** NEW ***** | |
659 | /* if track is inside this cluster set flags which will then | |
660 | * inhibit to add track points for the other clusters */ | |
661 | if (isInside) { | |
662 | gotInsideCluster = kTRUE; | |
663 | trackInsideCluster = i; | |
664 | } | |
665 | ||
666 | Float_t yLoc = dist3d[1]; | |
667 | Float_t rLoc = TMath::Sqrt(dist3d[0]*dist3d[0]+dist3d[2]*dist3d[2]); | |
668 | accept = (TMath::Abs(yLoc)<padDepth*0.5 && rLoc<dCut); | |
669 | ||
670 | //***** NEW ***** | |
671 | /* add point everytime that: | |
672 | * - the track is inside the cluster | |
673 | * - the track got inside the cluster, even when it eventually exited the cluster | |
674 | * - the tracks is within dCut from the cluster | |
675 | */ | |
676 | if (accept || isInside || gotInsideCluster) { | |
677 | ||
678 | Double_t timesCurrent[AliPID::kSPECIESC]; | |
679 | AliDebug(3,Form(" Momentum for track %d -> %f", iseed,t->P())); | |
680 | for (Int_t j=0;j<AliPID::kSPECIESC;j++) { | |
681 | timesCurrent[j] = timesOr[j] + times[j][istep]; | |
682 | } | |
683 | ||
684 | if (TMath::Abs(dist3d[1])<stepSize && !isClusterMatchable[i]) { | |
685 | isClusterMatchable[i] = kTRUE; | |
686 | fClusters[clind[i]].Update(t->GetID(),dist3d[1],dist3d[0],dist3d[2],trackPos[3][istep],timesCurrent);//x,y,z -> tracking RF | |
687 | t->AddTOFcluster(clind[i]); | |
688 | t->SetStatus(AliESDtrack::kTOFout); | |
689 | } | |
690 | AliDebug(2,Form(" dist3dLoc[0] = %f, dist3dLoc[1] = %f, dist3dLoc[2] = %f ",dist3d[0],dist3d[1],dist3d[2])); | |
691 | ||
692 | nfound++; | |
693 | ||
694 | AliDebug(3,Form(" C - istep=%d ~ %d %d ~ nfound=%d",istep,trackInsideCluster,i,nfound)); | |
695 | ||
696 | // ***** NEW ***** | |
697 | }//end if accept | |
698 | ||
699 | } //end for on the clusters | |
700 | } //end for on the steps | |
701 | if(nc) delete[] isClusterMatchable; | |
702 | ||
703 | for(Int_t isp=0;isp < AliPID::kSPECIESC;isp++){ | |
704 | delete[] times[isp]; | |
705 | } | |
706 | ||
707 | ||
708 | if (nfound == 0 ) { | |
709 | AliDebug(1,Form(" No matchable track points for the track number %d",iseed)); | |
710 | fnunmatch++; | |
711 | delete trackTOFin; | |
712 | continue; | |
713 | } | |
714 | ||
715 | AliDebug(1,Form(" Number of track points for the track number %d: %d",iseed,nfound)); | |
716 | ||
717 | Int_t nMatchedClusters = t->GetNTOFclusters(); | |
718 | ||
719 | if (nMatchedClusters==0) { | |
720 | AliDebug(1,Form("Reconstructed track %d doesn't match any TOF cluster", iseed)); | |
721 | fnunmatch++; | |
722 | delete trackTOFin; | |
723 | continue; | |
724 | } | |
725 | ||
726 | AliDebug(1,Form(" %d - matched (%d)",track->GetSeedIndex()/*iseed*/,nMatchedClusters)); | |
727 | ||
728 | fnmatch++; | |
729 | ||
730 | /* | |
731 | AliTOFcluster cTOF = AliTOFcluster(volIdClus, | |
732 | (Float_t)posClus[0],(Float_t)posClus[1],(Float_t)posClus[2], | |
733 | (Float_t)covClus[0],(Float_t)covClus[1],(Float_t)covClus[2], | |
734 | (Float_t)covClus[3],(Float_t)covClus[4],(Float_t)covClus[5], | |
735 | tofLabels,volIndices,parClu,kTRUE,index[i]); | |
736 | ||
737 | // Fill the track residual histograms. | |
738 | FillResiduals(trackTOFin,c,kFALSE); | |
739 | */ | |
740 | ||
741 | delete trackTOFin; | |
742 | ||
743 | } // loop on fSeeds | |
744 | ||
745 | for (Int_t ii=0; ii<4; ii++) delete [] trackPos[ii]; | |
746 | delete [] clind; | |
747 | ||
748 | } | |
749 | //_________________________________________________________________________ | |
750 | Int_t AliTOFtrackerV2::LoadClusters(TTree *cTree) { | |
751 | //-------------------------------------------------------------------- | |
752 | //This function loads the TOF clusters | |
753 | //-------------------------------------------------------------------- | |
754 | ||
755 | TBranch *branch=cTree->GetBranch("TOF"); | |
756 | if (!branch) { | |
757 | AliError("can't get the branch with the TOF clusters !"); | |
758 | return 1; | |
759 | } | |
760 | ||
761 | static TClonesArray dummy("AliTOFcluster",10000); | |
762 | dummy.Clear(); | |
763 | TClonesArray *clusters=&dummy; | |
764 | branch->SetAddress(&clusters); | |
765 | ||
766 | cTree->GetEvent(0); | |
767 | fN=clusters->GetEntriesFast(); | |
768 | AliInfo(Form("Number of clusters: %d",fN)); | |
769 | ||
770 | if(fClusters){ | |
771 | delete[] fClusters; | |
772 | fClusters = NULL; | |
773 | } | |
774 | ||
775 | if(fN) | |
776 | fClusters = new AliESDTOFcluster[fN]; | |
777 | else{ | |
778 | fClusters = new AliESDTOFcluster[1]; | |
779 | fN = 1; | |
780 | return 0; | |
781 | } | |
782 | ||
783 | for (Int_t i=0; i<fN; i++) { | |
784 | AliTOFcluster *c=(AliTOFcluster*)clusters->UncheckedAt(i); | |
785 | Int_t ind[5]; | |
786 | ind[0]=c->GetDetInd(0); | |
787 | ind[1]=c->GetDetInd(1); | |
788 | ind[2]=c->GetDetInd(2); | |
789 | ind[3]=c->GetDetInd(3); | |
790 | ind[4]=c->GetDetInd(4); | |
791 | Int_t calindex = AliTOFGeometry::GetIndex(ind); | |
792 | Int_t tofLabels[3]={c->GetLabel(0),c->GetLabel(1),c->GetLabel(2)}; | |
793 | AliESDTOFcluster esdTOFclus(i,calindex, | |
794 | AliTOFGeometry::TdcBinWidth()*c->GetTDC()/*ps*/, | |
795 | AliTOFGeometry::TdcBinWidth()*c->GetTDCRAW()/*ps*/, | |
796 | AliTOFGeometry::ToTBinWidth()*c->GetToT()*1E-3/*ns*/, | |
797 | tofLabels, | |
798 | c->GetDeltaBC(),c->GetL0L1Latency(), | |
799 | c->GetStatus(),c->GetZ(),c->GetPhi(),c->GetR()); | |
800 | ||
801 | fClusters[i] = esdTOFclus; | |
802 | ||
803 | } | |
804 | ||
805 | return 0; | |
806 | } | |
807 | //_________________________________________________________________________ | |
808 | void AliTOFtrackerV2::UnloadClusters() { | |
809 | //-------------------------------------------------------------------- | |
810 | //This function unloads TOF clusters | |
811 | //-------------------------------------------------------------------- | |
812 | ||
813 | // don't delete TOF clusters here because they should be written | |
814 | } | |
815 | ||
816 | //_________________________________________________________________________ | |
817 | Int_t AliTOFtrackerV2::FindClusterIndex(Double_t z) const { | |
818 | //-------------------------------------------------------------------- | |
819 | // This function returns the index of the nearest cluster | |
820 | //-------------------------------------------------------------------- | |
821 | if (fN==0) return 0; | |
822 | if (z <= fClusters[0].GetZ()) return 0; | |
823 | if (z > fClusters[fN-1].GetZ()) return fN; | |
824 | Int_t b=0, e=fN-1, m=(b+e)/2; | |
825 | for (; b<e; m=(b+e)/2) { | |
826 | if (z > fClusters[m].GetZ()) b=m+1; | |
827 | ||
828 | else e=m; | |
829 | } | |
830 | return m; | |
831 | } | |
832 | ||
833 | //_________________________________________________________________________ | |
834 | Bool_t AliTOFtrackerV2::GetTrackPoint(Int_t index, AliTrackPoint& p) const | |
835 | { | |
836 | // Get track space point with index i | |
837 | // Coordinates are in the global system | |
838 | AliESDTOFcluster *cl = &(fClusters[index]); | |
839 | Float_t xyz[3]; | |
840 | xyz[0] = cl->GetR()*TMath::Cos(cl->GetPhi()); | |
841 | xyz[1] = cl->GetR()*TMath::Sin(cl->GetPhi()); | |
842 | xyz[2] = cl->GetZ(); | |
843 | Float_t phiangle = (Int_t(cl->GetPhi()*TMath::RadToDeg()/20.)+0.5)*20.*TMath::DegToRad(); | |
844 | Float_t sinphi = TMath::Sin(phiangle), cosphi = TMath::Cos(phiangle); | |
845 | Int_t tofChannel=cl->GetTOFchannel(); | |
846 | Int_t ind[5]; fGeom->GetVolumeIndices(tofChannel,ind); | |
847 | Float_t tiltangle = AliTOFGeometry::GetAngles(ind[1],ind[2])*TMath::DegToRad(); | |
848 | Float_t sinth = TMath::Sin(tiltangle), costh = TMath::Cos(tiltangle); | |
849 | Float_t sigmay2 = AliTOFGeometry::XPad()*AliTOFGeometry::XPad()/12.; | |
850 | Float_t sigmaz2 = AliTOFGeometry::ZPad()*AliTOFGeometry::ZPad()/12.; | |
851 | Float_t cov[6]; | |
852 | cov[0] = sinphi*sinphi*sigmay2 + cosphi*cosphi*sinth*sinth*sigmaz2; | |
853 | cov[1] = -sinphi*cosphi*sigmay2 + sinphi*cosphi*sinth*sinth*sigmaz2; | |
854 | cov[2] = -cosphi*sinth*costh*sigmaz2; | |
855 | cov[3] = cosphi*cosphi*sigmay2 + sinphi*sinphi*sinth*sinth*sigmaz2; | |
856 | cov[4] = -sinphi*sinth*costh*sigmaz2; | |
857 | cov[5] = costh*costh*sigmaz2; | |
858 | p.SetXYZ(xyz[0],xyz[1],xyz[2],cov); | |
859 | ||
860 | // Detector numbering scheme | |
861 | Int_t nSector = AliTOFGeometry::NSectors(); | |
862 | Int_t nPlate = AliTOFGeometry::NPlates(); | |
863 | Int_t nStripA = AliTOFGeometry::NStripA(); | |
864 | Int_t nStripB = AliTOFGeometry::NStripB(); | |
865 | Int_t nStripC = AliTOFGeometry::NStripC(); | |
866 | ||
867 | Int_t isector = ind[0];//cl->GetDetInd(0); | |
868 | if (isector >= nSector) | |
869 | AliError(Form("Wrong sector number in TOF (%d) !",isector)); | |
870 | Int_t iplate = ind[1];//cl->GetDetInd(1); | |
871 | if (iplate >= nPlate) | |
872 | AliError(Form("Wrong plate number in TOF (%d) !",iplate)); | |
873 | Int_t istrip = ind[2];//cl->GetDetInd(2); | |
874 | ||
875 | Int_t stripOffset = 0; | |
876 | switch (iplate) { | |
877 | case 0: | |
878 | stripOffset = 0; | |
879 | break; | |
880 | case 1: | |
881 | stripOffset = nStripC; | |
882 | break; | |
883 | case 2: | |
884 | stripOffset = nStripC+nStripB; | |
885 | break; | |
886 | case 3: | |
887 | stripOffset = nStripC+nStripB+nStripA; | |
888 | break; | |
889 | case 4: | |
890 | stripOffset = nStripC+nStripB+nStripA+nStripB; | |
891 | break; | |
892 | default: | |
893 | AliError(Form("Wrong plate number in TOF (%d) !",iplate)); | |
894 | break; | |
895 | }; | |
896 | ||
897 | Int_t idet = (2*(nStripC+nStripB)+nStripA)*isector + | |
898 | stripOffset + | |
899 | istrip; | |
900 | UShort_t volid = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,idet); | |
901 | p.SetVolumeID((UShort_t)volid); | |
902 | return kTRUE; | |
903 | } | |
904 | //_________________________________________________________________________ | |
905 | ||
906 | void AliTOFtrackerV2::FillClusterArray(TObjArray* arr) const | |
907 | { | |
908 | // | |
909 | // Returns the TOF cluster array | |
910 | // | |
911 | ||
912 | if (fN==0) | |
913 | arr = 0x0; | |
914 | else | |
915 | for (Int_t i=0; i<fN; ++i) arr->Add(&(fClusters[i])); | |
916 | ||
917 | } | |
918 | //_________________________________________________________________________ | |
919 | Float_t AliTOFtrackerV2::CorrectTimeWalk( Float_t dist, Float_t tof) const { | |
920 | ||
921 | //dummy, for the moment | |
922 | Float_t tofcorr=0.; | |
923 | if(dist<AliTOFGeometry::ZPad()*0.5){ | |
924 | tofcorr=tof; | |
925 | //place here the actual correction | |
926 | }else{ | |
927 | tofcorr=tof; | |
928 | } | |
929 | return tofcorr; | |
930 | } | |
931 | //_________________________________________________________________________ | |
932 | void AliTOFtrackerV2::Clusterize(){ | |
933 | Int_t detId[5]; | |
934 | for(Int_t i=0; i < fN-1;i++){ | |
935 | AliESDTOFcluster *c1=&(fClusters[i]); | |
936 | if(!c1->GetStatus()) continue; | |
937 | ||
938 | Int_t chan1 = c1->GetTOFchannel(); | |
939 | AliTOFGeometry::GetVolumeIndices(chan1, detId); // Get volume index from channel index | |
940 | ||
941 | Int_t ieta = detId[2]/*strip*/*2 + detId[3]/*pad Z*/; | |
942 | if(detId[1]/*module*/ == 0) ieta += 0; | |
943 | else if(detId[1] == 1) ieta += 38; | |
944 | else if(detId[1] == 2) ieta += 76; | |
945 | else if(detId[1] == 3) ieta += 106; | |
946 | else if(detId[1] == 4) ieta += 144; | |
947 | Int_t iphi = detId[0]/*phi sector*/*48 + detId[4]/*pad x*/; | |
948 | ||
949 | ||
950 | for(Int_t j=i+1; j < fN;j++){ | |
951 | AliESDTOFcluster *c2=&(fClusters[j]); | |
952 | if(!c2->GetStatus()) continue; | |
953 | ||
954 | Int_t chan2 = c2->GetTOFchannel(); | |
955 | ||
956 | // check if the two TOF hits are in the same strip | |
957 | if(chan1/96 != chan2/96) continue; | |
958 | ||
959 | AliTOFGeometry::GetVolumeIndices(chan2, detId); // Get volume index from channel index | |
960 | Int_t ieta2 = detId[2]/*strip*/*2 + detId[3]/*pad Z*/; | |
961 | if(detId[1]/*module*/ == 0) ieta2 += 0; | |
962 | else if(detId[1] == 1) ieta2 += 38; | |
963 | else if(detId[1] == 2) ieta2 += 76; | |
964 | else if(detId[1] == 3) ieta2 += 106; | |
965 | else if(detId[1] == 4) ieta2 += 144; | |
966 | Int_t iphi2 = detId[0]/*phi sector*/*48 + detId[4]/*pad x*/; | |
967 | ||
968 | // check if the fired pad are close in space | |
969 | if(TMath::Abs(iphi-iphi2)>1 || TMath::Abs(ieta-ieta2)>1) continue; | |
970 | ||
971 | // check if the TOF time are close enough to be merged | |
972 | if(TMath::Abs(c1->GetTime() - c2->GetTime()) > 500/*in ps*/) continue; | |
973 | ||
974 | // merge them | |
975 | Int_t label[3] = {c2->GetLabel(0),c2->GetLabel(1),c2->GetLabel(2)}; | |
976 | fClusters[i].AddTOFhit(c2->GetClusterIndex(),chan2,c2->GetTime(),c2->GetTimeRaw(),c2->GetTOT(),label, | |
977 | c2->GetDeltaBC(),c2->GetL0L1Latency(),1,c2->GetZ(),c2->GetPhi(),c2->GetR()); | |
978 | ||
979 | c2->SetStatus(0); // only the merged one should be used | |
980 | j = fN; // cluster "i" merged go to the next one ("i+1") | |
981 | } | |
982 | } | |
983 | ||
984 | // second step of clusterization | |
985 | for(Int_t i=0; i < fN-1;i++){ | |
986 | AliESDTOFcluster *c1=&(fClusters[i]); | |
987 | if(!c1->GetStatus()) continue; | |
988 | ||
989 | Int_t chan1 = c1->GetTOFchannel(0); | |
990 | AliTOFGeometry::GetVolumeIndices(chan1, detId); // Get volume index from channel index | |
991 | ||
992 | Int_t ieta = detId[2]/*strip*/*2 + detId[3]/*pad Z*/; | |
993 | if(detId[1]/*module*/ == 0) ieta += 0; | |
994 | else if(detId[1] == 1) ieta += 38; | |
995 | else if(detId[1] == 2) ieta += 76; | |
996 | else if(detId[1] == 3) ieta += 106; | |
997 | else if(detId[1] == 4) ieta += 144; | |
998 | Int_t iphi = detId[0]/*phi sector*/*48 + detId[4]/*pad x*/; | |
999 | ||
1000 | Int_t ieta2,iphi2,chan2=chan1; | |
1001 | if(c1->GetNTOFhits() > 1){ | |
1002 | chan2 = c1->GetTOFchannel(1); | |
1003 | AliTOFGeometry::GetVolumeIndices(chan2, detId); // Get volume index from channel index | |
1004 | ||
1005 | ieta2 = detId[2]/*strip*/*2 + detId[3]/*pad Z*/; | |
1006 | if(detId[1]/*module*/ == 0) ieta2 += 0; | |
1007 | else if(detId[1] == 1) ieta2 += 38; | |
1008 | else if(detId[1] == 2) ieta2 += 76; | |
1009 | else if(detId[1] == 3) ieta2 += 106; | |
1010 | else if(detId[1] == 4) ieta2 += 144; | |
1011 | iphi2 = detId[0]/*phi sector*/*48 + detId[4]/*pad x*/; | |
1012 | } | |
1013 | else{ | |
1014 | iphi2=iphi; | |
1015 | ieta2=ieta; | |
1016 | } | |
1017 | ||
1018 | for(Int_t j=i+1; j < i;j++){ | |
1019 | AliESDTOFcluster *c2=&(fClusters[j]); | |
1020 | if(!c2->GetStatus()) continue; | |
1021 | ||
1022 | Int_t chan3 = c2->GetTOFchannel(); | |
1023 | ||
1024 | // check if the two TOF hits are in the same strip | |
1025 | if(chan1/96 != chan3/96) continue; | |
1026 | ||
1027 | AliTOFGeometry::GetVolumeIndices(chan3, detId); // Get volume index from channel index | |
1028 | Int_t ieta3 = detId[2]/*strip*/*2 + detId[3]/*pad Z*/; | |
1029 | if(detId[1]/*module*/ == 0) ieta3 += 0; | |
1030 | else if(detId[1] == 1) ieta3 += 38; | |
1031 | else if(detId[1] == 2) ieta3 += 76; | |
1032 | else if(detId[1] == 3) ieta3 += 106; | |
1033 | else if(detId[1] == 4) ieta3 += 144; | |
1034 | Int_t iphi3 = detId[0]/*phi sector*/*48 + detId[4]/*pad x*/; | |
1035 | ||
1036 | // check if the fired pad are close in space | |
1037 | if((TMath::Abs(iphi-iphi3)>1 && TMath::Abs(iphi2-iphi3)>1) || (TMath::Abs(ieta-ieta3)>1 && TMath::Abs(ieta2-ieta3)>1)) | |
1038 | continue; | |
1039 | ||
1040 | // check if the TOF time are close enough to be merged | |
1041 | if(TMath::Abs(c1->GetTime() - c2->GetTime()) > 500/*in ps*/) continue; | |
1042 | ||
1043 | // merge them | |
1044 | Int_t label[3] = {c2->GetLabel(0),c2->GetLabel(1),c2->GetLabel(2)}; | |
1045 | fClusters[i].AddTOFhit(c2->GetClusterIndex(),chan2,c2->GetTime(),c2->GetTimeRaw(),c2->GetTOT(),label, | |
1046 | c2->GetDeltaBC(),c2->GetL0L1Latency(),1,c2->GetZ(),c2->GetPhi(),c2->GetR()); | |
1047 | ||
1048 | if(c2->GetNTOFhits() > 1){ // in case also the second cluster has two hits | |
1049 | Int_t label2[3] = {c2->GetLabel(0,1),c2->GetLabel(1,1),c2->GetLabel(2,1)}; | |
1050 | fClusters[i].AddTOFhit(c2->GetClusterIndex(1),c2->GetTOFchannel(1),c2->GetTime(1),c2->GetTimeRaw(1), | |
1051 | c2->GetTOT(1),label2,c2->GetDeltaBC(2),c2->GetL0L1Latency(2),1,c2->GetZ(), | |
1052 | c2->GetPhi(),c2->GetR()); | |
1053 | } | |
1054 | ||
1055 | c1->SetStatus(0); // only the merged one should be used | |
1056 | j = fN; // cluster "i" merged go to the next one ("i+1") | |
1057 | } | |
1058 | } | |
1059 | } | |
1060 |