]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
update of GTU simulation
authorjklein <jklein@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 6 Jul 2011 08:25:11 +0000 (08:25 +0000)
committerjklein <jklein@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 6 Jul 2011 08:25:11 +0000 (08:25 +0000)
- allow for GTU simulation on ESD tracklets
- make use of new ESD track format
- remove sortability from AliTRDtrackletGTU
- insert tracklets based on HC instead of ROC
  to simplify sorting of the tracklets
- correct order of found tracks
- implement identical geometry constants as used in hardware

TRD/AliTRDgtuParam.cxx
TRD/AliTRDgtuParam.h
TRD/AliTRDgtuSim.cxx
TRD/AliTRDgtuSim.h
TRD/AliTRDgtuTMU.cxx
TRD/AliTRDgtuTMU.h
TRD/AliTRDtrackGTU.cxx
TRD/AliTRDtrackGTU.h
TRD/AliTRDtrackletGTU.cxx
TRD/AliTRDtrackletGTU.h

index 53fbcfebcea1d280bfe6058d16e8047ca5ecad67..68f1bb8bf8465f2fefd41c0b75e2b5c59394edb7 100644 (file)
@@ -38,6 +38,7 @@
 ClassImp(AliTRDgtuParam)
 
 AliTRDgtuParam *AliTRDgtuParam::fgInstance = 0;
+Bool_t AliTRDgtuParam::fgUseGTUconst = kTRUE;
 
 // ----- matching windows -----
       Int_t     AliTRDgtuParam::fgDeltaY     = 19;
