Add Jochens GTU simulation code
authorcblume <cblume@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 16 Oct 2008 09:03:50 +0000 (09:03 +0000)
committercblume <cblume@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 16 Oct 2008 09:03:50 +0000 (09:03 +0000)
15 files changed:
TRD/AliTRDgtuParam.cxx [new file with mode: 0644]
TRD/AliTRDgtuParam.h [new file with mode: 0644]
TRD/AliTRDgtuSim.cxx [new file with mode: 0644]
TRD/AliTRDgtuSim.h [new file with mode: 0644]
TRD/AliTRDgtuTMU.cxx [new file with mode: 0644]
TRD/AliTRDgtuTMU.h [new file with mode: 0644]
TRD/AliTRDmcmSim.cxx
TRD/AliTRDtrackGTU.cxx [new file with mode: 0644]
TRD/AliTRDtrackGTU.h [new file with mode: 0644]
TRD/AliTRDtrackletGTU.cxx [new file with mode: 0644]
TRD/AliTRDtrackletGTU.h [new file with mode: 0644]
TRD/AliTRDtrackletMCM.cxx [new file with mode: 0644]
TRD/AliTRDtrackletMCM.h [new file with mode: 0644]
TRD/AliTRDtrackletWord.cxx [new file with mode: 0644]
TRD/AliTRDtrackletWord.h [new file with mode: 0644]

