Bug fix in the constructor (thanks to A.Marin)
[u/mrichter/AliRoot.git] / TRD / AliTRDgtuTMU.cxx
index eeb9043..1740211 100644 (file)
@@ -44,41 +44,60 @@ ClassImp(AliTRDgtuTMU)
 AliTRDgtuTMU::AliTRDgtuTMU(Int_t stack, Int_t sector) :
   TObject(),
   fTracklets(0x0),
+  fTrackletsPostInput(0x0),
   fZChannelTracklets(0x0),
   fTracks(0x0),
   fGtuParam(0x0),
   fStack(-1),
   fSector(-1)
 {
+  // constructor which initializes the position information of the TMU
+
   fGtuParam = AliTRDgtuParam::Instance();
-  fTracklets = new TObjArray*[fGtuParam->GetNLayers()];
+
+  // store tracklets per link
+  fTracklets = new TObjArray*[fGtuParam->GetNLinks()];
+  for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
+    fTracklets[iLink] = new TObjArray();
+  }
+
+  // tracklets after input units per layer
+  fTrackletsPostInput = new TObjArray*[fGtuParam->GetNLayers()];
   fZChannelTracklets = new TList*[fGtuParam->GetNLayers()];
   for (Int_t layer = 0;  layer <  fGtuParam->GetNLayers(); layer++) {
-    fTracklets[layer] = new TObjArray();
     fZChannelTracklets[layer] = new TList[fGtuParam->GetNZChannels()];
+    fTrackletsPostInput[layer] = new TObjArray();
   }
+
   fTracks = new TList*[fGtuParam->GetNZChannels()];
   for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
       fTracks[zch] = new TList[fGtuParam->GetNRefLayers()];
   }
-  if (stack > -1) 
+
+  if (stack > -1)
       SetStack(stack);
   if (sector > -1)
       SetSector(sector);
 }
 
-AliTRDgtuTMU::~AliTRDgtuTMU() 
+AliTRDgtuTMU::~AliTRDgtuTMU()
 {
+  // destructor
+
   for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
     delete [] fTracks[zch];
   }
   delete [] fTracks;
   for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
-    fTracklets[layer]->Delete(); 
     delete [] fZChannelTracklets[layer];
-    delete fTracklets[layer];
+    //    delete [] fTrackletsPostInput[layer];
   }
   delete [] fZChannelTracklets;
+  //  delete [] fTrackletsPostInput;
+
+  for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
+    delete fTracklets[iLink];
+  }
   delete [] fTracklets;
 }
 
@@ -87,7 +106,7 @@ Bool_t AliTRDgtuTMU::SetSector(Int_t sector)
   // set the sector
 
   if (sector > -1 && sector < fGtuParam->GetGeo()->Nsector() ) {
-    fSector = sector; 
+    fSector = sector;
     return kTRUE;
   }
 
@@ -95,7 +114,7 @@ Bool_t AliTRDgtuTMU::SetSector(Int_t sector)
   return kFALSE;
 }
 
-Bool_t AliTRDgtuTMU::SetStack(Int_t stack) 
+Bool_t AliTRDgtuTMU::SetStack(Int_t stack)
 {
   // Set the stack (necessary for tracking)
 
@@ -108,7 +127,7 @@ Bool_t AliTRDgtuTMU::SetStack(Int_t stack)
   return kFALSE;
 }
 
-Bool_t AliTRDgtuTMU::Reset() 
+Bool_t AliTRDgtuTMU::Reset()
 {
   // delete all tracks
 
@@ -119,10 +138,13 @@ Bool_t AliTRDgtuTMU::Reset()
   }
 
   // delete all added tracklets
+  for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
+    fTracklets[iLink]->Clear();
+  }
   for (Int_t layer = 0; layer < fGtuParam->GetNLinks()/2; layer++) {
+    fTrackletsPostInput[layer]->Clear();
     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++)
       fZChannelTracklets[layer][zch].Clear();
-    fTracklets[layer]->Delete();
   }
 
   fSector = -1;
@@ -131,24 +153,23 @@ Bool_t AliTRDgtuTMU::Reset()
   return kTRUE;
 }
 
-Bool_t AliTRDgtuTMU::AddTracklet(AliTRDtrackletBase *tracklet, Int_t link) 
+Bool_t AliTRDgtuTMU::AddTracklet(AliTRDtrackletGTU *tracklet, Int_t link)
 {
   // add a tracklet on the given link
 
-  AliTRDtrackletGTU *trkl = new AliTRDtrackletGTU(tracklet); 
-  fTracklets[(Int_t) link/2]->Add(trkl);
+  fTracklets[link]->Add(tracklet);
   return kTRUE;
 }
 
 
-Bool_t AliTRDgtuTMU::RunTMU(TList *ListOfTracks, AliESDEvent *esd) 
+Bool_t AliTRDgtuTMU::RunTMU(TList *ListOfTracks, AliESDEvent *esd)
 {
   // performs the analysis as in a TMU module of the GTU, i. e.
   // track matching
   // calculation of track parameteres (pt, deflection, ???)
 
   if (fStack < 0 || fSector < 0) {
-    AliError("No valid stack/sector set for this TMU! Tracking aborted!");
+    AliError("No valid stack/sector set for this TMU! No tracking!");
     return kFALSE;
   }
 
@@ -174,12 +195,11 @@ Bool_t AliTRDgtuTMU::RunTMU(TList *ListOfTracks, AliESDEvent *esd)
   // ----- track finding -----
   AliDebug(1,"--------- Running tracking units ----------");
   for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
-    AliDebug(2,Form("Track finder for Zchannel: %i", zch));
     if (!RunTrackFinder(zch, ListOfTracks)) {
       AliError(Form("Track Finder in z-channel %i failed", zch));
       return kFALSE;
     }
-  } 
+  }
 
   // ----- Track Merging -----
   if (!RunTrackMerging(ListOfTracks)) {
@@ -205,19 +225,53 @@ Bool_t AliTRDgtuTMU::RunTMU(TList *ListOfTracks, AliESDEvent *esd)
   return kTRUE;
 }
 