@@ -55,15 +56,1140 @@ 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
-*/
+// ----- z-channel tables -----
+const Bool_t    AliTRDgtuParam::fgZChannelMap[5][16][6][16] = {
+
+{  /* --- Stack 0 --- */
+
+/*  . x x . . . . . . . . . . . . .  */
+/*  x . . . . . . . . . . . . . . .  */
+/*  X . . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  x . . . . . . . . . . . . . . .  */
+
+{{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . x x . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  . X . . . . . . . . . . . . . .  */
+/*  . x x . . . . . . . . . . . . .  */
+/*  . x x . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+
+{{0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . x x . . . . . . . . . . .  */
+/*  . x x . . . . . . . . . . . . .  */
+/*  . . X . . . . . . . . . . . . .  */
+/*  . . x x . . . . . . . . . . . .  */
+/*  . . x x . . . . . . . . . . . .  */
+/*  . x x . . . . . . . . . . . . .  */
+
+{{0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . x x . . . . . . . . . .  */
+/*  . . x x . . . . . . . . . . . .  */
+/*  . . . X . . . . . . . . . . . .  */
+/*  . . . x x . . . . . . . . . . .  */
+/*  . . . x x . . . . . . . . . . .  */
+/*  . . x x . . . . . . . . . . . .  */
+
+{{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . x x . . . . . . . . .  */
+/*  . . . x x . . . . . . . . . . .  */
+/*  . . . . X . . . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+/*  . . . x x . . . . . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+/*  . . . . . X . . . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+/*  . . . . . . X . . . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . x x x . . . . . . .  */
+/*  . . . . . . . X . . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . x x x . . . . .  */
+/*  . . . . . . . x x x . . . . . .  */
+/*  . . . . . . . . X . . . . . . .  */
+/*  . . . . . . . x x x . . . . . .  */
+/*  . . . . . . . x x x . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . x x x . . . .  */
+/*  . . . . . . . . x x x . . . . .  */
+/*  . . . . . . . . . X . . . . . .  */
+/*  . . . . . . . . x x x . . . . .  */
+/*  . . . . . . . . x x x . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . x x x . . .  */
+/*  . . . . . . . . . x x x . . . .  */
+/*  . . . . . . . . . . X . . . . .  */
+/*  . . . . . . . . . x x x . . . .  */
+/*  . . . . . . . . . x x x . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . . x x x . .  */
+/*  . . . . . . . . . . x x x . . .  */
+/*  . . . . . . . . . . . X . . . .  */
+/*  . . . . . . . . . . x x x . . .  */
+/*  . . . . . . . . . . x x x . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . . . x x x .  */
+/*  . . . . . . . . . . . x x x . .  */
+/*  . . . . . . . . . . . . X . . .  */
+/*  . . . . . . . . . . . x x x . .  */
+/*  . . . . . . . . . . . x x x . .  */
+/*  . . . . . . . . . . . x x . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}},
+
+/*  . . . . . . . . . . . . . x x x  */
+/*  . . . . . . . . . . . . x x x .  */
+/*  . . . . . . . . . . . . . X . .  */
+/*  . . . . . . . . . . . . x x x .  */
+/*  . . . . . . . . . . . . x x x .  */
+/*  . . . . . . . . . . . . x x . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}},
+
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . x x x  */
+/*  . . . . . . . . . . . . . . X .  */
+/*  . . . . . . . . . . . . . x x x  */
+/*  . . . . . . . . . . . . . x x x  */
+/*  . . . . . . . . . . . . . x x .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}},
+
+/*  . . . . . . . . . . . . . . . x  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . . X  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . x x  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}}},
+
+{  /* --- Stack 1 --- */
+
+/*  x x x . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  X . . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  x . . . . . . . . . . . . . . .  */
+
+{{1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . x x x . . . . . . . . . . . .  */
+/*  x x x . . . . . . . . . . . . .  */
+/*  . X . . . . . . . . . . . . . .  */
+/*  x x x . . . . . . . . . . . . .  */
+/*  x x x . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+
+{{0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . x x x . . . . . . . . . . .  */
+/*  . x x x . . . . . . . . . . . .  */
+/*  . . X . . . . . . . . . . . . .  */
+/*  . x x x . . . . . . . . . . . .  */
+/*  . x x x . . . . . . . . . . . .  */
+/*  . x x . . . . . . . . . . . . .  */
+
+{{0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . x x x . . . . . . . . . .  */
+/*  . . x x x . . . . . . . . . . .  */
+/*  . . . X . . . . . . . . . . . .  */
+/*  . . x x x . . . . . . . . . . .  */
+/*  . . x x x . . . . . . . . . . .  */
+/*  . . x x . . . . . . . . . . . .  */
+
+{{0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . x x x . . . . . . . . .  */
+/*  . . . x x x . . . . . . . . . .  */
+/*  . . . . X . . . . . . . . . . .  */
+/*  . . . x x x . . . . . . . . . .  */
+/*  . . . x x x . . . . . . . . . .  */
+/*  . . . x x . . . . . . . . . . .  */
+
+{{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . x x x . . . . . . . .  */
+/*  . . . . x x x . . . . . . . . .  */
+/*  . . . . . X . . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . x x x . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . . . X . . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . X . . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . . . X . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . x x . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+/*  . . . . . . . . . X . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . x x . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+/*  . . . . . . . . . . X . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . . x x . . .  */
+/*  . . . . . . . . . . . x x . . .  */
+/*  . . . . . . . . . . . X . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . . . x x . .  */
+/*  . . . . . . . . . . . . x x . .  */
+/*  . . . . . . . . . . . . X . . .  */
+/*  . . . . . . . . . . . x x . . .  */
+/*  . . . . . . . . . . . x x . . .  */
+/*  . . . . . . . . . . . x x . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}},
+
+/*  . . . . . . . . . . . . . x x .  */
+/*  . . . . . . . . . . . . . x x .  */
+/*  . . . . . . . . . . . . . X . .  */
+/*  . . . . . . . . . . . . x x . .  */
+/*  . . . . . . . . . . . . x x . .  */
+/*  . . . . . . . . . . . . x x . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}},
+
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . X .  */
+/*  . . . . . . . . . . . . . x x .  */
+/*  . . . . . . . . . . . . . x x .  */
+/*  . . . . . . . . . . . . . x x .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}},
+
+/*  . . . . . . . . . . . . . . . x  */
+/*  . . . . . . . . . . . . . . . x  */
+/*  . . . . . . . . . . . . . . . X  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . x x  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}}},
+
+{  /* --- Stack 2 --- */
+
+/*  x x . . . . . . . . . .          */
+/*  x x . . . . . . . . . .          */
+/*  X . . . . . . . . . . .          */
+/*  x . . . . . . . . . . .          */
+/*  x . . . . . . . . . . .          */
+/*  x . . . . . . . . . . .          */
+
+{{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . x x . . . . . . . . .          */
+/*  . x x . . . . . . . . .          */
+/*  . X . . . . . . . . . .          */
+/*  x x . . . . . . . . . .          */
+/*  x x . . . . . . . . . .          */
+/*  x x . . . . . . . . . .          */
+
+{{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . x x . . . . . . . .          */
+/*  . . x x . . . . . . . .          */
+/*  . . X . . . . . . . . .          */
+/*  . x x . . . . . . . . .          */
+/*  . x x . . . . . . . . .          */
+/*  . x x . . . . . . . . .          */
+
+{{0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . x x . . . . . . .          */
+/*  . . . x x . . . . . . .          */
+/*  . . . X . . . . . . . .          */
+/*  . . x x x . . . . . . .          */
+/*  . . x x x . . . . . . .          */
+/*  . . x x x . . . . . . .          */
+
+{{0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . x x x . . . . . .          */
+/*  . . . x x x . . . . . .          */
+/*  . . . . X . . . . . . .          */
+/*  . . . x x x . . . . . .          */
+/*  . . . x x x . . . . . .          */
+/*  . . . x x x . . . . . .          */
+
+{{0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . x x x . . . . .          */
+/*  . . . . x x x . . . . .          */
+/*  . . . . . X . . . . . .          */
+/*  . . . . x x x . . . . .          */
+/*  . . . . x x x . . . . .          */
+/*  . . . . x x x . . . . .          */
+
+{{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . x x x . . . .          */
+/*  . . . . . x x x . . . .          */
+/*  . . . . . . X . . . . .          */
+/*  . . . . . x x x . . . .          */
+/*  . . . . . x x x . . . .          */
+/*  . . . . . x x x . . . .          */
+
+{{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . x x x . . .          */
+/*  . . . . . . x x x . . .          */
+/*  . . . . . . . X . . . .          */
+/*  . . . . . . x x x . . .          */
+/*  . . . . . . x x x . . .          */
+/*  . . . . . . x x x . . .          */
+
+{{0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . x x . . .          */
+/*  . . . . . . . x x . . .          */
+/*  . . . . . . . . X . . .          */
+/*  . . . . . . . x x x . .          */
+/*  . . . . . . . x x x . .          */
+/*  . . . . . . . x x x . .          */
+
+{{0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . x x . .          */
+/*  . . . . . . . . x x . .          */
+/*  . . . . . . . . . X . .          */
+/*  . . . . . . . . . x x .          */
+/*  . . . . . . . . . x x .          */
+/*  . . . . . . . . . x x .          */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . x x .          */
+/*  . . . . . . . . . x x .          */
+/*  . . . . . . . . . . X .          */
+/*  . . . . . . . . . . x x          */
+/*  . . . . . . . . . . x x          */
+/*  . . . . . . . . . . x x          */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . x x          */
+/*  . . . . . . . . . . x x          */
+/*  . . . . . . . . . . . X          */
+/*  . . . . . . . . . . . x          */
+/*  . . . . . . . . . . . x          */
+/*  . . . . . . . . . . . x          */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}},
+
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+/*  . . . . . . . . . . . .          */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}},
+
+{  /* --- Stack 3 --- */
+
+/*  x . . . . . . . . . . . . . . .  */
+/*  x . . . . . . . . . . . . . . .  */
+/*  X . . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+
+{{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  x x . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  . X . . . . . . . . . . . . . .  */
+/*  . x x . . . . . . . . . . . . .  */
+/*  . x x . . . . . . . . . . . . .  */
+/*  . x x . . . . . . . . . . . . .  */
+
+{{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . x x . . . . . . . . . . . . .  */
+/*  . x x . . . . . . . . . . . . .  */
+/*  . . X . . . . . . . . . . . . .  */
+/*  . . x x . . . . . . . . . . . .  */
+/*  . . x x . . . . . . . . . . . .  */
+/*  . . x x . . . . . . . . . . . .  */
+
+{{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . x x . . . . . . . . . . . .  */
+/*  . . x x . . . . . . . . . . . .  */
+/*  . . . X . . . . . . . . . . . .  */
+/*  . . . x x . . . . . . . . . . .  */
+/*  . . . x x . . . . . . . . . . .  */
+/*  . . . x x . . . . . . . . . . .  */
+
+{{0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . x x . . . . . . . . . . .  */
+/*  . . . x x . . . . . . . . . . .  */
+/*  . . . . X . . . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+
+{{0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . x x . . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+/*  . . . . . X . . . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+
+{{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . x x . . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+/*  . . . . . . X . . . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . . . . X . . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . . X . . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . x x x . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . . . . X . . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . x x x . . . . .  */
+/*  . . . . . . . . . x x x . . . .  */
+/*  . . . . . . . . . . X . . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . x x x . . . .  */
+/*  . . . . . . . . . . x x x . . .  */
+/*  . . . . . . . . . . . X . . . .  */
+/*  . . . . . . . . . . x x x . . .  */
+/*  . . . . . . . . . . x x x . . .  */
+/*  . . . . . . . . . . . x x . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}},
+
+/*  . . . . . . . . . . x x x . . .  */
+/*  . . . . . . . . . . . x x x . .  */
+/*  . . . . . . . . . . . . X . . .  */
+/*  . . . . . . . . . . . x x x . .  */
+/*  . . . . . . . . . . . x x x . .  */
+/*  . . . . . . . . . . . . x x . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}},
+
+/*  . . . . . . . . . . . x x x . .  */
+/*  . . . . . . . . . . . . x x x .  */
+/*  . . . . . . . . . . . . . X . .  */
+/*  . . . . . . . . . . . . x x x .  */
+/*  . . . . . . . . . . . . x x x .  */
+/*  . . . . . . . . . . . . . x x .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}},
+
+/*  . . . . . . . . . . . . x x x .  */
+/*  . . . . . . . . . . . . . x x x  */
+/*  . . . . . . . . . . . . . . X .  */
+/*  . . . . . . . . . . . . . x x x  */
+/*  . . . . . . . . . . . . . x x x  */
+/*  . . . . . . . . . . . . . . x x  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}},
+
+/*  . . . . . . . . . . . . . x x x  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . . X  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . . x  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}},
+
+{  /* --- Stack 4 --- */
+
+/*  x . . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  X . . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+/*  x x . . . . . . . . . . . . . .  */
+
+{{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  x x . . . . . . . . . . . . . .  */
+/*  x x x . . . . . . . . . . . . .  */
+/*  . X . . . . . . . . . . . . . .  */
+/*  x x x . . . . . . . . . . . . .  */
+/*  x x x . . . . . . . . . . . . .  */
+/*  . x x . . . . . . . . . . . . .  */
+
+{{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  x x x . . . . . . . . . . . . .  */
+/*  . x x x . . . . . . . . . . . .  */
+/*  . . X . . . . . . . . . . . . .  */
+/*  . x x x . . . . . . . . . . . .  */
+/*  . x x x . . . . . . . . . . . .  */
+/*  . . x x . . . . . . . . . . . .  */
+
+{{1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . x x x . . . . . . . . . . . .  */
+/*  . . x x x . . . . . . . . . . .  */
+/*  . . . X . . . . . . . . . . . .  */
+/*  . . x x x . . . . . . . . . . .  */
+/*  . . x x x . . . . . . . . . . .  */
+/*  . . . x x . . . . . . . . . . .  */
+
+{{0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . x x x . . . . . . . . . . .  */
+/*  . . . x x x . . . . . . . . . .  */
+/*  . . . . X . . . . . . . . . . .  */
+/*  . . . x x x . . . . . . . . . .  */
+/*  . . . x x x . . . . . . . . . .  */
+/*  . . . . x x . . . . . . . . . .  */
+
+{{0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . x x x . . . . . . . . . .  */
+/*  . . . . x x x . . . . . . . . .  */
+/*  . . . . . X . . . . . . . . . .  */
+/*  . . . . x x x . . . . . . . . .  */
+/*  . . . . x x x . . . . . . . . .  */
+/*  . . . . . x x . . . . . . . . .  */
+
+{{0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . x x x . . . . . . . . .  */
+/*  . . . . . x x x . . . . . . . .  */
+/*  . . . . . . X . . . . . . . . .  */
+/*  . . . . . x x x . . . . . . . .  */
+/*  . . . . . x x x . . . . . . . .  */
+/*  . . . . . . x x . . . . . . . .  */
+
+{{0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . x x x . . . . . . . .  */
+/*  . . . . . . x x x . . . . . . .  */
+/*  . . . . . . . X . . . . . . . .  */
+/*  . . . . . . x x x . . . . . . .  */
+/*  . . . . . . x x x . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+
+{{0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . x x . . . . . . . .  */
+/*  . . . . . . . x x x . . . . . .  */
+/*  . . . . . . . . X . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . x x . . . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+/*  . . . . . . . . . X . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}},
+
+/*  . . . . . . . . x x . . . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+/*  . . . . . . . . . . X . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+/*  . . . . . . . . . x x . . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . x x . . . . .  */
+/*  . . . . . . . . . . . x x . . .  */
+/*  . . . . . . . . . . . X . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+/*  . . . . . . . . . . x x . . . .  */
+/*  . . . . . . . . . . . x x . . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0}},
+
+/*  . . . . . . . . . . x x . . . .  */
+/*  . . . . . . . . . . . . x x . .  */
+/*  . . . . . . . . . . . . X . . .  */
+/*  . . . . . . . . . . . x x . . .  */
+/*  . . . . . . . . . . . x x . . .  */
+/*  . . . . . . . . . . . . x x . .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0}},
+
+/*  . . . . . . . . . . . x x . . .  */
+/*  . . . . . . . . . . . . . x x .  */
+/*  . . . . . . . . . . . . . X . .  */
+/*  . . . . . . . . . . . . x x . .  */
+/*  . . . . . . . . . . . . x x . .  */
+/*  . . . . . . . . . . . . . x x .  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0}},
+
+/*  . . . . . . . . . . . . x x . .  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . X .  */
+/*  . . . . . . . . . . . . . x x .  */
+/*  . . . . . . . . . . . . . x x .  */
+/*  . . . . . . . . . . . . . . x x  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}},
+
+/*  . . . . . . . . . . . . . x x .  */
+/*  . . . . . . . . . . . . . . . x  */
+/*  . . . . . . . . . . . . . . . X  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . x x  */
+/*  . . . . . . . . . . . . . . . x  */
+
+{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}}
+
+};
 
 AliTRDgtuParam::AliTRDgtuParam() :
   fVertexSize(20.0),
@@ -141,63 +1267,81 @@ Int_t AliTRDgtuParam::GenerateZChannelMap()
   // assuming that the tracks come from the vertex
   // +/- fVertexSize in z-direction
 
-  Int_t iSec = 0; // sector is irrelevant
-  Bool_t collision = kFALSE;
+  if (fgUseGTUconst) {
+    for (Int_t iStack = 0; iStack < fGeo->Nstack(); iStack++) {
+      for (Int_t iChannel = 0; iChannel < fGeo->GetRowMax(fgkFixLayer, iStack, 0); iChannel++) {
+       for (Int_t iLayer = 0; iLayer < fGeo->Nlayer(); iLayer++) {
+         for (Int_t iRow = 0; iRow < fGeo->GetRowMax(iLayer, iStack, 0); iRow++) {
+           if (fgZChannelMap[iStack][iChannel][iLayer][iRow] != 0) {
+             fZChannelMap[iStack][iChannel][iLayer][iRow] = 1;
+             fZSubChannel[iStack][iChannel % fgkNZChannels][iLayer][iRow] = iChannel / fgkNZChannels + 1;
+           }
+         }
+       }
+      }
+    }
 
-  for (Int_t iStack = 0; iStack < fGeo->Nstack(); iStack++) {
+    return kTRUE;
+  }
+  else {
+    Int_t iSec = 0; // sector is irrelevant
+    Bool_t collision = kFALSE;
 
-    Float_t x[6] = { 0 };
-    Float_t z[6][16] = {{ 0 }};
-    Float_t dZ[6][16] = {{ 0 }};
+    for (Int_t iStack = 0; iStack < fGeo->Nstack(); iStack++) {
 
-    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++)
+      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++) {
+      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?
+       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;
+       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;
-       }
+         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;
+         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;
            }
-           else
-             fZSubChannel[iStack][fixRow % fgkNZChannels][iLayer][iRow] = fixRow / fgkNZChannels + 1;
-         }
 
+         }
        }
       }
     }
-  }
 
-  return ~collision;
+    return ~collision;
+  }
 }
 
 Bool_t AliTRDgtuParam::DisplayZChannelMap(Int_t zchannel, Int_t subchannel) const
@@ -254,7 +1398,7 @@ 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)) );
+  Int_t ci = TMath::Nint(GetChamberThickness() / fGeo->GetTime0(layer) * GetBinWidthY() / GetBinWidthdY() * (1 << (GetBitExcessAlpha() + GetBitExcessY() + 1)) );
   return ci;
 }
 
@@ -263,7 +1407,7 @@ 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()) );
+  Int_t ci = TMath::Nint(- (fGeo->GetTime0(layer) - xmid) / GetChamberThickness() * GetBinWidthdY() / GetBinWidthY() * (1 << GetBitExcessYProj()) );
   return ci;
 }
 
@@ -414,14 +1558,49 @@ Bool_t AliTRDgtuParam::GetIntersectionPoints(Int_t k, Float_t &x1, Float_t &x2)
     return kFALSE;
 }
 
-Float_t AliTRDgtuParam::GetPt(Int_t a, Float_t /* b */, Float_t x1, Float_t x2) const
+Int_t AliTRDgtuParam::GetPt(Int_t layerMask, Int_t a, Float_t /* b */, Float_t x1, Float_t x2) const
 {
   // returns 0.3 * B * 1/a (1/128 GeV/c)
   // a : offset, b : slope (not used)
 
-  Float_t c1 = x1 * x2 / 2. / 10000.; // conversion cm to m
-  Float_t r = 0;
-  if ( (a >> 1) != 0)
-    r = (0.3 * fMagField / 2. / (fgkBinWidthY/100.)) * (((Int_t) c1) << 8) / (a >> 1); //??? why shift of a?
-  return r;
+  if (fgUseGTUconst) {
+    //----- calculation as in the GTU ----
+    const Int_t maskIdLut[64] = {
+      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,
+      -1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1,  2, -1,  3,  4,  5,
+      -1, -1, -1, -1, -1, -1, -1,  6, -1, -1, -1,  7, -1,  8,  9, 10,
+      -1, -1, -1, 11, -1, 12, 13, 14, -1, 15, 16, 17, 18, 19, 20, 21
+    };
+
+    const Int_t c1Lut[32] = {
+      -2371, -2474, -2474, -2474, -2563, -2448, -2578, -2578,
+      -2578, -2670, -2557, -2578, -2578, -2670, -2557, -2578,
+      -2670, -2557, -2763, -2557, -2644, -2523,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1
+    };
+
+    Int_t layerMaskId = maskIdLut[layerMask];
+    Int_t c1 = c1Lut[layerMaskId];
+    Int_t c1Ext = c1 << 8;
+    Int_t ptRawStage4 = c1Ext / a;
+    Int_t ptRawComb4 = ptRawStage4;
+    Int_t ptExtComb4 = (ptRawComb4 > 0) ? ptRawComb4 + 33 : ptRawComb4 - 30;
+
+    return ((Int_t) ptExtComb4/2);
+  }
+  else {
+    //----- simple calculation -----
+    Float_t c1 = x1 * x2 / 2. / 10000.; // conversion cm to m
+    Float_t r = 0;
+    if ( (a >> 1) != 0)
+      r = (0.3 * fMagField / 2. / (fgkBinWidthY/100.)) * (((Int_t) c1) << 8) / (a >> 1); //??? why shift of a?
+
+    Int_t pt = (Int_t) (2 * r);
+    if (pt >= 0)
+      pt += 32;
+    else
+      pt -= 29;
+    pt /= 2;
+    return pt;
+  }
 }
index 84b50b4c18ff9eefbb21c7c559bfa602e70bd8ad..47a30e239d359304a518d3a82163cc3da1e92627 100644 (file)
@@ -53,7 +53,7 @@ class AliTRDgtuParam : public TObject {
   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 GetPt(Int_t a, Float_t b, Float_t x1, Float_t x2) const;
+  Int_t GetPt(Int_t layerMask, 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;
 
@@ -62,6 +62,9 @@ class AliTRDgtuParam : public TObject {
   static void SetDeltaY(Int_t dy) { fgDeltaY = dy; }
   static void SetDeltaAlpha(Int_t da) { fgDeltaAlpha = da; }
 
+  static void SetUseGTUconst(Bool_t b) { fgUseGTUconst = b; }
+  static Bool_t GetUseGTUconst() { return fgUseGTUconst; }
+
   // z-channel map
   Int_t GenerateZChannelMap(); // could have different modes (for beam-beam, cosmics, ...)
   Bool_t DisplayZChannelMap(Int_t zchannel = -1, Int_t subch = 0) const;
@@ -77,12 +80,9 @@ class AliTRDgtuParam : public TObject {
   void SetMagField(Float_t field) { fMagField = field; }
   Float_t GetMagField() const { return fMagField; }
 
- 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       Int_t fgDeltaY;         // accepted deviation in y_proj, default: 9
-  static       Int_t fgDeltaAlpha;      // accepted deviation in alpha, default: 11
   static const Int_t fgkNRefLayers = 3;         // no. of reference layers
 
   static const Float_t fgkBinWidthY; // bin width for y-position
@@ -95,6 +95,14 @@ class AliTRDgtuParam : public TObject {
   static const Int_t fgkBitExcessAlpha; // excess bits for alpha
   static const Int_t fgkBitExcessYProj; // excess bits for projected y-position
 
+ protected:
+  static       Int_t fgDeltaY;         // accepted deviation in y_proj, default: 9
+  static       Int_t fgDeltaAlpha;      // accepted deviation in alpha, default: 11
+
+  static       Bool_t fgUseGTUconst;    // use constants as in the GTU for the calculations
+                                              // instead of geometry derived quantities
+  static const Bool_t fgZChannelMap[5][16][6][16]; // z-channel tables as in GTU
+
   Float_t fVertexSize;         // assumed vertex size (z-dir.) for the z-channel map
 
   Int_t fZChannelMap[5][16][6][16];              // must be changed
index 80e995fc09f67a6a3811a9071a1f41c23dd00c26..90ae6c29dd03c28b9ad148c5cdc12346e78157f9 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "TFile.h"
 #include "TROOT.h"
+#include "TObject.h"
 #include "TClonesArray.h"
 
 #include "AliRun.h"
@@ -37,6 +38,7 @@
 #include "AliTreeLoader.h"
 #include "AliLog.h"
 #include "AliESDTrdTrack.h"
+#include "AliESDTrdTracklet.h"
 
 #include "AliTRDgtuSim.h"
 #include "AliTRDfeeParam.h"
@@ -57,8 +59,8 @@ AliTRDgtuSim::AliTRDgtuSim(AliRunLoader *rl)
   fTrackTree(0x0),
   fTrackletTree(0x0)
 {
-  fTrackletTree = new TTree("gtutracklets", "Tree with GTU tracklets");
-  fTrackletTree->SetDirectory(0);
+//   fTrackletTree = new TTree("gtutracklets", "Tree with GTU tracklets");
+//   fTrackletTree->SetDirectory(0);
 }
 
 AliTRDgtuSim::~AliTRDgtuSim()
@@ -66,7 +68,7 @@ AliTRDgtuSim::~AliTRDgtuSim()
   // destructor
 
   if (fTrackletArray)
-    fTrackletArray->Delete();
+    fTrackletArray->Clear();
   delete fTrackletArray;
   delete fTrackletTree;
 }
@@ -76,99 +78,104 @@ Bool_t AliTRDgtuSim::RunGTUFromTrackletFile(TString filename, Int_t event, Int_t
   // run the GTU from a file of tracklets
   // used for comparison to VHDL simulation
 
-    AliInfo(Form("Running the GTU simulation on file: %s", filename.Data()));
-    ifstream input(filename.Data());
+  ifstream input(filename.Data());
 
-    std::string str;
-    TString string;
-    int lineno = 0;
+  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;
+  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;
+  fTMU = 0x0;
 
-    AliDebug(5,"--------- Reading from file ----------");
-    while (getline(input, str)) {
-       lineno++;
-       string = str;
-       AliDebug(5,Form("Line %i : %s", lineno, string.Data()));
+  TClonesArray trklArray("AliTRDtrackletWord", 100);
+  TClonesArray trklArrayGTU("AliTRDtrackletGTU", 100);
 
-       TObjArray *tokens = string.Tokenize(" ");
-       if (tokens->GetEntriesFast() < 7) {
-           AliWarning(Form("Invalid input in line %i, too few parameters", lineno));
-           continue;
-       }
+  AliDebug(1, Form("--------- Reading from %s ----------", filename.Data()));
+  while (getline(input, str)) {
+    lineno++;
+    string = str;
 
-       if ( ((TObjString*) tokens->At(0))->GetString().Atoi() < event)
-           continue;
+    TObjArray *tokens = string.Tokenize(" ");
+    if (tokens->GetEntriesFast() < 7) {
+      AliWarning(Form("Invalid input in line %i, too few parameters", lineno));
+      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 ( ((TObjString*) tokens->At(0))->GetString().Atoi() < event)
+      continue;
 
-       if (iEvent != iEventPrev || iStack != iStackPrev || iSec != iSecPrev) {
-           if(fTMU) {
-               TList *listOfTracks = new TList();
-               fTMU->SetStack(iStackPrev);
-               fTMU->SetSector(iSecPrev);
-               fTMU->RunTMU(listOfTracks);
-               AliDebug(1,Form("--- There are %i tracks. Writing ...", listOfTracks->GetEntries()));
-               WriteTracksToTree(listOfTracks);
-               fTMU->WriteTrackletsToTree(fTrackletTree);
-               WriteTracksToLoader(listOfTracks);
-               WriteTracksToDataFile(listOfTracks, iEventPrev);
-               if (listOfTracks->GetEntries() > 0)
-                   AliDebug(2,Form("   %4.1f 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(), "%i", &trackletWord);
-           if (trackletWord == 0x10001000)
-               break;
-           AliDebug(2,Form("%i. tracklet: %s -> 0x%08x", i-4, ((TObjString*) tokens->At(i))->GetString().Data(), trackletWord));
-           AliTRDtrackletWord *trkl = new AliTRDtrackletWord(trackletWord);
-           if (fTMU)
-             fTMU->AddTracklet(trkl, iLink);
-       }
-    }
+    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 (fTMU && evcnt < noev) {
+    if ((iEvent != iEventPrev) ||
+       (iStack != iStackPrev) ||
+       (iSec != iSecPrev)) {
+      if(fTMU) {
        TList *listOfTracks = new TList();
        fTMU->SetStack(iStackPrev);
        fTMU->SetSector(iSecPrev);
        fTMU->RunTMU(listOfTracks);
+       AliDebug(1,Form("--- There are %i tracks. Writing ...", listOfTracks->GetEntries()));
        WriteTracksToTree(listOfTracks);
-       fTMU->WriteTrackletsToTree(fTrackletTree);
-       WriteTracksToLoader(listOfTracks);
+       // fTMU->WriteTrackletsToTree(fTrackletTree);
+       // WriteTracksToLoader(listOfTracks);
        WriteTracksToDataFile(listOfTracks, iEventPrev);
+       if (listOfTracks->GetEntries() > 0)
+         AliDebug(2,Form("   %4.1f GeV/c", ((AliTRDtrackGTU*) listOfTracks->At(0))->GetPt() ));
        delete fTMU;
+       fTMU = new AliTRDgtuTMU();
        delete listOfTracks;
-       fTMU = 0x0;
+       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(), "%i", &trackletWord);
+      if (trackletWord == 0x10001000)
+       break;
+      AliDebug(2, Form("link: %2i trkl: %2i - %s -> 0x%08x",
+                      iLink, i-4, ((TObjString*) tokens->At(i))->GetString().Data(), trackletWord));
+      AliTRDtrackletWord *tracklet = new (trklArray[trklArray.GetEntriesFast()])       AliTRDtrackletWord(trackletWord);
+      AliTRDtrackletGTU   *trkl    = new (trklArrayGTU[trklArrayGTU.GetEntriesFast()]) AliTRDtrackletGTU(tracklet);
+      if (fTMU)
+       fTMU->AddTracklet(trkl, iLink);
+    }
+  }
 
-    AliInfo(Form("Analyzed %i events", evcnt));
-    return kTRUE;
+  if (fTMU && evcnt < noev) {
+    TList *listOfTracks = new TList();
+    fTMU->SetStack(iStackPrev);
+    fTMU->SetSector(iSecPrev);
+    fTMU->RunTMU(listOfTracks);
+    WriteTracksToTree(listOfTracks);
+    // fTMU->WriteTrackletsToTree(fTrackletTree);
+    // WriteTracksToLoader(listOfTracks);
+    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)
@@ -179,10 +186,18 @@ Bool_t AliTRDgtuSim::RunGTU(AliLoader *loader, AliESDEvent *esd)
   if (!fFeeParam->GetTracklet())
     return kFALSE;
 
+  if (fTrackletArray)
+    fTrackletArray->Clear();
+
+  if (loader) {
     if (!LoadTracklets(loader)) {
        AliError("Could not load the tracklets. Nothing done ...");
        return kFALSE;
     }
+  }
+  else {
+    LoadTracklets(esd);
+  }
 
     AliDebug(1, Form("running on %i tracklets", fTrackletArray->GetEntriesFast()));
 
@@ -200,12 +215,11 @@ Bool_t AliTRDgtuSim::RunGTU(AliLoader *loader, AliESDEvent *esd)
     TList *listOfTracks = new TList();
 
     TIter next(fTrackletArray);
-    AliTRDtrackletBase *trkl;
 
-    while ((trkl = (AliTRDtrackletBase*) next())) {
+    while (AliTRDtrackletGTU *trkl = (AliTRDtrackletGTU*) next()) {
        iSec = trkl->GetDetector() / 30;
        iStack = (trkl->GetDetector() % 30) / 6;
-       iLink = 2 * (trkl->GetDetector() % 6) + (trkl->GetYbin() < 0 ? 0 : 1);
+       iLink = trkl->GetHCId() % 12;
 
        if (iStack != iStackPrev || iSec != iSecPrev) {
            if(fTMU) {
@@ -213,7 +227,7 @@ Bool_t AliTRDgtuSim::RunGTU(AliLoader *loader, AliESDEvent *esd)
                fTMU->SetSector(iSecPrev);
                fTMU->RunTMU(listOfTracks);
                WriteTracksToTree(listOfTracks);
-               fTMU->WriteTrackletsToTree(fTrackletTree);
+//             fTMU->WriteTrackletsToTree(fTrackletTree);
                WriteTracksToLoader(listOfTracks);
                WriteTracksToESD(listOfTracks, esd);
                fTMU->Reset();
@@ -225,8 +239,9 @@ Bool_t AliTRDgtuSim::RunGTU(AliLoader *loader, AliESDEvent *esd)
            iSecPrev = iSec;
        }
        AliDebug(1, Form("adding tracklet: 0x%08x", trkl->GetTrackletWord()));
-       if (fTMU)
+       if (fTMU) {
          fTMU->AddTracklet(trkl, iLink);
+       }
     }
 
     if (fTMU) {
@@ -234,7 +249,7 @@ Bool_t AliTRDgtuSim::RunGTU(AliLoader *loader, AliESDEvent *esd)
        fTMU->SetSector(iSecPrev);
        fTMU->RunTMU(listOfTracks);
        WriteTracksToTree(listOfTracks);
-       fTMU->WriteTrackletsToTree(fTrackletTree);
+//     fTMU->WriteTrackletsToTree(fTrackletTree);
        WriteTracksToLoader(listOfTracks);
        WriteTracksToESD(listOfTracks, esd);
        delete fTMU;
@@ -247,6 +262,21 @@ Bool_t AliTRDgtuSim::RunGTU(AliLoader *loader, AliESDEvent *esd)
     return kTRUE;
 }
 
+Bool_t AliTRDgtuSim::LoadTracklets(const AliESDEvent *const esd)
+{
+  AliDebug(1,"Loading tracklets from ESD event ...");
+
+  if (!fTrackletArray)
+    fTrackletArray = new TClonesArray("AliTRDtrackletGTU", 1000);
+
+  for (Int_t iTracklet = 0; iTracklet < esd->GetNumberOfTrdTracklets(); iTracklet++) {
+    AliESDTrdTracklet *trkl = esd->GetTrdTracklet(iTracklet);
+    new ((*fTrackletArray)[fTrackletArray->GetEntries()]) AliTRDtrackletGTU(trkl);
+  }
+
+  return kTRUE;
+}
+
 Bool_t AliTRDgtuSim::LoadTracklets(AliLoader *const loader)
 {
   // load the tracklets using the given loader
@@ -276,20 +306,13 @@ Bool_t AliTRDgtuSim::LoadTracklets(AliLoader *const loader)
     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);
-      }
+       fTrackletArray = new TClonesArray("AliTRDtrackletGTU", 1000);
 
-      AliTRDtrackletMCM *trkl = new AliTRDtrackletMCM;
+      AliTRDtrackletMCM *trkl = 0x0;
       trklbranch->SetAddress(&trkl);
       for (Int_t iTracklet = 0; iTracklet < trklbranch->GetEntries(); iTracklet++) {
        trklbranch->GetEntry(iTracklet);
-       new ((*fTrackletArray)[fTrackletArray->GetEntries()]) AliTRDtrackletMCM(*trkl);
+       new ((*fTrackletArray)[fTrackletArray->GetEntries()]) AliTRDtrackletGTU(new AliTRDtrackletMCM(*trkl));
       }
       return kTRUE;
     }
@@ -301,14 +324,7 @@ Bool_t AliTRDgtuSim::LoadTracklets(AliLoader *const loader)
 
   if (trackletTree) {
     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);
-    }
+      fTrackletArray = new TClonesArray("AliTRDtrackletGTU", 1000);
 
     Int_t hc;
     TClonesArray *ar = 0x0;
@@ -320,7 +336,7 @@ Bool_t AliTRDgtuSim::LoadTracklets(AliLoader *const loader)
       AliDebug(2, Form("%i tracklets in HC %i", ar->GetEntriesFast(), hc));
       for (Int_t iTracklet = 0; iTracklet < ar->GetEntriesFast(); iTracklet++) {
        AliTRDtrackletWord *trklWord = (AliTRDtrackletWord*) (*ar)[iTracklet];
-       new((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletWord(trklWord->GetTrackletWord(), hc);
+       new((*fTrackletArray)[fTrackletArray->GetEntriesFast()]) AliTRDtrackletGTU(new AliTRDtrackletWord(trklWord->GetTrackletWord(), hc));
       }
     }
     return kTRUE;
@@ -343,11 +359,34 @@ Bool_t AliTRDgtuSim::WriteTracksToDataFile(TList *listOfTracks, Int_t event)
     out = fopen("test.data", "a");
 
     AliDebug(1,Form("%i tracks found in event %i", listOfTracks->GetSize(), event));
-    fprintf(out, "0 %5i %2i %i  00000000\n", event, sm, stack);
+    // 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();
+
+       ULong64_t trackWord = 1;
+       AppendBits(trackWord,   1, 0);
+       AppendBits(trackWord,   6, trk->GetTrackletMask());
+       AppendBits(trackWord,  18, (Int_t) trk->GetA());
+       AppendBits(trackWord,  18, (Int_t) trk->GetB());
+       AppendBits(trackWord,  12, (Int_t) trk->GetC());
+       AppendBits(trackWord,   8, trk->GetPID());
+       fprintf(out, "ev. %i sec. %i stack %i - track word: 0x%016llx, ",
+               event, sm, stack, trackWord);
+
+       trackWord = 0;
+       AppendBits(trackWord, 11, 0); // flags
+       AppendBits(trackWord,  3, 0);
+       AppendBits(trackWord, 13, trk->GetYapprox());
+       AppendBits(trackWord,  6, trk->GetTrackletIndex(5));
+       AppendBits(trackWord,  6, trk->GetTrackletIndex(4));
+       AppendBits(trackWord,  6, trk->GetTrackletIndex(3));
+       AppendBits(trackWord,  6, trk->GetTrackletIndex(2));
+       AppendBits(trackWord,  6, trk->GetTrackletIndex(1));
+       AppendBits(trackWord,  6, trk->GetTrackletIndex(0));
+       fprintf(out, "extended track word: 0x%016llx\n", trackWord);
+
        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),
index d100059f6bf81a11e3c8ce83e666f5b85d81ba3f..ba15f4c07b7bf4d79fa634f22c4025e0d6691dca 100644 (file)
@@ -28,6 +28,7 @@ class AliTRDgtuSim : public TObject {
   ~AliTRDgtuSim();
 
   Bool_t LoadTracklets(AliLoader * const loader);
+  Bool_t LoadTracklets(const AliESDEvent * const esd);
 
   Bool_t RunGTU(AliLoader *loader, AliESDEvent *esd = 0x0);
   Bool_t RunGTUFromTrackletFile(TString filename, Int_t event, Int_t noev = 1);
@@ -47,6 +48,8 @@ class AliTRDgtuSim : public TObject {
   TTree        *fTrackTree;    // tree to hold the tracks of one event, used for writing in WriteTracksToFile()
   TTree         *fTrackletTree; // tree to hold the gtu tracklets
 
+  void AppendBits(ULong64_t &word, Int_t nBits, Int_t val) const { word = (word << nBits) | (val & ~(~0 << nBits)); }
+
  private:
   AliTRDgtuSim& operator=(const AliTRDgtuSim &rhs); // not implemented
   AliTRDgtuSim(const AliTRDgtuSim &rhs); // not implemented
index 00e4825adf92022c07454ddb0db8fd69ab7c0aab..92984079cf489c236ffbeb4749fce5a0585c386a 100644 (file)
@@ -44,6 +44,7 @@ ClassImp(AliTRDgtuTMU)
 AliTRDgtuTMU::AliTRDgtuTMU(Int_t stack, Int_t sector) :
   TObject(),
   fTracklets(0x0),
+  fTrackletsPostInput(0x0),
   fZChannelTracklets(0x0),
   fTracks(0x0),
   fGtuParam(0x0),
@@ -53,16 +54,26 @@ AliTRDgtuTMU::AliTRDgtuTMU(Int_t stack, Int_t sector) :
   // constructor which initializes the position information of the TMU
 
   fGtuParam = AliTRDgtuParam::Instance();
-  fTracklets = new TObjArray*[fGtuParam->GetNLayers()];
+
+  // store tracklets per link
+  fTracklets = new TObjArray*[fGtuParam->GetNLinks()];
+  for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
+    fTracklets[iLink] = new TObjArray();
+  }
+
+  // tracklets after input units per layer
+  fTrackletsPostInput = new TObjArray*[fGtuParam->GetNLayers()];
   fZChannelTracklets = new TList*[fGtuParam->GetNLayers()];
   for (Int_t layer = 0;  layer <  fGtuParam->GetNLayers(); layer++) {
-    fTracklets[layer] = new TObjArray();
     fZChannelTracklets[layer] = new TList[fGtuParam->GetNZChannels()];
+    fTrackletsPostInput[layer] = new TObjArray();
   }
+
   fTracks = new TList*[fGtuParam->GetNZChannels()];
   for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
       fTracks[zch] = new TList[fGtuParam->GetNRefLayers()];
   }
+
   if (stack > -1)
       SetStack(stack);
   if (sector > -1)
@@ -78,11 +89,15 @@ AliTRDgtuTMU::~AliTRDgtuTMU()
   }
   delete [] fTracks;
   for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
-    fTracklets[layer]->Delete();
     delete [] fZChannelTracklets[layer];
-    delete fTracklets[layer];
+    //    delete [] fTrackletsPostInput[layer];
   }
   delete [] fZChannelTracklets;
+  //  delete [] fTrackletsPostInput;
+
+  for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
+    delete fTracklets[iLink];
+  }
   delete [] fTracklets;
 }
 
@@ -123,10 +138,13 @@ Bool_t AliTRDgtuTMU::Reset()
   }
 
   // delete all added tracklets
+  for (Int_t iLink = 0; iLink < fGtuParam->GetNLinks(); iLink++) {
+    fTracklets[iLink]->Clear();
+  }
   for (Int_t layer = 0; layer < fGtuParam->GetNLinks()/2; layer++) {
+    fTrackletsPostInput[layer]->Clear();
     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++)
       fZChannelTracklets[layer][zch].Clear();
-    fTracklets[layer]->Delete();
   }
 
   fSector = -1;
@@ -135,12 +153,11 @@ Bool_t AliTRDgtuTMU::Reset()
   return kTRUE;
 }
 
-Bool_t AliTRDgtuTMU::AddTracklet(AliTRDtrackletBase *tracklet, Int_t link)
+Bool_t AliTRDgtuTMU::AddTracklet(AliTRDtrackletGTU *tracklet, Int_t link)
 {
   // add a tracklet on the given link
 
-  AliTRDtrackletGTU *trkl = new AliTRDtrackletGTU(tracklet);
-  fTracklets[(Int_t) link/2]->Add(trkl);
+  fTracklets[link]->Add(tracklet);
   return kTRUE;
 }
 
@@ -213,11 +230,38 @@ Bool_t AliTRDgtuTMU::RunInputUnit(Int_t layer)
 {
   // precalculations for the tracking and reconstruction
 
-  fTracklets[layer]->Sort();
-  TIter next(fTracklets[layer]);
+  Int_t iTrkl0 = 0; // A-side tracklet
+  Int_t iTrkl1 = 0; // B-side tracklet
+
+  while ((iTrkl0 < fTracklets[2*layer + 0]->GetEntriesFast()) || (iTrkl1 < fTracklets[2*layer + 1]->GetEntriesFast())) {
+    if (iTrkl1 >= fTracklets[2*layer + 1]->GetEntriesFast()) {
+      fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 0]->At(iTrkl0));
+      iTrkl0++;
+    }
+    else {
+      if (iTrkl0 >= fTracklets[2*layer + 0]->GetEntriesFast()) {
+       fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 1]->At(iTrkl1));
+       iTrkl1++;
+      }
+      else {
+       if (((AliTRDtrackletGTU*) fTracklets[2*layer + 1]->At(iTrkl1))->GetZbin() <
+           ((AliTRDtrackletGTU*) fTracklets[2*layer + 0]->At(iTrkl0))->GetZbin()) {
+         fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 1]->At(iTrkl1));
+         iTrkl1++;
+
+       }
+       else {
+         fTrackletsPostInput[layer]->AddLast(fTracklets[2*layer + 0]->At(iTrkl0));
+         iTrkl0++;
+       }
+      }
+    }
+  }
+
+  TIter next(fTrackletsPostInput[layer]);
 
   while ( AliTRDtrackletGTU *trk = (AliTRDtrackletGTU*) next() ) {
-    trk->SetIndex(fTracklets[layer]->IndexOf(trk));
+    trk->SetIndex(fTrackletsPostInput[layer]->IndexOf(trk));
 
     Int_t alpha = (trk->GetYbin() >> fGtuParam->GetBitExcessY()) * fGtuParam->GetCiAlpha(layer);
     alpha = ( 2 * trk->GetdY() - (alpha >> fGtuParam->GetBitExcessAlpha()) + 1 ) >> 1;
@@ -229,8 +273,9 @@ Bool_t AliTRDgtuTMU::RunInputUnit(Int_t layer)
 
     trk->SetYPrime(trk->GetYbin() + fGtuParam->GetYt(fStack, layer, trk->GetZbin()));
 
-    AliDebug(10, Form("InputUnit : GetIndex(): %3i, GetZbin(): %2i, GetY() : %5i, GetdY() : %3i, GetYPrime() : %5i, GetYProj() : %5i, GetAlpha() : %3i",
-                     trk->GetIndex(), trk->GetZbin(), trk->GetYbin(), trk->GetdY(), trk->GetYPrime(), trk->GetYProj(), trk->GetAlpha() ));
+    AliDebug(10, Form("0x%08x: idx: %3i, z: %2i, y: %5i, dy: %3i, y': %5i, y_proj: %5i, alpha: %3i, pid: %3i",
+                     trk->GetTrackletWord(), trk->GetIndex(), trk->GetZbin(), trk->GetYbin(), trk->GetdY(), trk->GetYPrime(),
+                     trk->GetYProj(), trk->GetAlpha(), trk->GetPID() ));
   }
   return kTRUE;
 }
@@ -239,28 +284,33 @@ Bool_t AliTRDgtuTMU::RunZChannelUnit(Int_t layer)
 {
   // run the z-channel unit
 
-  TIter next(fTracklets[layer]);
+  TIter next(fTrackletsPostInput[layer]);
 
   while (AliTRDtrackletGTU *trk = (AliTRDtrackletGTU*) next()) {
-    AliDebug(10,Form("*TMU* Tracklet in stack %d, layer %2d: 0x%08x ", fStack, layer, trk->GetTrackletWord()));
     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
       if (fGtuParam->IsInZChannel(fStack, layer, zch, trk->GetZbin()) ) {
        trk->SetSubChannel(zch, fGtuParam->GetZSubchannel(fStack, layer, zch, trk->GetZbin()) );
-//     printf("Z%i(%i) ", zch, trk->GetSubChannel(zch));
 
        TIter nexttrkl(&fZChannelTracklets[layer][zch], kIterBackward);
        AliTRDtrackletGTU *t = 0x0;
        while ((t = (AliTRDtrackletGTU*) nexttrkl.Next())) {
          if (t->GetSubChannel(zch) < trk->GetSubChannel(zch) ||
-             (t->GetSubChannel(zch) == trk->GetSubChannel(zch) && t->GetYProj() < trk->GetYProj()) )
+             ((t->GetSubChannel(zch) == trk->GetSubChannel(zch)) && (t->GetYProj() < trk->GetYProj())) ) {
            break;
+         }
        }
-       fZChannelTracklets[layer][zch].AddAfter(t, trk);
+       if (t)
+         fZChannelTracklets[layer][zch].AddAfter(t, trk);
+       else
+         fZChannelTracklets[layer][zch].AddFirst(trk);
       }
-//      else
-//       printf("      ");
     }
-//    printf("\n");
+    AliDebug(10, Form("stack %d, layer %2d: 0x%08x Z(2..0)=%i/%i/%i",
+                     fStack, layer, trk->GetTrackletWord(),
+                     fGtuParam->IsInZChannel(fStack, layer, 2, trk->GetZbin()) ? trk->GetSubChannel(2) : -1,
+                     fGtuParam->IsInZChannel(fStack, layer, 1, trk->GetZbin()) ? trk->GetSubChannel(1) : -1,
+                     fGtuParam->IsInZChannel(fStack, layer, 0, trk->GetZbin()) ? trk->GetSubChannel(0) : -1
+                     ));
   }
   return kTRUE;
 }
@@ -313,6 +363,18 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
 
      ready = kFALSE; // ready if all channels done
 
+//      for (Int_t iLayer = 0; iLayer < fGtuParam->GetNLayers(); iLayer++) {
+//        for (Int_t iTrkl = 0; iTrkl < fZChannelTracklets[iLayer][zch].GetEntries(); iTrkl++) {
+//      printf("%4i/%4i(%i,%i) ",
+//             ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetYProj(),
+//             ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetAlpha(),
+//             ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetIndex(),
+//             ((AliTRDtrackletGTU*) fZChannelTracklets[iLayer][zch].At(iTrkl))->GetSubChannel(zch)
+//             );
+//        }
+//        printf("\n");
+//      }
+
      for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
        notr[layer] = fZChannelTracklets[layer][zch].GetEntries();
        ptrA[layer] = 0; // notr[layer] > 0 ? 0 : -1;
@@ -398,8 +460,8 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
         if (trkB) {
           bHitB[layer] = ( !(trkB->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() < yMinus) ) &&
                            !(trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) ) &&
-                           !(alphaMinus > trkB->GetAlpha()) &&
-                           !(alphaPlus  > trkB->GetAlpha()) );
+                           !(trkB->GetAlpha() < alphaMinus) &&
+                           !(trkB->GetAlpha() > alphaPlus) );
           bAlignedB[layer] = (trkB->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() > yPlus) );
         }
         else {
@@ -461,7 +523,7 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
         }
 
         Bool_t registerTrack = kTRUE;
-        for (Int_t layerIdx = refLayerIdx; layerIdx > 0; layerIdx--) {
+        for (Int_t layerIdx = refLayerIdx-1; layerIdx >= 0; layerIdx--) {
            if (track->IsTrackletInLayer(fGtuParam->GetRefLayer(layerIdx))) {
              if ((track->GetTracklet(fGtuParam->GetRefLayer(layerIdx)))->GetSubChannel(zch) > 0) {
                AliDebug(1,"Not registered");
@@ -503,8 +565,9 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
             trkB = (AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]);
 
           if (trkA) {
-              if ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) &&
-                   !(trkA->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() > yPlus ) ) )  // trkA could hit trkRA
+            if ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) &&
+                 !(trkA->GetSubChannel(zch) > trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() > yPlus ) ) )  // trkA could hit trkRA
+            // if ( !(trkA->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkA->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkA->GetYProj() < yMinus) ) )
                   inc[layer] = 0;
               else if (trkB) {
                   if ( trkB->GetSubChannel(zch) < trkRA->GetSubChannel(zch) || (trkB->GetSubChannel(zch) == trkRA->GetSubChannel(zch) && trkB->GetYProj() < yMinus) )
@@ -530,7 +593,15 @@ Bool_t AliTRDgtuTMU::RunTrackFinder(Int_t zch, TList* /* ListOfTracks */)
           AliError(Form("Invalid increment: %i at ptrA: %i, notr: %i", inc[layer], ptrA[layer], notr[layer]));
 
 //      AliInfo(Form("Shifting layer: %i, notr: %i, ptrA: %i, ptrB: %i, inc: %i", layer, notr[layer], ptrA[layer], ptrB[layer], inc[layer]));
-        AliDebug(10,Form(" -- Layer: %i   %i   %i   +%i   %s  (no: %i)", layer, ptrA[layer], ptrB[layer], inc[layer], bDone[layer] ? "done" : "    ", notr[layer]));
+        AliDebug(10,Form(" -- Layer: %i   %2i(%2i)%s%s   %2i(%2i)%s%s   +%i   %s  (no: %i)",
+                         layer,
+                         ptrA[layer],
+                         (0 <= ptrA[layer] && ptrA[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrA[layer]))->GetIndex() : -1,
+                         bHitA[layer] ? "*" : " ", bAlignedA[layer] ? "+" : " ",
+                         ptrB[layer],
+                         (0 <= ptrB[layer] && ptrB[layer] < notr[layer]) ? ((AliTRDtrackletGTU*) fZChannelTracklets[layer][zch].At(ptrB[layer]))->GetIndex() : -1,
+                         bHitB[layer] ? "*" : " ", bAlignedB[layer] ? "+" : " ",
+                         inc[layer], bDone[layer] ? "done" : "    ", notr[layer]));
         ptrA[layer] += inc[layer];
         ptrB[layer] += inc[layer];
        }
@@ -579,7 +650,7 @@ Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
     AliTRDtrackGTU *trkStage0 = 0x0;
 
     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
-        // ----- Merging and Unification in Reflayers -----
+        // ----- Merging and Unification in Reflayers (seed_merger) -----
        do {
            done = kTRUE;
            trkStage0 = 0x0;
@@ -607,6 +678,33 @@ Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
        } while (trkStage0 != 0);
 
        Uniquifier(tracksRefMerged[zch], tracksRefUnique[zch]);
+
+       AliDebug(2, Form("zchannel %i", zch));
+       TIter trackRefMerged(tracksRefMerged[zch]);
+       while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackRefMerged())
+         AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, z_idx=%i",
+                          trk->GetRefLayerIdx(),
+                          trk->GetTrackletIndex(5),
+                          trk->GetTrackletIndex(4),
+                          trk->GetTrackletIndex(3),
+                          trk->GetTrackletIndex(2),
+                          trk->GetTrackletIndex(1),
+                          trk->GetTrackletIndex(0),
+                          trk->GetYapprox() >> 3,
+                          trk->GetZSubChannel()));
+       AliDebug(2, "uniquified:");
+       TIter trackRefUnique(tracksRefUnique[zch]);
+       while (AliTRDtrackGTU *trk = (AliTRDtrackGTU*) trackRefUnique())
+         AliDebug(2, Form("track ref layer %i : %i %i %i %i %i %i, y=%i, z_idx=%i",
+                          trk->GetRefLayerIdx(),
+                          trk->GetTrackletIndex(5),
+                          trk->GetTrackletIndex(4),
+                          trk->GetTrackletIndex(3),
+                          trk->GetTrackletIndex(2),
+                          trk->GetTrackletIndex(1),
+                          trk->GetTrackletIndex(0),
+                          trk->GetYapprox() >> 3,
+                          trk->GetZSubChannel()));
     }
 
 // ----- Merging in zchannels - 1st stage -----
@@ -614,7 +712,7 @@ Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
     do {
        done = kTRUE;
        trkStage0 = 0x0;
-       for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++) {
+       for (Int_t zch = fGtuParam->GetNZChannels() - 1; zch > -1; zch--) {
            AliTRDtrackGTU *trk = (AliTRDtrackGTU*) tracksRefUnique[zch]->First();
            if (trk == 0) {
                continue;
@@ -651,7 +749,7 @@ Bool_t AliTRDgtuTMU::RunTrackMerging(TList* ListOfTracks)
     do {
        done = kTRUE;
        trkStage0 = 0x0;
-       for (Int_t i = 0; i < 2; i++) {
+       for (Int_t i = 1; i >= 0; i--) {
            AliTRDtrackGTU *trk = (AliTRDtrackGTU*) tracksZSplitted[i]->First();
            if (trk == 0) {
                continue;
@@ -707,6 +805,7 @@ Bool_t AliTRDgtuTMU::RunTrackReconstruction(TList* ListOfTracks)
   while (AliTRDtrackGTU *track = (AliTRDtrackGTU*) next()) {
     CalculateTrackParams(track);
     CalculatePID(track);
+    AliDebug(1, Form("track with pid = %i", track->GetPID()));
   }
   return kTRUE;
 }
@@ -719,18 +818,65 @@ Bool_t AliTRDgtuTMU::CalculatePID(AliTRDtrackGTU *track)
     return kFALSE;
   }
 
-  Int_t nTracklets = 0;
-  Int_t pidSum = 0;
-  for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
-    if (!track->IsTrackletInLayer(layer)) {
-      continue;
+  if (AliTRDgtuParam::GetUseGTUconst) {
+    // averaging as in GTU
+    ULong64_t coeff;
+
+    // selection of coefficient for averaging
+    switch(track->GetTrackletMask()){
+    case 0x3f:
+      // 6 tracklets
+      coeff=0x5558; // approx. 1/6
+      break;
+
+    case 0x3e:
+    case 0x3d:
+    case 0x3b:
+    case 0x37:
+    case 0x2f:
+    case 0x1f:
+      // 5 tracklets
+      coeff=0x6666; // approx. 1/5
+      break;
+
+    default:
+      // 4 tracklets
+      coeff=0x8000; // = 0.25
     }
-    AliTRDtrackletGTU *trk = track->GetTracklet(layer);
-    pidSum += trk->GetPID();
-    nTracklets++;
+    coeff &= 0x1ffff; // 17-bit constant
+
+    ULong64_t sum = 0;
+    for (Int_t iLayer = 0; iLayer < fGtuParam->GetNLayers(); iLayer++) {
+      if ((track->GetTrackletMask() >> iLayer) & 1) {
+       sum += track->GetTracklet(iLayer)->GetPID();
+      }
+    }
+
+    ULong64_t sumExt = (sum << 1) & 0xfff; // 11 bit -> 12 bit vector
+    ULong64_t prod   = (sumExt * coeff) & 0xfffffffff; // 18x18 signed -> 36
+    ULong64_t prodFinal = ((prod >> 18) + ((prod >> 17) & 1)) & 0xff; // rounding term is equivalent to adding 5 to sum_ext
+
+    track->SetPID(prodFinal & 0xff);
+
+    return kTRUE;
+  }
+  else {
+
+    // simple averaging
+    Int_t nTracklets = 0;
+    Int_t pidSum = 0;
+    for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
+      if (!track->IsTrackletInLayer(layer)) {
+       continue;
+      }
+      AliTRDtrackletGTU *trk = track->GetTracklet(layer);
+      pidSum += trk->GetPID();
+      nTracklets++;
+    }
+    track->SetPID(pidSum/nTracklets);
+
+    return kTRUE;
   }
-  track->SetPID(pidSum/nTracklets);
-  return kTRUE;
 }
 
 Bool_t AliTRDgtuTMU::CalculateTrackParams(AliTRDtrackGTU *track)
@@ -773,15 +919,9 @@ Bool_t AliTRDgtuTMU::CalculateTrackParams(AliTRDtrackGTU *track)
   AliDebug(10,Form("Sum: a = %5i, b = %9.2f, c = %9.2f\n", a, b, c));
   track->SetFitParams(a, b, c);
 
-  Float_t r = fGtuParam->GetPt(a, b, x1, x2);
-  Int_t pt = (Int_t) (2 * r);
-  if (pt >= 0)
-      pt += 32;
-  else
-      pt -= 29;
-  pt /= 2;
+  Int_t pt = fGtuParam->GetPt(track->GetTrackletMask(), a, b, x1, x2);
   track->SetPtInt(pt);
-  AliDebug(5,Form("Track parameters: a = %i, b = %f, c = %f, x1 = %f, x2 = %f, r = %f, pt = %f (trkl mask: %i)", a, b, c, x1, x2, r, track->GetPt(), track->GetTrackletMask()));
+  AliDebug(5,Form("Track parameters: a = %i, b = %f, c = %f, x1 = %f, x2 = %f, pt = %f (trkl mask: %i)", a, b, c, x1, x2, track->GetPt(), track->GetTrackletMask()));
   return kTRUE;
 }
 
@@ -799,7 +939,7 @@ Bool_t AliTRDgtuTMU::WriteTrackletsToTree(TTree *trklTree)
 
   AliDebug(5,Form("---------- Writing tracklets to tree (not yet) ----------"));
   for (Int_t layer = 0; layer < fGtuParam->GetNLayers(); layer++) {
-    TIter next(fTracklets[layer]);
+    TIter next(fTrackletsPostInput[layer]);
     while ((trkl = (AliTRDtrackletGTU*) next())) {
        AliDebug(10,Form("InputUnit : GetIndex(): %3i, GetZbin(): %2i, GetY() : %5i, GetdY() : %3i, GetYPrime() : %5i, GetYProj() : %5i, GetAlpha() : %3i, Zidx(2..0): %i  %i  %i", trkl->GetIndex(), trkl->GetZbin(), trkl->GetYbin(), trkl->GetdY(), trkl->GetYPrime(), trkl->GetYProj(), trkl->GetAlpha(), trkl->GetSubChannel(2), trkl->GetSubChannel(1), trkl->GetSubChannel(0) ));
        branch->SetAddress(&trkl);
@@ -831,7 +971,7 @@ Bool_t AliTRDgtuTMU::Uniquifier(TList *inlist, TList *outlist)
        }
 
        if (tracksEqual) {
-           if (trkStage0->GetNTracklets() > trkStage1->GetNTracklets())
+           if (trkStage0->GetNTracklets() >= trkStage1->GetNTracklets())
                trkStage1 = trkStage0;
        }
        else {
index 2307dec2da69b2479931bca527249ac5b4d04b5c..0fb6b434d118624c48b886f9b06a56b4c77e846b 100644 (file)
@@ -30,7 +30,7 @@ class AliTRDgtuTMU : public TObject {
   Bool_t SetSector(Int_t sector);
   Bool_t SetStack(Int_t stack);
 
-  Bool_t AddTracklet(AliTRDtrackletBase *tracklet, Int_t link);
+  Bool_t AddTracklet(AliTRDtrackletGTU *tracklet, Int_t link);
   Bool_t WriteTrackletsToTree(TTree *trklTree);
 
   Bool_t RunTMU(TList *ListOfTracks = 0x0, AliESDEvent *esd = 0x0);
@@ -48,7 +48,9 @@ class AliTRDgtuTMU : public TObject {
   Bool_t CalculatePID(AliTRDtrackGTU *track);
 
 protected:
-  TObjArray **fTracklets; // holding all tracklets from one detector (i. e. one chamber)
+  TObjArray **fTracklets; // holding all tracklets per link
+  TObjArray **fTrackletsPostInput; // holding all tracklets of a layer
+                                  // after sorting/calculation in input units
   TList **fZChannelTracklets; // holding all tracklets for layer and z-channel
   TList **fTracks; // lists of tracks
   AliTRDgtuParam *fGtuParam; // pointer to the instance of the GtuParam class
index 9ade791e6340bbeeb935f25a0d884f712642062c..4eaa2b9fb63d3d3da2b1b1a4b48545eb322e37da 100644 (file)
@@ -85,7 +85,7 @@ void AliTRDtrackGTU::AddTracklet(const AliTRDtrackletGTU * const tracklet, Int_t
   fTrackletMask |= (1 << layer);
 }
 
-AliTRDtrackletGTU* AliTRDtrackGTU::GetTracklet(Int_t layer)
+AliTRDtrackletGTU* AliTRDtrackGTU::GetTracklet(Int_t layer) const
 {
 // get a pointer to the tracklet in the layer specified
 
@@ -149,14 +149,28 @@ Int_t AliTRDtrackGTU::GetYapprox()
 
 AliESDTrdTrack* AliTRDtrackGTU::CreateTrdTrack() const
 {
-// creates an AliESDTrdTrack to be added to the ESD
-
-    AliESDTrdTrack *trk = new AliESDTrdTrack();
-    trk->SetPID(fPID);
-    if (fLabel >= 0)
-       trk->SetLabel(fLabel);
+  // creates an AliESDTrdTrack to be added to the ESD
+
+  AliESDTrdTrack *trk = new AliESDTrdTrack();
+  trk->SetA((Int_t) fA);
+  trk->SetLayerMask(fTrackletMask);
+  trk->SetPID(fPID);
+  trk->SetB((Int_t) fB);
+  trk->SetStack(fStack);
+  trk->SetSector(fSector);
+  if (fLabel >= 0)
+    trk->SetLabel(fLabel);
+
+  for (Int_t iLayer = 0; iLayer < AliTRDgtuParam::GetNLayers(); iLayer++) {
+    AliTRDtrackletGTU *trklGTU = GetTracklet(iLayer);
+    if (trklGTU) {
+      AliESDTrdTracklet *trkl = trklGTU->GetTrackletESD();
+      if (trkl)
+       trk->AddTrackletReference(trkl, iLayer);
+    }
+  }
 
-    return trk;
+  return trk;
 }
 
 Bool_t AliTRDtrackGTU::CookLabel()
index fe557d0c4d04f119a9b36bc4d0aece36f93fe1be..812c881ddf224b9c186a05e4413c2cc6d98f05b5 100644 (file)
@@ -36,7 +36,7 @@ class AliTRDtrackGTU : public TObject {
   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);
+  AliTRDtrackletGTU* GetTracklet(Int_t layer) const;
 
 // ----- Quantities used internally for the calculation
   Float_t GetA() const { return fA; }
index 8212286ca7d4e3349a65cb63f1b484a20210df91..cb43782e23b5b020767776f5739802211b5561b6 100644 (file)
@@ -41,8 +41,8 @@ AliTRDtrackletBase* AliTRDtrackletGTU::fgkDummyTracklet = new AliTRDtrackletWord
 AliTRDtrackletGTU::AliTRDtrackletGTU() :
   AliTRDtrackletBase(),
   fGtuParam(AliTRDgtuParam::Instance()),
-  fTracklet(0x0), //fgkDummyTracklet),
-  fSubChannel(0x0),
+  fTracklet(fgkDummyTracklet),
+  fTrackletESD(0x0),
   fAssignedZ(kFALSE),
   fAlpha(0),
   fYProj(0),
@@ -51,7 +51,6 @@ AliTRDtrackletGTU::AliTRDtrackletGTU() :
 {
   // 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;
 }
@@ -59,8 +58,8 @@ AliTRDtrackletGTU::AliTRDtrackletGTU() :
 AliTRDtrackletGTU::AliTRDtrackletGTU(AliTRDtrackletBase *tracklet) :
   AliTRDtrackletBase(*tracklet),
   fGtuParam(AliTRDgtuParam::Instance()),
-  fTracklet(0x0),
-  fSubChannel(0x0),
+  fTracklet(fgkDummyTracklet),
+  fTrackletESD(0x0),
   fAssignedZ(kFALSE),
   fAlpha(0),
   fYProj(0),
@@ -69,7 +68,6 @@ AliTRDtrackletGTU::AliTRDtrackletGTU(AliTRDtrackletBase *tracklet) :
 {
   // 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;
@@ -78,11 +76,28 @@ AliTRDtrackletGTU::AliTRDtrackletGTU(AliTRDtrackletBase *tracklet) :
   }
 }
 
+AliTRDtrackletGTU::AliTRDtrackletGTU(AliESDTrdTracklet *tracklet) :
+  AliTRDtrackletBase(),
+  fGtuParam(AliTRDgtuParam::Instance()),
+  fTracklet(fgkDummyTracklet),
+  fTrackletESD(tracklet),
+  fAssignedZ(kFALSE),
+  fAlpha(0),
+  fYProj(0),
+  fYPrime(0),
+  fIndex(0)
+{
+  // ctor for an AliESDTrdTracklet
+
+  for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++)
+    fSubChannel[zch] = 0;
+}
+
 AliTRDtrackletGTU::AliTRDtrackletGTU(const AliTRDtrackletGTU& tracklet) :
   AliTRDtrackletBase(tracklet),
   fGtuParam(AliTRDgtuParam::Instance()),
   fTracklet(tracklet.fTracklet),
-  fSubChannel(0x0),
+  fTrackletESD(tracklet.fTrackletESD),
   fAssignedZ(tracklet.fAssignedZ),
   fAlpha(tracklet.fAlpha),
   fYProj(tracklet.fYProj),
@@ -91,7 +106,6 @@ AliTRDtrackletGTU::AliTRDtrackletGTU(const AliTRDtrackletGTU& tracklet) :
 {
   // copy ctor
 
-  fSubChannel = new Int_t[fGtuParam->GetNZChannels()];
   for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++)
     fSubChannel[zch] = tracklet.fSubChannel[zch];
 }
@@ -102,6 +116,7 @@ AliTRDtrackletGTU& AliTRDtrackletGTU::operator=(const AliTRDtrackletGTU &rhs)
 
   if (&rhs != this) {
     fTracklet = rhs.fTracklet;
+    fTrackletESD = rhs.fTrackletESD;
     for (Int_t zch = 0; zch < fGtuParam->GetNZChannels(); zch++)
       fSubChannel[zch] = rhs.fSubChannel[zch];
     fIndex = rhs.fIndex;
@@ -117,53 +132,6 @@ AliTRDtrackletGTU& AliTRDtrackletGTU::operator=(const AliTRDtrackletGTU &rhs)
 AliTRDtrackletGTU::~AliTRDtrackletGTU()
 {
   // dtor
-  if (fSubChannel)
-    delete [] fSubChannel;
-  fTracklet = 0x0;
-}
-
-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)
@@ -183,10 +151,12 @@ Int_t AliTRDtrackletGTU::GetLabel() const
 {
   // get the MC label for the tracklet, -1 if none
 
-    if ( fTracklet->IsA() == TClass::GetClass("AliTRDtrackletMCM"))
-       return ((AliTRDtrackletMCM*) fTracklet)->GetLabel();
-    else
-       return -1;
+  if (fTrackletESD)
+    return fTrackletESD->GetLabel();
+  else if ( fTracklet->IsA() == TClass::GetClass("AliTRDtrackletMCM"))
+    return ((AliTRDtrackletMCM*) fTracklet)->GetLabel();
+  else
+    return -1;
 }
 
 /*
index e6744d33ea196d931e5568eed5a5e097752a7a9d..7b169bb8ae6ed27b6f3f02347da13761b6672cf3 100644 (file)
 // --------------------------------------------------------
 
 #include "AliTRDtrackletBase.h"
+#include "AliESDTrdTracklet.h"
+#include "AliTRDgtuParam.h"
 #include "AliLog.h"
 
-class AliTRDgtuParam;
-
 class AliTRDtrackletGTU : public AliTRDtrackletBase {
  public:
   AliTRDtrackletGTU();
   AliTRDtrackletGTU(AliTRDtrackletBase *tracklet);
+  AliTRDtrackletGTU(AliESDTrdTracklet *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(); }
-  Int_t GetPID() const { return ((Int_t) (255 * fTracklet->GetPID())); }
-  Double_t GetPID(Int_t is) const { return fTracklet->GetPID(is); }
+  Int_t GetYbin() const { return fTrackletESD ? fTrackletESD->GetBinY() : fTracklet->GetYbin(); }
+  Int_t GetdY() const { return fTrackletESD ? fTrackletESD->GetBinDy() : fTracklet->GetdY(); }
+  Int_t GetZbin() const { return fTrackletESD ? fTrackletESD->GetBinZ() : fTracklet->GetZbin(); }
+  Int_t GetPID() const { return fTrackletESD ? fTrackletESD->GetPID() : ((Int_t) (256 * fTracklet->GetPID())); }
+  Double_t GetPID(Int_t is) const { return fTracklet ? fTracklet->GetPID(is) : 0.; }
 
   // ----- Getters for calculated properties -----
   Int_t GetYProj() const { return fYProj; }
@@ -45,7 +43,7 @@ class AliTRDtrackletGTU : public AliTRDtrackletBase {
 
   // ----- Getters for offline corresponding values -----
   Bool_t CookPID() { return kFALSE; }
-  Int_t GetDetector() const { return fTracklet->GetDetector(); }
+  Int_t GetDetector() const { return fTrackletESD ? fTrackletESD->GetDetector() : fTracklet->GetDetector(); }
   Int_t GetIndex() const { return fIndex; }
 
   Float_t GetdYdX() const { return (GetdY() * 140e-4 / 3.); }
@@ -53,8 +51,9 @@ class AliTRDtrackletGTU : public AliTRDtrackletBase {
   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(); }
+  AliTRDtrackletBase* GetTracklet() const { return fTracklet; }
+  AliESDTrdTracklet* GetTrackletESD() const { return fTrackletESD; }
+  UInt_t GetTrackletWord() const { return fTrackletESD ? fTrackletESD->GetTrackletWord() : fTracklet->GetTrackletWord(); }
 
   Int_t GetSide() const { return GetYbin() < 0 ? 0 : 1; }
 
@@ -73,9 +72,10 @@ class AliTRDtrackletGTU : public AliTRDtrackletBase {
 
  protected:
   AliTRDgtuParam *fGtuParam;    //!
-  AliTRDtrackletBase *fTracklet; // pointer to the underlying tracklet
+  AliTRDtrackletBase *fTracklet;    //! pointer to the underlying tracklet
+  AliESDTrdTracklet  *fTrackletESD; //! pointer to the underlying ESD tracklet
 
-  Int_t *fSubChannel;          //! [AliTRDgtuParam::GetNZChannels()]
+  Int_t  fSubChannel[AliTRDgtuParam::fgkNZChannels]; // z-channel assignments
   Bool_t fAssignedZ;           // tracklet assigned to a Z-channel
 
   Int_t fAlpha;                        // calculated value for alpha
@@ -87,7 +87,7 @@ class AliTRDtrackletGTU : public AliTRDtrackletBase {
 
  private:
 
-  ClassDef(AliTRDtrackletGTU, 1);
+  ClassDef(AliTRDtrackletGTU, 0);
 };
 
 #endif