diff --git a/TRD/AliTRDgtuParam.cxx b/TRD/AliTRDgtuParam.cxx
new file mode 100644 (file)
index 0000000..9c66775
--- /dev/null
@@ -0,0 +1,410 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id: AliTRDgtuParam.cxx 28397 2008-09-02 09:33:00Z cblume $ */
+
+////////////////////////////////////////////////////////////////////////////
+//                                                                        //
+//  Parameters for GTU simulation                                         //
+//                                                                        //
+//  Author: J. Klein (Jochen.Klein@cern.ch)                               //
+//                                                                        //
+////////////////////////////////////////////////////////////////////////////
+
+#include "TMath.h"
+#include "TMatrix.h"
+#include "TDecompLU.h"
+#include "TGraphAsymmErrors.h"
+#include "TCanvas.h"
+
+#include "AliLog.h"
+#include "AliTRDgtuParam.h"
+#include "AliTRDgeometry.h"
+#include "AliTRDpadPlane.h"
+
+ClassImp(AliTRDgtuParam)
+
+AliTRDgtuParam *AliTRDgtuParam::fgInstance = 0;
+
+// ----- Bin widths (granularity) -----
+const Float_t  AliTRDgtuParam::fgkBinWidthY  = 160e-4;
+const Float_t  AliTRDgtuParam::fgkBinWidthdY = 140e-4;
+
+// ----- Bit widths (used for internal representation) -----
+const Int_t    AliTRDgtuParam::fgkBitWidthY      = 13;
+const Int_t    AliTRDgtuParam::fgkBitWidthdY     = 7; 
+const Int_t    AliTRDgtuParam::fgkBitWidthYProj  = 10;
+const Int_t    AliTRDgtuParam::fgkBitExcessY     = 4; 
+const Int_t    AliTRDgtuParam::fgkBitExcessAlpha = 10; 
+const Int_t    AliTRDgtuParam::fgkBitExcessYProj = 2; 
+
+// ----- Tracking parameters -----
+/*
+const Int_t AliTRDgtuParam::fgkNZChannels = 3; // No. of z-channels
+const Int_t AliTRDgtuParam::fgkNLinks = 12;    // No. of links
+const Int_t AliTRDgtuParam::fgkFixLayer = 2;   // which layer is fixed for the generation of the z-channel map
+const Int_t AliTRDgtuParam::fgkDeltaY = 39;    // accepted deviation in y_proj, default: 9
+const Int_t AliTRDgtuParam::fgkDeltaAlpha = 31; // accepted deviation in alpha, default: 11
+const Int_t AliTRDgtuParam::fgkNRefLayers = 3;  // no. of reference layers
+*/
+
+AliTRDgtuParam::AliTRDgtuParam() :
+  fVertexSize(20.0),
+  fCurrTrackletMask(0),
+  fRefLayers(0x0),
+  fGeo(0x0)
+{
+  // default ctor
+  fGeo = new AliTRDgeometry();
+  fRefLayers = new Int_t[fgkNRefLayers];
+  fRefLayers[0] = 3;
+  fRefLayers[1] = 2;
+  fRefLayers[2] = 1;
+  zChannelGen(); 
+}
+
+AliTRDgtuParam::~AliTRDgtuParam() 
+{
+  // dtor
+
+  delete fGeo;
+  delete [] fRefLayers;
+}
+
+AliTRDgtuParam* AliTRDgtuParam::Instance() 
+{
+  // get (or create) the single instance
+
+  if (fgInstance == 0) 
+    fgInstance = new AliTRDgtuParam();
+
+  return fgInstance;
+}
+
+void AliTRDgtuParam::Terminate() 
+{
+  // destruct the instance
+
+  if (fgInstance != 0) {
+    delete fgInstance;
+    fgInstance = 0x0;
+  }
+}
+
+Bool_t AliTRDgtuParam::IsInZChannel(Int_t stack, Int_t layer, Int_t zchannel, Int_t zpos) const 
+{
+  return (fZSubChannel[stack][zchannel][layer][zpos] != 0);
+}
+
+Int_t AliTRDgtuParam::GetZSubchannel(Int_t stack, Int_t layer, Int_t zchannel, Int_t zpos) const
+{
+  return fZSubChannel[stack][zchannel][layer][zpos];
+}
+
+Int_t AliTRDgtuParam::GetRefLayer(Int_t refLayerIdx) const 
+{
+  if (refLayerIdx >= 0 && refLayerIdx < fgkNRefLayers)
+    return fRefLayers[refLayerIdx];
+  else 
+    return -1;
+}
+
+Int_t AliTRDgtuParam::zChannelGen() 
+{
+  // generate the z-channel map
+  // assuming that the tracks come from the vertex 
+  // +/- fVertexSize in z-direction
+
+  Int_t iSec = 0; // sector is irrelevant
+  Bool_t collision = kFALSE;
+
+  for (Int_t iStack = 0; iStack < fGeo->Nstack(); iStack++) {
+
+    Float_t X[6] = { 0 };
+    Float_t Z[6][16] = {{ 0 }};
+    Float_t dZ[6][16] = {{ 0 }};
+    
+    for (Int_t iLayer = 0; iLayer < fGeo->Nlayer(); iLayer++) {
+      AliTRDpadPlane *pp = fGeo->GetPadPlane(iLayer, iStack);
+      X[iLayer]  = fGeo->GetTime0(iLayer) - fGeo->CdrHght(); // ???
+      for (Int_t iRow = 0; iRow < fGeo->GetRowMax(iLayer, iStack, iSec); iRow++) {
+       Z[iLayer][iRow]  = pp->GetRowPos(iRow); // this is the right (pos. z-direction) border of the pad
+       dZ[iLayer][iRow] = pp->GetRowSize(iRow); // length of the pad in z-direction
+       for (Int_t i = 0; i < fgkNZChannels; i++) 
+           fZSubChannel[iStack][i][iLayer][iRow] = 0;
+      }
+    }
+
+    for (Int_t fixRow = 0; fixRow < fGeo->GetRowMax(fgkFixLayer, iStack, iSec); fixRow++) {
+       
+      Double_t fixZmin = Z[fgkFixLayer][fixRow] - dZ[fgkFixLayer][fixRow];  
+      Double_t fixZmax = Z[fgkFixLayer][fixRow];
+      Double_t fixX    = X[fgkFixLayer] + 1.5; // ??? 1.5 from where? 
+
+      for (Int_t iLayer = 0; iLayer < fGeo->Nlayer(); iLayer++) {
+       Double_t leftZ, rightZ;
+       
+       if (iLayer <= fgkFixLayer) {
+         leftZ  = (fixZmin + fVertexSize) * (X[iLayer] + 1.5) / fixX - fVertexSize;
+         rightZ = (fixZmax - fVertexSize) * (X[iLayer] + 1.5) / fixX + fVertexSize;
+       }
+       else {
+         leftZ  = (fixZmin - fVertexSize) * (X[iLayer] + 1.5) / fixX + fVertexSize;
+         rightZ = (fixZmax + fVertexSize) * (X[iLayer] + 1.5) / fixX - fVertexSize;
+       }
+       
+       Double_t epsilon = 0.001;
+       for (Int_t iRow = 0; iRow < fGeo->GetRowMax(iLayer, iStack, iSec); iRow++) {
+         if ( (Z[iLayer][iRow] )                    > (leftZ  + epsilon) && 
+              (Z[iLayer][iRow] - dZ[iLayer][iRow] ) < (rightZ - epsilon) ) {
+           fZChannelMap[iStack][fixRow][iLayer][iRow] = 1;
+           if (fZSubChannel[iStack][fixRow % fgkNZChannels][iLayer][iRow] != 0) {
+             AliError("Collision in Z-Channel assignment occured! No reliable tracking!!!");
+             collision = kTRUE;
+           }
+           else 
+             fZSubChannel[iStack][fixRow % fgkNZChannels][iLayer][iRow] = fixRow / fgkNZChannels + 1;
+         }
+
+       }
+      }
+    }
+  }
+
+  return ~collision;
+}
+
+Bool_t AliTRDgtuParam::DisplayZChannelMap(Int_t zchannel, Int_t subchannel) const 
+{
+  // display the z-channel map 
+
+  if (zchannel > fgkNZChannels) {
+    AliError("Invalid Z channel!");
+    return kFALSE;
+  }
+
+  Int_t zchmin = zchannel >= 0 ? zchannel : 0;
+  Int_t zchmax = zchannel >= 0 ? zchannel + 1 : fgkNZChannels;
+  Int_t i = 0;
+  Int_t j = 0;
+  TCanvas *c = new TCanvas("zchmap", "Z-Chhannel Mapping");
+  c->cd();
+  TGraph **graphz = new TGraph*[fgkNZChannels];
+  for (Int_t zch = zchmin; zch < zchmax; zch++) 
+    graphz[zch] = new TGraph;
+  TGraphAsymmErrors *graph = new TGraphAsymmErrors();
+  graph->SetTitle("Z-Channel Map");
+  graph->SetPoint(i, 0, 0); // vertex
+  graph->SetPointError(i++, 20, 20, 0, 0);
+  //  graph->SetRange //????
+  for (Int_t iLayer = 0; iLayer < fGeo->Nlayer(); iLayer++) {
+    for (Int_t iStack = 0; iStack < fGeo->Nstack(); iStack++) {
+      AliTRDpadPlane *pp = fGeo->GetPadPlane(iLayer, iStack);
+      for (Int_t iRow = 0; iRow < fGeo->GetRowMax(iLayer, iStack, 0); iRow++) {
+       graph->SetPoint(i, pp->GetRowPos(iRow), fGeo->GetTime0(iLayer) - fGeo->CdrHght());
+       graph->SetPointError(i++, pp->GetRowSize(iRow), 0, 0, 0);
+       for (Int_t zch = zchmin; zch < zchmax; zch++)
+         if (fZSubChannel[iStack][zch][iLayer][iRow] != 0)
+           if (subchannel == 0 || fZSubChannel[iStack][zch][iLayer][iRow] == subchannel)
+             graphz[zch]->SetPoint(j++, pp->GetRowPos(iRow)  - pp->GetRowSize(iRow)/2, fGeo->GetTime0(iLayer) - fGeo->CdrHght());
+      }
+    }
+  }
+  graph->SetMarkerStyle(kDot);
+  graph->Draw("AP");
+  for (Int_t zch = zchmin; zch < zchmax; zch++) {
+    graphz[zch]->SetMarkerStyle(kCircle);
+    graphz[zch]->SetMarkerColor(zch+2);
+    graphz[zch]->SetMarkerSize(0.3 + zch*0.2);
+    graphz[zch]->Draw("P");
+  }
+  return kTRUE;
+}
+
+Int_t AliTRDgtuParam::GetCiAlpha(Int_t layer) const 
+{
+  // get the constant for the calculation of alpha
+
+  Int_t Ci = (Int_t) (GetChamberThickness() / fGeo->GetTime0(layer) * GetBinWidthY() / GetBinWidthdY() * (1 << (GetBitExcessAlpha() + GetBitExcessY() + 1)) );
+  return Ci;
+}
+
+Int_t AliTRDgtuParam::GetCiYProj(Int_t layer) const 
+{
+  // get the constant for the calculation of y_proj
+
+  Float_t Xmid = (fGeo->GetTime0(0) + fGeo->GetTime0(fGeo->Nlayer()-1)) / 2.; 
+  Int_t Ci = (Int_t) (- (fGeo->GetTime0(layer) - Xmid) / GetChamberThickness() * GetBinWidthdY() / GetBinWidthY() * (1 << GetBitExcessYProj()) );
+  return Ci;
+}
+
+Int_t AliTRDgtuParam::GetYt(Int_t stack, Int_t layer, Int_t zrow) const
+{
+    return (Int_t) (- ( (layer % 2 ? 1 : -1) * 
+                       (GetGeo()->GetPadPlane(layer, stack)->GetRowPos(zrow) - GetGeo()->GetPadPlane(layer, stack)->GetRowSize(zrow) / 2) * 
+                       TMath::Tan(- 2.0 / 180.0 * TMath::Pi()) ) / 0.016 );
+}
+
+Bool_t AliTRDgtuParam::GenerateRecoCoefficients(Int_t trackletMask) 
+{
+  fCurrTrackletMask = trackletMask;
+
+  TMatrix a(GetNLayers(), 3);
+  TMatrix b(3, GetNLayers());
+  TMatrix c(3, 3);
+
+  for (Int_t layer = 0; layer < GetNLayers(); layer++) {
+      if ( (trackletMask & (1 << layer)) == 0) {
+         a(layer, 0) = 0;
+         a(layer, 1) = 0;
+         a(layer, 2) = 0;
+      } 
+      else {
+         a(layer, 0) = 1;
+         a(layer, 1) = fGeo->GetTime0(layer);
+         a(layer, 2) = (layer % 2 ? 1 : -1) * fGeo->GetTime0(layer);
+      }
+  }
+
+  b.Transpose(a);
+  c = b * a;
+  c.InvertFast();
+  b = c * b;
+
+  for (Int_t layer = 0; layer < GetNLayers(); layer++) {
+      fAki[layer] = b.GetMatrixArray()[layer];
+      fBki[layer] = b.GetMatrixArray()[GetNLayers() + layer];
+      fCki[layer] = b.GetMatrixArray()[2 * GetNLayers() + layer];
+    }
+  return kTRUE;
+}
+
+Float_t AliTRDgtuParam::GetAki(Int_t k, Int_t i) 
+{
+  // get A_ki for the calculation of the tracking parameters
+  if (fCurrTrackletMask != k)
+    GenerateRecoCoefficients(k);
+
+  return fAki[i];
+}
+
+Float_t AliTRDgtuParam::GetBki(Int_t k, Int_t i) 
+{
+  // get B_ki for the calculation of the tracking parameters
+
+  if (fCurrTrackletMask != k)
+    GenerateRecoCoefficients(k);
+
+  return fBki[i];
+}
+
+Float_t AliTRDgtuParam::GetCki(Int_t k, Int_t i) 
+{
+  // get B_ki for the calculation of the tracking parameters
+
+  if (fCurrTrackletMask != k)
+    GenerateRecoCoefficients(k);
+
+  return fCki[i];
+}
+
+/*
+Float_t AliTRDgtuParam::GetD(Int_t k) const 
+{
+  // get the determinant for the calculation of the tracking parameters
+
+  TMatrix t(3, 3);
+  for (Int_t i = 0; i < GetNLayers(); i++) {
+    if ( !((k >> i) & 0x1) )
+      continue;
+    Float_t xi = fGeo->GetTime0(i);
+    t(0,0) += 1;
+    t(1,0) += xi;
+    t(2,0) += TMath::Power(-1, i) * xi;
+    t(0,1) += xi;
+    t(1,1) += TMath::Power(xi, 2);
+    t(2,1) += TMath::Power(-1, i) * TMath::Power(xi, 2);
+    t(0,2) += TMath::Power(-1, i) * xi;
+    t(1,2) += TMath::Power(-1, i) * TMath::Power(xi, 2);
+    t(2,2) += TMath::Power(xi, 2);
+  }
+  return t.Determinant();
+}
+
+Bool_t AliTRDgtuParam::GetFitParams(TVectorD& rhs, Int_t k) 
+{
+  // calculate the fitting parameters
+  // will be changed!
+
+  TMatrix t(3,3);
+  for (Int_t i = 0; i < GetNLayers(); i++) {
+    if ( !((k >> i) & 0x1) )
+      continue;
+    Float_t xi = fGeo->GetTime0(i);
+    t(0,0) += 1;
+    t(1,0) += xi;
+    t(2,0) += TMath::Power(-1, i) * xi;
+    t(0,1) += xi;
+    t(1,1) += TMath::Power(xi, 2);
+    t(2,1) += TMath::Power(-1, i) * TMath::Power(xi, 2);
+    t(0,2) -= TMath::Power(-1, i) * xi;
+    t(1,2) -= TMath::Power(-1, i) * TMath::Power(xi, 2);
+    t(2,2) -= TMath::Power(xi, 2);
+  }
+  TDecompLU lr(t);
+  lr.Solve(rhs);
+  return lr.Decompose();
+}
+*/
+
+Bool_t AliTRDgtuParam::GetIntersectionPoints(Int_t k, Float_t &x1, Float_t &x2) 
+{
+  // get the x-coord. of the assumed circle/straight line intersection points
+
+  Int_t l1 = -1;
+  Int_t l2 = -1;
+  Int_t nHits = 0;
+  for (Int_t layer = 0; layer < GetNLayers(); layer++) {
+    if ( (k >> layer) & 0x1 ) {
+      if (l1 < 0) 
+       l1 = layer;
+      l2 = layer;
+      nHits++;
+    }
+  }
+
+  x1 = fGeo->GetTime0(l1) + 10./6 * (nHits -1);
+  x2 = fGeo->GetTime0(l2) - 10./6 * (nHits -1);
+
+  return ( (l1 >= 0) && (l2 >= 0) );
+}
+
+Float_t AliTRDgtuParam::GetRadius(Int_t a, Float_t b, Float_t x1, Float_t x2) 
+{
+  // get the radius for the track
+  Float_t d = (1 + b * b /2 ) * (x2 - x1);
+  Float_t c1 = x1 * x2 / 2;
+//  Float_t c2 = (x1 + x2) / (x1 * x2);
+  printf("c1: %f\n", c1);
+  Float_t r = (375. / 10000.) * c1 * 256 / (a >> 1);
+  return r;
+
+  Float_t y1 = a + b*x1;
+  Float_t y2 = a + b*x2;
+  Float_t alpha = TMath::Abs( TMath::ATan(y2/x2) - TMath::ATan(y1/x1) );
+  d = TMath::Sqrt( TMath::Power(x2-x1, 2) + TMath::Power(y2-y1, 2) );
+  r = d / 2. / TMath::Sin(alpha);
+  return r;
+}
diff --git a/TRD/AliTRDgtuParam.h b/TRD/AliTRDgtuParam.h
new file mode 100644 (file)
index 0000000..598e139
--- /dev/null
@@ -0,0 +1,116 @@
+#ifndef ALITRDGTUPARAM_H
+#define ALITRDGTUPARAM_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: AliTRDgtuParam.h 27496 2008-07-22 08:35:45Z cblume $ */
+
+// --------------------------------------------------------
+// 
+// Singleton class to hold the parameters steering the GTU 
+// tracking
+//
+// --------------------------------------------------------
+
+#include "TObject.h"
+#include "TVectorD.h"
+
+class AliTRDgeometry;
+
+class AliTRDgtuParam : public TObject {
+ public:
+  virtual ~AliTRDgtuParam();
+
+  static AliTRDgtuParam *Instance(); // Singleton
+  static void Terminate(); 
+
+  static inline Int_t GetNLinks() { return fgkNLinks; }
+  static inline Int_t GetNLayers() { return fgkNLinks/2; }
+  static inline Int_t GetNZChannels() { return fgkNZChannels; }
+  static inline Int_t GetNRefLayers() { return fgkNRefLayers; }
+
+  static inline Float_t GetChamberThickness() { return 3.0; }
+
+  // ----- Bin widths (granularity) -----
+  static inline Float_t GetBinWidthY() { return fgkBinWidthY; }
+  static inline Float_t GetBinWidthdY() { return fgkBinWidthdY; }
+
+  // ----- Bit Widths (used for internal representation) -----
+  static inline Int_t GetBitWidthY() { return fgkBitWidthY; }
+  static inline Int_t GetBitWidthdY() { return fgkBitWidthdY; }
+  static inline Int_t GetBitWidthYProj() { return fgkBitWidthYProj; }
+  static inline Int_t GetBitExcessY() { return fgkBitExcessY; }
+  static inline Int_t GetBitExcessAlpha() { return fgkBitExcessAlpha; }
+  static inline Int_t GetBitExcessYProj() { return fgkBitExcessYProj; }
+
+  AliTRDgeometry* GetGeo() const { return fGeo; }
+  Float_t GetVertexSize() const { return fVertexSize; }
+  Int_t GetCiAlpha(Int_t layer) const;
+  Int_t GetCiYProj(Int_t layer) const;
+  Int_t GetYt(Int_t stack, Int_t layer, Int_t zrow) const;
+  Int_t GetDeltaY() const { return fgkDeltaY; }
+  Int_t GetDeltaAlpha() const { return fgkDeltaAlpha; }
+  Int_t GetZSubchannel(Int_t stack, Int_t layer, Int_t zchannel, Int_t zpos) const;
+  Int_t GetRefLayer(Int_t refLayerIdx) const;
+//  Bool_t GetFitParams(TVectorD &rhs, Int_t k); // const
+  Bool_t GetIntersectionPoints(Int_t k, Float_t &x1, Float_t &x2); // const
+  Float_t GetRadius(Int_t a, Float_t b, Float_t x1, Float_t x2); // const
+
+  Bool_t IsInZChannel(Int_t stack, Int_t layer, Int_t zchannel, Int_t zpos) const;
+
+  void SetVertexSize(Float_t vertexsize) { fVertexSize = vertexsize; }
+
+  // z-channel map
+  Int_t zChannelGen(); // could have different modes (for beam-beam, cosmics, ...)
+  Bool_t DisplayZChannelMap(Int_t zchannel = -1, Int_t subch = 0) const;
+
+  // variables for pt-reconstruction (not used at the moment)
+  Bool_t GenerateRecoCoefficients(Int_t trackletMask);
+  Float_t GetAki(Int_t k, Int_t i);
+  Float_t GetBki(Int_t k, Int_t i);
+  Float_t GetCki(Int_t k, Int_t i);
+//  Float_t GetD(Int_t k) const;
+
+ protected:
+  static const Int_t fgkNZChannels = 3; // No. of z-channels
+  static const Int_t fgkNLinks = 12;   // No. of links
+  static const Int_t fgkFixLayer = 2;  // which layer is fixed for the generation of the z-channel map
+  static const Int_t fgkDeltaY = 39;   // accepted deviation in y_proj, default: 9
+  static const Int_t fgkDeltaAlpha = 31; // accepted deviation in alpha, default: 11
+  static const Int_t fgkNRefLayers = 3;         // no. of reference layers
+
+  static const Float_t fgkBinWidthY;
+  static const Float_t fgkBinWidthdY;
+
+  static const Int_t fgkBitWidthY;
+  static const Int_t fgkBitWidthdY;
+  static const Int_t fgkBitWidthYProj;
+  static const Int_t fgkBitExcessY;
+  static const Int_t fgkBitExcessAlpha;
+  static const Int_t fgkBitExcessYProj;
+  Float_t fVertexSize;         // assumed vertex size (z-dir.) for the z-channel map
+
+  Int_t fZChannelMap[5][16][6][16];              // must be changed
+  Int_t fZSubChannel[5][fgkNZChannels][6][16];    // must be changed
+
+  Int_t fCurrTrackletMask;
+  Float_t fAki[6];
+  Float_t fBki[6];
+  Float_t fCki[6];
+
+  Int_t *fRefLayers;           //[fgkNRefLayers] reference layers for track finding
+
+  AliTRDgeometry *fGeo;                //! pointer to the TRD geometry
+
+  static AliTRDgtuParam *fgInstance; // instance pointer
+
+ private:
+  AliTRDgtuParam();                         // instance only via Instance()
+  AliTRDgtuParam(const AliTRDgtuParam &rhs); // not implemented
+  AliTRDgtuParam& operator=(const AliTRDgtuParam &rhs); // not implemented
+
+  ClassDef(AliTRDgtuParam, 1);
+};
+
+#endif
diff --git a/TRD/AliTRDgtuSim.cxx b/TRD/AliTRDgtuSim.cxx
new file mode 100644 (file)
index 0000000..4303882
--- /dev/null
@@ -0,0 +1,386 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id: AliTRDgtuSim.cxx 28397 2008-09-02 09:33:00Z cblume $ */
+
+////////////////////////////////////////////////////////////////////////////
+//                                                                        //
+//  GTU simulation                                                        //
+//                                                                        //
+//  Authors: J. Klein (Jochen.Klein@cern.ch)                              //
+//                                                                        //
+////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <fstream>
+#include <string>
+
+#include "TFile.h"
+#include "TROOT.h"
+#include "TClonesArray.h"
+
+#include "AliTRDgtuSim.h"
+#include "AliTRDmcmTracklet.h"
+#include "AliTRDgtuTMU.h"
+#include "AliTRDtrackGTU.h"
+#include "AliTRDtrackletWord.h"
+#include "AliTRDtrackletMCM.h"
+#include "AliESDEvent.h"
+
+#include "AliRun.h"
+#include "AliRunLoader.h"
+#include "AliLoader.h"
+#include "AliLog.h"
+
+ClassImp(AliTRDgtuSim)
+
+AliTRDgtuSim::AliTRDgtuSim(AliRunLoader *rl) 
+  : TObject(),
+  fRunLoader(rl),
+  fTMU(0x0),
+  fTrackletArray(0x0),
+  fTrackTree(0x0),
+  fTrackletTree(0x0)
+{
+  fTrackletTree = new TTree("gtutracklets", "Tree with GTU tracklets");
+}
+
+AliTRDgtuSim::~AliTRDgtuSim() 
+{
+  if (fTrackletArray)
+    fTrackletArray->Delete();
+  delete fTrackletArray;
+  delete fTrackletTree;
+}
+
+Bool_t AliTRDgtuSim::RunGTUFromTrackletFile(TString filename, Int_t event, Int_t noev) 
+{
+    AliInfo(Form("Running the GTU simulation on file: %s", filename.Data()));
+    ifstream input(filename.Data());
+    
+    std::string str;
+    TString string;
+    int lineno = 0;
+    
+    Int_t iEventPrev = -1;
+    Int_t iStackPrev = -1;
+    Int_t iSecPrev = -1;
+    Int_t iSec = -1;
+    Int_t iStack = -1;
+    Int_t iLink = -1;
+    Int_t iEvent = -1;
+    Int_t evcnt = -1;
+    
+    fTMU = 0x0;
+    
+    AliInfo("--------- Reading from file ----------");
+    while (getline(input, str)) {
+       lineno++;
+       string = str;
+       AliInfo(Form("Line %i : %s", lineno, string.Data()));
+       
+       TObjArray *tokens = string.Tokenize(" ");
+       if (tokens->GetEntriesFast() < 7) {
+           AliWarning(Form("Invalid input in line %i, too few parameters", lineno));
+           continue;
+       }
+
+       if ( ((TObjString*) tokens->At(0))->GetString().Atoi() < event) 
+           continue;
+
+       iEvent = ((TObjString*) tokens->At(0))->GetString().Atoi();
+       iSec = ((TObjString*) tokens->At(1))->GetString().Atoi();
+       iStack = ((TObjString*) tokens->At(2))->GetString().Atoi();
+       iLink = 2 * ((TObjString*) tokens->At(3))->GetString().Atoi() + ((TObjString*) tokens->At(4))->GetString().Atoi();
+
+       if (iEvent != iEventPrev || iStack != iStackPrev || iSec != iSecPrev) {
+           if(fTMU) {
+               TList *ListOfTracks = new TList();
+               fTMU->SetStack(iStackPrev);
+               fTMU->SetSector(iSecPrev);
+               fTMU->RunTMU(ListOfTracks);
+               AliInfo(Form("--- There are %i tracks. Writing ...", ListOfTracks->GetEntries()));
+               WriteTracksToTree(ListOfTracks);
+               fTMU->WriteTrackletsToTree(fTrackletTree);
+               WriteTracksToDataFile(ListOfTracks, iEventPrev);
+               if (ListOfTracks->GetEntries() > 0) 
+                   AliInfo(Form("   %d GeV/c", ((AliTRDtrackGTU*) ListOfTracks->At(0))->GetPt() ));
+               delete fTMU;
+               fTMU = new AliTRDgtuTMU(); 
+               delete ListOfTracks;
+               ListOfTracks = 0x0;
+           } else {
+               fTMU = new AliTRDgtuTMU();
+           }
+           iStackPrev = iStack;
+           iSecPrev = iSec;
+           iEventPrev = iEvent;
+           evcnt++;
+           if (evcnt == noev)
+               break;
+       }
+       for (Int_t i = 5; i < tokens->GetEntriesFast(); i++) {
+           UInt_t trackletWord = 0;
+           sscanf(((TObjString*) tokens->At(i))->GetString().Data(), "%x", &trackletWord);
+           if (trackletWord == 0x10001000) 
+               break;
+           AliInfo(Form("%i. tracklet: %s -> 0x%08x", i-4, ((TObjString*) tokens->At(i))->GetString().Data(), trackletWord));
+           AliTRDtrackletWord *trkl = new AliTRDtrackletWord(trackletWord);
+           fTMU->AddTracklet(trkl, iLink);
+       }
+    }
+    
+    if (fTMU && evcnt < noev) {
+       TList *ListOfTracks = new TList();
+       fTMU->SetStack(iStackPrev);
+       fTMU->SetSector(iSecPrev);
+       fTMU->RunTMU(ListOfTracks);
+       WriteTracksToTree(ListOfTracks);
+       fTMU->WriteTrackletsToTree(fTrackletTree);
+       WriteTracksToDataFile(ListOfTracks, iEventPrev);
+       delete fTMU;
+       delete ListOfTracks;
+       fTMU = 0x0;
+    }
+
+    AliInfo(Form("Analyzed %i events", evcnt));
+    return kTRUE; 
+}
+
+Bool_t AliTRDgtuSim::RunGTU(AliLoader *loader, AliESDEvent *esd) 
+{
+    if (!LoadTracklets(loader)) {
+       AliError("Could not load the tracklets. Aborting ...");
+       return kFALSE;
+    }
+
+    Int_t iStackPrev = -1;
+    Int_t iSecPrev = -1;
+    Int_t iSec = -1;
+    Int_t iStack = -1;
+    Int_t iLink = -1;
+
+    if (fTMU) {
+       delete fTMU;
+       fTMU = 0x0;
+    }
+    
+    TList *ListOfTracks = new TList();
+    
+    TIter next(fTrackletArray);
+    AliTRDtrackletBase *trkl;
+
+    while (trkl = (AliTRDtrackletBase*) next()) {
+       iSec = trkl->GetDetector() / 30;
+       iStack = (trkl->GetDetector() % 30) / 6;
+       iLink = 2 * (trkl->GetDetector() % 6) + (trkl->GetYbin() < 0 ? 0 : 1);
+
+       if (iStack != iStackPrev || iSec != iSecPrev) {
+           if(fTMU) {
+               fTMU->SetStack(iStackPrev);
+               fTMU->SetSector(iSecPrev);
+               fTMU->RunTMU(ListOfTracks);
+               WriteTracksToTree(ListOfTracks);
+               fTMU->WriteTrackletsToTree(fTrackletTree);
+               WriteTracksToESD(ListOfTracks, esd);
+               fTMU->Reset();
+               ListOfTracks->Delete();
+           } else {
+               fTMU = new AliTRDgtuTMU();
+           }
+           iStackPrev = iStack;
+           iSecPrev = iSec;
+       }
+       fTMU->AddTracklet(trkl, iLink);
+    }
+    
+    if (fTMU) {
+       fTMU->SetStack(iStackPrev);
+       fTMU->SetSector(iSecPrev);
+       fTMU->RunTMU(ListOfTracks);
+       WriteTracksToTree(ListOfTracks);
+       fTMU->WriteTrackletsToTree(fTrackletTree);
+       WriteTracksToESD(ListOfTracks, esd);
+       delete fTMU;
+       fTMU = 0x0;
+       ListOfTracks->Delete();
+    }
+
+    delete ListOfTracks;
+
+    return kTRUE;
+}
+
+Bool_t AliTRDgtuSim::LoadTracklets(AliLoader *loader) 
+{
+  AliInfo("Loading tracklets ...");
+
+  if (!loader) {
+    AliError("No loader given!");
+    return kFALSE;
+  }
+
+  AliDataLoader *trackletLoader = loader->GetDataLoader("tracklets");
+  if (!trackletLoader) {
+      AliError("No tracklet loader found!");
+      return kFALSE;
+  }
+
+  trackletLoader->Load();
+  
+  TTree *trackletTree = trackletLoader->Tree();
+  if (!trackletTree) {
+    AliError("No tracklet tree found");
+    return kFALSE;
+  }  
+
+
+  TBranch *trklbranch = trackletTree->GetBranch("mcmtrklbranch");
+  if (trklbranch) {
+      if (!fTrackletArray)
+         fTrackletArray = new TClonesArray("AliTRDtrackletMCM", 1000);
+      else if ((TClass::GetClass("AliTRDtrackletMCM"))->InheritsFrom(fTrackletArray->Class()))
+         fTrackletArray->Delete();
+      else {
+         fTrackletArray->Delete();
+         delete fTrackletArray;
+         fTrackletArray = new TClonesArray("AliTRDtrackletMCM", 1000);
+      }
+
+      AliTRDtrackletMCM *trkl = new AliTRDtrackletMCM; 
+      trklbranch->SetAddress(&trkl);
+      for (Int_t iTracklet = 0; iTracklet < trklbranch->GetEntries(); iTracklet++) {
+         trklbranch->GetEntry(iTracklet);
+         new ((*fTrackletArray)[fTrackletArray->GetEntries()]) AliTRDtrackletMCM(*trkl);
+      }
+      return kTRUE;
+  }
+
+  trklbranch = trackletTree->GetBranch("trkbranch");
+
+  if (!trklbranch) {
+      AliError("Could not get trkbranch");
+      return kFALSE;
+  }
+  
+  if (!fTrackletArray)
+      fTrackletArray = new TClonesArray("AliTRDtrackletWord", 1000);
+  else if ((TClass::GetClass("AliTRDtrackletWord"))->InheritsFrom(fTrackletArray->Class()))
+      fTrackletArray->Delete();
+  else {
+      fTrackletArray->Delete();
+      delete fTrackletArray;
+      fTrackletArray = new TClonesArray("AliTRDtrackletWord", 1000);
+  }
+
+  Int_t notrkl = 0;
+  UInt_t *leaves = new UInt_t[258];
+  AliInfo(Form("No. of entries: %i", trklbranch->GetEntries()));
+  
+  for (Int_t iEntry = 0; iEntry < trklbranch->GetEntries(); iEntry++) {
+      trklbranch->SetAddress(leaves);
+      trklbranch->GetEntry(iEntry);
+      for (Int_t iTracklet = 0; iTracklet < 256; iTracklet++) {
+       if (leaves[2 + iTracklet] == 0)
+         break;
+       new((*fTrackletArray)[notrkl]) AliTRDtrackletWord(leaves[2 + iTracklet], leaves[0] + leaves[1]);
+       notrkl++;
+      }
+      AliInfo(Form("Entry: %3i: Det: %3i, side: %i, 1st tracklet: 0x%08x, no: %i", iEntry, leaves[0], leaves[1], leaves[2], notrkl));
+  }
+
+  return kTRUE;
+}
+
+Bool_t AliTRDgtuSim::WriteTracksToDataFile(TList *ListOfTracks, Int_t event) 
+{
+    Int_t sm = 0;
+    Int_t stack = 0;
+
+    FILE *out;
+    out = fopen("test.data", "a");
+
+    AliInfo(Form("%i tracks found in event %i", ListOfTracks->GetSize(), event));
+    fprintf(out, "0 %5i %2i %i  00000000\n", event, sm, stack);
+    for (Int_t i = 0; i < ListOfTracks->GetSize(); i++) {
+       AliTRDtrackGTU *trk = (AliTRDtrackGTU*) ListOfTracks->At(i);
+       sm = trk->GetSector();
+       stack = trk->GetStack();
+       fprintf(out, "1 %5i %2i %2i %3i %3i %3i %3i %3i %3i %3i %4i %f\n", event, sm, stack, trk->GetTrackletMask(), 
+              trk->GetTrackletIndex(5), 
+              trk->GetTrackletIndex(4), 
+              trk->GetTrackletIndex(3), 
+              trk->GetTrackletIndex(2), 
+              trk->GetTrackletIndex(1), 
+              trk->GetTrackletIndex(0),
+              trk->GetPtInt(), 
+              trk->GetPt());
+    }
+    fclose(out);
+    return kTRUE;
+}
+
+Bool_t AliTRDgtuSim::WriteTracksToTree(TList *ListOfTracks, Int_t /*event*/) 
+{
+  AliInfo(Form("Writing %i tracks to the tree...", ListOfTracks->GetEntries()));
+
+  if (!ListOfTracks)
+    return kFALSE;
+
+  if (ListOfTracks->GetEntries() <= 0) 
+    return kTRUE;
+
+  if (!fTrackTree)
+    fTrackTree = new TTree("gtutracks", "GTU tracks");
+
+  AliTRDtrackGTU *trk = 0x0;
+  TBranch *branch = fTrackTree->GetBranch("TRDgtuTrack");
+  if (!branch) {
+      branch = fTrackTree->Branch("TRDgtuTrack", "AliTRDtrackGTU", &trk, 32000, 99);
+  }
+
+  TIter next(ListOfTracks);
+  while (trk = (AliTRDtrackGTU*) next()) {
+      branch->SetAddress(&trk);
+      fTrackTree->Fill();   
+  }
+  fTrackTree->ResetBranchAddress(branch);
+
+  return kTRUE; 
+}
+
+Bool_t AliTRDgtuSim::WriteTreesToFile() {
+  TFile *f = TFile::Open("TRD.GtuTracking.root", "RECREATE");
+  f->cd();
+  if (fTrackTree)
+    f->WriteTObject(fTrackTree);
+  if (fTrackletTree)
+    f->WriteTObject(fTrackletTree);
+  f->Close();
+  return kTRUE;
+}
+
+Bool_t AliTRDgtuSim::WriteTracksToESD(TList *ListOfTracks, AliESDEvent *esd) 
+{
+    if (esd) {
+       TIter next(ListOfTracks);
+       while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) next()) {
+           AliESDTrdTrack *trdtrack = trk->CreateTrdTrack();
+           esd->AddTrdTrack(trdtrack);
+           delete trdtrack;
+       }
+    }
+    return kTRUE;
+}
diff --git a/TRD/AliTRDgtuSim.h b/TRD/AliTRDgtuSim.h
new file mode 100644 (file)
index 0000000..decaec7
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef ALITRDGTUSIM_H
+#define ALITRDGTUSIM_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: AliTRDgtuSim.h 27496 2008-07-22 08:35:45Z cblume $ */
+
+// --------------------------------------------------------
+// 
+// GTU simulation
+//
+// --------------------------------------------------------
+
+#include "TObject.h"
+
+class AliRunLoader;
+class AliLoader;
+class AliESDEvent;
+
+class AliTRDgtuTMU;
+class TTree;
+class TList;
+
+class AliTRDgtuSim : public TObject {
+ public:
+  AliTRDgtuSim(AliRunLoader *rl = 0x0);
+  ~AliTRDgtuSim();
+
+  Bool_t LoadTracklets(AliLoader *loader);
+
+  Bool_t RunGTU(AliLoader *loader, AliESDEvent *esd = 0x0);
+  Bool_t RunGTUFromTrackletFile(TString filename, Int_t event, Int_t noev = 1);
+
+  TTree* GetTreeOfTracks() { return fTrackTree; }
+  Bool_t WriteTracksToTree(TList *ListOfTracks, Int_t event = 0); 
+  Bool_t WriteTracksToDataFile(TList *ListOfTracks, Int_t event);
+  Bool_t WriteTreesToFile();
+  Bool_t WriteTracksToESD(TList *ListOfTracks, AliESDEvent *esd);
+
+ protected:
+  AliRunLoader         *fRunLoader;    //!
+  AliTRDgtuTMU         *fTMU;          // pointer to TMU simulation class
+  TClonesArray         *fTrackletArray;        // array of tracklets
+  TTree        *fTrackTree;    // tree to hold the tracks of one event, used for writing in WriteTracksToFile()
+  TTree         *fTrackletTree; // tree to hold the gtu tracklets
+
+ private:
+  AliTRDgtuSim& operator=(const AliTRDgtuSim &rhs); // not implemented
+  AliTRDgtuSim(const AliTRDgtuSim &rhs); // not implemented
+
+  ClassDef(AliTRDgtuSim, 1);
+};
+
+#endif
diff --git a/TRD/AliTRDgtuTMU.cxx b/TRD/AliTRDgtuTMU.cxx
new file mode 100644 (file)
index 0000000..5887e1f
--- /dev/null
@@ -0,0 +1,786 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id: AliTRDgtuTMU.cxx 28397 2008-09-02 09:33:00Z cblume $ */
+
+////////////////////////////////////////////////////////////////////////////
+//                                                                        //
+//  Track Matching Unit (TMU) simulation                                  //
+//                                                                        //
+//  Author: J. Klein (Jochen.Klein@cern.ch)                               //
+//                                                                        //
+////////////////////////////////////////////////////////////////////////////
+
+#include "TTree.h"
+#include "TList.h"
+#include "TVectorD.h"
+#include "TMath.h"
+
+#include "AliESDEvent.h"
+#include "AliESDTrdTrack.h"
+
+#include "AliLog.h"
+#include "AliTRDgeometry.h"
+#include "AliTRDpadPlane.h"
+
+#include "AliTRDgtuParam.h"
+#include "AliTRDgtuTMU.h"
+#include "AliTRDtrackGTU.h"
+
+ClassImp(AliTRDgtuTMU)
+
+AliTRDgtuTMU::AliTRDgtuTMU(Int_t stack, Int_t sector) :
+  TObject(),
+  fTracklets(0x0),
+  fZChannelTracklets(0x0),
+  fTracks(0x0),
+  fGtuParam(0x0),
+  fStack(-1),
+  fSector(-1)
+{
+  fGtuParam = AliTRDgtuParam::Instance();
+  fTracklets = 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()];
+  }
+  fTracks = new TList*[fGtuParam->GetNZChannels()];
+  for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
+      fTracks[zch] = new TList[fGtuParam->GetNRefLayers()];
+  }
+  if (stack > -1) 
+      SetStack(stack);
+  if (sector > -1)
+      SetSector(sector);
+}
+
+AliTRDgtuTMU::~AliTRDgtuTMU() 
+{
+  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 [] fZChannelTracklets;
+  delete [] fTracklets;
+}
+
+Bool_t AliTRDgtuTMU::SetSector(Int_t sector)
+{
+  // set the sector
+
+  if (sector > -1 && sector < fGtuParam->GetGeo()->Nsector() ) {
+    fSector = sector; 
+    return kTRUE;
+  }
+
+  AliError(Form("Invalid sector given: %i", sector));
+  return kFALSE;
+}
+
+Bool_t AliTRDgtuTMU::SetStack(Int_t stack) 
+{
+  // Set the stack (necessary for tracking)
+
+  if (stack > -1 && stack < fGtuParam->GetGeo()->Nstack() ) {
+    fStack = stack;
+    return kTRUE;
+  }
+
+  AliError(Form("Invalid stack given: %i", stack));
+  return kFALSE;
+}
+
+Bool_t AliTRDgtuTMU::Reset() 
+{
+  // delete all tracks
+
+  for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
+    for (Int_t reflayeridx = 0; reflayeridx < fGtuParam->GetNRefLayers(); reflayeridx++) {
+      fTracks[zch][reflayeridx].Clear();
+    }
+  }
+
+  // delete all added tracklets
+  for (Int_t layer = 0; layer < fGtuParam->GetNLinks()/2; layer++) {
+    for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++)
+      fZChannelTracklets[layer][zch].Clear();
+    fTracklets[layer]->Delete();
+  }
+
+  fSector = -1;
+  fStack = -1;
+
+  return kTRUE;
+}
+
+Bool_t AliTRDgtuTMU::AddTracklet(AliTRDtrackletBase *tracklet, Int_t link) 
+{
+  // add a tracklet on the given link
+
+  AliTRDtrackletGTU *trkl = new AliTRDtrackletGTU(tracklet); 
+  fTracklets[(Int_t) link/2]->Add(trkl);
+  return kTRUE;
+}
+
+
+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!");
+    return kFALSE;
+  }
+
+  // ----- Input units -----
+  AliInfo("--------- Running Input units ----------");
+  for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
+    if (!RunInputUnit(layer)) {
+      AliError(Form("Input unit in layer %i failed", layer));
+      return kFALSE;
+    }
+  }
+
+  // ----- Z-channel units -----
+  AliInfo("--------- Running Z-channel units ----------");
+  for (Int_t layer = 0;  layer <  fGtuParam->GetNLayers(); layer++) {
+    fZChannelTracklets[layer] = new TList[fGtuParam->GetNZChannels()];
+    if (!RunZChannelUnit(layer)) {
+      AliError(Form("Z-Channel unit in layer %i failed", layer));
+      return kFALSE;
+    }
+  }
+
+  // ----- track finding -----
+  AliInfo("--------- Running tracking units ----------");
+  for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
+    AliInfo(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)) {
+    AliError("Track merging failed");
+    return kFALSE;
+  }
+
+  // ----- track reconstruction -----
+  if (!RunTrackReconstruction(ListOfTracks)) {
+    AliError("Track reconstruction failed");
+    return kFALSE;
+  }
+
+  if (esd) {
+      TIter next(ListOfTracks);
+      while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) next()) {
+         AliESDTrdTrack *trdtrack = trk->CreateTrdTrack();
+         esd->AddTrdTrack(trdtrack);
+         delete trdtrack;
+      }
+  }
+
+  return kTRUE;
+}
+
+Bool_t AliTRDgtuTMU::RunInputUnit(Int_t layer) 
+{
+  // precalculations for the tracking and reconstruction
+
+  fTracklets[layer]->Sort();
+  TIter next(fTracklets[layer]);
+
+  while ( AliTRDtrackletGTU *trk = (AliTRDtrackletGTU*) next() ) {
+    trk->SetIndex(fTracklets[layer]->IndexOf(trk));
+
+    Int_t alpha = (trk->GetYbin() >> fGtuParam->GetBitExcessY()) * fGtuParam->GetCiAlpha(layer); 
+    alpha = ( 2 * trk->GetdY() - (alpha >> fGtuParam->GetBitExcessAlpha()) + 1 ) >> 1;
+    trk->SetAlpha(alpha);
+
+    Int_t yproj = trk->GetdY() * (fGtuParam->GetCiYProj(layer)); 
+    yproj = ( ( ( (yproj >> fGtuParam->GetBitExcessYProj()) + trk->GetYbin() ) >> 2) + 1) >> 1;
+    trk->SetYProj(yproj);
+
+    trk->SetYPrime(trk->GetYbin() + fGtuParam->GetYt(fStack, layer, trk->GetZbin()));
+
+//    printf("InputUnit : GetIndex(): %3i, GetZbin(): %2i, GetY() : %5i, GetdY() : %3i, GetYPrime() : %5i, GetYProj() : %5i, GetAlpha() : %3i \n", 
+//        trk->GetIndex(), trk->GetZbin(), trk->GetYbin(), trk->GetdY(), trk->GetYPrime(), trk->GetYProj(), trk->GetAlpha() );
+  }
+  return kTRUE;
+}
+
+Bool_t AliTRDgtuTMU::RunZChannelUnit(Int_t layer) 
+{
+  // run the z-channel unit
+
+  TIter next(fTracklets[layer]);
+
+  while (AliTRDtrackletGTU *trk = (AliTRDtrackletGTU*) next()) {
+    printf("*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()) )
+           break;
+       }
+       fZChannelTracklets[layer][zch].AddAfter(t, trk);
+      }
+      else 
+         printf("      ");
+    }
+    printf("\n");
+  }
+  return kTRUE;
+}
+
+Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList *ListOfTracks) 
+{
+  // run the track finding
+
+   Int_t       *notr = new Int_t[fGtuParam->GetNLayers()];
+   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      *bHitB     = new Bool_t[fGtuParam->GetNLayers()];
+   Bool_t      *bAligned  = new Bool_t[fGtuParam->GetNLayers()];
+   Bool_t      *bAlignedA = new Bool_t[fGtuParam->GetNLayers()];
+   Bool_t      *bAlignedB = new Bool_t[fGtuParam->GetNLayers()];
+   Bool_t      *bDone     = new Bool_t[fGtuParam->GetNLayers()];
+   Bool_t       ready;
+
+   Int_t       *inc      = new Int_t[fGtuParam->GetNLayers()];
+   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;
+
+   AliTRDtrackletGTU   *trkRA  = 0x0;  // reference tracklet A
+   AliTRDtrackletGTU   *trkRB  = 0x0;  // reference tracklet B
+   AliTRDtrackletGTU   *trkA   = 0x0;  // tracklet A in current layer
+   AliTRDtrackletGTU   *trkB   = 0x0;  // tracklet B in current layer
+/*
+   AliTRDtrackletGTU   *trkEnd = new AliTRDtrackletGTU();
+   for (Int_t i = 0; i < fGtuParam->GetNZChannels(); i++) 
+       trkEnd->SetSubChannel(i, 7);
+   trkEnd->SetYProj(0);
+   trkEnd->SetAlpha(0);
+*/
+
+   for (Int_t refLayerIdx = 0; refLayerIdx < fGtuParam->GetNRefLayers(); refLayerIdx++) {
+     Int_t reflayer = fGtuParam->GetRefLayer(refLayerIdx);
+     AliInfo(Form("~~~~~ Reflayer: %i", reflayer));
+
+     ready = kFALSE; // ready if all channels done
+
+     for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
+       notr[layer] = fZChannelTracklets[layer][zch].GetEntries();
+       ptrA[layer] = 0; // notr[layer] > 0 ? 0 : -1;
+       ptrB[layer] = 1; // notr[layer] > 1 ? 1 : -1;
+
+// not necessary here
+//       bDone[layer] = (ptrB[layer] >= notr[layer] - 1); // trkB is last one
+//       bDone[layer] = (notr[layer] <= 0);
+//       ready = ready && bDone[layer];
+
+       if (reflayer == 1)
+        AliInfo(Form("in layer: %i (zchannel = %i) there are: %i tracklets", layer, zch, notr[layer]));
+     }
+     
+     if (ptrA[reflayer] < 0 && ptrB[reflayer] < 0) 
+       continue;
+
+     while (!ready) {
+       // ----- reference tracklets -----
+       trkRA = 0x0;
+       trkRB = 0x0;
+       if (0 <= ptrA[reflayer] && ptrA[reflayer] < notr[reflayer])
+        trkRA = (AliTRDtrackletGTU*) fZChannelTracklets[reflayer][zch].At(ptrA[reflayer]);
+       else  {
+        AliInfo(Form("No valid tracklet in the reference at ptr: %i! Aborting!", ptrA[reflayer]));
+        break; 
+       }
+
+       if (0 <= ptrB[reflayer] && ptrB[reflayer] < notr[reflayer])
+        trkRB = (AliTRDtrackletGTU*) fZChannelTracklets[reflayer][zch].At(ptrB[reflayer]);
+
+       AliInfo(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();
+       if (trkRB) {
+        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();
+       }
+
+       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;
+
+        if (layer == reflayer) {
+          bHitA[layer] = kTRUE;
+          bAligned[layer] = kTRUE;
+          NHits++;
+          continue; 
+        }
+
+        trkA = 0x0;
+        trkB = 0x0;
+        if (0 <= ptrA[layer] && ptrA[layer] < notr[layer])
+          trkA = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]);
+        if (0 <= ptrB[layer] && ptrB[layer] < notr[layer])
+          trkB = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]);
+
+        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) ); 
+        }
+        else {
+          bHitA[layer] = 0;
+          bAlignedA[layer] = kTRUE;
+        }
+
+        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) );
+        } 
+        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++;
+        else if (!bAligned[layer] )
+          NUnc++;
+        if (trkRB) {
+          if (trkA) {
+            if ((trkA->GetSubChannel(zch) > trkRB->GetSubChannel(zch)) || (trkA->GetSubChannel(zch) == trkRB->GetSubChannel(zch) && trkA->GetYProj() > YBplus) )
+              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
+                    incprime[layer] = 1;
+                else 
+                    incprime[layer] = 0;
+            }
+            else 
+                incprime[layer] = 1;
+
+            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
+                        incprime[layer] = 2;
+                }
+                else 
+                    incprime[layer] = 2;
+            }
+        }
+       } // end of loop over layers
+
+       AliInfo(Form("logic calculation finished, Nhits: %i", NHits));
+
+       if (NHits >= 4) {
+        // ----- track registration -----
+        AliInfo("***** 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) 
+            track->AddTracklet((AliTRDtrackletGTU* ) fZChannelTracklets[layer][zch].At(ptrA[layer]), 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--) {
+            if (track->IsTrackletInLayer(fGtuParam->GetRefLayer(layerIdx)))
+                registerTrack = kFALSE;
+        }
+        if (registerTrack) {
+            track->SetZChannel(zch);
+            track->SetRefLayerIdx(refLayerIdx);
+            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?
+         inc[reflayer] = 0;
+       else if (NWayBeyond > 2) // no track possible for both reference tracklets
+        inc[reflayer] = 2;
+       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]; 
+        }
+       else { // reflayer is not shifted
+        for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
+          if (layer == reflayer || notr[layer] == 0)
+            continue;
+          inc[layer] = 0;
+          trkA = 0x0;
+          trkB = 0x0;
+          if (0 <= ptrA[layer] && ptrA[layer] < notr[layer])
+            trkA = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]);
+
+          if (0 <= ptrB[layer] && ptrB[layer] < notr[layer])
+            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
+                  inc[layer] = 0;
+              else if (trkB) {
+                  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) ) )
+                      inc[layer] = 1;
+                  else 
+                      inc[layer] = incprime[layer];
+              }
+              else 
+                  inc[layer] = incprime[layer];
+          }
+        }
+       }
+       
+       ready = kTRUE;
+       for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
+
+        bDone[layer] = ptrB[layer] < 0 || ptrB[layer] >= notr[layer];
+        ready = ready && bDone[layer];
+
+        if (inc[layer] != 0 && ptrA[layer] >= notr[layer])
+          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]));
+        AliInfo(Form(" -- Layer: %i   %i   %i   +%i   %s  (no: %i)", layer, ptrA[layer], ptrB[layer], inc[layer], bDone[layer] ? "done" : "    ", notr[layer]));
+        ptrA[layer] += inc[layer];
+        ptrB[layer] += inc[layer];
+       }
+
+     } // end of while
+   } // end of loop over reflayer
+
+   delete [] bHitA;
+   delete [] bHitB;
+   delete [] bAligned;
+   delete [] bDone;
+   delete [] inc;
+   delete [] incprime;
+   delete [] bAlignedA;
+   delete [] bAlignedB;
+   delete [] notr;
+   delete [] ptrA;
+   delete [] ptrB;
+
+   return kTRUE;
+}
+
+Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks) 
+{
+    TList **tracksRefMerged = new TList*[fGtuParam->GetNZChannels()];
+    TList **tracksRefUnique = new TList*[fGtuParam->GetNZChannels()];
+
+    for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
+       tracksRefMerged[zch] = new TList;
+       tracksRefUnique[zch] = new TList;
+    }
+
+    TList *tracksZMergedStage0 = new TList;
+    TList *tracksZUniqueStage0 = new TList;
+
+    TList **tracksZSplitted = new TList*[2];
+    for (Int_t i = 0; i < 2; i++)
+       tracksZSplitted[i] = new TList;
+
+    TList *tracksZMergedStage1 = new TList;
+
+    AliTRDtrackGTU **trk = new AliTRDtrackGTU*[fGtuParam->GetNRefLayers()];
+
+    Bool_t done = kFALSE;
+    Int_t minIdx = 0;
+    AliTRDtrackGTU *trkStage0 = 0x0;
+
+    for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
+        // ----- Merging and Unification in Reflayers -----
+       do {
+           done = kTRUE;
+           trkStage0 = 0x0;
+           for (Int_t refLayerIdx = 0; refLayerIdx < fGtuParam->GetNRefLayers(); refLayerIdx++) {
+               trk[refLayerIdx] = (AliTRDtrackGTU*) fTracks[zch][refLayerIdx].First();
+               if (trk[refLayerIdx] == 0) {
+                   continue;
+               }
+               else if (trkStage0 == 0x0 ) {
+                   trkStage0 = trk[refLayerIdx];
+                   minIdx = refLayerIdx;
+                   done = kFALSE;
+               }
+               else if (trk[refLayerIdx]->GetZSubChannel() < trkStage0->GetZSubChannel() || 
+                        (trk[refLayerIdx]->GetZSubChannel() == trkStage0->GetZSubChannel() && trk[refLayerIdx]->GetYapprox() < trkStage0->GetYapprox()) ) {
+                   minIdx = refLayerIdx;
+                   trkStage0 = trk[refLayerIdx];
+                   done = kFALSE;
+               }
+           }
+
+           tracksRefMerged[zch]->Add(trkStage0);
+           fTracks[zch][minIdx].RemoveFirst();
+       } while (trkStage0 != 0);
+
+       Uniquifier(tracksRefMerged[zch], tracksRefUnique[zch]);
+    }
+
+// ----- Merging in zchannels - 1st stage -----
+    
+    do {
+       done = kTRUE;
+       trkStage0 = 0x0;
+       for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
+           AliTRDtrackGTU *trk = (AliTRDtrackGTU*) tracksRefUnique[zch]->First();
+           if (trk == 0) {
+               continue;
+           }
+           else if (trkStage0 == 0x0 ) {
+               trkStage0 = trk;
+               minIdx = zch;
+               done = kFALSE;
+           }
+           else if ( ((trk->GetZChannel() + 3 * trk->GetZSubChannel()) / 2 - 1) < ((trkStage0->GetZChannel() + 3 * trkStage0->GetZSubChannel()) / 2 -1 ) ) {
+               minIdx = zch;
+               trkStage0 = trk;
+               done = kFALSE;
+           }
+       }
+       
+       
+       tracksZMergedStage0->Add(trkStage0);
+       tracksRefUnique[minIdx]->RemoveFirst();
+    } while (trkStage0 != 0);
+    
+    Uniquifier(tracksZMergedStage0, tracksZUniqueStage0);
+    
+// ----- Splitting in z -----
+    
+    TIter next(tracksZUniqueStage0);
+    while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) next()) {
+       tracksZSplitted[(trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) % 2]->Add(trk);
+    }
+    
+// ----- Merging in zchanels - 2nd stage -----
+    
+    do {
+       done = kTRUE;
+       trkStage0 = 0x0;
+       for (Int_t i = 0; i < 2; i++) {
+           AliTRDtrackGTU *trk = (AliTRDtrackGTU*) tracksZSplitted[i]->First();
+           if (trk == 0) {
+               continue;
+           }
+           else if (trkStage0 == 0x0 ) {
+               trkStage0 = trk;
+               minIdx = i;
+               done = kFALSE;
+           }
+           else if ( ((trk->GetZChannel() + 3 * (trk->GetZSubChannel() - 1)) / 2) < ((trkStage0->GetZChannel() + 3 * (trkStage0->GetZSubChannel() - 1)) / 2) ) {
+               minIdx = i;
+               trkStage0 = trk;
+               done = kFALSE;
+           }
+       }
+       
+       tracksZMergedStage1->Add(trkStage0);
+       tracksZSplitted[minIdx]->RemoveFirst();
+    } while (trkStage0 != 0);
+    
+    Uniquifier(tracksZMergedStage1, ListOfTracks);
+    
+    return kTRUE;
+}
+
+Bool_t AliTRDgtuTMU::RunTrackReconstruction(TList* ListOfTracks) 
+{
+  TIter next(ListOfTracks);
+  while (AliTRDtrackGTU *track = (AliTRDtrackGTU*) next()) {
+    CalculateTrackParams(track);
+  }
+  return kTRUE;
+}
+
+Bool_t AliTRDgtuTMU::CalculateTrackParams(AliTRDtrackGTU *track) 
+{
+  // calculate the track parameters
+
+  if (!track) {
+    AliError("No track to calculate!");
+    return kFALSE;
+  }
+
+  Int_t a = 0;
+  Float_t b = 0;
+  Float_t c = 0;
+  Float_t x1;
+  Float_t x2;
+
+  AliInfo(Form("There are %i tracklets in this track.", track->GetNTracklets()));
+
+  for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
+    if (!track->IsTrackletInLayer(layer)) {
+      continue;
+    }
+    AliTRDtrackletGTU *trk = track->GetTracklet(layer);
+    if (!trk) {
+      AliError(Form("Could not get tracklet in layer %i\n", layer));
+      continue;
+    }
+    AliInfo(Form("trk yprime: %i", trk->GetYPrime()));
+    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();
+  }
+  if (a < 0)
+      a += 3;
+  a = a >> 2;
+
+  fGtuParam->GetIntersectionPoints(track->GetTrackletMask(), x1, x2);
+  AliInfo(Form("Intersection points: %f, %f", x1, x2));
+  AliInfo(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);
+  AliInfo(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;
+}
+
+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);
+  }
+
+  AliInfo(Form("---------- Writing tracklets to tree (not yet) ----------"));
+  for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
+    TIter next(fTracklets[layer]);
+    while (trkl = (AliTRDtrackletGTU*) next()) {
+       AliInfo(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)
+{
+    TIter next(inlist);
+    AliTRDtrackGTU *trkStage0 = 0x0;
+    AliTRDtrackGTU *trkStage1 = 0x0;
+
+    do {
+       trkStage0 = (AliTRDtrackGTU*) next();
+
+       Bool_t tracks_equal = 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;
+                   break;
+               }
+           }
+       }
+
+       if (tracks_equal) {
+           if (trkStage0->GetNTracklets() > trkStage1->GetNTracklets())
+               trkStage1 = trkStage0;
+       } 
+       else {
+           if (trkStage1 != 0x0) 
+               outlist->Add(trkStage1);
+           trkStage1 = trkStage0;
+       } 
+       
+    } while (trkStage1 != 0x0);
+    return kTRUE;
+}
diff --git a/TRD/AliTRDgtuTMU.h b/TRD/AliTRDgtuTMU.h
new file mode 100644 (file)
index 0000000..0aeb420
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef ALITRDGTUTMU_H
+#define ALITRDGTUTMU_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: AliTRDgtuTMU.h 27496 2008-07-22 08:35:45Z cblume $ */
+
+//--------------------------------------------------------------------
+//
+// This class simulates the tracklet processing in a TMU
+//
+//--------------------------------------------------------------------
+
+#include "TObject.h"
+#include "TList.h"
+
+#include "AliTRDtrackletGTU.h"
+#include "AliTRDgtuParam.h"
+
+class TTree;
+class TBranch;
+class AliTRDtrackGTU;
+class AliESDEvent;
+
+class AliTRDgtuTMU : public TObject {
+ public:
+  AliTRDgtuTMU(Int_t stack = -1, Int_t sector = -1);
+  ~AliTRDgtuTMU();
+
+  Bool_t SetSector(Int_t sector);
+  Bool_t SetStack(Int_t stack);
+
+  Bool_t AddTracklet(AliTRDtrackletBase *tracklet, Int_t link);
+  Bool_t WriteTrackletsToTree(TTree *trklTree);
+
+  Bool_t RunTMU(TList *ListOfTracks = 0x0, AliESDEvent *esd = 0x0);
+  Bool_t Reset();
+
+  // ----- successive stages of the processing in the TMU -----
+  Bool_t RunInputUnit(Int_t layer);
+  Bool_t RunZChannelUnit(Int_t layer);
+  Bool_t RunTrackFinder(Int_t zchannel, TList* ListOfTracks);
+  Bool_t RunTrackMerging(TList* ListOfTracks); 
+  Bool_t RunTrackReconstruction(TList* ListOfTracks);
+
+  Bool_t CalculateTrackParams(AliTRDtrackGTU *track); 
+  Bool_t Uniquifier(TList* inlist, TList *outlist);
+
+protected:
+  TObjArray **fTracklets; // holding all tracklets from one detector (i. e. one chamber)
+  TList **fZChannelTracklets; // holding all tracklets for layer and z-channel
+  TList **fTracks;
+  AliTRDgtuParam *fGtuParam; // pointer to the instance of the GtuParam class
+
+  Int_t fStack;                        // Stack of this TMU
+  Int_t fSector;               // Sector of this TMU
+
+ private:
+  AliTRDgtuTMU(const AliTRDgtuTMU &rhs);              // not implemented
+  AliTRDgtuTMU& operator=(const AliTRDgtuTMU &rhs);   // not implemented
+
+  ClassDef(AliTRDgtuTMU, 1);
+};
+
+#endif
index e91d226..edcbfd8 100644 (file)
@@ -105,7 +105,10 @@ The default raw version is 2.
 // additional for new tail filter and/or tracklet
 #include "AliTRDtrapAlu.h"
 #include "AliTRDpadPlane.h"