-Bool_t AliTRDgtuTMU::RunInputUnit(Int_t layer) 
+Bool_t AliTRDgtuTMU::RunInputUnit(Int_t layer)
 {
   // precalculations for the tracking and reconstruction
 
-  fTracklets[layer]->Sort();
-  TIter next(fTracklets[layer]);
+  Int_t iTrkl0 = 0; // A-side tracklet
+  Int_t iTrkl1 = 0; // B-side tracklet
+
+  while ((iTrkl0 < fTracklets[2*layer + 0]->GetEntriesFast()) || (iTrkl1 < fTracklets[2*layer + 1]->GetEntriesFast())) {
+    if (iTrkl1 >= fTracklets[2*layer + 1]->GetEntriesFast()) {
+      fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 0]->At(iTrkl0));
+      iTrkl0++;
+    }
+    else {
+      if (iTrkl0 >= fTracklets[2*layer + 0]->GetEntriesFast()) {
+       fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 1]->At(iTrkl1));
+       iTrkl1++;
+      }
+      else {
+       if (((AliTRDtrackletGTU*) fTracklets[2*layer + 1]->At(iTrkl1))->GetZbin() <
+           ((AliTRDtrackletGTU*) fTracklets[2*layer + 0]->At(iTrkl0))->GetZbin()) {
+         fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 1]->At(iTrkl1));
+         iTrkl1++;
+
+       }
+       else {
+         fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 0]->At(iTrkl0));
+         iTrkl0++;
+       }
+      }
+    }
+  }
+
+  TIter next(fTrackletsPostInput[layer]);
 
   while ( AliTRDtrackletGTU *trk = (AliTRDtrackletGTU*) next() ) {
-    trk->SetIndex(fTracklets[layer]->IndexOf(trk));
+    trk->SetIndex(fTrackletsPostInput[layer]->IndexOf(trk));
 
-    Int_t alpha = (trk->GetYbin() >> fGtuParam->GetBitExcessY()) * fGtuParam->GetCiAlpha(layer); 
+    Int_t alpha = (trk->GetYbin() >> fGtuParam->GetBitExcessY()) * fGtuParam->GetCiAlpha(layer);
     alpha = ( 2 * trk->GetdY() - (alpha >> fGtuParam->GetBitExcessAlpha()) + 1 ) >> 1;
-    trk->SetAlpha(alpha);
+    // wrapping projected alpha as in hardware
+    if ((alpha < -64) || (alpha > 63))
+      AliError(Form("alpha out of range: %i", alpha));
+    alpha = alpha & 0x7f;
+    if (alpha & 0x40)
+      trk->SetAlpha(0xffffffc0 | alpha);
+    else
+      trk->SetAlpha(alpha);
 
     Int_t yproj = trk->GetdY() * (fGtuParam->GetCiYProj(layer)); //??? sign?
     yproj = ( ( ( (yproj >> fGtuParam->GetBitExcessYProj()) + trk->GetYbin() ) >> 2) + 1) >> 1;
@@ -225,43 +279,49 @@ Bool_t AliTRDgtuTMU::RunInputUnit(Int_t layer)
 
     trk->SetYPrime(trk->GetYbin() + fGtuParam->GetYt(fStack, layer, trk->GetZbin()));
 
-    AliDebug(10, Form("InputUnit : GetIndex(): %3i, GetZbin(): %2i, GetY() : %5i, GetdY() : %3i, GetYPrime() : %5i, GetYProj() : %5i, GetAlpha() : %3i", 
-                     trk->GetIndex(), trk->GetZbin(), trk->GetYbin(), trk->GetdY(), trk->GetYPrime(), trk->GetYProj(), trk->GetAlpha() ));
+    AliDebug(10, Form("0x%08x: idx: %3i, z: %2i, y: %5i, dy: %3i, y': %5i, y_proj: %5i, alpha: %3i, pid: %3i",
+                     trk->GetTrackletWord(), trk->GetIndex(), trk->GetZbin(), trk->GetYbin(), trk->GetdY(), trk->GetYPrime(),
+                     trk->GetYProj(), trk->GetAlpha(), trk->GetPID() ));
   }
   return kTRUE;
 }
 
-Bool_t AliTRDgtuTMU::RunZChannelUnit(Int_t layer) 
+Bool_t AliTRDgtuTMU::RunZChannelUnit(Int_t layer)
 {
   // run the z-channel unit
 
-  TIter next(fTracklets[layer]);
+  TIter next(fTrackletsPostInput[layer]);
 
   while (AliTRDtrackletGTU *trk = (AliTRDtrackletGTU*) next()) {
-    AliDebug(10,Form("*TMU* Tracklet in stack %d, layer %2d: 0x%08x ", fStack, layer, trk->GetTrackletWord()));
     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
       if (fGtuParam->IsInZChannel(fStack, layer, zch, trk->GetZbin()) ) {
        trk->SetSubChannel(zch, fGtuParam->GetZSubchannel(fStack, layer, zch, trk->GetZbin()) );
-//     printf("Z%i(%i) ", zch, trk->GetSubChannel(zch));
 
        TIter nexttrkl(&fZChannelTracklets[layer][zch], kIterBackward);
        AliTRDtrackletGTU *t = 0x0;
        while ((t = (AliTRDtrackletGTU*) nexttrkl.Next())) {
-         if (t->GetSubChannel(zch) < trk->GetSubChannel(zch) || 
-             (t->GetSubChannel(zch) == trk->GetSubChannel(zch) && t->GetYProj() < trk->GetYProj()) )
+         if (t->GetSubChannel(zch) < trk->GetSubChannel(zch) ||
+             ((t->GetSubChannel(zch) == trk->GetSubChannel(zch)) && (t->GetYProj() < trk->GetYProj())) ) {
            break;
+         }
        }
-       fZChannelTracklets[layer][zch].AddAfter(t, trk);
+       if (t)
+         fZChannelTracklets[layer][zch].AddAfter(t, trk);
+       else
+         fZChannelTracklets[layer][zch].AddFirst(trk);
       }
-//      else 
-//       printf("      ");
     }
-//    printf("\n");
+    AliDebug(10, Form("stack %d, layer %2d: 0x%08x Z(2..0)=%i/%i/%i",
+                     fStack, layer, trk->GetTrackletWord(),
+                     fGtuParam->IsInZChannel(fStack, layer, 2, trk->GetZbin()) ? trk->GetSubChannel(2) : -1,
+                     fGtuParam->IsInZChannel(fStack, layer, 1, trk->GetZbin()) ? trk->GetSubChannel(1) : -1,
+                     fGtuParam->IsInZChannel(fStack, layer, 0, trk->GetZbin()) ? trk->GetSubChannel(0) : -1
+                     ));
   }
   return kTRUE;
 }
 
-Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */) 
+Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
 {
   // run the track finding
 
@@ -269,7 +329,7 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
    Int_t       *ptrA = new Int_t[fGtuParam->GetNLayers()];
    Int_t       *ptrB = new Int_t[fGtuParam->GetNLayers()];
 
-   Bool_t      *bHitA     = new Bool_t[fGtuParam->GetNLayers()]; 
+   Bool_t      *bHitA     = new Bool_t[fGtuParam->GetNLayers()];
    Bool_t      *bHitB     = new Bool_t[fGtuParam->GetNLayers()];
    Bool_t      *bAligned  = new Bool_t[fGtuParam->GetNLayers()];
    Bool_t      *bAlignedA = new Bool_t[fGtuParam->GetNLayers()];
@@ -281,15 +341,15 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
    Int_t       *incprime = new Int_t[fGtuParam->GetNLayers()];
 
 // ----- signals within current layer -----
-   Int_t       Yplus;
-   Int_t       Yminus;            
-   Int_t       YBplus;    
-   Int_t       YBminus;
-   Int_t       Alphaplus;
-   Int_t       Alphaminus; 
-   Int_t       NHits;
-   Int_t       NUnc;   
-   Int_t       NWayBeyond;
+   Int_t       yPlus;
+   Int_t       yMinus;
+   Int_t       ybPlus;
+   Int_t       ybMinus;
+   Int_t       alphaPlus;
+   Int_t       alphaMinus;
+   Int_t       nHits;
+   Int_t       nUnc;
+   Int_t       nWayBeyond;
 
    AliTRDtrackletGTU   *trkRA  = 0x0;  // reference tracklet A
    AliTRDtrackletGTU   *trkRB  = 0x0;  // reference tracklet B
@@ -297,7 +357,7 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
    AliTRDtrackletGTU   *trkB   = 0x0;  // tracklet B in current layer
 /*
    AliTRDtrackletGTU   *trkEnd = new AliTRDtrackletGTU();
-   for (Int_t i = 0; i < fGtuParam->GetNZChannels(); i++) 
+   for (Int_t i = 0; i < fGtuParam->GetNZChannels(); i++)
        trkEnd->SetSubChannel(i, 7);
    trkEnd->SetYProj(0);
    trkEnd->SetAlpha(0);
@@ -305,10 +365,22 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
 
    for (Int_t refLayerIdx = 0; refLayerIdx < fGtuParam->GetNRefLayers(); refLayerIdx++) {
      Int_t reflayer = fGtuParam->GetRefLayer(refLayerIdx);
-     AliDebug(5,Form("~~~~~ Reflayer: %i", reflayer));
+     AliDebug(5,Form("Tracking for z-channel: %i, reflayer: %i", zch, reflayer));
 
      ready = kFALSE; // ready if all channels done
 
+//      for (Int_t iLayer = 0; iLayer < fGtuParam->GetNLayers(); iLayer++) {
+//        for (Int_t iTrkl = 0; iTrkl < fZChannelTracklets[iLayer][zch].GetEntries(); iTrkl++) {
+//      printf("%4i/%4i(%i,%i) ",
+//             ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetYProj(),
+//             ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetAlpha(),
+//             ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetIndex(),
+//             ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetSubChannel(zch)
+//             );
+//        }
+//        printf("\n");
+//      }
+
      for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
        notr[layer] = fZChannelTracklets[layer][zch].GetEntries();
        ptrA[layer] = 0; // notr[layer] > 0 ? 0 : -1;
@@ -322,8 +394,8 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
        if (reflayer == 1)
         AliDebug(5,Form("in layer: %i (zchannel = %i) there are: %i tracklets", layer, zch, notr[layer]));
      }
-     
-     if (ptrA[reflayer] < 0 && ptrB[reflayer] < 0) 
+
+     if (ptrA[reflayer] < 0 && ptrB[reflayer] < 0)
        continue;
 
      while (!ready) {
@@ -334,30 +406,29 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
         trkRA = (AliTRDtrackletGTU*) fZChannelTracklets[reflayer][zch].At(ptrA[reflayer]);
        else  {
         AliDebug(10,Form("No valid tracklet in the reference at ptr: %i! Nothing done!", ptrA[reflayer]));
-        break; 
+        break;
        }
 
        if (0 <= ptrB[reflayer] && ptrB[reflayer] < notr[reflayer])
         trkRB = (AliTRDtrackletGTU*) fZChannelTracklets[reflayer][zch].At(ptrB[reflayer]);
 
-       AliDebug(10,Form("ptrRA: %i, ptrRB: %i", ptrA[reflayer], ptrB[reflayer]));
-       Yplus     = trkRA->GetYProj() + fGtuParam->GetDeltaY();
-       Yminus    = trkRA->GetYProj() - fGtuParam->GetDeltaY();
-       Alphaplus  = trkRA->GetAlpha() + fGtuParam->GetDeltaAlpha();
-       Alphaminus = trkRA->GetAlpha() - fGtuParam->GetDeltaAlpha();
+       yPlus     = trkRA->GetYProj() + fGtuParam->GetDeltaY();
+       yMinus    = trkRA->GetYProj() - fGtuParam->GetDeltaY();
+       alphaPlus  = trkRA->GetAlpha() + fGtuParam->GetDeltaAlpha();
+       alphaMinus = trkRA->GetAlpha() - fGtuParam->GetDeltaAlpha();
        if (trkRB) {
-        YBplus           = trkRB->GetYProj() + fGtuParam->GetDeltaY();
-        YBminus          = trkRB->GetYProj() - fGtuParam->GetDeltaY();
+        ybPlus           = trkRB->GetYProj() + fGtuParam->GetDeltaY();
+        ybMinus          = trkRB->GetYProj() - fGtuParam->GetDeltaY();
        }
        else { // irrelevant (should be, is it?)
-        YBplus           = trkRA->GetYProj() + fGtuParam->GetDeltaY();
-        YBminus          = trkRA->GetYProj() - fGtuParam->GetDeltaY();
+        ybPlus           = trkRA->GetYProj() + fGtuParam->GetDeltaY();
+        ybMinus          = trkRA->GetYProj() - fGtuParam->GetDeltaY();
        }
 
-       NHits     = 0;
-       NUnc      = 0;
-       NWayBeyond = 0;
-       
+       nHits     = 0;
+       nUnc      = 0;
+       nWayBeyond = 0;
+
        for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
         bHitA[layer] = bHitB[layer] = bAligned[layer] = kFALSE;
         inc[layer] = incprime[layer] = 0;
@@ -365,8 +436,8 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
         if (layer == reflayer) {
           bHitA[layer] = kTRUE;
           bAligned[layer] = kTRUE;
-          NHits++;
-          continue; 
+          nHits++;
+          continue;
         }
 
         trkA = 0x0;
@@ -379,12 +450,12 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
         bAlignedA[layer] = kFALSE;
         bAlignedB[layer] = kFALSE;
 
-        if (trkA) { 
-          bHitA[layer] = ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < Yminus) ) &&
-                           !(trkA->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() > Yplus)  ) &&
-                           !(trkA->GetAlpha() < Alphaminus) &&
-                           !(trkA->GetAlpha() > Alphaplus) );
-          bAlignedA[layer] = !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < Yminus) ); 
+        if (trkA) {
+          bHitA[layer] = ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) &&
+                           !(trkA->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() > yPlus)  ) &&
+                           !(trkA->GetAlpha() < alphaMinus) &&
+                           !(trkA->GetAlpha() > alphaPlus) );
+          bAlignedA[layer] = !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) );
         }
         else {
           bHitA[layer] = 0;
@@ -392,72 +463,72 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
         }
 
         if (trkB) {
-          bHitB[layer] = ( !(trkB->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() < Yminus) ) &&
-                           !(trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > Yplus) ) &&
-                           !(Alphaminus > trkB->GetAlpha()) &&
-                           !(Alphaplus  > trkB->GetAlpha()) );
-          bAlignedB[layer] = (trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > Yplus) );
-        } 
+          bHitB[layer] = ( !(trkB->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() < yMinus) ) &&
+                           !(trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) ) &&
+                           !(trkB->GetAlpha() < alphaMinus) &&
+                           !(trkB->GetAlpha() > alphaPlus) );
+          bAlignedB[layer] = (trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) );
+        }
         else {
           bHitB[layer] = 0;
           bAlignedB[layer] = kTRUE;
         }
-         
+
         bAligned[layer] = bAlignedA[layer] || bAlignedB[layer]; //???
 //      bAligned[layer] = bAlignedA[layer]; //???
-         
+
         if (bAligned[layer] && (bHitA[layer] || bHitB[layer]) )
-          NHits++;
+          nHits++;
         else if (!bAligned[layer] )
-          NUnc++;
+          nUnc++;
         if (trkRB) {
           if (trkA) {
-            if ((trkA->GetSubChannel(zch) > trkRB->GetSubChannel(zch)) || (trkA->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkA->GetYProj() > YBplus) )
-              NWayBeyond++;
+            if ((trkA->GetSubChannel(zch) > trkRB->GetSubChannel(zch)) || (trkA->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkA->GetYProj() > ybPlus) )
+              nWayBeyond++;
           }
-          else 
-            NWayBeyond++;
+          else
+            nWayBeyond++;
         }
 
         //  pre-calculation for the layer shifting (alignment w. r. t. trkRB)
         if (trkA) {
             if(trkRB) {
-                if ((trkA->GetSubChannel(zch) < trkRB->GetSubChannel(zch)) || (trkA->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkA->GetYProj() < YBminus )) // could trkA be aligned for trkRB
+                if ((trkA->GetSubChannel(zch) < trkRB->GetSubChannel(zch)) || (trkA->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkA->GetYProj() < ybMinus )) // could trkA be aligned for trkRB
                     incprime[layer] = 1;
-                else 
+                else
                     incprime[layer] = 0;
             }
-            else 
+            else
                 incprime[layer] = 1;
 
-            if (trkB) { 
+            if (trkB) {
                 if (trkRB) {
-                    if ((trkB->GetSubChannel(zch) < trkRB->GetSubChannel(zch)) || (trkB->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkB->GetYProj() < YBminus )) // could trkB be aligned for trkRB
+                    if ((trkB->GetSubChannel(zch) < trkRB->GetSubChannel(zch)) || (trkB->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkB->GetYProj() < ybMinus )) // could trkB be aligned for trkRB
                         incprime[layer] = 2;
                 }
-                else 
+                else
                     incprime[layer] = 2;
             }
         }
        } // end of loop over layers
 
-       AliDebug(5,Form("logic calculation finished, Nhits: %i", NHits));
+       AliDebug(5,Form("logic calculation finished, Nhits: %i %s",
+                      nHits, (nHits >= 4) ? "-> track found" : ""));
 
-       if (NHits >= 4) {
+       if (nHits >= 4) {
         // ----- track registration -----
-        AliDebug(1,"***** TMU: Track found *****");
         AliTRDtrackGTU *track = new AliTRDtrackGTU();
         track->SetSector(fSector);
         track->SetStack(fStack);
         for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++ ) {
-          if (bHitA[layer] || layer == reflayer) 
+          if (bHitA[layer] || layer == reflayer)
             track->AddTracklet((AliTRDtrackletGTU* ) fZChannelTracklets[layer][zch].At(ptrA[layer]), layer );
-          else if (bHitB[layer]) 
+          else if (bHitB[layer])
             track->AddTracklet((AliTRDtrackletGTU* ) fZChannelTracklets[layer][zch].At(ptrB[layer]), layer );
         }
 
         Bool_t registerTrack = kTRUE;
-        for (Int_t layerIdx = refLayerIdx; layerIdx > 0; layerIdx--) {
+        for (Int_t layerIdx = refLayerIdx-1; layerIdx >= 0; layerIdx--) {
            if (track->IsTrackletInLayer(fGtuParam->GetRefLayer(layerIdx))) {
              if ((track->GetTracklet(fGtuParam->GetRefLayer(layerIdx)))->GetSubChannel(zch) > 0) {
                AliDebug(1,"Not registered");
@@ -471,19 +542,19 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
             fTracks[zch][refLayerIdx].Add(track);
         }
        }
-       
-       if ( (NUnc != 0) && (NUnc + NHits >= 4) ) // could this position of the reference layer give some track //??? special check in case of hit?
+
+       if ( (nUnc != 0) && (nUnc + nHits >= 4) ) // could this position of the reference layer give some track //??? special check in case of hit?
          inc[reflayer] = 0;
-       else if (NWayBeyond > 2) // no track possible for both reference tracklets
+       else if (nWayBeyond > 2) // no track possible for both reference tracklets
         inc[reflayer] = 2;
-       else 
+       else
         inc[reflayer] = 1;
-       
+
        if (inc[reflayer] != 0) // reflayer is shifted
         for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
           if (layer == reflayer)
             continue;
-          inc[layer] = incprime[layer]; 
+          inc[layer] = incprime[layer];
         }
        else { // reflayer is not shifted
         for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
@@ -499,25 +570,26 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
             trkB = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]);
 
           if (trkA) {
-              if ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < Yminus) ) && 
-                   !(trkA->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() > Yplus ) ) )  // trkA could hit trkRA
+            if ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) &&
+                 !(trkA->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() > yPlus ) ) )  // trkA could hit trkRA
+            // if ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) )
                   inc[layer] = 0;
               else if (trkB) {
-                  if ( trkB->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() < Yminus) )
+                  if ( trkB->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() < yMinus) )
                       inc[layer] = 2;
-                  else if ( !(trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > Yplus) ) )
+                  else if ( !(trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) ) )
                       inc[layer] = 1;
-                  else 
+                  else
                       inc[layer] = incprime[layer];
               }
-              else 
+              else
                   inc[layer] = incprime[layer];
           }
         }
        }
-       
+
        ready = kTRUE;
-       for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
+       for (Int_t layer = fGtuParam->GetNLayers()-1; layer >= 0; layer--) {
 
         bDone[layer] = ptrB[layer] < 0 || ptrB[layer] >= notr[layer];
         ready = ready && bDone[layer];
@@ -526,7 +598,21 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
           AliError(Form("Invalid increment: %i at ptrA: %i, notr: %i", inc[layer], ptrA[layer], notr[layer]));
 
 //      AliInfo(Form("Shifting layer: %i, notr: %i, ptrA: %i, ptrB: %i, inc: %i", layer, notr[layer], ptrA[layer], ptrB[layer], inc[layer]));
-        AliDebug(10,Form(" -- Layer: %i   %i   %i   +%i   %s  (no: %i)", layer, ptrA[layer], ptrB[layer], inc[layer], bDone[layer] ? "done" : "    ", notr[layer]));
+        AliDebug(10,Form("    Layer: %i   %2i(%2i, %2i, %4i, %3i)%s%s   %2i(%2i, %2i, %4i, %3i)%s%s   +%i   %s  (no: %i)",
+                         layer,
+                         ptrA[layer],
+                         (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetIndex() : -1,
+                         (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetSubChannel(zch) : -1,
+                         (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetYProj() : -1,
+                         (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetAlpha() : -1,
+                         bHitA[layer] ? "*" : " ", bAlignedA[layer] ? "+" : " ",
+                         ptrB[layer],
+                         (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetIndex() : -1,
+                         (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetSubChannel(zch) : -1,
+                         (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetYProj() : -1,
+                         (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetAlpha() : -1,
+                         bHitB[layer] ? "*" : " ", bAlignedB[layer] ? "+" : " ",
+                         inc[layer], bDone[layer] ? "done" : "    ", notr[layer]));
         ptrA[layer] += inc[layer];
         ptrB[layer] += inc[layer];
        }
@@ -549,7 +635,7 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
    return kTRUE;
 }
 
-Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks) 
+Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
 {
     TList **tracksRefMerged = new TList*[fGtuParam->GetNZChannels()];
     TList **tracksRefUnique = new TList*[fGtuParam->GetNZChannels()];
@@ -575,7 +661,7 @@ Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
     AliTRDtrackGTU *trkStage0 = 0x0;
 
     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
-        // ----- Merging and Unification in Reflayers -----
+        // ----- Merging and Unification in Reflayers (seed_merger) -----
        do {
            done = kTRUE;
            trkStage0 = 0x0;
@@ -589,7 +675,7 @@ Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
                    minIdx = refLayerIdx;
                    done = kFALSE;
                }
-               else if (trkInRefLayer[refLayerIdx]->GetZSubChannel() < trkStage0->GetZSubChannel() || 
+               else if (trkInRefLayer[refLayerIdx]->GetZSubChannel() < trkStage0->GetZSubChannel() ||
                         (trkInRefLayer[refLayerIdx]->GetZSubChannel() == trkStage0->GetZSubChannel() && trkInRefLayer[refLayerIdx]->GetYapprox() < trkStage0->GetYapprox()) ) {
                    minIdx = refLayerIdx;
                    trkStage0 = trkInRefLayer[refLayerIdx];
@@ -603,14 +689,41 @@ Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
        } while (trkStage0 != 0);
 
        Uniquifier(tracksRefMerged[zch], tracksRefUnique[zch]);
+
+       AliDebug(2, Form("zchannel %i", zch));
+       TIter trackRefMerged(tracksRefMerged[zch]);
+       while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackRefMerged())
+         AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, z_idx=%i",
+                          AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
+                          trk->GetTrackletIndex(5),
+                          trk->GetTrackletIndex(4),
+                          trk->GetTrackletIndex(3),
+                          trk->GetTrackletIndex(2),
+                          trk->GetTrackletIndex(1),
+                          trk->GetTrackletIndex(0),
+                          trk->GetYapprox() >> 3,
+                          trk->GetZSubChannel()));
+       AliDebug(2, "uniquified:");
+       TIter trackRefUnique(tracksRefUnique[zch]);
+       while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackRefUnique())
+         AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, z_idx=%i",
+                          AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
+                          trk->GetTrackletIndex(5),
+                          trk->GetTrackletIndex(4),
+                          trk->GetTrackletIndex(3),
+                          trk->GetTrackletIndex(2),
+                          trk->GetTrackletIndex(1),
+                          trk->GetTrackletIndex(0),
+                          trk->GetYapprox() >> 3,
+                          trk->GetZSubChannel()));
     }
 
 // ----- Merging in zchannels - 1st stage -----
-    
+
     do {
        done = kTRUE;
        trkStage0 = 0x0;
-       for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
+        for (Int_t zch = fGtuParam->GetNZChannels() - 1; zch > -1; zch--) {
            AliTRDtrackGTU *trk = (AliTRDtrackGTU*) tracksRefUnique[zch]->First();
            if (trk == 0) {
                continue;
@@ -620,34 +733,82 @@ Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
                minIdx = zch;
                done = kFALSE;
            }
-           else if ( ((trk->GetZChannel() + 3 * trk->GetZSubChannel()) / 2 - 1) < ((trkStage0->GetZChannel() + 3 * trkStage0->GetZSubChannel()) / 2 -1 ) ) {
+           else if ( ((trk->GetZChannel() + 3 * trk->GetZSubChannel()) / 2 - 1) <  ((trkStage0->GetZChannel() + 3 * trkStage0->GetZSubChannel()) / 2 -1 ) ||
+                     (((trk->GetZChannel() + 3 * trk->GetZSubChannel()) / 2 - 1) == ((trkStage0->GetZChannel() + 3 * trkStage0->GetZSubChannel()) / 2 -1 ) && (trk->GetYapprox() < trkStage0->GetYapprox()) ) ) {
                minIdx = zch;
                trkStage0 = trk;
                done = kFALSE;
            }
        }
-       
+
        if (!trkStage0)
           break;
        tracksZMergedStage0->Add(trkStage0);
        tracksRefUnique[minIdx]->RemoveFirst();
     } while (trkStage0 != 0);
-    
+
     Uniquifier(tracksZMergedStage0, tracksZUniqueStage0);
-    
+
+    AliDebug(2, "stage 0:");
+    TIter trackZMergedStage0(tracksZMergedStage0);
+    while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZMergedStage0())
+      AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
+                      AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
+                      trk->GetTrackletIndex(5),
+                      trk->GetTrackletIndex(4),
+                      trk->GetTrackletIndex(3),
+                      trk->GetTrackletIndex(2),
+                      trk->GetTrackletIndex(1),
+                      trk->GetTrackletIndex(0),
+                      trk->GetYapprox() >> 3,
+                      trk->GetZChannel(),
+                      trk->GetZSubChannel()));
+
+    AliDebug(2, "uniquified:");
+    TIter trackZUniqueStage0(tracksZUniqueStage0);
+    while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZUniqueStage0())
+      AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
+                      AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
+                      trk->GetTrackletIndex(5),
+                      trk->GetTrackletIndex(4),
+                      trk->GetTrackletIndex(3),
+                      trk->GetTrackletIndex(2),
+                      trk->GetTrackletIndex(1),
+                      trk->GetTrackletIndex(0),
+                      trk->GetYapprox() >> 3,
+                      trk->GetZChannel(),
+                      trk->GetZSubChannel()));
+
 // ----- Splitting in z -----
-    
+
     TIter next(tracksZUniqueStage0);
     while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) next()) {
        tracksZSplitted[(trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) % 2]->Add(trk);
     }
-    
+
+    for (Int_t i = 0; i < 2; i++) {
+      AliDebug(2, Form("split %i:", i));
+      TIter trackZSplit(tracksZSplitted[i]);
+      while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZSplit())
+       AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
+                        AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
+                        trk->GetTrackletIndex(5),
+                        trk->GetTrackletIndex(4),
+                        trk->GetTrackletIndex(3),
+                        trk->GetTrackletIndex(2),
+                        trk->GetTrackletIndex(1),
+                        trk->GetTrackletIndex(0),
+                        trk->GetYapprox() >> 3,
+                        trk->GetZChannel(),
+                        trk->GetZSubChannel()));
+    }
+
 // ----- Merging in zchanels - 2nd stage -----
-    
+
     do {
        done = kTRUE;
        trkStage0 = 0x0;
-       for (Int_t i = 0; i < 2; i++) {
+       for (Int_t i = 1; i >= 0; i--) {
            AliTRDtrackGTU *trk = (AliTRDtrackGTU*) tracksZSplitted[i]->First();
            if (trk == 0) {
                continue;
@@ -657,55 +818,158 @@ Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
                minIdx = i;
                done = kFALSE;
            }
-           else if ( ((trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) / 2) < ((trkStage0->GetZChannel() + 3 * (trkStage0->GetZSubChannel() - 1)) / 2) ) {
+           else if ( (((trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) / 2) <  ((trkStage0->GetZChannel() + 3 * (trkStage0->GetZSubChannel() - 1)) / 2)) ||
+                     ((((trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) / 2) == ((trkStage0->GetZChannel() + 3 * (trkStage0->GetZSubChannel() - 1)) / 2)) && (trk->GetYapprox() < trkStage0->GetYapprox()) ) ) {
                minIdx = i;
                trkStage0 = trk;
                done = kFALSE;
            }
        }
-       
+
         if (!trkStage0)
           break;
        tracksZMergedStage1->Add(trkStage0);
        tracksZSplitted[minIdx]->RemoveFirst();
     } while (trkStage0 != 0);
-    
+
     Uniquifier(tracksZMergedStage1, ListOfTracks);
-    
+
+    AliDebug(2, "merged:");
+    TIter trackZMergedStage1(tracksZMergedStage1);
+    while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackZMergedStage1())
+      AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
+                      AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
+                      trk->GetTrackletIndex(5),
+                      trk->GetTrackletIndex(4),
+                      trk->GetTrackletIndex(3),
+                      trk->GetTrackletIndex(2),
+                      trk->GetTrackletIndex(1),
+                      trk->GetTrackletIndex(0),
+                      trk->GetYapprox() >> 3,
+                      trk->GetZChannel(),
+                      trk->GetZSubChannel()));
+
+    AliDebug(2, "uniquified:");
+    TIter track(ListOfTracks);
+    while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) track())
+      AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, zch=%i idx=%i",
+                      AliTRDgtuParam::GetRefLayer(trk->GetRefLayerIdx()),
+                      trk->GetTrackletIndex(5),
+                      trk->GetTrackletIndex(4),
+                      trk->GetTrackletIndex(3),
+                      trk->GetTrackletIndex(2),
+                      trk->GetTrackletIndex(1),
+                      trk->GetTrackletIndex(0),
+                      trk->GetYapprox() >> 3,
+                      trk->GetZChannel(),
+                      trk->GetZSubChannel()));
+
+    // cleaning up
+    for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
+      delete tracksRefMerged[zch];
+      delete tracksRefUnique[zch];
+    }
+    delete [] tracksRefMerged;
+    delete [] tracksRefUnique;
+
+
+    delete tracksZMergedStage0;
+    delete tracksZUniqueStage0;
+
+    for (Int_t i = 0; i < 2; i++)
+      delete tracksZSplitted[i];
+    delete [] tracksZSplitted;
+
+    delete tracksZMergedStage1;
+
+    delete [] trkInRefLayer;
+
     return kTRUE;
 }
 
-Bool_t AliTRDgtuTMU::RunTrackReconstruction(TList* ListOfTracks) 
+Bool_t AliTRDgtuTMU::RunTrackReconstruction(TList* ListOfTracks)
 {
+  // run the track reconstruction for all tracks in the list
+
   TIter next(ListOfTracks);
   while (AliTRDtrackGTU *track = (AliTRDtrackGTU*) next()) {
     CalculateTrackParams(track);
     CalculatePID(track);
+    AliDebug(1, Form("track with pid = %i", track->GetPID()));
   }
   return kTRUE;
 }
 
 Bool_t AliTRDgtuTMU::CalculatePID(AliTRDtrackGTU *track)
 {
+  // calculate PID for the given track
   if (!track) {
     AliError("No track to calculate!");
     return kFALSE;
   }
 
-  Int_t nTracklets = 0;
-  Int_t pidSum = 0;
-  for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
-    if (!track->IsTrackletInLayer(layer)) {
-      continue;
+  if (AliTRDgtuParam::GetUseGTUconst()) {
+    // averaging as in GTU
+    ULong64_t coeff;
+
+    // selection of coefficient for averaging
+    switch(track->GetTrackletMask()){
+    case 0x3f:
+      // 6 tracklets
+      coeff=0x5558; // approx. 1/6
+      break;
+
+    case 0x3e:
+    case 0x3d:
+    case 0x3b:
+    case 0x37:
+    case 0x2f:
+    case 0x1f:
+      // 5 tracklets
+      coeff=0x6666; // approx. 1/5
+      break;
+
+    default:
+      // 4 tracklets
+      coeff=0x8000; // = 0.25
     }
-    AliTRDtrackletGTU *trk = track->GetTracklet(layer);
-    pidSum += trk->GetPID();
-    nTracklets++;
+    coeff &= 0x1ffff; // 17-bit constant
+
+    ULong64_t sum = 0;
+    for (Int_t iLayer = 0; iLayer < fGtuParam->GetNLayers(); iLayer++) {
+      if ((track->GetTrackletMask() >> iLayer) & 1) {
+       sum += track->GetTracklet(iLayer)->GetPID();
+      }
+    }
+
+    sum = sum & 0x7ff;
+    ULong64_t prod   = (sum * coeff) & 0xfffffffffull;
+    ULong64_t prodFinal = ((prod >> 17) + ((prod >> 16) & 1)) & 0xff;
+
+    track->SetPID(prodFinal & 0xff);
+
+    return kTRUE;
+  }
+  else {
+
+    // simple averaging
+    Int_t nTracklets = 0;
+    Int_t pidSum = 0;
+    for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
+      if (!track->IsTrackletInLayer(layer)) {
+       continue;
+      }
+      AliTRDtrackletGTU *trk = track->GetTracklet(layer);
+      pidSum += trk->GetPID();
+      nTracklets++;
+    }
+    track->SetPID(pidSum/nTracklets);
+
+    return kTRUE;
   }
-  track->SetPID(pidSum/nTracklets);
 }
 
-Bool_t AliTRDgtuTMU::CalculateTrackParams(AliTRDtrackGTU *track) 
+Bool_t AliTRDgtuTMU::CalculateTrackParams(AliTRDtrackGTU *track)
 {
   // calculate the track parameters
 
@@ -731,8 +995,8 @@ Bool_t AliTRDgtuTMU::CalculateTrackParams(AliTRDtrackGTU *track)
       AliError(Form("Could not get tracklet in layer %i\n", layer));
       continue;
     }
-    AliDebug(10,Form("trk yprime: %i", trk->GetYPrime()));
-    a += (((Int_t) (2048 * fGtuParam->GetAki(track->GetTrackletMask(), layer))) * trk->GetYPrime() + 1) >> 8; 
+    AliDebug(10,Form("  layer %i trk yprime: %6i, aki: %6i", layer, trk->GetYPrime(), (Int_t) (2048 * fGtuParam->GetAki(track->GetTrackletMask(), layer))));
+    a += (((Int_t) (2048 * fGtuParam->GetAki(track->GetTrackletMask(), layer))) * trk->GetYPrime() + 1) >> 8;
     b += fGtuParam->GetBki(track->GetTrackletMask(), layer) * trk->GetYPrime() * fGtuParam->GetBinWidthY();
     c += fGtuParam->GetCki(track->GetTrackletMask(), layer) * trk->GetYPrime() * fGtuParam->GetBinWidthY();
   }
@@ -740,49 +1004,20 @@ Bool_t AliTRDgtuTMU::CalculateTrackParams(AliTRDtrackGTU *track)
       a += 3;
   a = a >> 2;
 
-  fGtuParam->GetIntersectionPoints(track->GetTrackletMask(), x1, x2);
-  AliDebug(10,Form("Intersection points: %f, %f", x1, x2));
-  AliDebug(10,Form("Sum: a = %5i, b = %9.2f, c = %9.2f\n", a, b, c));
   track->SetFitParams(a, b, c);
 
-  Float_t r = fGtuParam->GetRadius(a, b, x1, x2);
-  Int_t pt = (Int_t) (2 * r);
-  if (pt >= 0) 
-      pt += 32;
-  else
-      pt -= 29;
-  pt /= 2;
-  track->SetPtInt(pt);
-  AliDebug(5,Form("Track parameters: a = %i, b = %f, c = %f, x1 = %f, x2 = %f, r = %f, pt = %f (trkl mask: %i)", a, b, c, x1, x2, r, track->GetPt(), track->GetTrackletMask()));
-  return kTRUE;
-}
+  fGtuParam->GetIntersectionPoints(track->GetTrackletMask(), x1, x2);
 
-Bool_t AliTRDgtuTMU::WriteTrackletsToTree(TTree *trklTree)
-{
-  if (!trklTree) {
-    AliError("No tree given");
-    return kFALSE;
-  }
-  AliTRDtrackletGTU *trkl = 0x0;
-  TBranch *branch = trklTree->GetBranch("gtutracklets");
-  if (!branch) {
-      branch = trklTree->Branch("gtutracklets", "AliTRDtrackletGTU", &trkl, 32000, 99);
-  }
+  AliDebug(5,Form("  Track parameters: a = %i, b = %f, c = %f, x1 = %f, x2 = %f, pt = %f (trkl mask: %i)", a, b, c, x1, x2, track->GetPt(), track->GetTrackletMask()));
 
-  AliDebug(5,Form("---------- Writing tracklets to tree (not yet) ----------"));
-  for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
-    TIter next(fTracklets[layer]);
-    while ((trkl = (AliTRDtrackletGTU*) next())) {
-       AliDebug(10,Form("InputUnit : GetIndex(): %3i, GetZbin(): %2i, GetY() : %5i, GetdY() : %3i, GetYPrime() : %5i, GetYProj() : %5i, GetAlpha() : %3i, Zidx(2..0): %i  %i  %i", trkl->GetIndex(), trkl->GetZbin(), trkl->GetYbin(), trkl->GetdY(), trkl->GetYPrime(), trkl->GetYProj(), trkl->GetAlpha(), trkl->GetSubChannel(2), trkl->GetSubChannel(1), trkl->GetSubChannel(0) ));
-       branch->SetAddress(&trkl);
-       trklTree->Fill();
-    }
-  }
   return kTRUE;
 }
 
+
 Bool_t AliTRDgtuTMU::Uniquifier(TList *inlist, TList *outlist)
 {
+  // remove multiple occurences of the same track
+
     TIter next(inlist);
     AliTRDtrackGTU *trkStage0 = 0x0;
     AliTRDtrackGTU *trkStage1 = 0x0;
@@ -790,26 +1025,26 @@ Bool_t AliTRDgtuTMU::Uniquifier(TList *inlist, TList *outlist)
     do {
        trkStage0 = (AliTRDtrackGTU*) next();
 
-       Bool_t tracks_equal = kFALSE;
+       Bool_t tracksEqual = kFALSE;
        if (trkStage0 != 0 && trkStage1 != 0) {
            for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
                if (trkStage0->GetTrackletIndex(layer) != -1 && trkStage0->GetTrackletIndex(layer) == trkStage1->GetTrackletIndex(layer)) {
-                   tracks_equal = kTRUE;
+                   tracksEqual = kTRUE;
                    break;
                }
            }
        }
 
-       if (tracks_equal) {
-           if (trkStage0->GetNTracklets() > trkStage1->GetNTracklets())
+       if (tracksEqual) {
+           if (trkStage0->GetNTracklets() >= trkStage1->GetNTracklets())
                trkStage1 = trkStage0;
-       } 
+       }
        else {
-           if (trkStage1 != 0x0) 
+           if (trkStage1 != 0x0)
                outlist->Add(trkStage1);
            trkStage1 = trkStage0;
-       } 
-       
+       }
+
     } while (trkStage1 != 0x0);
     return kTRUE;
 }