]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDgtuTMU.cxx
Coverity 21238
[u/mrichter/AliRoot.git] / TRD / AliTRDgtuTMU.cxx
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
16 /* $Id: AliTRDgtuTMU.cxx 28397 2008-09-02 09:33:00Z cblume $ */
17
18 ////////////////////////////////////////////////////////////////////////////
19 //                                                                        //
20 //  Track Matching Unit (TMU) simulation                                  //
21 //                                                                        //
22 //  Author: J. Klein (Jochen.Klein@cern.ch)                               //
23 //                                                                        //
24 ////////////////////////////////////////////////////////////////////////////
25
26 #include "TTree.h"
27 #include "TList.h"
28 #include "TVectorD.h"
29 #include "TMath.h"
30
31 #include "AliESDEvent.h"
32 #include "AliESDTrdTrack.h"
33
34 #include "AliLog.h"
35 #include "AliTRDgeometry.h"
36 #include "AliTRDpadPlane.h"
37
38 #include "AliTRDgtuParam.h"
39 #include "AliTRDgtuTMU.h"
40 #include "AliTRDtrackGTU.h"
41
42 ClassImp(AliTRDgtuTMU)
43
44 AliTRDgtuTMU::AliTRDgtuTMU(Int_t stack, Int_t sector) :
45   TObject(),
46   fTracklets(0x0),
47   fTrackletsPostInput(0x0),
48   fZChannelTracklets(0x0),
49   fTracks(0x0),
50   fGtuParam(0x0),
51   fStack(-1),
52   fSector(-1)
53 {
54   // constructor which initializes the position information of the TMU
55
56   fGtuParam = AliTRDgtuParam::Instance();
57
58   // store tracklets per link
59   fTracklets = new TObjArray*[fGtuParam->GetNLinks()];
60   for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
61     fTracklets[iLink] = new TObjArray();
62   }
63
64   // tracklets after input units per layer
65   fTrackletsPostInput = new TObjArray*[fGtuParam->GetNLayers()];
66   fZChannelTracklets = new TList*[fGtuParam->GetNLayers()];
67   for (Int_t layer = 0;  layer <  fGtuParam->GetNLayers(); layer++) {
68     fZChannelTracklets[layer] = new TList[fGtuParam->GetNZChannels()];
69     fTrackletsPostInput[layer] = new TObjArray();
70   }
71
72   fTracks = new TList*[fGtuParam->GetNZChannels()];
73   for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
74       fTracks[zch] = new TList[fGtuParam->GetNRefLayers()];
75   }
76
77   if (stack > -1)
78       SetStack(stack);
79   if (sector > -1)
80       SetSector(sector);
81 }
82
83 AliTRDgtuTMU::~AliTRDgtuTMU()
84 {
85   // destructor
86
87   for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
88     delete [] fTracks[zch];
89   }
90   delete [] fTracks;
91   for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
92     delete [] fZChannelTracklets[layer];
93     //    delete [] fTrackletsPostInput[layer];
94   }
95   delete [] fZChannelTracklets;
96   //  delete [] fTrackletsPostInput;
97
98   for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
99     delete fTracklets[iLink];
100   }
101   delete [] fTracklets;
102 }
103
104 Bool_t AliTRDgtuTMU::SetSector(Int_t sector)
105 {
106   // set the sector
107
108   if (sector > -1 && sector < fGtuParam->GetGeo()->Nsector() ) {
109     fSector = sector;
110     return kTRUE;
111   }
112
113   AliError(Form("Invalid sector given: %i", sector));
114   return kFALSE;
115 }
116
117 Bool_t AliTRDgtuTMU::SetStack(Int_t stack)
118 {
119   // Set the stack (necessary for tracking)
120
121   if (stack > -1 && stack < fGtuParam->GetGeo()->Nstack() ) {
122     fStack = stack;
123     return kTRUE;
124   }
125
126   AliError(Form("Invalid stack given: %i", stack));
127   return kFALSE;
128 }
129
130 Bool_t AliTRDgtuTMU::Reset()
131 {
132   // delete all tracks
133
134   for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
135     for (Int_t reflayeridx = 0; reflayeridx < fGtuParam->GetNRefLayers(); reflayeridx++) {
136       fTracks[zch][reflayeridx].Clear();
137     }
138   }
139
140   // delete all added tracklets
141   for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
142     fTracklets[iLink]->Clear();
143   }
144   for (Int_t layer = 0; layer < fGtuParam->GetNLinks()/2; layer++) {
145     fTrackletsPostInput[layer]->Clear();
146     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++)
147       fZChannelTracklets[layer][zch].Clear();
148   }
149
150   fSector = -1;
151   fStack = -1;
152
153   return kTRUE;
154 }
155
156 Bool_t AliTRDgtuTMU::AddTracklet(AliTRDtrackletGTU *tracklet, Int_t link)
157 {
158   // add a tracklet on the given link
159
160   fTracklets[link]->Add(tracklet);
161   return kTRUE;
162 }
163
164
165 Bool_t AliTRDgtuTMU::RunTMU(TList *ListOfTracks, AliESDEvent *esd)
166 {
167   // performs the analysis as in a TMU module of the GTU, i. e.
168   // track matching
169   // calculation of track parameteres (pt, deflection, ???)
170
171   if (fStack < 0 || fSector < 0) {
172     AliError("No valid stack/sector set for this TMU! No tracking!");
173     return kFALSE;
174   }
175
176   // ----- Input units -----
177   AliDebug(1,"--------- Running Input units ----------");
178   for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
179     if (!RunInputUnit(layer)) {
180       AliError(Form("Input unit in layer %i failed", layer));
181       return kFALSE;
182     }
183   }
184
185   // ----- Z-channel units -----
186   AliDebug(1,"--------- Running Z-channel units ----------");
187   for (Int_t layer = 0;  layer <  fGtuParam->GetNLayers(); layer++) {
188     fZChannelTracklets[layer] = new TList[fGtuParam->GetNZChannels()];
189     if (!RunZChannelUnit(layer)) {
190       AliError(Form("Z-Channel unit in layer %i failed", layer));
191       return kFALSE;
192     }
193   }
194
195   // ----- track finding -----
196   AliDebug(1,"--------- Running tracking units ----------");
197   for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
198     if (!RunTrackFinder(zch, ListOfTracks)) {
199       AliError(Form("Track Finder in z-channel %i failed", zch));
200       return kFALSE;
201     }
202   }
203
204   // ----- Track Merging -----
205   if (!RunTrackMerging(ListOfTracks)) {
206     AliError("Track merging failed");
207     return kFALSE;
208   }
209
210   // ----- track reconstruction -----
211   if (!RunTrackReconstruction(ListOfTracks)) {
212     AliError("Track reconstruction failed");
213     return kFALSE;
214   }
215
216   // ----- label calculation and ESD storage -----
217   TIter next(ListOfTracks);
218   while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) next()) {
219     trk->CookLabel();
220     if (esd) {
221       AliESDTrdTrack *trdtrack = trk->CreateTrdTrack();
222       esd->AddTrdTrack(trdtrack);
223       delete trdtrack;
224     }
225   }
226
227   return kTRUE;
228 }
229
230 Bool_t AliTRDgtuTMU::RunInputUnit(Int_t layer)
231 {
232   // precalculations for the tracking and reconstruction
233
234   Int_t iTrkl0 = 0; // A-side tracklet
235   Int_t iTrkl1 = 0; // B-side tracklet
236
237   while ((iTrkl0 < fTracklets[2*layer + 0]->GetEntriesFast()) || (iTrkl1 < fTracklets[2*layer + 1]->GetEntriesFast())) {
238     if (iTrkl1 >= fTracklets[2*layer + 1]->GetEntriesFast()) {
239       fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 0]->At(iTrkl0));
240       iTrkl0++;
241     }
242     else {
243       if (iTrkl0 >= fTracklets[2*layer + 0]->GetEntriesFast()) {
244         fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 1]->At(iTrkl1));
245         iTrkl1++;
246       }
247       else {
248         if (((AliTRDtrackletGTU*) fTracklets[2*layer + 1]->At(iTrkl1))->GetZbin() <
249             ((AliTRDtrackletGTU*) fTracklets[2*layer + 0]->At(iTrkl0))->GetZbin()) {
250           fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 1]->At(iTrkl1));
251           iTrkl1++;
252
253         }
254         else {
255           fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 0]->At(iTrkl0));
256           iTrkl0++;
257         }
258       }
259     }
260   }
261
262   TIter next(fTrackletsPostInput[layer]);
263
264   while ( AliTRDtrackletGTU *trk = (AliTRDtrackletGTU*) next() ) {
265     trk->SetIndex(fTrackletsPostInput[layer]->IndexOf(trk));
266
267     Int_t alpha = (trk->GetYbin() >> fGtuParam->GetBitExcessY()) * fGtuParam->GetCiAlpha(layer);
268     alpha = ( 2 * trk->GetdY() - (alpha >> fGtuParam->GetBitExcessAlpha()) + 1 ) >> 1;
269     // wrapping projected alpha as in hardware
270     if ((alpha < -64) || (alpha > 63))
271       AliError(Form("alpha out of range: %i", alpha));
272     alpha = alpha & 0x7f;
273     if (alpha & 0x40)
274       trk->SetAlpha(0xffffffc0 | alpha);
275     else
276       trk->SetAlpha(alpha);
277
278     Int_t yproj = trk->GetdY() * (fGtuParam->GetCiYProj(layer));
279     yproj = ( ( ( (yproj >> fGtuParam->GetBitExcessYProj()) + trk->GetYbin() ) >> 2) + 1) >> 1;
280     trk->SetYProj(yproj);
281
282     trk->SetYPrime(trk->GetYbin() + fGtuParam->GetYt(fStack, layer, trk->GetZbin()));
283
284     AliDebug(10, Form("0x%08x: idx: %3i, z: %2i, y: %5i, dy: %3i, y': %5i, y_proj: %5i, alpha: %3i, pid: %3i, c: %5i, yt: %5i",
285                       trk->GetTrackletWord(), trk->GetIndex(), trk->GetZbin(), trk->GetYbin(), trk->GetdY(), trk->GetYPrime(),
286                       trk->GetYProj(), trk->GetAlpha(), trk->GetPID(),
287                       fGtuParam->GetCiYProj(layer), fGtuParam->GetYt(fStack, layer, trk->GetZbin()) ));
288   }
289   return kTRUE;
290 }
291
292 Bool_t AliTRDgtuTMU::RunZChannelUnit(Int_t layer)
293 {
294   // run the z-channel unit
295
296   TIter next(fTrackletsPostInput[layer]);
297
298   while (AliTRDtrackletGTU *trk = (AliTRDtrackletGTU*) next()) {
299     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
300       if (fGtuParam->IsInZChannel(fStack, layer, zch, trk->GetZbin()) ) {
301         trk->SetSubChannel(zch, fGtuParam->GetZSubchannel(fStack, layer, zch, trk->GetZbin()) );
302
303         TIter nexttrkl(&fZChannelTracklets[layer][zch], kIterBackward);
304         AliTRDtrackletGTU *t = 0x0;
305         while ((t = (AliTRDtrackletGTU*) nexttrkl.Next())) {
306           if (t->GetSubChannel(zch) < trk->GetSubChannel(zch) ||
307               ((t->GetSubChannel(zch) == trk->GetSubChannel(zch)) && (t->GetYProj() < trk->GetYProj())) ) {
308             break;
309           }
310         }
311         if (t)
312           fZChannelTracklets[layer][zch].AddAfter(t, trk);
313         else
314           fZChannelTracklets[layer][zch].AddFirst(trk);
315       }
316     }
317     AliDebug(10, Form("stack %d, layer %2d: 0x%08x Z(2..0)=%i/%i/%i",
318                       fStack, layer, trk->GetTrackletWord(),
319                       fGtuParam->IsInZChannel(fStack, layer, 2, trk->GetZbin()) ? trk->GetSubChannel(2) : -1,
320                       fGtuParam->IsInZChannel(fStack, layer, 1, trk->GetZbin()) ? trk->GetSubChannel(1) : -1,
321                       fGtuParam->IsInZChannel(fStack, layer, 0, trk->GetZbin()) ? trk->GetSubChannel(0) : -1
322                       ));
323   }
324   return kTRUE;
325 }
326
327 Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
328 {
329   // run the track finding
330
331    Int_t        *notr = new Int_t[fGtuParam->GetNLayers()];
332    Int_t        *ptrA = new Int_t[fGtuParam->GetNLayers()];
333    Int_t        *ptrB = new Int_t[fGtuParam->GetNLayers()];
334
335    Bool_t       *bHitA     = new Bool_t[fGtuParam->GetNLayers()];
336    Bool_t       *bHitB     = new Bool_t[fGtuParam->GetNLayers()];
337    Bool_t       *bAligned  = new Bool_t[fGtuParam->GetNLayers()];
338    Bool_t       *bAlignedA = new Bool_t[fGtuParam->GetNLayers()];
339    Bool_t       *bAlignedB = new Bool_t[fGtuParam->GetNLayers()];
340    Bool_t       *bDone     = new Bool_t[fGtuParam->GetNLayers()];
341    Bool_t        ready;
342
343    Int_t        *inc      = new Int_t[fGtuParam->GetNLayers()];
344    Int_t        *incprime = new Int_t[fGtuParam->GetNLayers()];
345
346 // ----- signals within current layer -----
347    Int_t        yPlus;
348    Int_t        yMinus;
349    Int_t        ybPlus;
350    Int_t        ybMinus;
351    Int_t        alphaPlus;
352    Int_t        alphaMinus;
353    Int_t        nHits;
354    Int_t        nUnc;
355    Int_t        nWayBeyond;
356
357    AliTRDtrackletGTU    *trkRA  = 0x0;  // reference tracklet A
358    AliTRDtrackletGTU    *trkRB  = 0x0;  // reference tracklet B
359    AliTRDtrackletGTU    *trkA   = 0x0;  // tracklet A in current layer
360    AliTRDtrackletGTU    *trkB   = 0x0;  // tracklet B in current layer
361 /*
362    AliTRDtrackletGTU    *trkEnd = new AliTRDtrackletGTU();
363    for (Int_t i = 0; i < fGtuParam->GetNZChannels(); i++)
364        trkEnd->SetSubChannel(i, 7);
365    trkEnd->SetYProj(0);
366    trkEnd->SetAlpha(0);
367 */
368
369    for (Int_t refLayerIdx = 0; refLayerIdx < fGtuParam->GetNRefLayers(); refLayerIdx++) {
370      Int_t reflayer = fGtuParam->GetRefLayer(refLayerIdx);
371      AliDebug(5,Form("Tracking for z-channel: %i, reflayer: %i", zch, reflayer));
372
373      ready = kFALSE; // ready if all channels done
374
375 //      for (Int_t iLayer = 0; iLayer < fGtuParam->GetNLayers(); iLayer++) {
376 //        for (Int_t iTrkl = 0; iTrkl < fZChannelTracklets[iLayer][zch].GetEntries(); iTrkl++) {
377 //       printf("%4i/%4i(%i,%i) ",
378 //              ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetYProj(),
379 //              ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetAlpha(),
380 //              ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetIndex(),
381 //              ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetSubChannel(zch)
382 //              );
383 //        }
384 //        printf("\n");
385 //      }
386
387      for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
388        notr[layer] = fZChannelTracklets[layer][zch].GetEntries();
389        ptrA[layer] = 0; // notr[layer] > 0 ? 0 : -1;
390        ptrB[layer] = 1; // notr[layer] > 1 ? 1 : -1;
391
392 // not necessary here
393 //       bDone[layer] = (ptrB[layer] >= notr[layer] - 1); // trkB is last one
394 //       bDone[layer] = (notr[layer] <= 0);
395 //       ready = ready && bDone[layer];
396
397        if (reflayer == 1)
398          AliDebug(5,Form("in layer: %i (zchannel = %i) there are: %i tracklets", layer, zch, notr[layer]));
399      }
400
401      if (ptrA[reflayer] < 0 && ptrB[reflayer] < 0)
402        continue;
403
404      while (!ready) {
405        // ----- reference tracklets -----
406        trkRA = 0x0;
407        trkRB = 0x0;
408        if (0 <= ptrA[reflayer] && ptrA[reflayer] < notr[reflayer])
409          trkRA = (AliTRDtrackletGTU*) fZChannelTracklets[reflayer][zch].At(ptrA[reflayer]);
410        else  {
411          AliDebug(10,Form("No valid tracklet in the reference at ptr: %i! Nothing done!", ptrA[reflayer]));
412          break;
413        }
414
415        if (0 <= ptrB[reflayer] && ptrB[reflayer] < notr[reflayer])
416          trkRB = (AliTRDtrackletGTU*) fZChannelTracklets[reflayer][zch].At(ptrB[reflayer]);
417
418        yPlus      = trkRA->GetYProj() + fGtuParam->GetDeltaY();
419        yMinus     = trkRA->GetYProj() - fGtuParam->GetDeltaY();
420        alphaPlus  = trkRA->GetAlpha() + fGtuParam->GetDeltaAlpha();
421        alphaMinus = trkRA->GetAlpha() - fGtuParam->GetDeltaAlpha();
422        if (trkRB) {
423          ybPlus           = trkRB->GetYProj() + fGtuParam->GetDeltaY();
424          ybMinus          = trkRB->GetYProj() - fGtuParam->GetDeltaY();
425        }
426        else { // irrelevant (should be, is it?)
427          ybPlus           = trkRA->GetYProj() + fGtuParam->GetDeltaY();
428          ybMinus          = trkRA->GetYProj() - fGtuParam->GetDeltaY();
429        }
430
431        nHits      = 0;
432        nUnc       = 0;
433        nWayBeyond = 0;
434
435        for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
436          bHitA[layer] = bHitB[layer] = bAligned[layer] = kFALSE;
437          inc[layer] = incprime[layer] = 0;
438
439          if (layer == reflayer) {
440            bHitA[layer] = kTRUE;
441            bAligned[layer] = kTRUE;
442            nHits++;
443            continue;
444          }
445
446          trkA = 0x0;
447          trkB = 0x0;
448          if (0 <= ptrA[layer] && ptrA[layer] < notr[layer])
449            trkA = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]);
450          if (0 <= ptrB[layer] && ptrB[layer] < notr[layer])
451            trkB = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]);
452
453          bAlignedA[layer] = kFALSE;
454          bAlignedB[layer] = kFALSE;
455
456          if (trkA) {
457            bHitA[layer] = ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) &&
458                             !(trkA->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() > yPlus)  ) &&
459                             !(trkA->GetAlpha() < alphaMinus) &&
460                             !(trkA->GetAlpha() > alphaPlus) );
461            bAlignedA[layer] = !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) );
462          }
463          else {
464            bHitA[layer] = 0;
465            bAlignedA[layer] = kTRUE;
466          }
467
468          if (trkB) {
469            bHitB[layer] = ( !(trkB->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() < yMinus) ) &&
470                             !(trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) ) &&
471                             !(trkB->GetAlpha() < alphaMinus) &&
472                             !(trkB->GetAlpha() > alphaPlus) );
473            bAlignedB[layer] = (trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) );
474          }
475          else {
476            bHitB[layer] = 0;
477            bAlignedB[layer] = kTRUE;
478          }
479
480          bAligned[layer] = bAlignedA[layer] || bAlignedB[layer]; //???
481 //       bAligned[layer] = bAlignedA[layer]; //???
482
483          if (bAligned[layer] && (bHitA[layer] || bHitB[layer]) )
484            nHits++;
485          else if (!bAligned[layer] )
486            nUnc++;
487          if (trkRB) {
488            if (trkA) {
489              if ((trkA->GetSubChannel(zch) > trkRB->GetSubChannel(zch)) || (trkA->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkA->GetYProj() > ybPlus) )
490                nWayBeyond++;
491            }
492            else
493              nWayBeyond++;
494          }
495
496          //  pre-calculation for the layer shifting (alignment w. r. t. trkRB)
497          if (trkA) {
498              if(trkRB) {
499                  if ((trkA->GetSubChannel(zch) < trkRB->GetSubChannel(zch)) || (trkA->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkA->GetYProj() < ybMinus )) // could trkA be aligned for trkRB
500                      incprime[layer] = 1;
501                  else
502                      incprime[layer] = 0;
503              }
504              else
505                  incprime[layer] = 1;
506
507              if (trkB) {
508                  if (trkRB) {
509                      if ((trkB->GetSubChannel(zch) < trkRB->GetSubChannel(zch)) || (trkB->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkB->GetYProj() < ybMinus )) // could trkB be aligned for trkRB
510                          incprime[layer] = 2;
511                  }
512                  else
513                      incprime[layer] = 2;
514              }
515          }
516        } // end of loop over layers
517
518        AliDebug(5,Form("logic calculation finished, Nhits: %i %s",
519                        nHits, (nHits >= 4) ? "-> track found" : ""));
520
521        if (nHits >= 4) {
522          // ----- track registration -----
523          AliTRDtrackGTU *track = new AliTRDtrackGTU();
524          track->SetSector(fSector);
525          track->SetStack(fStack);
526          for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++ ) {
527            if (bHitA[layer] || layer == reflayer)
528              track->AddTracklet((AliTRDtrackletGTU* ) fZChannelTracklets[layer][zch].At(ptrA[layer]), layer );
529            else if (bHitB[layer])
530              track->AddTracklet((AliTRDtrackletGTU* ) fZChannelTracklets[layer][zch].At(ptrB[layer]), layer );
531          }
532
533          Bool_t registerTrack = kTRUE;
534          for (Int_t layerIdx = refLayerIdx-1; layerIdx >= 0; layerIdx--) {
535            if (track->IsTrackletInLayer(fGtuParam->GetRefLayer(layerIdx))) {
536              if ((track->GetTracklet(fGtuParam->GetRefLayer(layerIdx)))->GetSubChannel(zch) > 0) {
537                AliDebug(1,"Not registered");
538                  registerTrack = kFALSE;
539              }
540            }
541          }
542          if (registerTrack) {
543              track->SetZChannel(zch);
544              track->SetRefLayerIdx(refLayerIdx);
545              fTracks[zch][refLayerIdx].Add(track);
546          }
547        }
548
549        if ( (nUnc != 0) && (nUnc + nHits >= 4) ) // could this position of the reference layer give some track //??? special check in case of hit?
550           inc[reflayer] = 0;
551        else if (nWayBeyond > 2) // no track possible for both reference tracklets
552          inc[reflayer] = 2;
553        else
554          inc[reflayer] = 1;
555
556        if (inc[reflayer] != 0) // reflayer is shifted
557          for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
558            if (layer == reflayer)
559              continue;
560            inc[layer] = incprime[layer];
561          }
562        else { // reflayer is not shifted
563          for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
564            if (layer == reflayer || notr[layer] == 0)
565              continue;
566            inc[layer] = 0;
567            trkA = 0x0;
568            trkB = 0x0;
569            if (0 <= ptrA[layer] && ptrA[layer] < notr[layer])
570              trkA = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]);
571
572            if (0 <= ptrB[layer] && ptrB[layer] < notr[layer])
573              trkB = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]);
574
575            if (trkA) {
576              if ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) &&
577                   !(trkA->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() > yPlus ) ) )  // trkA could hit trkRA
578              // if ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) )
579                    inc[layer] = 0;
580                else if (trkB) {
581                    if ( trkB->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() < yMinus) )
582                        inc[layer] = 2;
583                    else if ( !(trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) ) )
584                        inc[layer] = 1;
585                    else
586                        inc[layer] = incprime[layer];
587                }
588                else
589                    inc[layer] = incprime[layer];
590            }
591          }
592        }
593
594        ready = kTRUE;
595        for (Int_t layer = fGtuParam->GetNLayers()-1; layer >= 0; layer--) {
596
597          bDone[layer] = ptrB[layer] < 0 || ptrB[layer] >= notr[layer];
598          ready = ready && bDone[layer];
599
600          if (inc[layer] != 0 && ptrA[layer] >= notr[layer])
601            AliError(Form("Invalid increment: %i at ptrA: %i, notr: %i", inc[layer], ptrA[layer], notr[layer]));
602
603 //       AliInfo(Form("Shifting layer: %i, notr: %i, ptrA: %i, ptrB: %i, inc: %i", layer, notr[layer], ptrA[layer], ptrB[layer], inc[layer]));
604          AliDebug(10,Form("    Layer: %i   %2i(%2i, %2i, %4i, %3i)%s%s   %2i(%2i, %2i, %4i, %3i)%s%s   +%i   %s  (no: %i)",
605                           layer,
606                           ptrA[layer],
607                           (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetIndex() : -1,
608                           (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetSubChannel(zch) : -1,
609                           (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetYProj() : -1,
610                           (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetAlpha() : -1,
611                           bHitA[layer] ? "*" : " ", bAlignedA[layer] ? "+" : " ",
612                           ptrB[layer],
613                           (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetIndex() : -1,
614                           (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetSubChannel(zch) : -1,
615                           (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetYProj() : -1,
616                           (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetAlpha() : -1,
617                           bHitB[layer] ? "*" : " ", bAlignedB[layer] ? "+" : " ",
618                           inc[layer], bDone[layer] ? "done" : "    ", notr[layer]));
619          ptrA[layer] += inc[layer];
620          ptrB[layer] += inc[layer];
621        }
622
623      } // end of while
624    } // end of loop over reflayer
625
626    delete [] bHitA;
627    delete [] bHitB;
628    delete [] bAligned;
629    delete [] bDone;
630    delete [] inc;
631    delete [] incprime;
632    delete [] bAlignedA;
633    delete [] bAlignedB;
634    delete [] notr;
635    delete [] ptrA;
636    delete [] ptrB;
637
638    return kTRUE;
639 }
640
641 Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
642 {
643     TList **tracksRefMerged = new TList*[fGtuParam->GetNZChannels()];
644     TList **tracksRefUnique = new TList*[fGtuParam->GetNZChannels()];
645
646     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
647         tracksRefMerged[zch] = new TList;
648         tracksRefUnique[zch] = new TList;
649     }
650
651     TList *tracksZMergedStage0 = new TList;
652     TList *tracksZUniqueStage0 = new TList;
653
654     TList **tracksZSplitted = new TList*[2];
655     for (Int_t i = 0; i < 2; i++)
656         tracksZSplitted[i] = new TList;
657
658     TList *tracksZMergedStage1 = new TList;
659
660     AliTRDtrackGTU **trkInRefLayer = new AliTRDtrackGTU*[fGtuParam->GetNRefLayers()];
661
662     // Bool_t done = kFALSE;
663     Int_t minIdx = 0;
664     AliTRDtrackGTU *trkStage0 = 0x0;
665
666     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
667         // ----- Merging and Unification in Reflayers (seed_merger) -----
668         do {
669           // done = kTRUE;
670             trkStage0 = 0x0;
671             for (Int_t refLayerIdx = 0; refLayerIdx < fGtuParam->GetNRefLayers(); refLayerIdx++) {
672                 trkInRefLayer[refLayerIdx] = (AliTRDtrackGTU*) fTracks[zch][refLayerIdx].First();
673                 if (trkInRefLayer[refLayerIdx] == 0) {
674                     continue;
675                 }
676                 else if (trkStage0 == 0x0 ) {
677                     trkStage0 = trkInRefLayer[refLayerIdx];
678                     minIdx = refLayerIdx;
679                     // done = kFALSE;
680                 }
681                 else if ( (trkInRefLayer[refLayerIdx]->GetZSubChannel() < trkStage0->GetZSubChannel()) ||
682                           ((trkInRefLayer[refLayerIdx]->GetZSubChannel() == trkStage0->GetZSubChannel()) &&
683                            ((trkInRefLayer[refLayerIdx]->GetYapprox() >> 3) < (trkStage0->GetYapprox() >> 3)) ) ) {
684                     minIdx = refLayerIdx;
685                     trkStage0 = trkInRefLayer[refLayerIdx];
686                     // done = kFALSE;
687                 }
688             }
689             if (!trkStage0)
690               break;
691             tracksRefMerged[zch]->Add(trkStage0);
692             fTracks[zch][minIdx].RemoveFirst();
693         } while (trkStage0 != 0);
694
695         Uniquifier(tracksRefMerged[zch], tracksRefUnique[zch]);
696
697         AliDebug(2, Form("zchannel %i", zch));
698         TIter trackRefMerged(tracksRefMerged[zch]);
699         while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackRefMerged())
700           AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, z_idx=%i",
701                            AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
702                            trk->GetTrackletIndex(5),
703                            trk->GetTrackletIndex(4),
704                            trk->GetTrackletIndex(3),
705                            trk->GetTrackletIndex(2),
706                            trk->GetTrackletIndex(1),
707                            trk->GetTrackletIndex(0),
708                            trk->GetYapprox() >> 3,
709                            trk->GetZSubChannel()));
710         AliDebug(2, "uniquified:");
711         TIter trackRefUnique(tracksRefUnique[zch]);
712         while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackRefUnique())
713           AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, z_idx=%i",
714                            AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
715                            trk->GetTrackletIndex(5),
716                            trk->GetTrackletIndex(4),
717                            trk->GetTrackletIndex(3),
718                            trk->GetTrackletIndex(2),
719                            trk->GetTrackletIndex(1),
720                            trk->GetTrackletIndex(0),
721                            trk->GetYapprox() >> 3,
722                            trk->GetZSubChannel()));
723     }
724
725 // ----- Merging in zchannels - 1st stage -----
726
727     if (AliTRDgtuParam::GetUseGTUmerge()) {
728       Int_t notEmpty;
729       do {
730         Bool_t lowerThan[3] = { kFALSE, kFALSE, kFALSE };
731         AliTRDtrackGTU *trk[3] = { 0x0, 0x0, 0x0 };
732         for (Int_t iChannel = 0; iChannel < fGtuParam->GetNZChannels(); ++iChannel)
733           trk[iChannel] = (AliTRDtrackGTU*) tracksRefUnique[iChannel]->First();
734
735         for (Int_t iChannel = 0; iChannel < fGtuParam->GetNZChannels(); ++iChannel) {
736           AliTRDtrackGTU *trk1 = trk[iChannel];
737           AliTRDtrackGTU *trk2 = trk[(iChannel + 1) % 3];
738           if (trk1 && trk2) {
739             Int_t sortnum1 = (trk1->GetZChannel() + 3 * trk1->GetZSubChannel()) / 2 - 1;
740             Int_t sortnum2 = (trk2->GetZChannel() + 3 * trk2->GetZSubChannel()) / 2 - 1;
741             AliDebug(5, Form("comparing tracks %i - %i: %i - %i",
742                              trk1->GetZChannel(), trk2->GetZChannel(),
743                              sortnum1, sortnum2));
744             if ( (sortnum1 < sortnum2) ||
745                  ((sortnum1 == sortnum2) &&
746                   ((trk1->GetYapprox() >> 3) < (trk2->GetYapprox() >> 3)) ) ) {
747               lowerThan[iChannel] = kTRUE;
748             }
749           }
750         }
751
752         notEmpty = (trk[2] ? (1 << 2) : 0) |
753           (trk[1] ? (1 << 1) : 0) |
754           (trk[0] ? (1 << 0) : 0);
755         Int_t pop = -1;
756
757         switch (notEmpty) {
758           // one track only
759         case 0x1:
760           pop = 0;
761           break;
762         case 0x2:
763           pop = 1;
764           break;
765         case 0x4:
766           pop = 2;
767           break;
768
769           // two tracks
770         case 0x3:
771           if (lowerThan[0])
772             pop = 0;
773           else
774             pop = 1;
775           break;
776         case 0x5:
777           if (lowerThan[2])
778             pop = 2;
779           else
780             pop = 0;
781           break;
782         case 0x6:
783           if (lowerThan[1])
784             pop = 1;
785           else
786             pop = 2;
787           break;
788
789           // three tracks
790         case 0x7:
791           if (lowerThan[0]) {
792             if (lowerThan[2])
793               pop = 2;
794             else
795               pop = 0;
796           } else {
797             if (lowerThan[1])
798               pop = 1;
799             else
800               pop = 2;
801           }
802           break;
803
804           // no tracks
805         default:
806           // nop
807           ;
808         }
809
810         if (pop > -1) {
811           tracksZMergedStage0->Add(trk[pop]);
812           tracksRefUnique[pop]->RemoveFirst();
813         }
814       } while (notEmpty);
815     }
816     else {
817       // there is still a difference between this implementation and
818       // the hardware algorithm, only for expert use
819
820       do {
821         // done = kTRUE;
822         trkStage0 = 0x0;
823         // compare tracks from all adjacent zchannels
824         // (including comparison of channels 2 and 0)
825         for (Int_t i = fGtuParam->GetNZChannels() - 1; i > -1; i--) {
826           Int_t zch = i % 3;
827           AliTRDtrackGTU *trk = (AliTRDtrackGTU*) tracksRefUnique[zch]->First();
828           if (trk == 0) {
829             continue;
830           }
831           else if (trkStage0 == 0x0 ) {
832             trkStage0 = trk;
833             minIdx = zch;
834             // done = kFALSE;
835           }
836           else {
837             Int_t sortnum1 = (trk->GetZChannel() + 3 * trk->GetZSubChannel()) / 2 - 1;
838             Int_t sortnum2 = (trkStage0->GetZChannel() + 3 * trkStage0->GetZSubChannel()) / 2 - 1;
839             AliDebug(5, Form("comparing tracks %i - %i: %i - %i",
840                              trk->GetZChannel(), trkStage0->GetZChannel(),
841                              sortnum1, sortnum2));
842             if ( (sortnum1 < sortnum2) ||
843                  ((sortnum1 == sortnum2) &&
844                   ((trk->GetYapprox() >> 3) < (trkStage0->GetYapprox() >> 3)) ) ) {
845               minIdx = zch;
846               trkStage0 = trk;
847               // done = kFALSE;
848             }
849           }
850         }
851
852         if (!trkStage0)
853           break;
854         tracksZMergedStage0->Add(trkStage0);
855         tracksRefUnique[minIdx]->RemoveFirst();
856       } while (trkStage0 != 0);
857     }
858
859     Uniquifier(tracksZMergedStage0, tracksZUniqueStage0);
860
861     AliDebug(2, "stage 0:");
862     TIter trackZMergedStage0(tracksZMergedStage0);
863     while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZMergedStage0())
864       AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
865                        AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
866                        trk->GetTrackletIndex(5),
867                        trk->GetTrackletIndex(4),
868                        trk->GetTrackletIndex(3),
869                        trk->GetTrackletIndex(2),
870                        trk->GetTrackletIndex(1),
871                        trk->GetTrackletIndex(0),
872                        trk->GetYapprox() >> 3,
873                        trk->GetZChannel(),
874                        trk->GetZSubChannel()));
875
876     AliDebug(2, "uniquified:");
877     TIter trackZUniqueStage0(tracksZUniqueStage0);
878     while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZUniqueStage0())
879       AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
880                        AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
881                        trk->GetTrackletIndex(5),
882                        trk->GetTrackletIndex(4),
883                        trk->GetTrackletIndex(3),
884                        trk->GetTrackletIndex(2),
885                        trk->GetTrackletIndex(1),
886                        trk->GetTrackletIndex(0),
887                        trk->GetYapprox() >> 3,
888                        trk->GetZChannel(),
889                        trk->GetZSubChannel()));
890
891 // ----- Splitting in z -----
892
893     TIter next(tracksZUniqueStage0);
894     while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) next()) {
895         tracksZSplitted[(trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) % 2]->Add(trk);
896     }
897
898     for (Int_t i = 0; i < 2; i++) {
899       AliDebug(2, Form("split %i:", i));
900       TIter trackZSplit(tracksZSplitted[i]);
901       while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZSplit())
902         AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
903                          AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
904                          trk->GetTrackletIndex(5),
905                          trk->GetTrackletIndex(4),
906                          trk->GetTrackletIndex(3),
907                          trk->GetTrackletIndex(2),
908                          trk->GetTrackletIndex(1),
909                          trk->GetTrackletIndex(0),
910                          trk->GetYapprox() >> 3,
911                          trk->GetZChannel(),
912                          trk->GetZSubChannel()));
913     }
914
915 // ----- Merging in zchanels - 2nd stage -----
916
917     do {
918       // done = kTRUE;
919         trkStage0 = 0x0;
920         for (Int_t i = 1; i >= 0; i--) {
921             AliTRDtrackGTU *trk = (AliTRDtrackGTU*) tracksZSplitted[i]->First();
922             if (trk == 0) {
923                 continue;
924             }
925             else if (trkStage0 == 0x0 ) {
926                 trkStage0 = trk;
927                 minIdx = i;
928                 // done = kFALSE;
929             }
930             else if (  (((trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) / 2) <  ((trkStage0->GetZChannel() + 3 * (trkStage0->GetZSubChannel() - 1)) / 2)) ||
931                       ((((trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) / 2) == ((trkStage0->GetZChannel() + 3 * (trkStage0->GetZSubChannel() - 1)) / 2)) &&
932                        ((trk->GetYapprox() >> 3) < (trkStage0->GetYapprox() >> 3)) ) ) {
933                 minIdx = i;
934                 trkStage0 = trk;
935                 // done = kFALSE;
936             }
937         }
938
939         if (!trkStage0)
940           break;
941         tracksZMergedStage1->Add(trkStage0);
942         tracksZSplitted[minIdx]->RemoveFirst();
943     } while (trkStage0 != 0);
944
945     Uniquifier(tracksZMergedStage1, ListOfTracks);
946
947     AliDebug(2, "merged:");
948     TIter trackZMergedStage1(tracksZMergedStage1);
949     while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZMergedStage1())
950       AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
951                        AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
952                        trk->GetTrackletIndex(5),
953                        trk->GetTrackletIndex(4),
954                        trk->GetTrackletIndex(3),
955                        trk->GetTrackletIndex(2),
956                        trk->GetTrackletIndex(1),
957                        trk->GetTrackletIndex(0),
958                        trk->GetYapprox() >> 3,
959                        trk->GetZChannel(),
960                        trk->GetZSubChannel()));
961
962     AliDebug(2, "uniquified:");
963     TIter track(ListOfTracks);
964     while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) track())
965       AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
966                        AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
967                        trk->GetTrackletIndex(5),
968                        trk->GetTrackletIndex(4),
969                        trk->GetTrackletIndex(3),
970                        trk->GetTrackletIndex(2),
971                        trk->GetTrackletIndex(1),
972                        trk->GetTrackletIndex(0),
973                        trk->GetYapprox() >> 3,
974                        trk->GetZChannel(),
975                        trk->GetZSubChannel()));
976
977     // cleaning up
978     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
979       delete tracksRefMerged[zch];
980       delete tracksRefUnique[zch];
981     }
982     delete [] tracksRefMerged;
983     delete [] tracksRefUnique;
984
985
986     delete tracksZMergedStage0;
987     delete tracksZUniqueStage0;
988
989     for (Int_t i = 0; i < 2; i++)
990       delete tracksZSplitted[i];
991     delete [] tracksZSplitted;
992
993     delete tracksZMergedStage1;
994
995     delete [] trkInRefLayer;
996
997     return kTRUE;
998 }
999
1000 Bool_t AliTRDgtuTMU::RunTrackReconstruction(TList* ListOfTracks)
1001 {
1002   // run the track reconstruction for all tracks in the list
1003
1004   TIter next(ListOfTracks);
1005   while (AliTRDtrackGTU *track = (AliTRDtrackGTU*) next()) {
1006     CalculateTrackParams(track);
1007     CalculatePID(track);
1008     AliDebug(1, Form("track with pid = %i", track->GetPID()));
1009   }
1010   return kTRUE;
1011 }
1012
1013 Bool_t AliTRDgtuTMU::CalculatePID(AliTRDtrackGTU *track)
1014 {
1015   // calculate PID for the given track
1016   if (!track) {
1017     AliError("No track to calculate!");
1018     return kFALSE;
1019   }
1020
1021   if (AliTRDgtuParam::GetUseGTUconst()) {
1022     // averaging as in GTU
1023     AliDebug(1, "using GTU constants for PID calculation");
1024     ULong64_t coeff;
1025
1026     // selection of coefficient for averaging
1027     switch(track->GetTrackletMask()){
1028     case 0x3f:
1029       // 6 tracklets
1030       coeff=0x5558; // approx. 1/6
1031       break;
1032
1033     case 0x3e:
1034     case 0x3d:
1035     case 0x3b:
1036     case 0x37:
1037     case 0x2f:
1038     case 0x1f:
1039       // 5 tracklets
1040       coeff=0x6666; // approx. 1/5
1041       break;
1042
1043     default:
1044       // 4 tracklets
1045       coeff=0x8000; // = 0.25
1046     }
1047     coeff &= 0x1ffff; // 17-bit constant
1048
1049     ULong64_t sum = 0;
1050     Int_t i = 0;
1051     for (Int_t iLayer = 0; iLayer < fGtuParam->GetNLayers(); iLayer++) {
1052       if ((track->GetTrackletMask() >> iLayer) & 1) {
1053         sum += track->GetTracklet(iLayer)->GetPID();
1054         ++i;
1055       }
1056     }
1057
1058     Float_t av = 1./i * sum;
1059     sum = sum & 0x7ff;
1060     ULong64_t prod   = (sum * coeff) & 0xfffffffffull;
1061     ULong64_t prodFinal = ((prod >> 17) + ((prod >> 16) & 1)) & 0xff;
1062
1063     if (TMath::Abs((prodFinal & 0xff) - av) > 0.5)
1064       AliError(Form("problem with PID averaging (hw <-> ar): %3lli <-> %4.1f", prodFinal & 0xff, av));
1065     track->SetPID(prodFinal & 0xff);
1066
1067     return kTRUE;
1068   }
1069   else {
1070
1071     // simple averaging
1072     Int_t nTracklets = 0;
1073     Int_t pidSum = 0;
1074     for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
1075       if (!track->IsTrackletInLayer(layer)) {
1076         continue;
1077       }
1078       AliTRDtrackletGTU *trk = track->GetTracklet(layer);
1079       pidSum += trk->GetPID();
1080       nTracklets++;
1081     }
1082
1083     if (nTracklets>0)
1084       track->SetPID(pidSum/nTracklets);
1085     else
1086       AliError("Track without contributing tracklets, no PID assigned");
1087
1088     return kTRUE;
1089   }
1090 }
1091
1092 Bool_t AliTRDgtuTMU::CalculateTrackParams(AliTRDtrackGTU *track)
1093 {
1094   // calculate the track parameters
1095
1096   if (!track) {
1097     AliError("No track to calculate!");
1098     return kFALSE;
1099   }
1100
1101   Int_t a = 0;
1102   Float_t b = 0;
1103   Float_t c = 0;
1104   Float_t x1;
1105   Float_t x2;
1106
1107   AliDebug(5,Form("There are %i tracklets in this track.", track->GetNTracklets()));
1108
1109   for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
1110     if (!track->IsTrackletInLayer(layer)) {
1111       continue;
1112     }
1113     AliTRDtrackletGTU *trk = track->GetTracklet(layer);
1114     if (!trk) {
1115       AliError(Form("Could not get tracklet in layer %i\n", layer));
1116       continue;
1117     }
1118     AliDebug(10,Form("  layer %i trk yprime: %6i, aki: %6i", layer, trk->GetYPrime(),
1119                      fGtuParam->GetAki(track->GetTrackletMask(), layer)));
1120     a += (((fGtuParam->GetAki(track->GetTrackletMask(), layer) * trk->GetYPrime()) >> 7) + 1) >> 1;
1121     b += fGtuParam->GetBki(track->GetTrackletMask(), layer) * trk->GetYPrime() * fGtuParam->GetBinWidthY();
1122     c += fGtuParam->GetCki(track->GetTrackletMask(), layer) * trk->GetYPrime() * fGtuParam->GetBinWidthY();
1123   }
1124   if (a < 0)
1125       a += 3;
1126   a = a >> 2;
1127
1128   track->SetFitParams(a << 2, b, c);
1129
1130   fGtuParam->GetIntersectionPoints(track->GetTrackletMask(), x1, x2);
1131
1132   AliDebug(5,Form("  Track parameters: a16 = %i, a18 = %i, b = %f, c = %f, x1 = %f, x2 = %f, pt = %f (trkl mask: %i)",
1133                   a, a << 2, b, c, x1, x2, track->GetPt(), track->GetTrackletMask()));
1134
1135   return kTRUE;
1136 }
1137
1138
1139 Bool_t AliTRDgtuTMU::Uniquifier(const TList *inlist, TList *outlist)
1140 {
1141   // remove multiple occurences of the same track
1142
1143     TIter next(inlist);
1144     AliTRDtrackGTU *trkStage0 = 0x0;
1145     AliTRDtrackGTU *trkStage1 = 0x0;
1146
1147     do {
1148         trkStage0 = (AliTRDtrackGTU*) next();
1149
1150         Bool_t tracksEqual = kFALSE;
1151         if (trkStage0 != 0 && trkStage1 != 0) {
1152             for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
1153                 if (trkStage0->GetTrackletIndex(layer) != -1 && trkStage0->GetTrackletIndex(layer) == trkStage1->GetTrackletIndex(layer)) {
1154                     tracksEqual = kTRUE;
1155                     break;
1156                 }
1157             }
1158         }
1159
1160         if (tracksEqual) {
1161             if (trkStage0->GetNTracklets() >= trkStage1->GetNTracklets())
1162                 trkStage1 = trkStage0;
1163         }
1164         else {
1165             if (trkStage1 != 0x0)
1166                 outlist->Add(trkStage1);
1167             trkStage1 = trkStage0;
1168         }
1169
1170     } while (trkStage1 != 0x0);
1171     return kTRUE;
1172 }