+#include "AliTRDtrackletMCM.h"
 
+#include "AliRun.h"
+#include "AliLoader.h"
 
 ClassImp(AliTRDmcmSim)
 
@@ -2436,250 +2439,20 @@ void AliTRDmcmSim::Tracklet(){
   if (!fFeeParam->GetMCTrackletOutput()) return;
  
   
-  // structure: in the current directory a root-file called "TRD_readout_tree.root" is stored with subdirectories SMxx/sx (supermodule, stack);
-  // in each of these subdirectories 6 trees according to layers are saved, called lx; 
-  // whenever a mcm of that layer had a bit-word!=0, a branch containing an array with 4 (possibly some valued 0) elements is added;
-  // branch-name: mcmxxxwd; 
-  // another branch contains the channel-number (mcmxxxch)
-  
-  
   AliLog::SetClassDebugLevel("AliTRDmcmSim", 10);
   AliLog::SetFileOutput("../log/tracklet.log");
   
-  UInt_t* trackletWord;
+   UInt_t* trackletWord;
   Int_t*  adcChannel;
 
   Int_t u = 0;
-    
+
   // testing for wordnr in order to speed up the simulation
-  
-  if (wordnr == 0 && fNextEvent == 0) {
+  if (wordnr == 0) 
     return;
-  }
-
-   
-  Int_t mcmNr = fRobPos * (fGeo->MCMmax()) + fMcmPos;
-  
-  Char_t* SMName    = new Char_t[4];
-  Char_t* stackName = new Char_t[2];
-  Char_t* layerName = new Char_t[2];
-
-  Char_t* treeName  = new Char_t[2];
-  Char_t* treeTitle = new Char_t[8];
-  Char_t* branchNameWd = new Char_t[8]; // mcmxxxwd bit word
-  Char_t* branchNameCh = new Char_t[8]; // mcmxxxch channel
-   
-  Char_t* dirName = NULL;
-  Char_t* treeFile  = NULL; 
-  Char_t* evFile = NULL;
-  Char_t* curDir = new Char_t[255];
-  
-  for (Int_t i = 0; i<255; i++) {
-    curDir[i]='n';
-  }
-  sprintf(curDir,"%s",gSystem->BaseName(gSystem->WorkingDirectory()));
-  Int_t rawEvent = 0;
-  Int_t nrPos = 3;
-  
-
-  while(curDir[nrPos]!='n'){
-    
-   
-    switch(curDir[nrPos]) {
-    case '0':
-      rawEvent = rawEvent*10 + 0;
-      break;
-    case '1':
-      rawEvent = rawEvent*10 + 1;
-      break;
-    case '2':
-      rawEvent = rawEvent*10 + 2;
-      break;
-    case '3':
-      rawEvent = rawEvent*10 + 3;
-      break;
-    case '4':
-      rawEvent = rawEvent*10 + 4;
-      break;
-    case '5':
-      rawEvent = rawEvent*10 + 5;
-      break;
-    case '6':
-      rawEvent = rawEvent*10 + 6;
-      break;
-    case '7':
-      rawEvent = rawEvent*10 + 7;
-      break;
-    case '8':
-      rawEvent = rawEvent*10 + 8;
-      break;
-    case '9':
-      rawEvent = rawEvent*10 + 9;
-      break;
-   
-    }
-    nrPos = nrPos + 1; 
-  }
-  delete [] curDir;
-    
-  //if (!gSystem->ChangeDirectory("../TRD_Tracklet")) {
-   // gSystem->MakeDirectory("../TRD_Tracklet");
-    //gSystem->ChangeDirectory("../TRD_Tracklet");
-    //}
-
-  gSystem->ChangeDirectory("..");
-  
-  
-  TFile *f = new TFile("TRD_readout_tree.root","update");
-  TTree *tree          = NULL;
-  TBranch *branch      = NULL;
-  TBranch *branchCh   = NULL; 
-   
-  Int_t iEventNr = 0; 
-  Int_t dignr = 10; // nr of digits of a integer
-  Int_t space = 1;  // additional char-space
-  
-  
-  evFile = new Char_t[2+space];
-  sprintf(evFile,"ev%d",iEventNr);
-
-  
-  while(f->cd(evFile)){
-    iEventNr = iEventNr + 1;
-    if (iEventNr/dignr > 0) {
-      dignr = dignr * 10;
-      space = space + 1;
-    }
-    delete [] evFile;
-    evFile = NULL;
-    evFile = new Char_t[2+space];
-    sprintf(evFile,"ev%d",iEventNr); 
-  }
-  
-  if(iEventNr == rawEvent) { fNextEvent = 1; } // new event
-   
-  if (fNextEvent == 1) {
-    fNextEvent = 0;
-    // turn to head directory
-    f->mkdir(evFile);
-    f->cd(evFile);
-    // create all subdirectories and trees in case of new event
    
-     
-    for (Int_t iSector = 0; iSector < 18; iSector++) {
+  //Int_t mcmNr = fRobPos * (fGeo->MCMmax()) + fMcmPos;
   
-      if (iSector < 10) {
-       sprintf(SMName,"SM0%d",iSector);
-      }
-      else {
-       sprintf(SMName,"SM%d",iSector);
-      }
-
-      for (Int_t iStack = 0; iStack < 5; iStack++) {
-       sprintf(stackName,"s%d",iStack);
-       
-       f->cd(evFile);
-       if (iStack == 0) {
-         gDirectory->mkdir(SMName);
-       }
-       gDirectory->cd(SMName);
-       gDirectory->mkdir(stackName);
-       gDirectory->cd(stackName);
-       
-       for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
-         sprintf(layerName,"l%d",iLayer);
-         sprintf(treeName,"%s",layerName);
-         sprintf(treeTitle,"%s%s%s",SMName,stackName,layerName);
-         tree = new TTree(treeName,treeTitle);
-         tree->Write("",TObject::kOverwrite);
-         delete tree;
-         tree = NULL;
-       }
-      }
-    }
-   
-    
-  }
-
-    
-  else {
-    iEventNr = iEventNr - 1;
-    dignr = dignr/10;
-    if (iEventNr/dignr == 0) space = space - 1;
-    delete [] evFile;
-    evFile = NULL;
-    evFile = new Char_t[2+space];
-    sprintf(evFile,"ev%d",iEventNr);    
-  }
-  
-  if (wordnr == 0) {
-    delete [] SMName;
-    delete [] stackName;
-    delete [] layerName;
-    delete [] treeName;
-    delete [] treeTitle;
-    delete [] branchNameWd;
-    delete [] branchNameCh;
-    delete [] evFile;
-    f->Close();
-    dirName   = new Char_t[6+space];
-    //sprintf(dirName,"../raw%d",iEventNr);
-    sprintf(dirName,"raw%d",iEventNr);
-    gSystem->ChangeDirectory(dirName);
-    delete [] dirName;
-    return;
-  }
-  
-  dirName   = new Char_t[6+space];
-  //sprintf(dirName,"../raw%d",iEventNr);
-  sprintf(dirName,"raw%d",iEventNr);
-  f->cd(evFile);
-  if (fSector < 10) {
-    sprintf(SMName,"SM0%d",fSector);
-  }
-  else {
-    sprintf(SMName,"SM%d",fSector);
-  }
-  sprintf(stackName,"s%d",fStack);
-  sprintf(layerName,"l%d",fLayer);
-  sprintf(treeName,"%s",layerName);
-  sprintf(treeTitle,"%s%s%s",SMName,stackName,layerName);
-  treeFile = new Char_t[13+space];
-  sprintf(treeFile,"%s/%s/%s/%s",evFile,SMName,stackName,treeName);
-  delete [] evFile;
-  evFile = NULL;
-  gDirectory->cd(SMName);
-  gDirectory->cd(stackName);
-  tree = (TTree*)f->Get(treeFile);
-  delete [] treeFile;
-  treeFile = NULL;
-
-
-  //make branch with number of words and fill
-
-  if (mcmNr < 10) {
-    sprintf(branchNameWd,"mcm00%dwd",mcmNr);
-    sprintf(branchNameCh,"mcm00%dch",mcmNr);
-  }
-  else {
-    if (mcmNr < 100) {
-      sprintf(branchNameWd,"mcm0%dwd",mcmNr); 
-      sprintf(branchNameCh,"mcm0%dch",mcmNr);
-    }
-    else {
-      sprintf(branchNameWd,"mcm%dwd",mcmNr); 
-      sprintf(branchNameCh,"mcm%dch",mcmNr);
-    }
-  }
-
-      
-  
-  // fill the tracklet word; here wordnr > 0
-
   trackletWord = new UInt_t[fMaxTracklets];
   adcChannel   = new Int_t[fMaxTracklets];
 
@@ -2695,48 +2468,42 @@ void AliTRDmcmSim::Tracklet(){
          u = u + 1;
       }
   }
-  
-  branch = tree->GetBranch(branchNameWd);
-  if(!branch) {
-    //make branch and fill
-    branch = tree->Branch(branchNameWd,trackletWord,"trackletWord[4]/i"); // 32 bit unsigned integer
-    branch->Fill();
-  }
 
-  branchCh = tree->GetBranch(branchNameCh);
-  if(!branchCh) {
-    //make branch and fill
-    branchCh = tree->Branch(branchNameCh,adcChannel,"adcChannel[4]/i"); // 32 bit unsigned integer
-    branchCh->Fill();
+ AliDataLoader *dl = gAlice->GetRunLoader()->GetLoader("TRDLoader")->GetDataLoader("tracklets");
+  if (!dl) {
+    AliError("Could not get the tracklets data loader!");
   }
+  else {
+    TTree *trackletTree = dl->Tree();
+    if (!trackletTree)
+      dl->MakeTree();
+    trackletTree = dl->Tree();
 
-  tree->Write("",TObject::kOverwrite);
+   AliTRDtrackletMCM *trkl = new AliTRDtrackletMCM(); 
+   TBranch *trkbranch = trackletTree->GetBranch("mcmtrklbranch");
+   if (!trkbranch)
+       trkbranch = trackletTree->Branch("mcmtrklbranch", "AliTRDtrackletMCM", &trkl, 32000);
+    trkbranch->SetAddress(&trkl);
 
-  delete [] SMName;
-  delete [] stackName;
-  delete [] layerName;
-  delete [] treeName;
-  delete [] treeTitle;
-  delete [] branchNameWd;
-  delete [] branchNameCh;
-  delete [] trackletWord;
-  delete [] adcChannel;
-  
-  f->Close();
-  gSystem->ChangeDirectory(dirName);
-  delete [] dirName;
-  
+    for (Int_t iTracklet = 0; iTracklet < fMaxTracklets; iTracklet++) {
+       if (trackletWord[iTracklet] == 0)
+           continue;
+       trkl->SetTrackletWord(trackletWord[iTracklet]);
+       trkl->SetDetector(30*fSector + 6*fStack + fLayer);
+       trkl->SetROB(fRobPos);
+       trkl->SetMCM(fMcmPos);
+       trackletTree->Fill();
+//     AliInfo(Form("Filling tracklet tree with trkl: %i", iTracklet));
+    }
+    delete trkl;
+    dl->WriteData("OVERWRITE");
+  }
 
 
   // to be done:
   // error measure for quality of fit (not necessarily needed for the trigger)
   // cluster quality threshold (not yet set)
   // electron probability
-  
-
-   
 }
 
 
diff --git a/TRD/AliTRDtrackGTU.cxx b/TRD/AliTRDtrackGTU.cxx
new file mode 100644 (file)
index 0000000..0157c73
--- /dev/null
@@ -0,0 +1,131 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////
+//                                                                        //
+//  A GTU track                                                           //
+//                                                                        //
+//  Author: J. Klein (Jochen.Klein@cern.ch)                               //
+//                                                                        //
+////////////////////////////////////////////////////////////////////////////
+
+/* $Id: AliTRDtrackGTU.cxx 27566 2008-07-24 15:31:08Z cblume $ */
+
+#include "TObject.h"
+#include "TObjArray.h"
+
+#include "AliLog.h"
+#include "AliTRDgtuParam.h"
+#include "AliTRDtrackGTU.h"
+#include "AliTRDtrackletGTU.h"
+#include "AliESDTrdTrack.h"
+
+ClassImp(AliTRDtrackGTU)
+    
+AliTRDtrackGTU::AliTRDtrackGTU() :
+  TObject(),
+  fStack(-1),
+  fSector(-1),
+  fPt(0),
+  fPID(0),
+  fTracklets(0x0),
+  fTrackletMask(0),
+  fNTracklets(0),
+  fRefLayerIdx(-1),
+  fZChannel(-1),
+  fZSubChannel(-1),
+  fA(0),
+  fB(0),
+  fC(0)
+{
+  fTracklets = new TClonesArray("AliTRDtrackletGTU", 6);
+  for (Int_t iTracklet = 0; iTracklet < 6; iTracklet++)
+      new ((*fTracklets)[iTracklet]) AliTRDtrackletGTU();
+//  fTracklets->BypassStreamer(kFALSE);
+}
+
+AliTRDtrackGTU::~AliTRDtrackGTU()
+{
+  fTracklets->Delete();
+  delete fTracklets;
+}
+
+void AliTRDtrackGTU::AddTracklet(AliTRDtrackletGTU *tracklet, Int_t layer) 
+{
+  if ( (fTrackletMask & (1 << layer)) != 0 ) {
+    AliError(Form("Only one tracklet per layer (%i) possible! Mask: 0x%02x", layer, fTrackletMask));
+    return;
+  }
+
+  new ((*fTracklets)[layer]) AliTRDtrackletGTU(*tracklet);
+  fNTracklets++;
+  fTrackletMask |= (1 << layer);
+}
+
+AliTRDtrackletGTU* AliTRDtrackGTU::GetTracklet(Int_t layer) 
+{
+  return ((AliTRDtrackletGTU*) (*fTracklets)[layer]);
+}
+
+Int_t AliTRDtrackGTU::GetNTracklets() const
+{
+  return fNTracklets;
+}
+
+Bool_t AliTRDtrackGTU::IsTrackletInLayer(Int_t layer) const 
+{
+  if ( (GetTrackletMask() & (1 << layer)) != 0)
+    return kTRUE;
+  else 
+    return kFALSE;
+}
+
+void AliTRDtrackGTU::SetFitParams(Float_t a, Float_t b, Float_t c) 
+{
+  fA = a; 
+  fB = b;
+  fC = c;
+}
+
+Int_t AliTRDtrackGTU::GetZSubChannel() 
+{
+  if (fZSubChannel < 0) {
+    for (Int_t layer = 0; layer < AliTRDgtuParam::GetNLayers(); layer++)
+    {
+      if (IsTrackletInLayer(layer))
+       fZSubChannel = ((AliTRDtrackletGTU*) (*fTracklets)[layer])->GetSubChannel(GetZChannel());
+    }
+  }
+  return fZSubChannel;
+}
+
+Int_t AliTRDtrackGTU::GetYapprox() 
+{
+  for (Int_t layer = 0; layer < AliTRDgtuParam::GetNLayers(); layer++) 
+  {
+    if (IsTrackletInLayer(layer))
+      return ((AliTRDtrackletGTU*) (*fTracklets)[layer])->GetYProj();
+  }
+  return 0;
+}
+
+AliESDTrdTrack* AliTRDtrackGTU::CreateTrdTrack() const
+{
+    AliESDTrdTrack *trk = new AliESDTrdTrack();
+    trk->SetPt(1./128. * fPt);
+    trk->SetPID(fPID);
+    trk->SetDetector(fSector * 30 + fStack * 6);
+    return trk;
+}
diff --git a/TRD/AliTRDtrackGTU.h b/TRD/AliTRDtrackGTU.h
new file mode 100644 (file)
index 0000000..c799207
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef ALITRDTRACKGTU_H
+#define ALITRDTRACKGTU_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: AliTRDtrackGTU.h 27496 2008-07-22 08:35:45Z cblume $ */
+
+//---------------------------------------------------------------
+//
+// TRD track as calculated in the GTU (for L1 contribution)
+//
+//---------------------------------------------------------------
+
+#include "TClonesArray.h"
+
+#include "AliTRDtrackletGTU.h"
+#include "AliESDTrdTrack.h"
+
+class AliTRDtrackGTU : public TObject {
+ public:
+  AliTRDtrackGTU();
+  ~AliTRDtrackGTU();
+
+// ----- Track properties
+  Int_t    GetPtInt() const { return fPt; }
+  Float_t  GetPt() const { return (Float_t) fPt / 128.; }
+  Int_t    GetPID() const { return fPID; }
+  Int_t    GetSector() const { return fSector; }
+  Int_t    GetStack() const { return fStack; }
+
+  AliESDTrdTrack* CreateTrdTrack() const;
+
+// ----- compositing tracklets
+  Int_t    GetNTracklets() const;
+  Int_t    GetTrackletMask() const { return fTrackletMask; }
+  Bool_t   IsTrackletInLayer(Int_t layer) const;
+  Int_t    GetTrackletIndex(Int_t layer) { return IsTrackletInLayer(layer) ? ((AliTRDtrackletGTU*) (*fTracklets)[layer])->GetIndex() : -1; } 
+  AliTRDtrackletGTU* GetTracklet(Int_t layer);
+
+// ----- Quantities used internally for the calculation
+  Float_t GetA() const { return fA; }
+  Float_t GetB() const { return fB; }
+  Float_t GetC() const { return fC; }
+  Int_t GetZChannel() const { return fZChannel; }
+  Int_t GetZSubChannel();
+  Int_t GetRefLayerIdx() const { return fRefLayerIdx; }
+  Int_t GetYapprox();
+
+
+  void AddTracklet(AliTRDtrackletGTU *tracklet, Int_t layer);
+
+  void SetStack(Int_t stack) { fStack = stack; }
+  void SetSector(Int_t sector) { fSector = sector; }
+  void SetPtInt(Int_t pt) { fPt = pt; }
+  void SetPID(Int_t pid) { fPID = pid; }
+
+  void SetZChannel(Int_t zch) { fZChannel = zch; }
+  void SetRefLayerIdx(Int_t reflayer) { fRefLayerIdx = reflayer; }
+//  void SetInnerIntPoint(Float_t *x);
+//  void SetOuterIntPoint(Float_t *x);
+  void SetFitParams(Float_t a, Float_t b, Float_t c);
+
+ protected:
+
+  Int_t fStack;
+  Int_t fSector;
+
+  Int_t fPt; // pt in integer representation
+  Int_t fPID;
+
+  TClonesArray *fTracklets;
+  Int_t fTrackletMask;
+  Int_t fNTracklets;
+
+  Int_t fRefLayerIdx;
+  Int_t fZChannel;
+  Int_t fZSubChannel; 
+
+  Float_t fA; 
+  Float_t fB; 
+  Float_t fC; 
+
+ private:
+  AliTRDtrackGTU(const AliTRDtrackGTU &rhs); // not implemented
+  AliTRDtrackGTU& operator=(const AliTRDtrackGTU &rhs); // not implemented
+
+  ClassDef(AliTRDtrackGTU, 1);
+};
+
+#endif
diff --git a/TRD/AliTRDtrackletGTU.cxx b/TRD/AliTRDtrackletGTU.cxx
new file mode 100644 (file)
index 0000000..675a954
--- /dev/null
@@ -0,0 +1,197 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id: AliTRDtrackletGTU.cxx 28397 2008-09-02 09:33:00Z cblume $ */
+
+////////////////////////////////////////////////////////////////////////////
+//                                                                        //
+//  GTU tracklet                                                          //
+//                                                                        //
+//  Author: J. Klein (Jochen.Klein@cern.ch)                               //
+//                                                                        //
+////////////////////////////////////////////////////////////////////////////
+
+#include "TMath.h"
+
+#include "AliTRDtrackletGTU.h"
+#include "AliTRDtrackletWord.h"
+#include "AliTRDmcmTracklet.h"
+#include "AliLog.h"
+#include "AliTRDgtuParam.h"
+#include "AliTRDgeometry.h"
+#include "AliTRDpadPlane.h"
+
+ClassImp(AliTRDtrackletGTU)
+
+AliTRDtrackletBase* AliTRDtrackletGTU::fgkDummyTracklet = new AliTRDtrackletWord(0);
+
+AliTRDtrackletGTU::AliTRDtrackletGTU() :
+  AliTRDtrackletBase(),
+  fGtuParam(AliTRDgtuParam::Instance()),
+  fTracklet(fgkDummyTracklet), 
+  fSubChannel(0x0),
+  fAssignedZ(kFALSE),
+  fAlpha(0),
+  fYProj(0),
+  fYPrime(0),
+  fIndex(0)
+{
+  // ctor for any tracklet deriving from AliTRDtrackletBase
+
+  fSubChannel = new Int_t[fGtuParam->GetNZChannels()];
+  for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) 
+    fSubChannel[zch] = 0;
+}
+
+AliTRDtrackletGTU::AliTRDtrackletGTU(AliTRDtrackletBase *tracklet) :
+  AliTRDtrackletBase(*tracklet),
+  fGtuParam(AliTRDgtuParam::Instance()),
+  fTracklet(0x0), 
+  fSubChannel(0x0),
+  fAssignedZ(kFALSE),
+  fAlpha(0),
+  fYProj(0),
+  fYPrime(0),
+  fIndex(0)
+{
+  // ctor for any tracklet deriving from AliTRDtrackletBase
+
+  fSubChannel = new Int_t[fGtuParam->GetNZChannels()];
+  for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) 
+    fSubChannel[zch] = 0;
+  fTracklet = tracklet;
+}
+
+AliTRDtrackletGTU::AliTRDtrackletGTU(const AliTRDtrackletGTU& tracklet) :
+  AliTRDtrackletBase(tracklet),
+  fGtuParam(AliTRDgtuParam::Instance()),
+  fTracklet(tracklet.fTracklet), 
+  fSubChannel(0x0),
+  fAssignedZ(tracklet.fAssignedZ),
+  fAlpha(tracklet.fAlpha),
+  fYProj(tracklet.fYProj),
+  fYPrime(tracklet.fYPrime), 
+  fIndex(tracklet.fIndex)
+{
+  // copy ctor
+
+  fSubChannel = new Int_t[fGtuParam->GetNZChannels()];
+  for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) 
+    fSubChannel[zch] = tracklet.fSubChannel[zch];
+}
+
+AliTRDtrackletGTU& AliTRDtrackletGTU::operator=(const AliTRDtrackletGTU &rhs)
+{
+  if (&rhs != this) {
+    fTracklet = rhs.fTracklet;
+    for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) 
+      fSubChannel[zch] = rhs.fSubChannel[zch];
+    fIndex = rhs.fIndex;
+    fYPrime = rhs.fYPrime;
+    fYProj = rhs.fYProj;
+    fAlpha = rhs.fAlpha;
+    fAssignedZ = rhs.fAssignedZ;
+  }
+  
+  return *this;
+}
+
+AliTRDtrackletGTU::~AliTRDtrackletGTU() 
+{
+  // dtor
+  if (fSubChannel)
+    delete [] fSubChannel; 
+}
+
+Int_t AliTRDtrackletGTU::Compare(const TObject *o) const {
+  // sorting w. r. t. Z, Y if no z-channel assigned (as needed in input unit)
+  // otherwise w. r. t. Z, Y_proj
+  // must be changed to Z-channel, Y_proj
+  // will be changed
+
+  if (!o) 
+    return 0;
+
+  if (!o->InheritsFrom("AliTRDtrackletGTU")) {
+      AliError("Cannot compare to object not deriving from AliTRDtrackletGTU");
+      return 0;
+  }
+
+  if (!fAssignedZ) {
+    if ( GetZbin() < ((AliTRDtrackletGTU*) o)->GetZbin()) 
+      return -1;
+    else if (GetZbin() > ((AliTRDtrackletGTU*) o)->GetZbin()) 
+      return 1;
+    else 
+      if (GetYbin() < ((AliTRDtrackletGTU*) o)->GetYbin())
+       return -1;
+      else if (GetYbin() > ((AliTRDtrackletGTU*) o)->GetYbin())
+       return 1;
+      else 
+       return 0;
+  }
+  else {
+    // sorting should be according to zsubindex, not to Z !!!
+    // therefore this depends on the zch
+    if (GetZbin() < ((AliTRDtrackletGTU*) o)->GetZbin()) 
+      return -1;
+    else if (GetZbin() > ((AliTRDtrackletGTU*) o)->GetZbin()) 
+      return 1;
+    else 
+      if (GetYProj() < ((AliTRDtrackletGTU*) o)->GetYProj())
+       return -1;
+      else if (GetYProj() > ((AliTRDtrackletGTU*) o)->GetYProj())
+       return 1;
+      else 
+       return 0;
+  }
+}
+
+void AliTRDtrackletGTU::SetSubChannel(Int_t zch, Int_t subch) 
+{
+  // set the subchannel in the given z-channel
+  fAssignedZ = kTRUE;
+  fSubChannel[zch] = subch;
+}
+
+Int_t AliTRDtrackletGTU::GetSubChannel(Int_t zch) 
+{
+  // get the subchannel in the given z-channel
+  return fSubChannel[zch];
+}
+
+/*
+Float_t AliTRDtrackletGTU::GetPhysX(Int_t layer) 
+{
+  // get the x-position (in the local system) assuming the tracklet is in the given layer
+  return fGtuParam->GetGeo()->GetTime0(layer);
+}
+
+Float_t AliTRDtrackletGTU::GetPhysY() 
+{
+  // 
+  return GetYbin() * 0.0160; 
+}
+
+Float_t AliTRDtrackletGTU::GetPhysAlpha() 
+{
+  return GetAlpha() * 0.01; // wrong factor!
+}
+
+Float_t AliTRDtrackletGTU::GetPhysZ(Int_t stack, Int_t layer) 
+{
+  return fGtuParam->GetGeo()->GetPadPlane(layer, stack)->GetRowPos(GetZbin()); // not the middle of a pad!
+}
+*/
diff --git a/TRD/AliTRDtrackletGTU.h b/TRD/AliTRDtrackletGTU.h
new file mode 100644 (file)
index 0000000..9ea7997
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef ALITRDTRACKLETGTU_H
+#define ALITRDTRACKLETGTU_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: AliTRDtrackletGTU.h 27496 2008-07-22 08:35:45Z cblume $ */
+
+// --------------------------------------------------------
+// 
+// GTU tracklet
+// 
+//
+// --------------------------------------------------------
+
+#include "AliTRDtrackletBase.h"
+#include "AliLog.h"
+
+class AliTRDmcmTracklet;
+class AliTRDgtuParam;
+
+class AliTRDtrackletGTU : public AliTRDtrackletBase {
+ public:
+  AliTRDtrackletGTU();
+//  AliTRDtrackletGTU(UInt_t tracklet_word = 0);
+  AliTRDtrackletGTU(AliTRDtrackletBase *tracklet); 
+  AliTRDtrackletGTU(const AliTRDtrackletGTU& trk);
+
+  ~AliTRDtrackletGTU();
+
+  AliTRDtrackletGTU& operator=(const AliTRDtrackletGTU &rhs); 
+
+  Bool_t IsSortable() const { return kTRUE; }
+  Int_t Compare(const TObject *o) const;
+
+  // ----- Getters for information from the tracklet word -----
+  Int_t GetYbin() const { return fTracklet->GetYbin(); }
+  Int_t GetdY() const { return fTracklet->GetdY(); }
+  Int_t GetZbin() const { return fTracklet->GetZbin(); }
+  Double_t GetPID() const { return fTracklet->GetPID(); }
+  Double_t GetPID(Int_t is) const { return fTracklet->GetPID(is); }
+
+  // ----- Getters for calculated properties -----
+  Int_t GetYProj() const { return fYProj; }
+  Int_t GetAlpha() const { return fAlpha; }
+  Int_t GetYPrime() const { return fYPrime; }
+  Int_t GetSubChannel(Int_t zch);
+
+  // ----- Getters for offline corresponding values -----
+  Bool_t CookPID() { return kFALSE; }
+  Int_t GetDetector() const { return fTracklet->GetDetector(); }
+  Int_t GetIndex() const { return fIndex; }
+
+  Float_t GetdYdX() const { return (GetdY() * 140e-4 / 3.); }
+  Float_t GetX() const { return 0; }
+  Float_t GetY() const { return (GetYbin() * 160e-4); }
+  Float_t GetZ() const { return 0; }
+
+//  AliTRDtrackletBase* GetTracklet() const { return fTracklet; }
+  UInt_t GetTrackletWord() const { return fTracklet->GetTrackletWord(); }
+
+  Int_t GetSide() const { return GetYbin() < 0 ? 0 : 1; } 
+
+  // ----- Setters -----
+  void SetAlpha(Int_t alpha) { fAlpha = alpha; }
+  void SetYProj(Int_t yproj) { fYProj = yproj; }
+  void SetYPrime(Int_t yprime) { fYPrime = yprime; }
+
+  void SetSubChannel(Int_t zch, Int_t subch);
+  void SetDetector(Int_t /* id */ ) { AliError("Cannot change base tracklet"); }
+  void SetIndex(Int_t idx) { fIndex = idx; }
+
+  void RemoveTracklet() { fTracklet = fgkDummyTracklet; }
+
+ protected:
+  AliTRDgtuParam *fGtuParam;    //!
+  const AliTRDtrackletBase *fTracklet; // always points to a valid tracklet
+
+  Int_t *fSubChannel;          //! [AliTRDgtuParam::GetNZChannels()]
+  Bool_t fAssignedZ;           // tracklet assigned to a Z-channel
+
+  Int_t fAlpha;                        // calculated value for alpha
+  Int_t fYProj;                        // calculated value for y_proj
+  Int_t fYPrime;               // calculated value for y'
+  Int_t fIndex;
+
+  static AliTRDtrackletBase* fgkDummyTracklet;
+
+ private:
+
+  ClassDef(AliTRDtrackletGTU, 1);
+};
+
+#endif
diff --git a/TRD/AliTRDtrackletMCM.cxx b/TRD/AliTRDtrackletMCM.cxx
new file mode 100644 (file)
index 0000000..6c530e1
--- /dev/null
@@ -0,0 +1,85 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id: AliTRDtrackletMCM.cxx 28397 2008-09-02 09:33:00Z cblume $ */
+
+////////////////////////////////////////////////////////////////////////////
+//                                                                        //
+//  MCM tracklet                                                          //
+//                                                                        //
+//  Author: J. Klein (Jochen.Klein@cern.ch)                               //
+//                                                                        //
+////////////////////////////////////////////////////////////////////////////
+
+#include "AliTRDtrackletMCM.h"
+#include "AliLog.h"
+
+ClassImp(AliTRDtrackletMCM)
+
+AliTRDtrackletMCM::AliTRDtrackletMCM(UInt_t trackletWord) :
+  AliTRDtrackletBase(),
+  fHCId(-1),
+  fTrackletWord(trackletWord), 
+  fMCM(-1), 
+  fROB(-1)
+{ 
+
+}
+
+AliTRDtrackletMCM::AliTRDtrackletMCM(UInt_t trackletWord, Int_t hcid) :
+  AliTRDtrackletBase(),
+  fHCId(hcid),
+  fTrackletWord(trackletWord), 
+  fMCM(-1),
+  fROB(-1)
+{ 
+
+}
+
+AliTRDtrackletMCM::AliTRDtrackletMCM(const AliTRDtrackletMCM &rhs) :
+  AliTRDtrackletBase(rhs),
+  fHCId(rhs.fHCId),
+  fTrackletWord(rhs.fTrackletWord),
+  fMCM(rhs.fMCM),
+  fROB(rhs.fROB)
+{
+
+}
+
+AliTRDtrackletMCM::~AliTRDtrackletMCM() 
+{
+
+}
+
+Int_t AliTRDtrackletMCM::GetYbin() const {
+  // returns (signed) value of Y
+  if (fTrackletWord & 0x1000) {
+    return -((~(fTrackletWord-1)) & 0x1fff);
+  }
+  else {
+    return (fTrackletWord & 0x1fff);
+  }
+}
+
+Int_t AliTRDtrackletMCM::GetdY() const 
+{
+  // returns (signed) value of the deflection length
+  if (fTrackletWord & (1 << 19)) {
+    return -((~((fTrackletWord >> 13) - 1)) & 0x7f);
+  }
+  else {
+    return ((fTrackletWord >> 13) & 0x7f);
+  }
+}
diff --git a/TRD/AliTRDtrackletMCM.h b/TRD/AliTRDtrackletMCM.h
new file mode 100644 (file)
index 0000000..26d153d
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef ALITRDTRACKLETMCM_H
+#define ALITRDTRACKLETMCM_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: AliTRDtrackletMCM.h 27496 2008-07-22 08:35:45Z cblume $ */
+
+//-----------------------------------
+//
+// TRD tracklet word (as from FEE)
+// only 32-bit of information + detector ID
+//
+//----------------------------------
+
+#include "AliTRDtrackletBase.h"
+
+class AliTRDtrackletMCM : public AliTRDtrackletBase {
+ public:
+  AliTRDtrackletMCM(UInt_t tracklet_word = 0);
+  AliTRDtrackletMCM(UInt_t tracklet_word, Int_t hcid);
+  AliTRDtrackletMCM(const AliTRDtrackletMCM &rhs);
+  ~AliTRDtrackletMCM();
+
+  // ----- Getters for contents of tracklet word -----
+  Int_t GetYbin() const; 
+  Int_t GetdY() const; 
+  Int_t GetZbin() const { return ((fTrackletWord >> 20) & 0xf); }
+  Int_t GetPID() const { return ((fTrackletWord >> 24) & 0xff); }
+
+  // ----- Getters for MCM-tracklet information -----
+  Int_t GetMCM() const { return fMCM; }
+  Int_t GetROB() const { return fROB; }
+
+  // ----- Getters for offline corresponding values -----
+  Bool_t CookPID() { return kFALSE; }
+  Double_t GetPID(Int_t /* is */) const { return 0; }
+  Int_t GetDetector() const { return fHCId / 2; }
+  Int_t GetHCId() const { return fHCId; }
+  Float_t GetdYdX() const { return (GetdY() * 140e-4 / 3.); }
+  Float_t GetX() const { return 0; }
+  Float_t GetY() const { return (GetYbin() * 160e-4); }
+  Float_t GetZ() const { return 0; }
+
+  UInt_t GetTrackletWord() const { return fTrackletWord; }
+  void SetTrackletWord(UInt_t trackletWord) { fTrackletWord = trackletWord; }
+
+  void SetDetector(Int_t id) { fHCId = 2 * id + (GetYbin() < 0 ? 0 : 1); }
+  void SetHCId(Int_t id) { fHCId = id; }
+  void SetMCM(Int_t mcm) { fMCM = mcm; }
+  void SetROB(Int_t rob) { fROB = rob; }
+
+ protected:
+  Int_t fHCId;                  // half-chamber ID (only transient)
+  UInt_t fTrackletWord;                // tracklet word: PID | Z | deflection length | Y 
+                               //          bits:  12   4            7          13
+  Int_t fMCM;
+  Int_t fROB;
+
+  ClassDef(AliTRDtrackletMCM, 1);
+};
+
+#endif
diff --git a/TRD/AliTRDtrackletWord.cxx b/TRD/AliTRDtrackletWord.cxx
new file mode 100644 (file)
index 0000000..8923f84
--- /dev/null
@@ -0,0 +1,79 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id: AliTRDtrackletWord.cxx 28397 2008-09-02 09:33:00Z cblume $ */
+
+////////////////////////////////////////////////////////////////////////////
+//                                                                        //
+//  A tracklet word as from FEE                                           //
+//                                                                        //
+//  Author: J. Klein (Jochen.Klein@cern.ch)                               //
+//                                                                        //
+////////////////////////////////////////////////////////////////////////////
+
+#include "AliTRDtrackletWord.h"
+#include "AliLog.h"
+
+ClassImp(AliTRDtrackletWord)
+
+AliTRDtrackletWord::AliTRDtrackletWord(UInt_t trackletWord) :
+  AliTRDtrackletBase(),
+  fHCId(-1),
+  fTrackletWord(trackletWord)
+{ 
+
+}
+
+AliTRDtrackletWord::AliTRDtrackletWord(UInt_t trackletWord, Int_t hcid) :
+  AliTRDtrackletBase(),
+  fHCId(hcid),
+  fTrackletWord(trackletWord)
+{ 
+
+}
+
+AliTRDtrackletWord::AliTRDtrackletWord(const AliTRDtrackletWord &rhs) :
+  AliTRDtrackletBase(rhs),
+  fHCId(rhs.fHCId),
+  fTrackletWord(rhs.fTrackletWord)
+{
+
+}
+
+AliTRDtrackletWord::~AliTRDtrackletWord() 
+{
+
+}
+
+Int_t AliTRDtrackletWord::GetYbin() const {
+  // returns (signed) value of Y
+  if (fTrackletWord & 0x1000) {
+    return -((~(fTrackletWord-1)) & 0x1fff);
+  }
+  else {
+    return (fTrackletWord & 0x1fff);
+  }
+}
+
+Int_t AliTRDtrackletWord::GetdY() const 
+{
+  // returns (signed) value of the deflection length
+  if (fTrackletWord & (1 << 19)) {
+    return -((~((fTrackletWord >> 13) - 1)) & 0x7f);
+  }
+  else {
+    return ((fTrackletWord >> 13) & 0x7f);
+  }
+}
diff --git a/TRD/AliTRDtrackletWord.h b/TRD/AliTRDtrackletWord.h
new file mode 100644 (file)
index 0000000..6bb5f01
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef ALITRDTRACKLETWORD_H
+#define ALITRDTRACKLETWORD_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id: AliTRDtrackletWord.h 27496 2008-07-22 08:35:45Z cblume $ */
+
+//-----------------------------------
+//
+// TRD tracklet word (as from FEE)
+// only 32-bit of information + detector ID
+//
+//----------------------------------
+
+#include "AliTRDtrackletBase.h"
+
+class AliTRDtrackletWord : public AliTRDtrackletBase {
+ public:
+  AliTRDtrackletWord(UInt_t tracklet_word = 0);
+  AliTRDtrackletWord(UInt_t tracklet_word, Int_t hcid);
+  AliTRDtrackletWord(const AliTRDtrackletWord &rhs);
+  ~AliTRDtrackletWord();
+
+  // ----- Getters for contents of tracklet word -----
+  Int_t GetYbin() const; 
+  Int_t GetdY() const; 
+  Int_t GetZbin() const { return ((fTrackletWord >> 20) & 0xf); }
+  Int_t GetPID() const { return ((fTrackletWord >> 24) & 0xff); }
+
+  // ----- Getters for offline corresponding values -----
+  Bool_t CookPID() { return kFALSE; }
+  Double_t GetPID(Int_t /* is */) const { return 0; }
+  Int_t GetDetector() const { return fHCId / 2; }
+  Int_t GetHCId() const { return fHCId; }
+  Float_t GetdYdX() const { return (GetdY() * 140e-4 / 3.); }
+  Float_t GetX() const { return 0; }
+  Float_t GetY() const { return (GetYbin() * 160e-4); }
+  Float_t GetZ() const { return 0; }
+
+  UInt_t GetTrackletWord() const { return fTrackletWord; }
+  void SetTrackletWord(UInt_t trackletWord) { fTrackletWord = trackletWord; }
+
+  void SetDetector(Int_t id) { fHCId = 2 * id + (GetYbin() < 0 ? 0 : 1); }
+  void SetHCId(Int_t id) { fHCId = id; }
+
+ protected:
+  Int_t fHCId;                  //! half-chamber ID (only transient)
+  UInt_t fTrackletWord;                // tracklet word: PID | Z | deflection length | Y 
+                               //          bits:  12   4            7          13
+
+  ClassDef(AliTRDtrackletWord, 1);
+};
+
+#endif