Adding TRD trigger (B.Vulpescu)
authorhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 3 Apr 2006 14:53:09 +0000 (14:53 +0000)
committerhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 3 Apr 2006 14:53:09 +0000 (14:53 +0000)
21 files changed:
STEER/AliESD.cxx
STEER/AliESD.h
STEER/AliESDTrdTrack.cxx [new file with mode: 0644]
STEER/AliESDTrdTrack.h [new file with mode: 0644]
STEER/AliEventTag.cxx
STEER/ESDLinkDef.h
STEER/libESD.pkg
TRD/AliTRDReconstructor.cxx
TRD/AliTRDmcm.cxx [new file with mode: 0644]
TRD/AliTRDmcm.h [new file with mode: 0644]
TRD/AliTRDmcmTracklet.cxx [new file with mode: 0644]
TRD/AliTRDmcmTracklet.h [new file with mode: 0644]
TRD/AliTRDtrigParam.cxx [new file with mode: 0644]
TRD/AliTRDtrigParam.h [new file with mode: 0644]
TRD/AliTRDtrigger.cxx [new file with mode: 0644]
TRD/AliTRDtrigger.h [new file with mode: 0644]
TRD/AliTRDzmaps.h [new file with mode: 0644]
TRD/Calib/PIDLQ/Run0_0_v0_s1.root [new file with mode: 0644]
TRD/TRDdEdxHistogramsV1_BV.root [new file with mode: 0644]
TRD/TRDrecLinkDef.h
TRD/libTRDrec.pkg

index 1c80105..4e96fac 100644 (file)
@@ -35,9 +35,9 @@ AliESD::AliESD():
   fMagneticField(0),
   fZDCN1Energy(0),
   fZDCP1Energy(0),
-  fZDCEMEnergy(0),
   fZDCN2Energy(0),
   fZDCP2Energy(0),
+  fZDCEMEnergy(0),
   fZDCParticipants(0),
   fT0zVertex(0),
   fPrimaryVertex(),
@@ -46,6 +46,7 @@ AliESD::AliESD():
   fHLTHoughTracks("AliESDHLTtrack",15000),
   fMuonTracks("AliESDMuonTrack",30),
   fPmdTracks("AliESDPmdTrack",3000),
+  fTrdTracks("AliESDTrdTrack",300),
   fV0s("AliESDv0",200),  
   fCascades("AliESDcascade",20),
   fKinks("AliESDkink",4000),
@@ -71,6 +72,7 @@ AliESD::~AliESD()
   fHLTHoughTracks.Delete();
   fMuonTracks.Delete();
   fPmdTracks.Delete();
+  fTrdTracks.Delete();
   fV0s.Delete();
   fCascades.Delete();
   fKinks.Delete();
@@ -109,9 +111,9 @@ void AliESD::Reset()
   fMagneticField=0;
   fZDCN1Energy=0;
   fZDCP1Energy=0;
-  fZDCEMEnergy=0;
   fZDCN2Energy=0;
   fZDCP2Energy=0;
+  fZDCEMEnergy=0;
   fZDCParticipants=0;
   fT0zVertex=0;
   fPrimaryVertex.Reset();
@@ -120,6 +122,7 @@ void AliESD::Reset()
   fHLTHoughTracks.Clear();
   fMuonTracks.Clear();
   fPmdTracks.Clear();
+  fTrdTracks.Clear();
   fV0s.Clear();
   fCascades.Clear();
   fCaloClusters.Clear();
@@ -155,6 +158,7 @@ void AliESD::Print(Option_t *) const
   printf("                 emcal     %d\n", GetNumberOfEMCALClusters());
   printf("                 muon      %d\n", GetNumberOfMuonTracks());
   printf("                 pmd       %d\n", GetNumberOfPmdTracks());
+  printf("                 trd       %d\n", GetNumberOfTrdTracks());
   printf("                 v0        %d\n", GetNumberOfV0s());
   printf("                 cascades  %d\n)", GetNumberOfCascades());
   printf("                 kinks     %d\n)", GetNumberOfKinks());
index ebc0f6e..fc6c304 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "AliESDMuonTrack.h"
 #include "AliESDPmdTrack.h"
+#include "AliESDTrdTrack.h"
 #include "AliESDVertex.h"
 #include "AliESDcascade.h"
 #include "AliESDkink.h"
@@ -55,6 +56,9 @@ public:
   AliESDPmdTrack *GetPmdTrack(Int_t i) const {
     return (AliESDPmdTrack *)fPmdTracks.UncheckedAt(i);
   }
+  AliESDTrdTrack *GetTrdTrack(Int_t i) const {
+    return (AliESDTrdTrack *)fTrdTracks.UncheckedAt(i);
+  }
 
   Int_t  AddTrack(const AliESDtrack *t) {
     AliESDtrack * track = new(fTracks[fTracks.GetEntriesFast()]) AliESDtrack(*t);
@@ -74,6 +78,9 @@ public:
   void AddPmdTrack(const AliESDPmdTrack *t) {
     new(fPmdTracks[fPmdTracks.GetEntriesFast()]) AliESDPmdTrack(*t);
   }
+  void AddTrdTrack(const AliESDTrdTrack *t) {
+    new(fTrdTracks[fTrdTracks.GetEntriesFast()]) AliESDTrdTrack(*t);
+  }
 
   AliESDv0 *GetV0(Int_t i) const {
     return (AliESDv0 *)fV0s.UncheckedAt(i);
@@ -131,6 +138,7 @@ public:
   Int_t GetNumberOfHLTHoughTracks()     const {return fHLTHoughTracks.GetEntriesFast();}
   Int_t GetNumberOfMuonTracks() const {return fMuonTracks.GetEntriesFast();}
   Int_t GetNumberOfPmdTracks() const {return fPmdTracks.GetEntriesFast();}
+  Int_t GetNumberOfTrdTracks() const {return fTrdTracks.GetEntriesFast();}
   Int_t GetNumberOfV0s()      const {return fV0s.GetEntriesFast();}
   Int_t GetNumberOfCascades() const {return fCascades.GetEntriesFast();}
   Int_t GetNumberOfKinks() const {return fKinks.GetEntriesFast();}
@@ -197,6 +205,7 @@ protected:
   TClonesArray fHLTHoughTracks;  // HLT ESD tracks from Hough Transform method
   TClonesArray fMuonTracks;      // MUON ESD tracks
   TClonesArray fPmdTracks;       // PMD ESD tracks
+  TClonesArray fTrdTracks;       // TRD ESD tracks (triggered)
   TClonesArray fV0s;             // V0 vertices
   TClonesArray fCascades;        // Cascade vertices
   TClonesArray fKinks;           // Kinks
diff --git a/STEER/AliESDTrdTrack.cxx b/STEER/AliESDTrdTrack.cxx
new file mode 100644 (file)
index 0000000..0c9449c
--- /dev/null
@@ -0,0 +1,101 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// The TRD trigger stores the found tracks as ESDTrdTrack objects in the ESD 
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "AliESDTrdTrack.h"
+
+ClassImp(AliESDTrdTrack)
+
+//_____________________________________________________________________________
+AliESDTrdTrack::AliESDTrdTrack():
+  TObject(),
+  fYproj(0),
+  fZproj(0),
+  fSlope(0),
+  fDetector(-1),
+  fNtracklets(0),
+  fNplanes(0),
+  fNclusters(0),
+  fPt(0),
+  fPhi(0),
+  fEta(0),
+  fLabel(-1),
+  fPID(0),
+  fIsElectron(kFALSE)
+{
+
+  //
+  // Default constructor
+  //
+
+}
+
+//_____________________________________________________________________________
+AliESDTrdTrack::AliESDTrdTrack(const AliESDTrdTrack& track):
+  TObject(track),
+  fYproj(track.fYproj),
+  fZproj(track.fZproj),
+  fSlope(track.fSlope),
+  fDetector(track.fDetector),
+  fNtracklets(track.fNtracklets),
+  fNplanes(track.fNplanes),
+  fNclusters(track.fNclusters),
+  fPt(track.fPt),
+  fPhi(track.fPhi),
+  fEta(track.fEta),
+  fLabel(track.fLabel),
+  fPID(track.fPID),
+  fIsElectron(track.fIsElectron)
+{
+
+  //
+  // Copy contructor
+  //
+
+}
+
+//_____________________________________________________________________________
+AliESDTrdTrack& AliESDTrdTrack::operator=(const AliESDTrdTrack& track)
+{
+  // 
+  // Equal operator
+  //
+
+  if (this == &track)
+    return *this;
+
+  fYproj      = track.fYproj;
+  fZproj      = track.fZproj;
+  fSlope      = track.fSlope;
+  fDetector   = track.fDetector;
+  fNtracklets = track.fNtracklets;
+  fNplanes    = track.fNplanes;
+  fNclusters  = track.fNclusters;
+  fPt         = track.fPt;
+  fPhi        = track.fPhi;
+  fEta        = track.fEta;
+  fLabel      = track.fLabel;
+  fPID        = track.fPID;
+  fIsElectron = track.fIsElectron;
+
+  return *this;
+
+}
+
diff --git a/STEER/AliESDTrdTrack.h b/STEER/AliESDTrdTrack.h
new file mode 100644 (file)
index 0000000..248f85f
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef ALIESDTRDTRACK_H
+#define ALIESDTRDTRACK_H
+
+//
+//  Tracks from the TRD Global Tracking Unit (GTU, trigger)
+//  
+
+#include "TObject.h"
+
+class AliESDTrdTrack : public TObject {
+
+ public:
+
+  AliESDTrdTrack();
+  virtual ~AliESDTrdTrack(){};
+  AliESDTrdTrack(const AliESDTrdTrack& track);
+  AliESDTrdTrack& operator=(const AliESDTrdTrack& track);
+
+  Float_t GetYproj()     { return fYproj; };
+  Float_t GetZproj()     { return fZproj; };
+  Float_t GetSlope()     { return fSlope; };
+  Int_t   GetDetector()  { return fDetector; };
+  Int_t   GetTracklets() { return fNtracklets; };
+  Int_t   GetPlanes()    { return fNplanes; };
+  Int_t   GetClusters()  { return fNclusters; };
+  Float_t GetPt()        { return fPt; };
+  Float_t GetPhi()       { return fPhi; };
+  Float_t GetEta()       { return fEta; };
+  Int_t   GetLabel()     { return fLabel; };
+  Float_t GetPID()       { return fPID; };
+  Bool_t  IsElectron()   { return fIsElectron; }
+
+  void SetYproj(Float_t val)     { fYproj = val; };
+  void SetZproj(Float_t val)     { fZproj = val; };
+  void SetSlope(Float_t val)     { fSlope = val; };
+  void SetDetector(Int_t det)    { fDetector = det; };
+  void SetTracklets(Int_t val)   { fNtracklets = val; };
+  void SetPlanes(Int_t val)      { fNplanes = val; };
+  void SetClusters(Int_t val)    { fNclusters = val; };
+  void SetPt(Float_t val)        { fPt = val; };
+  void SetPhi(Float_t val)       { fPhi = val; };
+  void SetEta(Float_t val)       { fEta = val; };
+  void SetLabel(Int_t val)       { fLabel = val; };
+  void SetPID(Float_t val)       { fPID = val; };
+  void SetIsElectron(Bool_t val) { fIsElectron = val; };
+
+ protected:
+
+  Float_t fYproj;                                   // Average values calculated
+  Float_t fZproj;                                   // from the tracklets 
+  Float_t fSlope;                                   //
+  Int_t   fDetector;                                // First detector in the module
+  Int_t   fNtracklets;                              // Number of tracklets
+  Int_t   fNplanes;                                 // Number of TRD planes
+  Int_t   fNclusters;                               // Total number of clusters
+  Float_t fPt;                                      // Transverse momentum
+  Float_t fPhi;                                     // Phi angle at the vertex
+  Float_t fEta;                                     // Eta at the vertex
+  Int_t   fLabel;                                   // Track label
+  Float_t fPID;                                     // PID electron likelihood
+  Bool_t  fIsElectron;                              // Electron flag
+
+  ClassDef(AliESDTrdTrack,1)
+
+};
+
+#endif
index 5107b01..154d564 100644 (file)
@@ -43,9 +43,9 @@ ClassImp(AliEventTag)
     fTriggerInfo(-10),
     fZDCNeutron1Energy(-10.0),
     fZDCProton1Energy(-10.0),
-    fZDCEMEnergy(-10.0),
     fZDCNeutron2Energy(-10.0),
     fZDCProton2Energy(-10.0),
+    fZDCEMEnergy(-10.0),
     fT0VertexZ(-10.0),
     fNumberOfTracks(-10),
     fNumberOfPositiveTracks(-10),
index d9fabc3..d366084 100644 (file)
@@ -14,6 +14,7 @@
 #pragma link C++ class  AliESDtrack+;
 #pragma link C++ class  AliESDMuonTrack+;
 #pragma link C++ class  AliESDPmdTrack+;
+#pragma link C++ class  AliESDTrdTrack+;
 #pragma link C++ class  AliESDHLTtrack+;
 #pragma link C++ class  AliESDv0+;
 #pragma link C++ class  AliESDcascade+;
index b296b36..67b028c 100644 (file)
@@ -1,6 +1,6 @@
 SRCS = AliESD.cxx \
        AliESDtrack.cxx \
-       AliESDMuonTrack.cxx AliESDPmdTrack.cxx AliESDHLTtrack.cxx \
+       AliESDMuonTrack.cxx AliESDPmdTrack.cxx AliESDTrdTrack.cxx AliESDHLTtrack.cxx \
        AliESDv0.cxx AliESDcascade.cxx AliVertex.cxx AliESDVertex.cxx \
        AliESDpid.cxx AliESDkink.cxx AliESDV0MI.cxx \
        AliESDCaloCluster.cxx \
index 6ef4923..501081a 100644 (file)
 #include <TFile.h>
 #include "AliRawReader.h"
 #include "AliLog.h"
+#include "AliTRDtrigger.h"
+#include "AliTRDtrigParam.h"
+#include "AliRun.h"
+#include "AliESDTrdTrack.h"
+#include "AliESD.h"
 
 ClassImp(AliTRDReconstructor)
 
@@ -56,6 +61,34 @@ void AliTRDReconstructor::Reconstruct(AliRunLoader* runLoader) const
   }
 
   loader->UnloadRecPoints();
+
+  // Trigger (tracklets, LTU)
+
+  AliTRDtrigger trdTrigger("Trigger","Trigger class"); 
+
+  AliTRDtrigParam *trigp = new AliTRDtrigParam("TRDtrigParam","TRD Trigger parameters");
+
+  if (runLoader->GetAliRun() == 0x0) runLoader->LoadgAlice();
+  gAlice = runLoader->GetAliRun();
+  Double_t x[3] = { 0.0, 0.0, 0.0 };
+  Double_t b[3];
+  gAlice->Field(x,b);  // b[] is in kilo Gauss
+  Float_t field = b[2] * 0.1; // Tesla
+  Info("Reconstruct","Trigger set for magnetic field = %f Tesla \n",field);
+
+  trigp->SetField(field);
+  trigp->Init();
+  trdTrigger.SetParameter(trigp);
+
+  for (Int_t iEvent = 0; iEvent < nEvents; iEvent++) {
+    trdTrigger.Open(runLoader->GetFileName(), iEvent);
+    trdTrigger.ReadDigits();
+    trdTrigger.MakeTracklets();
+    trdTrigger.WriteTracklets(-1);
+  }
+
+  loader->UnloadTracks();
+
 }
 
 //_____________________________________________________________________________
@@ -82,6 +115,34 @@ void AliTRDReconstructor::Reconstruct(AliRunLoader* runLoader,
   }
 
   loader->UnloadRecPoints();
+
+  // Trigger (tracklets, LTU)
+
+  AliTRDtrigger trdTrigger("Trigger","Trigger class"); 
+
+  AliTRDtrigParam *trigp = new AliTRDtrigParam("TRDtrigParam","TRD Trigger parameters");
+
+  if (runLoader->GetAliRun() == 0x0) runLoader->LoadgAlice();
+  gAlice = runLoader->GetAliRun();
+  Double_t x[3] = { 0.0, 0.0, 0.0 };
+  Double_t b[3];
+  gAlice->Field(x,b);  // b[] is in kilo Gauss
+  Float_t field = b[2] * 0.1; // Tesla
+  Info("Reconstruct","Trigger set for magnetic field = %f Tesla \n",field);
+
+  trigp->SetField(field);
+  trigp->Init();
+  trdTrigger.SetParameter(trigp);
+
+  for (Int_t iEvent = 0; iEvent < nEvents; iEvent++) {
+    trdTrigger.Open(runLoader->GetFileName(), iEvent);
+    trdTrigger.ReadDigits(rawReader);
+    trdTrigger.MakeTracklets();
+    trdTrigger.WriteTracklets(-1);
+  }
+
+  loader->UnloadTracks();
+
 }
 
 //_____________________________________________________________________________
@@ -94,7 +155,7 @@ AliTracker* AliTRDReconstructor::CreateTracker(AliRunLoader* runLoader) const
 }
 
 //_____________________________________________________________________________
-void AliTRDReconstructor::FillESD(AliRunLoader* /*runLoader*/, 
+void AliTRDReconstructor::FillESD(AliRunLoader* runLoader, 
                                  AliESD* esd) const
 {
 // make PID
@@ -106,6 +167,57 @@ void AliTRDReconstructor::FillESD(AliRunLoader* /*runLoader*/,
   };
   AliTRDpidESD trdPID(parTRD);
   trdPID.MakePID(esd);
+
+  // Trigger (tracks, GTU)
+
+  AliTRDtrigger trdTrigger("Trigger","Trigger class"); 
+
+  AliTRDtrigParam *trigp = new AliTRDtrigParam("TRDtrigParam","TRD Trigger parameters");
+
+  if (runLoader->GetAliRun() == 0x0) runLoader->LoadgAlice();
+  gAlice = runLoader->GetAliRun();
+  Double_t x[3] = { 0.0, 0.0, 0.0 };
+  Double_t b[3];
+  gAlice->Field(x,b);  // b[] is in kilo Gauss
+  Float_t field = b[2] * 0.1; // Tesla
+  Info("FillESD","Trigger set for magnetic field = %f Tesla \n",field);
+
+  trigp->SetField(field);
+  trigp->Init();
+
+  trdTrigger.SetParameter(trigp);
+  trdTrigger.SetRunLoader(runLoader);
+  trdTrigger.Init();
+
+  Int_t iEvent = runLoader->GetEventNumber(); 
+  runLoader->GetEvent(iEvent);
+  trdTrigger.ReadTracklets(runLoader);
+
+  AliESDTrdTrack *TrdTrack = new AliESDTrdTrack();
+  AliTRDgtuTrack *GtuTrack;
+
+  Int_t nTracks = trdTrigger.GetNumberOfTracks();
+  for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
+
+    GtuTrack = trdTrigger.GetTrack(iTrack);
+
+    TrdTrack->SetYproj(GtuTrack->GetYproj());
+    TrdTrack->SetZproj(GtuTrack->GetZproj());
+    TrdTrack->SetSlope(GtuTrack->GetSlope());
+    TrdTrack->SetDetector(GtuTrack->GetDetector());
+    TrdTrack->SetTracklets(GtuTrack->GetTracklets());
+    TrdTrack->SetPlanes(GtuTrack->GetPlanes());
+    TrdTrack->SetClusters(GtuTrack->GetClusters());
+    TrdTrack->SetPt(GtuTrack->GetPt());
+    TrdTrack->SetPhi(GtuTrack->GetPhi());
+    TrdTrack->SetEta(GtuTrack->GetEta());
+    TrdTrack->SetLabel(GtuTrack->GetLabel());
+    TrdTrack->SetPID(GtuTrack->GetPID());
+
+    esd->AddTrdTrack(TrdTrack);
+
+  }
+
 }
 
 
diff --git a/TRD/AliTRDmcm.cxx b/TRD/AliTRDmcm.cxx
new file mode 100644 (file)
index 0000000..2e751da
--- /dev/null
@@ -0,0 +1,802 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/*
+$Log$
+Revision 1.1.1.1  2004/08/19 14:58:11  vulpescu
+CVS head
+
+Revision 1.1.1.1  2004/08/18 07:47:17  vulpescu
+test
+
+*/
+
+#include <TMath.h>
+#include <TH2F.h>
+
+#include "AliTRDmcm.h"
+#include "AliTRDtrigParam.h"
+
+ClassImp(AliTRDmcm)
+
+//_____________________________________________________________________________
+AliTRDmcm::AliTRDmcm() 
+{
+
+  //
+  // AliTRDmcm default constructor
+  //
+
+  fTrigParam = 0;
+
+  fNtrk = 0;
+  for (Int_t i = 0; i < kMaxTrackletsPerMCM; i++) {
+    fTrkIndex[i] = 0;
+  }
+  fRobId = 0;
+  fChaId = 0;
+  fRow = 0;
+  fColFirst = 0;
+  fColLast = 0;
+  for (Int_t i = 0; i < kMcmCol; i++) {
+    fPadHits[i] = 0;
+    for (Int_t j = 0; j < kMcmTBmax; j++) {
+      fADC[i][j] = 0.0;
+      fIsClus[i][j] = kFALSE;
+    }
+  }
+  fPadThr = 0;
+  fClusThr = 0;
+  fTime1 = 0;
+  fTime2 = 0;
+  fNtrkSeeds = 0;
+  for (Int_t i = 0; i < kMaxTrackletsPerMCM; i++) {
+    fSeedCol[i] = -1;
+  }
+
+  fR1 = 0.0;
+  fR2 = 0.0;
+  fC1 = 0.0;
+  fC2 = 0.0;
+  fPedestal = 0.0;
+
+  fId = 0;
+
+}
+
+//_____________________________________________________________________________
+AliTRDmcm::AliTRDmcm(AliTRDtrigParam *trigp, const Int_t id) 
+{
+  //
+  // AliTRDmcm constructor
+  //
+
+  fTrigParam = trigp;
+
+  fNtrk = 0;
+  for (Int_t i = 0; i < kMaxTrackletsPerMCM; i++) {
+    fTrkIndex[i] = 0;
+  }
+  fRobId = 0;
+  fChaId = 0;
+  fRow = 0;
+  fColFirst = 0;
+  fColLast = 0;
+  for (Int_t i = 0; i < kMcmCol; i++) {
+    fPadHits[i] = 0;
+    for (Int_t j = 0; j < kMcmTBmax; j++) {
+      fADC[i][j] = 0.0;
+      fIsClus[i][j] = kFALSE;
+    }
+  }
+  fPadThr  = fTrigParam->GetPadThr();
+  fClusThr = fTrigParam->GetClusThr();
+  fTime1 = fTrigParam->GetTime1();
+  fTime2 = fTrigParam->GetTime2();
+  fNtrkSeeds = 0;
+  for (Int_t i = 0; i < kMaxTrackletsPerMCM; i++) {
+    fSeedCol[i] = -1;
+  }
+  
+  fR1 = 0.0;
+  fR2 = 0.0;
+  fC1 = 0.0;
+  fC2 = 0.0;
+  fPedestal = 0.0;
+
+  fTrigParam->GetFilterParam(fR1,fR2,fC1,fC2,fPedestal);
+
+  fId = id;
+
+}
+
+//_____________________________________________________________________________
+AliTRDmcm::~AliTRDmcm() 
+{
+
+  //
+  // AliTRDmcm destructor
+  //
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmcm::AddTrk(const Int_t id) 
+{
+  //
+  // Add a tracklet index
+  //
+
+  fTrkIndex[fNtrk] = id;
+  fNtrk++;
+
+  return;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmcm::Reset()
+{
+  //
+  // Reset MCM data
+  //
+
+  for (Int_t i = 0; i < kMcmCol; i++) {
+    fPadHits[i] = 0;
+    for (Int_t j = 0; j < kMcmTBmax; j++) {
+      fADC[i][j] = 0.0;
+      fIsClus[i][j] = kFALSE;
+    }
+  }
+  for (Int_t i = 0; i < kMaxTrackletsPerMCM; i++) {
+    fSeedCol[i] = -1;
+  }
+  
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDmcm::Run()
+{
+  //
+  // Run MCM
+  //
+
+  if ( fTrigParam->GetDebugLevel() > 1 ) printf("AliTRDmcm::Run MCM %d\n",Id());
+
+  Float_t Amp[3] = {0.0, 0.0, 0.0};
+  Int_t   nClus;
+  Int_t   ClusCol[kMcmCol/2];
+  Float_t ClusAmp[kMcmCol/2];
+  Float_t VeryLarge;
+  Int_t   ClusMin = -1;
+  
+  for (Int_t iTime = fTime1; iTime <= fTime2; iTime++) {  // main TB loop
+
+    // find clusters...
+    nClus = 0;
+    for (Int_t iCol = 1; iCol < (kMcmCol-1); iCol++) {
+      Amp[0] = fADC[iCol-1][iTime];
+      Amp[1] = fADC[iCol  ][iTime];
+      Amp[2] = fADC[iCol+1][iTime];
+      if (IsCluster(Amp)) {
+       fIsClus[iCol][iTime] = kTRUE;
+       ClusCol[nClus] = iCol;
+       ClusAmp[nClus] = Amp[0]+Amp[1]+Amp[2];
+       nClus++;
+       if (nClus == kMcmCol/2) {
+         printf("Too many clusters in time bin %2d MCM %d...\n",iTime,Id());
+         //return kFALSE;
+         break;
+       }
+      }
+    }
+
+    // ...but no more than six...
+    if (nClus > (Int_t)kSelClus) {
+      for (Int_t j = kSelClus/2; j < nClus-kSelClus/2; j++) {
+       fIsClus[ClusCol[j]][iTime] = kFALSE;
+      } 
+    }
+
+    // ...and take the largest four.
+
+    Int_t nClusPlus = nClus - kMaxClus;
+    for (Int_t iPlus = 0; iPlus < nClusPlus; iPlus++ ) {
+      VeryLarge = 1.E+10;
+      for (Int_t i = 0; i < nClus; i++) {
+       if (fIsClus[ClusCol[i]][iTime]) {
+         if (ClusAmp[i] <= VeryLarge) {
+           VeryLarge = ClusAmp[i];
+           ClusMin = i;
+         }
+       }
+      }
+      fIsClus[ClusCol[ClusMin]][iTime] = kFALSE;
+    }
+
+    AddTimeBin(iTime);
+
+  }  // end main TB loop
+  
+  if (fTrigParam->GetDebugLevel() > 1) {
+    for (Int_t i = fTime1; i <= fTime2; i++) {
+      printf("%2d: ",i);
+      for (Int_t j = 0; j < kMcmCol; j++) {
+       printf("%1d ",fIsClus[j][i]);
+      }
+      printf("\n");
+    }
+    printf("PadHits:     ");
+    for (Int_t iPad = 0; iPad < kMcmCol; iPad++) {
+      printf("%2d ",fPadHits[iPad]);
+    }
+    printf("\n");
+  }
+  
+  if ((fNtrkSeeds = CreateSeeds())) {
+
+    return kTRUE;
+
+  }
+
+  return kFALSE;
+
+}
+//_____________________________________________________________________________
+Int_t AliTRDmcm::CreateSeeds()
+{
+  //
+  // Make column seeds (from Falk Lesser, ex KIP)
+  //
+
+  if ( fTrigParam->GetDebugLevel() > 1 ) printf("AliTRDmcm::CreateSeeds MCM %d \n",Id());
+
+  Int_t nSeeds = 0;
+
+  // working array for hit sums
+  Int_t fHit2padSum[2][kMcmCol];            
+
+  // initialize the array
+  for( Int_t i = 0; i < 2; i++ ) {
+    for( Int_t j = 0; j < kMcmCol; j++ ) {
+      if( i == 0 ) {
+       fHit2padSum[i][j] = j; 
+      } else {
+       fHit2padSum[i][j] = -1; 
+      }
+    }
+  }
+
+  Int_t Sum10 = fTrigParam->GetSum10();
+  Int_t Sum12 = fTrigParam->GetSum12();
+
+  // build the 2padSum
+  Int_t Nsum2seed = 0;
+  for( Int_t i = 0; i < kMcmCol; i++ ) {
+    if( i < (kMcmCol-1) ) {
+      if( (fPadHits[i] >= Sum10) && ((fPadHits[i] + fPadHits[i+1]) >= Sum12) ) {
+       fHit2padSum[1][i] = fPadHits[i] + fPadHits[i+1]; 
+      } else {
+       fHit2padSum[1][i] = -1;
+      }
+    } else {
+      if ( fPadHits[i] >= Sum12 ) {
+       fHit2padSum[1][i] = fPadHits[i]; 
+      } else {
+       fHit2padSum[1][i] = -1;
+      }
+    }
+    if (fHit2padSum[1][i] > 0) Nsum2seed++;
+  }
+
+  if (fTrigParam->GetDebugLevel() > 1) {
+    printf("fHit2padSum: ");
+    for( Int_t i = 0; i < kMcmCol; i++ ) {
+      printf("%2d ",fHit2padSum[0][i]);
+    }
+    printf("\n");
+    printf("             ");
+    for( Int_t i = 0; i < kMcmCol; i++ ) {
+      printf("%2d ",fHit2padSum[1][i]);
+    }
+    printf("\n");
+  }
+
+  // sort the sums in decreasing order of the amplitude        
+  Sort(kMcmCol,&fHit2padSum[0][0],&fHit2padSum[1][0],1);
+
+  if (fTrigParam->GetDebugLevel() > 1) {
+    printf("fHit2padSum: ");
+    for( Int_t i = 0; i < kMcmCol; i++ ) {
+      printf("%2d ",fHit2padSum[0][i]);
+    }
+    printf("\n");
+    printf("             ");
+    for( Int_t i = 0; i < kMcmCol; i++ ) {
+      printf("%2d ",fHit2padSum[1][i]);
+    }
+    printf("\n");
+  }
+
+  // arrange (maximum number of) candidates in increasing order of the column number
+  nSeeds = TMath::Min(Nsum2seed,kMaxTrackletsPerMCM);
+  Sort(nSeeds,&fHit2padSum[1][0],&fHit2padSum[0][0],0);
+
+  for (Int_t i = 0; i < nSeeds; i++) {
+    fSeedCol[i] = fHit2padSum[0][i];
+  }
+
+  if (fTrigParam->GetDebugLevel() > 1) {
+    printf("Found %d seeds before multiple rejection. \n",nSeeds);
+    printf("fHit2padSum: ");
+    for( Int_t i = 0; i < kMcmCol; i++ ) {
+      printf("%2d ",fHit2padSum[0][i]);
+    }
+    printf("\n");
+    printf("             ");
+    for( Int_t i = 0; i < kMcmCol; i++ ) {
+      printf("%2d ",fHit2padSum[1][i]);
+    }
+    printf("\n");
+  }
+
+  // reject multiple found tracklets
+  Int_t imax = nSeeds-1;
+  for (Int_t i = 0; i < imax; i++) {
+
+    if ((fHit2padSum[0][i]+1) == fHit2padSum[0][i+1]) {
+      nSeeds--;
+      if (fHit2padSum[1][i] >= fHit2padSum[1][i+1]) {
+       if (fTrigParam->GetDebugLevel() > 1) 
+         printf("Reject seed %1d in col %02d. \n",i,fHit2padSum[0][i+1]);
+       fSeedCol[i+1] = -1;
+      } else {
+       if (fTrigParam->GetDebugLevel() > 1) 
+         printf("Reject seed %1d in col %02d. \n",i,fHit2padSum[0][i]);
+       fSeedCol[i] = -1;
+      }
+    }
+
+  }
+
+  if ( fTrigParam->GetDebugLevel() > 1 ) {
+    printf("Found %d seeds in MCM %d ",nSeeds,Id());
+    for (Int_t i = 0; i < (imax+1); i++) {
+      if (fSeedCol[i] >= 0) printf(", %02d ",fSeedCol[i]);
+    }
+    printf("\n");
+  }
+
+  return nSeeds;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmcm::Sort(Int_t nel, Int_t *x1, Int_t *x2, Int_t dir)
+{
+
+  // Sort two parallel vectors (x1[nel], x2[nel]) after the second one (x2)
+  // in the direction: dir = 0 ascending order
+  //                   dir = 1 descending order
+
+  Bool_t sort;
+  Int_t tmp1, tmp2;
+
+  if ( dir == 0 ) {
+
+    do { 
+      sort = kTRUE;
+      for ( Int_t i = 0; i < (nel-1); i++ )
+       if ( x2[i+1] < x2[i] ) {
+         tmp2 = x2[i]; 
+         x2[i] = x2[i+1]; 
+         x2[i+1] = tmp2;
+         tmp1 = x1[i]; 
+         x1[i] = x1[i+1]; 
+         x1[i+1] = tmp1;
+         sort = kFALSE;
+       }
+    } while ( sort == kFALSE );
+
+  }
+
+  if ( dir == 1 ) {
+
+    do { 
+      sort = kTRUE;
+      for ( Int_t i = 0; i < (nel-1); i++ )
+       if ( x2[i+1] > x2[i] ) {
+         tmp2 = x2[i]; 
+         x2[i] = x2[i+1]; 
+         x2[i+1] = tmp2;
+         tmp1 = x1[i]; 
+         x1[i] = x1[i+1]; 
+         x1[i+1] = tmp1;
+         sort = kFALSE;
+       }
+    } while ( sort == kFALSE );
+
+  }
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmcm::AddTimeBin(const Int_t iTime)
+{
+  //
+  // Build column seeds
+  //
+
+  for (Int_t iPad = 1; iPad < (kMcmCol-1); iPad++) {
+    if (fIsClus[iPad][iTime]) {
+      fPadHits[iPad]++;
+    }
+  }
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDmcm::IsCluster(Float_t amp[3])
+{
+  //
+  // Find if the amplitudes amp[0], amp[1], amp[2] are a cluster
+  //
+
+  // -> shape
+  if (amp[0] > amp[1] || amp[2] > amp[1]) return kFALSE;
+
+  // -> cluster amplitude
+  if ((amp[0]+amp[1]+amp[2]) < fClusThr) return kFALSE;
+
+  // -> pad amplitude
+  if (amp[0] < fPadThr && amp[2] < fPadThr) return kFALSE;
+
+  return kTRUE;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmcm::Filter(Int_t nexp, Int_t ftype)
+{
+  //
+  // exponential filter
+  //
+
+  Double_t sour[kMcmTBmax];
+  Double_t Dtarg[kMcmTBmax];
+  Int_t    Itarg[kMcmTBmax];
+
+  switch(ftype) {
+
+  case 0:
+
+    for (Int_t iCol = 0; iCol < kMcmCol; iCol++) {
+      for (Int_t iTime = 0; iTime < kMcmTBmax; iTime++) {
+       sour[iTime] = fADC[iCol][iTime];
+      }
+      DeConvExpA(sour,Dtarg,kMcmTBmax,nexp);
+      for (Int_t iTime = 0; iTime < kMcmTBmax; iTime++) {
+       //fADC[iCol][iTime] = (Int_t)TMath::Max(0.0,Dtarg[iTime]);
+       fADC[iCol][iTime] = TMath::Max(0.0,Dtarg[iTime]);
+      }
+    }
+    break;
+
+  case 1:
+
+    for (Int_t iCol = 0; iCol < kMcmCol; iCol++) {
+      for (Int_t iTime = 0; iTime < kMcmTBmax; iTime++) {
+       sour[iTime] = fADC[iCol][iTime];
+      }
+      DeConvExpD(sour,Itarg,kMcmTBmax,nexp);
+      for (Int_t iTime = 0; iTime < kMcmTBmax; iTime++) {
+       fADC[iCol][iTime] = Itarg[iTime];
+      }
+    }
+    break;
+
+  case 2:
+
+    for (Int_t iCol = 0; iCol < kMcmCol; iCol++) {
+      for (Int_t iTime = 0; iTime < kMcmTBmax; iTime++) {
+       sour[iTime] = fADC[iCol][iTime];
+      }
+      DeConvExpMI(sour,Dtarg,kMcmTBmax);
+      for (Int_t iTime = 0; iTime < kMcmTBmax; iTime++) {
+       //fADC[iCol][iTime] = (Int_t)TMath::Max(0.0,Dtarg[iTime]);
+       fADC[iCol][iTime] = TMath::Max(0.0,Dtarg[iTime]);
+      }
+    }
+    break;
+
+  default:
+
+    printf("Invalid filter type %d ! \n",ftype);
+    return;
+
+  }
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmcm::DeConvExpA(Double_t *source, Double_t *target, Int_t n, Int_t nexp) 
+{
+
+  Double_t rates[2];
+  Double_t coefficients[2];
+
+  // initialize (coefficient = alpha, rates = lambda)
+  
+  // FilterOpt.C (aliroot@pel:/homel/aliroot/root/work/beamt/CERN02)
+  Double_t R1, R2, C1, C2;
+  R1 = (Double_t)fR1;
+  R2 = (Double_t)fR2;
+  C1 = (Double_t)fC1;
+  C2 = (Double_t)fC2;
+  
+  coefficients[0] = C1;
+  coefficients[1] = C2;
+
+  Double_t Dt = 0.100;
+  rates[0] = TMath::Exp(-Dt/(R1));
+  rates[1] = TMath::Exp(-Dt/(R2));
+  
+  Int_t i, k;
+  Double_t reminder[2];
+  Double_t correction, result;
+
+  /* attention: computation order is important */
+  correction=0.0;
+  for ( k=0; k<nexp; k++ ) reminder[k]=0.0;
+    
+  for ( i=0; i<n; i++ ) {
+    result = ( source[i] - correction );    // no rescaling
+    target[i] = result;
+    
+    for ( k=0; k<nexp; k++ ) reminder[k] = rates[k] * ( reminder[k] + coefficients[k] * result);
+      
+    correction=0.0;
+    for ( k=0; k<nexp; k++ ) correction += reminder[k];
+  }
+  
+}
+
+//_____________________________________________________________________________
+void AliTRDmcm::DeConvExpD(Double_t *source, Int_t *target, Int_t n, Int_t nexp) {
+
+  Int_t fAlpha_l, fAlpha_s, fLambda_l, fLambda_s, fTailPed;
+  Int_t iAlpha_l, iAlpha_s, iLambda_l, iLambda_s;
+
+  // FilterOpt.C (aliroot@pel:/homel/aliroot/root/work/beamt/CERN02)
+  // initialize (coefficient = alpha, rates = lambda)
+
+  fLambda_l = 0; fAlpha_l = 0; fLambda_s = 0; fAlpha_s = 0;
+  iLambda_l = 0; iAlpha_l = 0; iLambda_s = 0; iAlpha_s = 0;
+
+  Double_t Dt = 0.100;
+
+  Double_t R1, R2, C1, C2;
+  R1 = (Double_t)fR1;
+  R2 = (Double_t)fR2;
+  C1 = (Double_t)fC1;
+  C2 = (Double_t)fC2;
+
+  fLambda_l = (Int_t)((TMath::Exp(-Dt/R1)-0.75)*2048.0);
+  fLambda_s = (Int_t)((TMath::Exp(-Dt/R2)-0.25)*2048.0);
+  iLambda_l = fLambda_l & 0x01FF; iLambda_l |= 0x0600;         //  9 bit paramter + fixed bits
+  iLambda_s = fLambda_s & 0x01FF; iLambda_s |= 0x0200;         //  9 bit paramter + fixed bits
+
+  if (nexp == 1) {
+    fAlpha_l = (Int_t)(C1*2048.0);
+    iAlpha_l = fAlpha_l & 0x03FF;                              // 10 bit paramter
+  }
+  if (nexp == 2) {
+    fAlpha_l = (Int_t)(C1*2048.0);
+    fAlpha_s = (Int_t)((C2-0.5)*2048.0);
+    iAlpha_l = fAlpha_l & 0x03FF;                              // 10 bit paramter
+    iAlpha_s = fAlpha_s & 0x03FF; iAlpha_s |= 0x0400;          // 10 bit paramter + fixed bits
+  }
+  
+  Double_t iAl = iAlpha_l / 2048.0;           // alpha L: correspondence to floating point numbers
+  Double_t iAs = iAlpha_s / 2048.0;           // alpha S: correspondence to floating point numbers
+  Double_t iLl = iLambda_l / 2048.0;          // lambda L: correspondence to floating point numbers
+  Double_t iLs = iLambda_s / 2048.0;          // lambda S: correspondence to floating point numbers
+
+  Int_t h1,h2;
+  Int_t rem1, rem2;
+  Int_t correction, result;
+  Int_t iFactor = ((Int_t)fPedestal)<<2;
+
+  Double_t xi = 1-(iLl*iAs + iLs*iAl);             // calculation of equilibrium values of the
+  rem1 = (Int_t)((iFactor/xi) * ((1-iLs)*iLl*iAl)); // internal registers to prevent switch on effects.
+  rem2 = (Int_t)((iFactor/xi) * ((1-iLl)*iLs*iAs));
+  
+  // further initialization
+  if ( (rem1 + rem2) > 0x0FFF ) {
+    correction = 0x0FFF;
+  } else {
+    correction = (rem1 + rem2) & 0x0FFF;
+  }
+
+  fTailPed = iFactor - correction;
+
+  for (Int_t i=0; i<n; i++) {
+
+    result = ( (Int_t)source[i] - correction );
+    if ( result<0 ) {                          
+      result = 0;
+    }
+
+    target[i] = result;
+                                                        
+    h1 = ( rem1 + ((iAlpha_l * result) >> 11) );
+    if ( h1 > 0x0FFF ) {
+      h1 = 0x0FFF;
+    } else {
+      h1 &= 0x0FFF;
+    }
+
+    h2 = ( rem2 + ((iAlpha_s * result) >> 11));
+    if ( h2 > 0x0FFF ) {
+      h2 = 0x0FFF;
+    } else {
+      h2 &= 0x0FFF;
+    }
+  
+    rem1 = (iLambda_l * h1 ) >> 11;
+    rem2 = (iLambda_s * h2 ) >> 11;
+    
+    if ( (rem1 + rem2) > 0x0FFF ) {
+      correction = 0x0FFF;
+    } else {
+      correction = (rem1 + rem2) & 0x0FFF;
+    }
+  }
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmcm::DeConvExpMI(Double_t *source, Double_t *target, Int_t n) {
+
+   Double_t Sig1[100], Sig2[100], Sig3[100];//, Sig4[100];
+   for (Int_t i = 0; i < n; i++) Sig1[i] = source[i];
+
+   Float_t Dt = 0.100;
+
+   //Float_t lambda0 = 9.8016*Dt;  // short
+   //Float_t lambda1 = 1.0778*Dt;  // long
+
+   Float_t lambda0 = (1.0/fR2)*Dt;
+   Float_t lambda1 = (1.0/fR1)*Dt;
+
+   TailMakerSpline(Sig1,Sig2,lambda0,n);
+   TailCancelationMI(Sig2,Sig3,0.7,lambda1,n);
+
+   for (Int_t i = 0; i < n; i++) target[i] = Sig3[i];
+
+}
+
+//______________________________________________________________________________
+void AliTRDmcm::TailMakerSpline(Double_t *ampin, Double_t *ampout, Double_t lambda, Int_t n) {
+
+   Double_t l = TMath::Exp(-lambda*0.5);
+   //
+   //
+   Double_t in[1000];
+   Double_t out[1000];
+   // initialize in[] and out[] goes 0 ... 2*n+19
+   for (Int_t i=0; i<n*2+20; i++){
+     in[i] = 0;
+     out[i]= 0;
+   }
+
+   // in[] goes 0, 1
+   in[0] = ampin[0];
+   in[1] = (ampin[0]+ampin[1])*0.5;
+   
+   // add charge to the end
+   for (Int_t i=0; i<22; i++){
+     // in[] goes 2*n-2, 2*n-1, ... , 2*n+19 
+     in[2*(n-1)+i] = ampin[n-1];
+   }
+
+   // use arithm mean
+   for (Int_t i=1; i<n-1; i++){
+     // in[] goes 2, 3, ... , 2*n-4, 2*n-3
+     in[2*i]    = ampin[i];
+     in[2*i+1]  = ((ampin[i]+ampin[i+1]))/2.;
+   }
+   /*
+   // add charge to the end
+   for (Int_t i=-2; i<22; i++){
+     // in[] goes 2*n-4, 2*n-3, ... , 2*n+19 
+     in[2*(n-1)+i] = ampin[n-1];
+   }
+
+   // use spline mean
+   for (Int_t i=1; i<n-2; i++){
+     // in[] goes 2, 3, ... , 2*n-6, 2*n-5
+     in[2*i]    = ampin[i];
+     in[2*i+1]  = (9.*(ampin[i]+ampin[i+1])-(ampin[i-1]+ampin[i+2]))/16;
+   }
+   */
+   //
+   Double_t temp;
+   out[2*n]      = in[2*n];
+   temp          = 0;
+   for (int i=2*n; i>=0; i--){
+     out[i]      = in[i]   + temp;
+     temp        = l*(temp+in[i]);
+   }
+
+   //
+   for (int i=0;i<n;i++){
+     //ampout[i]      = out[2*i+1];  // org
+     ampout[i]      = out[2*i];
+   }
+
+}
+
+//______________________________________________________________________________
+void AliTRDmcm::TailCancelationMI(Double_t *ampin, Double_t *ampout, Double_t norm, Double_t lambda, Int_t n) {
+
+   Double_t L = TMath::Exp(-lambda*0.5);
+   Double_t K = L*(1.-norm*lambda*0.5);
+   //
+   //
+   Double_t in[1000];
+   Double_t out[1000];
+   // initialize in[] and out[] goes 0 ... 2*n+19
+   for (Int_t i=0; i<n*2+20; i++){
+     in[i] = 0;
+     out[i]= 0;
+   }
+
+   // in[] goes 0, 1
+   in[0] = ampin[0];
+   in[1] = (ampin[0]+ampin[1])*0.5;
+
+   // add charge to the end
+   for (Int_t i=-2; i<22; i++){
+     // in[] goes 2*n-4, 2*n-3, ... , 2*n+19 
+     in[2*(n-1)+i] = ampin[n-1];
+   }
+
+   //
+   for (Int_t i=1; i<n-2; i++){
+     // in[] goes 2, 3, ... , 2*n-6, 2*n-5
+     in[2*i]    = ampin[i];
+     in[2*i+1]  = (9.*(ampin[i]+ampin[i+1])-(ampin[i-1]+ampin[i+2]))/16.;
+     //in[2*i+1]  = ((ampin[i]+ampin[i+1]))/2.;
+   }
+
+   //
+   Double_t temp;
+   out[0]     = in[0];
+   temp       = in[0];
+   for (int i=1; i<=2*n; i++){
+     out[i]      = in[i]   + (K-L)*temp;
+     temp        = in[i]   +  K*temp;
+   }
+   //
+   //
+   for (int i=0; i<n; i++){
+     //ampout[i]      = out[2*i+1];  // org
+     //ampout[i]      = TMath::Max(out[2*i+1], 0.0);  // org
+     ampout[i]      = TMath::Max(out[2*i], 0.0);
+   }
+
+}
+
diff --git a/TRD/AliTRDmcm.h b/TRD/AliTRDmcm.h
new file mode 100644 (file)
index 0000000..870fb0c
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef ALITRDMCM_H
+#define ALITRDMCM_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+///////////////////////////////////////////////////////
+//  Multi Chip Module object                         //
+///////////////////////////////////////////////////////
+
+#include <TObject.h>
+
+const Int_t kMaxTrackletsPerMCM = 4;
+const Int_t kMcmCol = 21;
+const Int_t kMcmTBmax = 60;
+const Int_t kSelClus = 6;
+const Int_t kMaxClus = 4;
+
+class AliTRDtrigParam;
+
+class AliTRDmcm : public TObject {
+
+ public:
+
+  AliTRDmcm();
+  AliTRDmcm(AliTRDtrigParam *trigp, const Int_t id);
+  virtual ~AliTRDmcm();
+
+  Int_t   Ntrk()                                          { return fNtrk; };
+  Int_t  *GetTrkIndex()                                   { return &fTrkIndex[0]; };
+  Int_t   GetRobId()                                      { return fRobId; };
+  Int_t   GetChaId()                                      { return fChaId; };
+  void    SetRobId(const Int_t id)                        { fRobId = id; };
+  void    SetChaId(const Int_t id)                        { fChaId = id; };
+  void    SetRow(const Int_t row)                         { fRow = row; };
+  Int_t   GetRow()                                        { return fRow; };
+  void    SetColRange(const Int_t colf, const Int_t coll) { fColFirst = colf; fColLast = coll; };
+  void    GetColRange(Int_t &colf, Int_t &coll)           { colf = fColFirst; coll = fColLast; };
+  void    AddTrk(const Int_t id);
+  void    SetADC(const Int_t icol, const Int_t itb, const Float_t adc) 
+    { fADC[icol][itb] = adc; };
+  Float_t GetADC(const Int_t icol, const Int_t itb)       { return fADC[icol][itb]; };
+  void    Reset();
+  Bool_t  Run();
+  void    SetCluster(const Int_t icol, const Int_t itb)      { fIsClus[icol][itb] = kTRUE; };
+  void    UnSetCluster(const Int_t icol, const Int_t itb)    { fIsClus[icol][itb] = kFALSE; };
+  Bool_t  IsCluster(Float_t amp[3]);
+  void    AddTimeBin(const Int_t itime);
+  Int_t   CreateSeeds();
+  void    Sort(const Int_t nel, Int_t *x1, Int_t *x2, Int_t dir);
+  Int_t   GetNtrkSeeds()                           { return fNtrkSeeds; };
+  Int_t  *GetSeedCol()                             { return &fSeedCol[0]; };
+  Int_t  *GetPadHits()                             { return &fPadHits[0]; };
+  Bool_t  IsCluster(const Int_t icol, const Int_t itim) { return fIsClus[icol][itim]; };
+
+  void Filter(Int_t nexp, Int_t ftype = 0);
+  void DeConvExpA(Double_t *source, Double_t *target, Int_t n, Int_t nexp);
+  void DeConvExpD(Double_t *source, Int_t    *target, Int_t n, Int_t nexp);
+  void DeConvExpMI(Double_t *source, Double_t *target, Int_t n);
+  void TailMakerSpline(Double_t *ampin, Double_t *ampout, Double_t lambda, Int_t n);
+  void TailCancelationMI(Double_t *ampin, Double_t *ampout, Double_t norm, Double_t lambda, Int_t n);
+
+  Int_t  Id()                          { return fId; };
+
+ protected:
+
+  AliTRDtrigParam *fTrigParam;                //! pointer to the trigger parameters class
+
+  Int_t   fNtrk;                              //  number of found tracklets
+  Int_t   fTrkIndex[kMaxTrackletsPerMCM];     //  index of found tracklets
+  Int_t   fRobId;                             //  ROB id
+  Int_t   fChaId;                             //  Chamber id
+  Int_t   fRow;                               //  pad row number (0-11 or 0-15)
+  Int_t   fColFirst;                          //  first pad column
+  Int_t   fColLast;                           //  last pad column (<)
+  Float_t fADC[kMcmCol][kMcmTBmax];           //! array with MCM ADC values
+  Bool_t  fIsClus[kMcmCol][kMcmTBmax];        //! flag of a cluster maximum
+  Int_t   fTime1;                             //  first time bin for tracking (incl.)
+  Int_t   fTime2;                             //  last  time bin for tracking (incl.)
+  Float_t fClusThr;                           //  cluster threshold
+  Float_t fPadThr;                            //  pad threshold
+  Int_t   fPadHits[kMcmCol];                  //  hit counter in pads
+  Int_t   fNtrkSeeds;                         //  number of found seeds
+  Int_t   fSeedCol[kMaxTrackletsPerMCM];      //  column number of found tracklet seeds
+  Float_t fR1;                                // filter parameters (1 = long, 2 = short component)
+  Float_t fR2;                                //
+  Float_t fC1;                                //
+  Float_t fC2;                                //
+  Float_t fPedestal;                          //
+
+  Int_t fId;                                  // dummy id
+
+  ClassDef(AliTRDmcm,1)                       // TRD mcm
+
+};
+
+#endif
diff --git a/TRD/AliTRDmcmTracklet.cxx b/TRD/AliTRDmcmTracklet.cxx
new file mode 100644 (file)
index 0000000..4155d74
--- /dev/null
@@ -0,0 +1,420 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+#include <TGraph.h>
+#include <TMath.h>
+#include <TF1.h>
+
+#include "AliTRDcalibDB.h"
+#include "AliTRDCommonParam.h"
+#include "AliTRDpadPlane.h"
+#include "AliTRDgeometry.h"
+
+#include "AliTRDmcmTracklet.h"
+
+ClassImp(AliTRDmcmTracklet)
+
+//_____________________________________________________________________________
+AliTRDmcmTracklet::AliTRDmcmTracklet() 
+{
+
+  //
+  // AliTRDmcmTracklet default constructor
+  //
+
+  fDetector = -1;
+  fRow      = -1;
+
+  for (Int_t time = 0; time < kNtimeBins; time++) {
+    for (Int_t icl = 0; icl < kNclsPads; icl++) {
+      fADC[time][icl] = 0;
+    }
+    for (Int_t it = 0; it < kNdict; it++) {
+      fTrack[time][it] = -1;
+    }
+    fTime[time]   = 0;
+    fCol[time]    = 0;
+  }
+
+  fNclusters  =  0;
+  fN          =  0;
+  fTrackLabel = -1;
+
+  fGPos = 0;
+  fGAmp = 0;
+
+  fSlope  = 0.0;
+  fOffset = 0.0;
+  fTime0  = 0.0;
+  fRowz   = 0.0;
+  fPt     = 0.0;
+  fdQdl   = 0.0;
+
+}
+
+//_____________________________________________________________________________
+AliTRDmcmTracklet::AliTRDmcmTracklet(Int_t det, Int_t row, Int_t n) 
+{
+
+  //
+  // AliTRDmcmTracklet default constructor
+  //
+
+  fDetector = det;
+  fRow      = row;
+
+  for (Int_t time = 0; time < kNtimeBins; time++) {
+    for (Int_t icl = 0; icl < kNclsPads; icl++) {
+      fADC[time][icl] = 0;
+    }
+    for (Int_t it = 0; it < kNdict; it++) {
+      fTrack[time][it] = -1;
+    }
+    fTime[time]   = 0;
+    fCol[time]    = 0;
+  }
+
+  fNclusters = 0;
+
+  fN = n;
+
+  fTrackLabel = -1;
+
+  fGPos = new TGraph(0);
+  fGAmp = new TGraph(0);
+
+  fSlope  = 0.0;
+  fOffset = 0.0;
+  fTime0  = 0.0;
+  fRowz   = 0.0;
+  fPt     = 0.0;
+  fdQdl   = 0.0;
+
+}
+
+//_____________________________________________________________________________
+AliTRDmcmTracklet::~AliTRDmcmTracklet() 
+{
+
+  //
+  // AliTRDmcmTracklet destructor
+  //
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmcmTracklet::MakeTrackletGraph(AliTRDgeometry *geo, Float_t field) 
+{
+
+  //
+  // Tracklet graph of positions (global coordinates, rotated [cm])
+  //
+  
+  if (!geo) {
+    Error("MakeTrackletGraph","No geometry.");
+    return;
+  }
+  
+  AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
+  if (!commonParam)
+  {
+    Error("MakeTrackletGraph","No common params.");
+    return;
+  }
+
+  AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
+  if (!calibration)
+  {
+    Error("MakeTrackletGraph","No instance of AliTRDcalibDB.");
+    return;
+  }
+
+  Int_t iplan, icham;
+
+  iplan = geo->GetPlane(fDetector);
+  icham = geo->GetChamber(fDetector);
+
+  AliTRDpadPlane *padPlane = commonParam->GetPadPlane(iplan,icham);
+
+  Float_t SamplFreq = calibration->GetSamplingFrequency();
+
+  Int_t time, col;
+  Float_t amp[3];
+  Float_t Xpos, Ypos, Xzero, ColSize, TimeBinSize;
+  Float_t vDrift, OmegaTau, LorentzAngle, ThetaSlope;
+  Float_t TiltingAngle;
+  Int_t npg = 0;
+
+  for (Int_t icl = 0; icl < fNclusters; icl++) {
+
+    time   = GetClusterTime(icl);
+
+    amp[0] = GetClusterADC(icl)[0];
+    amp[1] = GetClusterADC(icl)[1];
+    amp[2] = GetClusterADC(icl)[2];
+
+    col    = GetClusterCol(icl);
+
+    if (amp[0] < 0.0 || amp[1] < 0.0 || amp[2] < 0.0) continue;
+
+    Ypos = GetClusY(amp,iplan);
+
+    ColSize = padPlane->GetColSize(col);
+    vDrift = calibration->GetVdrift(fDetector,col,fRow);
+    TimeBinSize = vDrift/SamplFreq;
+    
+    // From v4-03-Release to HEAD28Mar06 the sign has changed from "-" to "+" 
+    // due to a change in the digitizer
+    OmegaTau = +TMath::Sign(1.0,(Double_t)field)*GetOmegaTau(vDrift,TMath::Abs(field));
+    LorentzAngle = TMath::ATan(OmegaTau)*180.0/TMath::Pi();
+    
+    Xpos = (time+0.5) * TimeBinSize;
+    Xpos = geo->GetTime0(iplan) - Xpos;
+
+    Ypos = padPlane->GetColPos(col) - (Ypos + 0.5) * ColSize;
+
+    // ExB correction
+    Xzero = geo->GetTime0(iplan);
+    Ypos = Ypos + (Xpos-Xzero) * OmegaTau;
+
+    // tilted pads correction
+    ThetaSlope = - padPlane->GetRowPos(fRow)/geo->GetTime0(iplan);
+    TiltingAngle = padPlane->GetTiltingAngle()/180.0*TMath::Pi();
+    Ypos = Ypos - (Xpos-Xzero) * ThetaSlope * TMath::Sin(TiltingAngle);
+
+    fGPos->SetPoint(npg,(Double_t)Xpos,(Double_t)Ypos);
+    npg++;
+
+  }
+
+  fGPos->Set(npg);
+  
+  fTime0 = geo->GetTime0(iplan) - AliTRDgeometry::CdrHght() - 0.5*AliTRDgeometry::CamHght();
+  fRowz = 0.5*(padPlane->GetRowPos(fRow) + padPlane->GetRowPos(fRow+1));
+
+  Double_t xMin = 0, xMax = 0, x, y;
+  fGPos->GetPoint(0    ,x,y); xMax = x + 0.1;
+  fGPos->GetPoint(npg-1,x,y); xMin = x - 0.1;
+  
+  TF1 *line = new TF1("line","[0]+x*[1]",xMin,xMax);
+  fGPos->Fit(line,"WRQ0");
+
+  fOffset = line->Eval(fTime0);
+  fSlope  = TMath::ATan(line->GetParameter(1))*180.0/TMath::Pi();
+
+  line->Delete();
+  
+  Float_t fX = fTime0;
+  Float_t fY = fOffset;
+  
+  Float_t infSlope = TMath::ATan(fY/fX)/TMath::Pi()*180.0;    
+  Float_t alpha = fSlope - infSlope;
+  Float_t R = TMath::Sqrt(fX*fX + fY*fY)/(2.0*TMath::Sin(alpha/180.0*TMath::Pi()));
+
+  fPt = 0.3 * field * 0.01 * R;
+  
+  return;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmcmTracklet::MakeClusAmpGraph() 
+{
+  //
+  // Tracklet graph of cluster charges
+  //
+
+  AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
+  if (!calibration)
+  {
+    Error("MakeClusAmpGraph","No instance of AliTRDcalibDB.");
+    return;
+  }
+
+  Int_t time;
+  Float_t amp[3];
+  Int_t npg = 0;
+  fdQdl = 0.0;
+  for (Int_t icl = 0; icl < fNclusters; icl++) {
+
+    time   = GetClusterTime(icl);
+
+    amp[0] = GetClusterADC(icl)[0];
+    amp[1] = GetClusterADC(icl)[1];
+    amp[2] = GetClusterADC(icl)[2];
+
+    fGAmp->SetPoint(npg,(Double_t)(time+0.5),(Double_t)(amp[0]+amp[1]+amp[2]));
+    npg++;
+
+    fdQdl += amp[0]+amp[1]+amp[2];
+
+  }
+
+  fGAmp->Set(npg);
+
+  fdQdl /= (Float_t)npg;
+
+  return;
+
+}
+
+//_____________________________________________________________________________
+Float_t AliTRDmcmTracklet::GetClusY(Float_t *adc, Int_t pla) 
+{
+  //
+  // Cluster position in the phi direction in pad units (relative to the pad border)
+  //
+
+  Float_t Ypos = 0.0;
+
+  Float_t A0 = adc[0];
+  Float_t A1 = adc[1];
+  Float_t A2 = adc[2];
+
+  Float_t T1, T2, W1 ,W2;
+
+  Float_t W = 1.0;  // pad units
+
+  Float_t Sigma = 0.0;
+
+  switch(pla) {
+  case 0:
+    Sigma = 0.515; break;
+  case 1:
+    Sigma = 0.501; break;
+  case 2:
+    Sigma = 0.491; break;
+  case 3:
+    Sigma = 0.481; break;
+  case 4:
+    Sigma = 0.471; break;
+  case 5:
+    Sigma = 0.463; break;
+  default:
+    Error("GetClusY","Wrong plane number.");
+    return 0.0;
+  }
+
+  Sigma *= W;
+
+  T1 = 0.0;
+  W1 = 0.0;
+  if( A0 > 0 ) {
+    W1 = A0*A0;
+    //W1 = A0;
+    T1 = W1*((Sigma*Sigma)/W*TMath::Log(A1/A0)-0.5*W);
+  }
+  T2 = 0.0;
+  W2 = 0.0;
+  if( A2 > 0 ) {
+    W2 = A2*A2;
+    //W2 = A2;
+    T2 = W2*((Sigma*Sigma)/W*TMath::Log(A2/A1)+0.5*W);
+  }
+
+  Ypos = W*(T1+T2)/(W1+W2);  // range: -0.5*W ... +0.5*W
+
+  return Ypos;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmcmTracklet::CookLabel(Float_t frac) 
+{
+  //
+  // Cook the track label from cluster labels
+  //
+
+  const Int_t kMaxTracks = 10;
+  Int_t trackLabel[kMaxTracks];
+  Int_t trackCount[kMaxTracks];
+  for (Int_t it = 0; it < kMaxTracks; it++) {
+    trackLabel[it] = -1;
+    trackCount[it] = 0;
+  }
+
+  Bool_t counted;
+  Int_t label, nTracks = 0;
+  for (Int_t icl = 0; icl < fNclusters; icl++) {
+
+    for (Int_t id = 0; id < kNdict; id++) {
+
+      if (fTrack[icl][id] == -1) continue;
+
+      label = fTrack[icl][id];
+
+      counted = kFALSE;
+      for (Int_t it = 0; it < nTracks; it++) {
+       if (label == trackLabel[it]) {
+         trackCount[it]++;
+         counted = kTRUE;
+         break;
+       }
+      }
+      if (!counted) {
+       trackLabel[nTracks] = label;
+       trackCount[nTracks]++;
+       nTracks++;
+       if (nTracks == kMaxTracks) {
+         Warning("CookLabel","Too many tracks for this tracklet.");
+         nTracks--;
+         break;
+       }
+      }
+
+    }
+
+  }
+
+  for (Int_t it = 0; it < kMaxTracks; it++) {
+    if (trackCount[it] >= (Int_t)(frac*fNclusters)) {
+      fTrackLabel = trackLabel[it];
+      break;
+    }
+  }
+
+}
+
+//_____________________________________________________________________________
+Float_t AliTRDmcmTracklet::GetOmegaTau(Float_t vdrift, Float_t field)
+{
+  //
+  // Returns omega*tau (tan(Lorentz-angle)) for a given drift velocity <vd> 
+  // and a B-field <b> for Xe/CO2 (15%).
+  // The values are according to a GARFIELD simulation.
+  //
+
+  //
+  // Copy of the "AliTRDcalibDB" function, taking as argument the magnetic field too
+  //
+  
+  const Int_t kNb = 5;
+  Float_t p0[kNb] = {  0.004810,  0.007412,  0.010252,  0.013409,  0.016888 };
+  Float_t p1[kNb] = {  0.054875,  0.081534,  0.107333,  0.131983,  0.155455 };
+  Float_t p2[kNb] = { -0.008682, -0.012896, -0.016987, -0.020880, -0.024623 };
+  Float_t p3[kNb] = {  0.000155,  0.000238,  0.000330,  0.000428,  0.000541 };
+
+  Int_t ib = ((Int_t) (10 * (field - 0.15)));
+  ib       = TMath::Max(  0,ib);
+  ib       = TMath::Min(kNb,ib);
+
+  Float_t alphaL = p0[ib] 
+      + p1[ib] * vdrift
+      + p2[ib] * vdrift*vdrift
+      + p3[ib] * vdrift*vdrift*vdrift;
+
+  return TMath::Tan(alphaL);
+
+}
diff --git a/TRD/AliTRDmcmTracklet.h b/TRD/AliTRDmcmTracklet.h
new file mode 100644 (file)
index 0000000..c79ebde
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef ALITRDMCMTRACKLET_H
+#define ALITRDMCMTRACKLET_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+///////////////////////////////////////////////////////
+//  Tracklet object (MCM/TRIGGER)                    //
+///////////////////////////////////////////////////////
+
+#include <TObject.h>
+
+const Int_t kNclsPads  =  3;
+const Int_t kNtimeBins = 30;
+const Int_t kNdict     =  3;
+
+class TGraph;
+
+class AliTRDgeometry;
+
+class AliTRDmcmTracklet : public TObject {
+
+ public:
+
+  AliTRDmcmTracklet();
+  AliTRDmcmTracklet(Int_t det, Int_t row, Int_t n);
+  virtual ~AliTRDmcmTracklet();
+
+  void AddCluster(Int_t icol, Int_t itb, Float_t *adc, Int_t *track) { 
+    if (fNclusters >= kNtimeBins) return;
+    for (Int_t icl = 0; icl < kNclsPads; icl++) {
+      //fADC[fNclusters][icl] = (Int_t)adc[icl]; 
+      fADC[fNclusters][icl] = adc[icl]; 
+    }
+    fTrack[fNclusters][0] = track[0];
+    fTrack[fNclusters][1] = track[1];
+    fTrack[fNclusters][2] = track[2];
+    fTime[fNclusters] = itb;
+    fCol[fNclusters] = icol;
+    fNclusters++;
+  };
+
+  Float_t  *GetClusterADC(Int_t icl)      { return fADC[icl];  };
+  Int_t     GetClusterTime(Int_t icl)     { return fTime[icl]; };
+  Int_t     GetClusterCol(Int_t icl)      { return fCol[icl];  };
+
+  TGraph   *GetTrackletGraph() { return fGPos; };
+  TGraph   *GetClusAmpGraph()  { return fGAmp; };
+
+  virtual void MakeTrackletGraph(AliTRDgeometry *geo = 0, Float_t field = 0);
+  virtual void MakeClusAmpGraph();
+
+  Float_t   GetClusY(Float_t *adc, Int_t pla);
+
+  Int_t     GetNumber() { return fN; };
+
+  void      CookLabel(Float_t frac);
+  Int_t     GetLabel() { return fTrackLabel; };
+
+  Int_t     GetNclusters()    { return fNclusters; };
+  Int_t     GetDetector()     { return fDetector; };
+  Int_t     GetRow()          { return fRow; };
+  Float_t   GetOffset() { return fOffset; };
+  Float_t   GetSlope()  { return fSlope; };
+  Float_t   GetTime0()  { return fTime0; };
+  Float_t   GetRowz()   { return fRowz; };
+  Float_t   GetPt()     { return fPt; };
+  Float_t   GetdQdl()   { return fdQdl; };
+
+  Float_t   GetOmegaTau(Float_t vdrift, Float_t field);
+
+ protected:
+
+  Int_t   fDetector;                     //  TRD detector number (0 ... 539)
+  Int_t   fRow;                          //  Row number in the detector
+  Float_t fADC[kNtimeBins][kNclsPads];   //  Array of ADC values in a pad group
+  Int_t   fTrack[kNtimeBins][kNdict];    //! Array of track dictionary values
+  Int_t   fTrackLabel;                   //  Cooked track label
+  Int_t   fTime[kNtimeBins];             //  Array of time bin values
+  Int_t   fCol[kNtimeBins];              //  Array of pad column values
+  Int_t   fNclusters;                    //  Number of clusters in the tracklet
+
+  Int_t   fN;                            // Tracklet number
+
+  TGraph *fGPos;                         //! Positions
+  TGraph *fGAmp;                         //! Amplitudes
+
+  Float_t fTime0;                        // X position at the entrance window
+  Float_t fRowz;                         // Z position of the row center
+  Float_t fSlope;                        // Slope [deg]
+  Float_t fOffset;                       // Offset
+  Float_t fPt;                           // Transverse momentum
+  Float_t fdQdl;                         // Charge per unit length
+
+  ClassDef(AliTRDmcmTracklet,1)          // Track segment for the TRD (Tracklet)
+
+};
+
+#endif
diff --git a/TRD/AliTRDtrigParam.cxx b/TRD/AliTRDtrigParam.cxx
new file mode 100644 (file)
index 0000000..2683df9
--- /dev/null
@@ -0,0 +1,185 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  TRD trigger parameters class                                                      //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include "AliTRDgeometry.h"
+
+#include "AliTRDtrigParam.h"
+
+ClassImp(AliTRDtrigParam)
+
+//_____________________________________________________________________________
+AliTRDtrigParam::AliTRDtrigParam():TNamed()
+{
+  //
+  // AliTRDtrigParam default constructor
+  //
+
+  fDebug      = 0;
+  fTime1      = 0;
+  fTime2      = 0;
+  fClusThr    = 0;
+  fPadThr     = 0;
+  fSum10      = 0;
+  fSum12      = 0;
+  fTCOn       = 0;
+  fTCnexp     = 0;
+  fFilterType = 0;
+  fR1         = 0;
+  fR2         = 0;
+  fC1         = 0;
+  fC2         = 0;
+  fPedestal   = 0;
+  fDeltaY     = 0.0;
+  fDeltaS     = 0.0;
+  fXprojPlane = 0.0;
+  fField      = 0.0;
+  fLtuPtCut   = 0.0;
+  fGtuPtCut   = 0.0;
+
+}
+
+//_____________________________________________________________________________
+AliTRDtrigParam::AliTRDtrigParam(const Text_t *name, const Text_t *title)
+                :TNamed(name,title)
+{
+  //
+  // AliTRDtrigParam constructor
+  //
+
+  fDebug      =    0;
+  fTime1      =    2;
+  fTime2      =   22;
+  fClusThr    = 10.0;
+  fPadThr     =    1;
+  fSum10      =    2;
+  fSum12      =   10;
+  fTCOn       =    1;
+  fTCnexp     =    1;
+  fFilterType =    0;
+  fR1         =  0.0;
+  fR2         =  0.0;
+  fC1         =  0.0;
+  fC2         =  0.0;
+  fPedestal   =  0.0;
+  fDeltaY     =  2.0;
+  fDeltaS     =  2.5;
+  fXprojPlane =  0.0;
+  fField      =  0.0;
+  fLtuPtCut   =  2.3;
+  fGtuPtCut   =  3.0;
+
+  // PASA.v.4
+
+  if (fTCnexp == 1) {
+    fR1         = 1.1563;
+    fR2         = 0.1299;
+    fC1         = 0.0657;
+    fC2         = 0.0000;
+  }
+
+  if (fTCnexp == 2) {
+    fR1         = 1.1563;
+    fR2         = 0.1299;
+    fC1         = 0.1141;
+    fC2         = 0.6241;
+  }
+
+}
+
+//_____________________________________________________________________________
+AliTRDtrigParam::AliTRDtrigParam(const AliTRDtrigParam &p):TNamed(p)
+{
+  //
+  // AliTRDtrigParam copy constructor
+  //
+
+  ((AliTRDtrigParam &) p).Copy(*this);
+
+}
+
+//_____________________________________________________________________________
+AliTRDtrigParam::~AliTRDtrigParam()
+{
+  //
+  // AliTRDtrigParam destructor
+  //
+}
+
+//_____________________________________________________________________________
+AliTRDtrigParam &AliTRDtrigParam::operator=(const AliTRDtrigParam &p)
+{
+  //
+  // Assignment operator
+  //
+
+  if (this != &p) ((AliTRDtrigParam &) p).Copy(*this);
+  return *this;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDtrigParam::Copy(TObject &p) const
+{
+  //
+  // Copy function
+  //
+
+  ((AliTRDtrigParam &) p).fDebug      = fDebug;
+  ((AliTRDtrigParam &) p).fTime1      = fTime1;
+  ((AliTRDtrigParam &) p).fTime2      = fTime2;
+  ((AliTRDtrigParam &) p).fClusThr    = fClusThr;
+  ((AliTRDtrigParam &) p).fPadThr     = fPadThr;
+  ((AliTRDtrigParam &) p).fSum10      = fSum10;
+  ((AliTRDtrigParam &) p).fSum12      = fSum12;
+  ((AliTRDtrigParam &) p).fTCOn       = fTCOn;
+  ((AliTRDtrigParam &) p).fTCnexp     = fTCnexp;
+  ((AliTRDtrigParam &) p).fFilterType = fFilterType;
+  ((AliTRDtrigParam &) p).fR1         = fR1;
+  ((AliTRDtrigParam &) p).fR2         = fR2;
+  ((AliTRDtrigParam &) p).fC1         = fC1;
+  ((AliTRDtrigParam &) p).fC2         = fC2;
+  ((AliTRDtrigParam &) p).fPedestal   = fPedestal;
+  ((AliTRDtrigParam &) p).fDeltaY     = fDeltaY;
+  ((AliTRDtrigParam &) p).fDeltaS     = fDeltaS;
+  ((AliTRDtrigParam &) p).fXprojPlane = fXprojPlane;
+  ((AliTRDtrigParam &) p).fField      = fField;
+  ((AliTRDtrigParam &) p).fLtuPtCut   = fLtuPtCut;
+  ((AliTRDtrigParam &) p).fGtuPtCut   = fGtuPtCut;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDtrigParam::Init()
+{
+  //
+  // Initialize the other parameters
+  //
+
+  Float_t fXplane0, fXplane5;
+
+  fXplane0 = AliTRDgeometry::GetTime0(0) - AliTRDgeometry::CdrHght() - 0.5*AliTRDgeometry::CamHght(); 
+
+  fXplane5 = AliTRDgeometry::GetTime0(5) - AliTRDgeometry::CdrHght() - 0.5*AliTRDgeometry::CamHght();
+
+  fXprojPlane = 0.5 * (fXplane0 + fXplane5);
+
+}
+
diff --git a/TRD/AliTRDtrigParam.h b/TRD/AliTRDtrigParam.h
new file mode 100644 (file)
index 0000000..179b6fe
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef ALITRDTRIGPARAM_H
+#define ALITRDTRIGPARAM_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  TRD trigger parameters class                                             //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include <TNamed.h>
+
+class AliTRDtrigParam : public TNamed {
+
+ public:
+
+  AliTRDtrigParam();
+  AliTRDtrigParam(const Text_t* name, const Text_t* title);
+  AliTRDtrigParam(const AliTRDtrigParam &p);   
+  virtual ~AliTRDtrigParam();
+  AliTRDtrigParam &operator=(const AliTRDtrigParam &p); 
+
+  virtual void     Copy(TObject &p) const;
+  virtual void     Init();
+
+  void    SetTimeRange(const Int_t time1, const Int_t time2) { fTime1 = time1; fTime2 = time2; };
+  Int_t   GetTime1()                                   const { return fTime1; };
+  Int_t   GetTime2()                                   const { return fTime2; };
+  void    SetClusThr(const Float_t clth)                     { fClusThr = clth; };
+  void    SetPadThr(const Float_t path)                      { fPadThr = path;  };
+  Float_t GetClusThr()                                 const { return fClusThr; };
+  Float_t GetPadThr()                                  const { return fPadThr;  };
+  void    SetSum10(const Int_t sum)                          { fSum10 = sum; };
+  void    SetSum12(const Int_t sum)                          { fSum12 = sum; };
+  Int_t   GetSum10()                                   const { return fSum10; };
+  Int_t   GetSum12()                                   const { return fSum12; };
+
+  void    SetTailCancelation(Int_t tcOn = 0)               { fTCOn = tcOn; };
+  void    SetNexponential(Int_t nexp = 1)                  { fTCnexp = nexp; };
+  void    SetFilterType(Int_t ftype = 0)                   { fFilterType = ftype; };
+  void    SetFilterParam(Float_t r1, Float_t r2, Float_t c1, Float_t c2, Float_t ped) 
+    { fR1 = r1; fR2 = r2; fC1 = c1; fC2 = c2; fPedestal = ped; };
+
+  Int_t   GetTailCancelation()                       const { return fTCOn; };
+  Int_t   GetNexponential()                          const { return fTCnexp; };
+  Int_t   GetFilterType()                            const { return fFilterType; };
+  void    GetFilterParam(Float_t &r1, Float_t &r2, Float_t &c1, Float_t &c2, Float_t &ped) const { 
+    r1 = fR1; r2 = fR2; c1 = fC1; c2 = fC2; ped = fPedestal; 
+  };
+
+  void    SetADCnoise(const Float_t adcn)                  { fADCnoise = adcn; };
+  Float_t GetADCnoise()                                    { return fADCnoise; };
+
+  void    SetDebugLevel(const Int_t deb) { fDebug = deb;  };
+  Int_t   GetDebugLevel()                { return fDebug; };
+
+  void    SetDeltaY(Float_t dy) { fDeltaY = dy; };
+  Float_t GetDeltaY()           { return fDeltaY; };
+  void    SetDeltaS(Float_t ds) { fDeltaS = ds; };
+  Float_t GetDeltaS()           { return fDeltaS; };
+
+  Float_t GetXprojPlane() { return fXprojPlane; };
+
+  void    SetField(Float_t b) { fField = b; };
+  Float_t GetField() { return fField; };
+
+  void    SetLtuPtCut(Float_t ptcut) { fLtuPtCut = ptcut; };
+  Float_t GetLtuPtCut() { return fLtuPtCut; };
+
+  void    SetGtuPtCut(Float_t ptcut) { fGtuPtCut = ptcut; };
+  Float_t GetGtuPtCut() { return fGtuPtCut; };
+
+ protected:
+
+  Int_t    fDebug;                         // debugging flag
+
+  Int_t    fTime1;                         // first time bin for tracking (incl.)
+  Int_t    fTime2;                         // last  time bin for tracking (incl.)
+  Float_t  fClusThr;                       // cluster threshold
+  Float_t  fPadThr;                        // pad threshold
+  Int_t    fSum10;                         // MCM CreateSeeds: Min_Thr_Left_Neighbour
+  Int_t    fSum12;                         // MCM CreateSeeds: Min_Sum_From_Two_Neighbours
+  Int_t    fTCOn;                          // tail cancelation flag
+  Int_t    fTCnexp;                        // number of exp in filter
+  Int_t    fFilterType;                    // filter type (0=A - analog, 1=D - digital)
+  Float_t  fR1;                            // filter parameters (1 = long, 2 = short component)
+  Float_t  fR2;                            //
+  Float_t  fC1;                            //
+  Float_t  fC2;                            //
+  Float_t  fPedestal;                      //
+  Float_t  fADCnoise;                      // ADC noise (not contained in the digitizer)
+
+  Float_t  fDeltaY;                        // Y (offset) matching window in the GTU
+  Float_t  fDeltaS;                        // Slope matching window in the GTU
+
+  Float_t  fXprojPlane;                    // Projection plane (X) for GTU matching
+
+  Float_t  fLtuPtCut;                      // Local pt cut
+  Float_t  fGtuPtCut;                      // Global pt cut
+
+  Float_t  fField;                         // Magnetic field
+
+  ClassDef(AliTRDtrigParam,1)                  // TRD trigger parameter class
+
+};
+
+#endif
diff --git a/TRD/AliTRDtrigger.cxx b/TRD/AliTRDtrigger.cxx
new file mode 100644 (file)
index 0000000..c66342c
--- /dev/null
@@ -0,0 +1,1622 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  TRD trigger class                                                        //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include <TTree.h>
+#include <TBranch.h>
+#include <TMatrixD.h>
+
+#include "AliLog.h"
+#include "AliRun.h"
+#include "AliRunLoader.h"
+#include "AliLoader.h"
+#include "AliHeader.h"
+#include "AliRawReader.h"
+
+#include "AliTRDdigitsManager.h"
+#include "AliTRDgeometry.h"
+#include "AliTRDdataArrayI.h"
+#include "AliTRDcalibDB.h"
+#include "AliTRDCommonParam.h"
+#include "Cal/AliTRDCalPIDLQ.h"
+#include "AliTRDrawData.h"
+
+#include "AliTRDtrigger.h"
+#include "AliTRDmcmTracklet.h"
+#include "AliTRDtrigParam.h"
+#include "AliTRDmcm.h"
+
+ClassImp(AliTRDtrigger)
+ClassImp(AliTRDltuTracklet)
+ClassImp(AliTRDgtuTrack)
+ClassImp(AliTRDmodule)
+
+//_____________________________________________________________________________
+AliTRDltuTracklet::AliTRDltuTracklet(Int_t det, 
+                                    Int_t row, 
+                                    Float_t rowz,
+                                    Float_t slope, 
+                                    Float_t offset, 
+                                    Float_t time, 
+                                    Int_t ncl,
+                                    Int_t label,
+                                    Float_t q) 
+{
+  //
+  // AliTRDltuTracklet constructor
+  //
+
+  fDetector  = det;
+  fRow       = row;
+  fRowz      = rowz;
+  fSlope     = slope;
+  fX         = time;
+  fY         = offset;
+  fNclusters = ncl;
+  fLabel     = label;
+  fQ         = q;
+
+}
+
+//_____________________________________________________________________________
+Float_t AliTRDltuTracklet::GetPt(Float_t field)
+{
+  // transverse momentum calculation
+  // curvature R = (fX*fX + fY*fY) / (2 * sin(alpha))
+  // alpha = angle deviation from "infinite momentum"
+  //
+  // consistent with AliTRDmcmTracklet::GetPt(...)
+
+  Float_t InfSlope = TMath::ATan(fY/fX)/TMath::Pi()*180.0;    
+  Float_t alpha = fSlope - InfSlope;
+  Float_t R = TMath::Sqrt(fX*fX + fY*fY)/(2.0*TMath::Sin(alpha/180.0*TMath::Pi()));
+  
+  Float_t Pt = 0.3 * field * 0.01 * R;
+  return Pt;
+}
+
+//_____________________________________________________________________________
+Int_t AliTRDltuTracklet::Compare(const TObject * o) const
+{
+  //
+  // compare two LTU tracklets according to the intercept point Y1
+  //
+
+  AliTRDltuTracklet *ltutrk = (AliTRDltuTracklet*)o;
+
+  if (fRow      != ltutrk->fRow)      return +1;
+  if (fDetector != ltutrk->fDetector) return +1;
+
+  if (fY <  ltutrk->fY) return -1;
+  if (fY == ltutrk->fY) return  0;
+
+  return 1;
+
+}
+
+//_____________________________________________________________________________
+Float_t AliTRDltuTracklet::GetYproj(Float_t xpl)
+{
+
+  Float_t Yproj;
+
+  Yproj = fY + TMath::Tan(fSlope/180.0*TMath::Pi()) * (xpl - fX);
+
+  return Yproj;
+
+}
+
+//_____________________________________________________________________________
+Float_t AliTRDltuTracklet::GetZproj(Float_t xpl)
+{
+
+  Float_t Zproj;
+
+  Zproj = fRowz * xpl / fX;
+
+  return Zproj;
+
+}
+
+//_____________________________________________________________________________
+AliTRDgtuTrack::AliTRDgtuTrack()
+{
+
+  fYproj = 0.0;
+  fZproj = 0.0;
+  fSlope = 0.0;
+  fDetector = -1;
+  fNtracklets = 0;
+  fNplanes = 0;
+  fNclusters = 0;
+  fPt = 0.0;
+  fPhi = 0.0;
+  fEta = 0.0;
+  fLabel = -1;
+  fPID = 0.0;
+  fIsElectron = kFALSE;
+
+  fTracklets = new TObjArray(400);
+
+}
+
+//_____________________________________________________________________________
+AliTRDgtuTrack::AliTRDgtuTrack(const AliTRDgtuTrack& track):
+  TObject(track),
+  fYproj(track.fYproj),
+  fZproj(track.fZproj),
+  fSlope(track.fSlope),
+  fDetector(track.fDetector),
+  fNtracklets(track.fNtracklets),
+  fNplanes(track.fNplanes),
+  fNclusters(track.fNclusters),
+  fPt(track.fPt),
+  fPhi(track.fPhi),
+  fEta(track.fEta),
+  fLabel(track.fLabel),
+  fPID(track.fPID),
+  fIsElectron(track.fIsElectron)
+{
+  //
+  // copy contructor
+  //
+
+  fTracklets = NULL;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDgtuTrack::AddTracklet(AliTRDltuTracklet *trk)
+{
+
+  Tracklets()->Add(trk);
+
+}
+
+//_____________________________________________________________________________
+AliTRDltuTracklet* AliTRDgtuTrack::GetTracklet(Int_t pos)
+{
+
+  if (fTracklets == 0) return 0;
+  void * trk = fTracklets->UncheckedAt(pos);
+  if (trk == 0) return 0;
+
+  return (AliTRDltuTracklet*)trk;
+
+}
+
+//_____________________________________________________________________________
+Int_t AliTRDgtuTrack::Compare(const TObject * o) const
+{
+
+  AliTRDgtuTrack *gtutrack = (AliTRDgtuTrack*)o;
+
+  if (fYproj <  gtutrack->GetYproj()) return -1;
+  if (fYproj == gtutrack->GetYproj()) return  0;
+
+  return +1;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDgtuTrack::Reset()
+{
+
+  fYproj = 0.0;
+  fZproj = 0.0;
+  fSlope = 0.0;
+  fDetector = -1;
+  fNtracklets = 0;
+  fNplanes = 0;
+  fNclusters = 0;
+  fPt = 0.0;
+  fPhi = 0.0;
+  fEta = 0.0;
+  fLabel = -1;
+  fPID = 0.0;
+  fIsElectron = kFALSE;
+  
+}
+
+//_____________________________________________________________________________
+void AliTRDgtuTrack::Track(Float_t xpl, Float_t field)
+{
+
+  AliTRDltuTracklet *trk;
+  Int_t nTracklets = GetNtracklets();
+  Float_t fC[kNmaxTrk][3];            // X, Y, Z  coordinates of segments
+
+  fYproj = 0.0;
+  fZproj = 0.0;
+  fSlope = 0.0;
+  fNclusters = 0;
+  fNplanes = 0;
+  fNtracklets = GetNtracklets();
+  Int_t InDetector[kNplan];
+  for (Int_t i = 0; i < kNplan; i++) InDetector[i] = -1;
+  Int_t iDet, nDet = 0;
+  Bool_t NewDetector;
+  for (Int_t i = 0; i < nTracklets; i++) {
+
+    trk = GetTracklet(i);
+    fYproj += trk->GetYproj(xpl);
+    fZproj += trk->GetZproj(xpl);
+    fSlope += trk->GetSlope();
+    fNclusters += trk->GetNclusters();
+    iDet = trk->GetDetector();
+
+    NewDetector = kTRUE;
+    for (Int_t id = 0; id < nDet; id++) {
+      if (iDet == InDetector[id]) {
+       NewDetector = kFALSE;
+       break;
+      }
+    }
+    if (NewDetector) {
+      InDetector[nDet++] = iDet;
+      fNplanes++;
+    }
+
+    fC[i][0] = trk->GetTime0();
+    fC[i][1] = trk->GetOffset();
+    fC[i][2] = trk->GetRowz();
+
+  }
+  fYproj /= (Float_t)nTracklets;
+  fZproj /= (Float_t)nTracklets;
+  fSlope /= (Float_t)nTracklets;
+
+  Float_t X[kNmaxTrk+1], Y[kNmaxTrk+1], Z[kNmaxTrk+1];
+  Bool_t count[kNmaxTrk];
+  for (Int_t i = 0; i < kNmaxTrk; i++) count[i] = kFALSE;
+
+  Int_t iXmin = -1;
+  Int_t j = 0;
+  X[0] = Y[0] = Z[0] = 0.0;
+  while (j < nTracklets) {
+    iXmin = -1;
+    for (Int_t i = 0; i < nTracklets; i++) {
+      if (count[i]) continue;
+      if (iXmin == -1) {
+       iXmin = i;
+       continue;
+      }
+      if (fC[i][0] < fC[iXmin][0]) iXmin = i;
+    }
+    X[j+1] = fC[iXmin][0];
+    Y[j+1] = fC[iXmin][1];
+    Z[j+1] = fC[iXmin][2];
+    j++;
+    count[iXmin] = kTRUE;
+  }
+
+  TMatrixD smatrix(2,2);
+  TMatrixD sums(2,1);
+  TMatrixD res(2,1);
+  Double_t x, y;
+  Float_t A, B;
+
+  smatrix.Zero();
+  sums.Zero();
+  for (Int_t i = 0; i < nTracklets; i++) {
+    x = (Double_t)X[i+1];
+    y = (Double_t)Y[i+1];
+    smatrix(0,0) += 1.0;
+    smatrix(1,1) += x*x;
+    smatrix(0,1) += x;
+    smatrix(1,0) += x;
+    sums(0,0)    += y;
+    sums(1,0)    += x*y;
+  }
+  res = smatrix.Invert() * sums;
+  A = res(0,0);
+  B = res(1,0);
+
+  Float_t dist = AliTRDgeometry::GetTime0(1) - AliTRDgeometry::GetTime0(0);
+
+  Float_t fX1 = X[1]          + dist * (Float_t)(nTracklets-1)/6.0;
+  Float_t fY1 = A + B * fX1;
+  Float_t fX2 = X[nTracklets] - dist * (Float_t)(nTracklets-1)/6.0;
+  Float_t fY2 = A + B * fX2;
+  Float_t D12 = TMath::Sqrt((fX2-fX1)*(fX2-fX1)+(fY2-fY1)*(fY2-fY1));
+  Float_t Alpha = TMath::ATan(fY2/fX2) - TMath::ATan(fY1/fX1);
+  Float_t R = (D12/2.0)/TMath::Sin(Alpha);
+
+  fPt = 0.3 * field * 0.01 * R;
+
+  Float_t D1 = fX1*fX1+fY1*fY1;
+  Float_t D2 = fX2*fX2+fY2*fY2;
+  Float_t D  = fX1*fY2-fX2*fY1;
+  
+  Float_t Xc = (D1*fY2-D2*fY1)/(2*D);
+  Float_t Yc = (D2*fX1-D1*fX2)/(2*D);
+
+  if (Yc != 0.0) {
+    fPhi = TMath::ATan(Xc/Yc);
+  } else {
+    fPhi = TMath::PiOver2();
+  }
+
+  fPhi *= 180.0/TMath::Pi();
+
+  smatrix.Zero();
+  sums.Zero();
+  for (Int_t i = 0; i < nTracklets+1; i++) {
+    x = (Double_t)Z[i];
+    y = (Double_t)X[i];
+    smatrix(0,0) += 1.0;
+    smatrix(1,1) += x*x;
+    smatrix(0,1) += x;
+    smatrix(1,0) += x;
+    sums(0,0)    += y;
+    sums(1,0)    += x*y;
+  }
+  res = smatrix.Invert() * sums;
+  A = res(0,0);
+  B = res(1,0);
+  Float_t theta = TMath::ATan(B);
+  
+  if (theta < 0.0) theta = TMath::Pi() + theta;
+  
+  if (theta == 0.0) {
+    fEta = 0.0;
+  } else {
+    fEta = -TMath::Log(TMath::Tan(theta/2.0));
+  }
+  
+}
+
+//_____________________________________________________________________________
+void AliTRDgtuTrack::MakePID()
+{
+
+  //
+  // Electron likelihood signal
+  //
+
+  AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
+  if (!calibration)
+  {
+    Error("MakePID","No instance of AliTRDcalibDB.");
+    return;  
+  }
+  const AliTRDCalPIDLQ *pd = calibration->GetPIDLQObject();
+  
+  AliTRDltuTracklet *trk;
+  Int_t nTracklets = GetNtracklets();
+  Int_t det, pla;
+  Float_t sl, th, q, probPio = 1.0, probEle = 1.0;
+  for (Int_t i = 0; i < nTracklets; i++) {
+
+    trk = GetTracklet(i);
+
+    sl = TMath::Abs(trk->GetSlope());     // tracklet inclination in X-y plane
+    th = trk->GetRowz()/trk->GetTime0();  // tracklet inclination in X-z plane
+    th = TMath::ATan(TMath::Abs(th));
+
+    q = trk->GetQ() 
+      * TMath::Cos(sl/180.0*TMath::Pi()) 
+      * TMath::Cos(th/180.0*TMath::Pi());
+
+    det = trk->GetDetector();
+    pla = trk->GetPlane(det);
+
+    // unclear yet factor to match the PS distributions = 5.8
+    // not explained only by the tail filter ...
+
+    // AliRoot v4-03-07 , v4-03-Release
+    //q = q * 5.8;
+
+    // Temporary (B. Vulpescu):
+    // The charge distributions do not match the new changes in simulation (A. Bercuci),
+    // which are nevertheless now in agreement with the beam tests.
+    // Some tricks will be used to still have reasonable results
+    // To match the existing charge distributions, the charge per layer has to be modified
+    // as folows:
+    /*
+      if (k == 0) {
+      // electrons
+      q = 4.3 * q + 95.0;
+      } else {
+      // others
+      q = 4.2 * q + 70.0;
+      }
+    */
+    // Since at tracking time we have no information on the particle type, we will modify
+    // instead the charge distributions accordingly. This will slow down the sampling.
+    // The modified distributions are in TRDdEdxHistogramsV1_BV.root and the CDB has
+    // been regenerated with AliTRDCreateDummyCDB.C
+    // The new PIDLQ data base has the version :
+    // I-AliCDBLocal::Get: CDB object retrieved: path "TRD/Calib/PIDLQ"; run range [0,0];
+    // version v0_s1
+
+    probEle *= pd->GetProbability(0,TMath::Abs(fPt),q);
+    probPio *= pd->GetProbability(2,TMath::Abs(fPt),q);
+
+  }
+
+  if ((probEle+probPio) > 0.0) {
+    fPID = probEle/(probEle+probPio);
+  } else {
+    fPID = 0.0;
+  }
+
+  // Thresholds for LQ cut at 90% electron efficiency (from AliRoot v4-03-07)
+  // P [GeV/c]  fPIDcut (between 0 and 1)
+  // 2          0.925
+  // 3          0.915
+  // 4          0.875
+  // 5          0.855
+  // 6          0.845
+  // 8          0.785
+  // 10         0.735
+  //
+  // PIDcut = 0.978 - 0.024 * P[GeV/c]
+  //Float_t PIDcut = 0.978 - 0.024 * TMath::Abs(fPt);
+
+  // HEAD28Mar06 with modified distributions (A. Bercuci changes, P. Shukla distributions)
+  Float_t PIDcut = 0.829 - 0.032 * TMath::Abs(fPt);
+
+  fIsElectron = kFALSE;
+  if (fPID >= PIDcut) {
+    fIsElectron = kTRUE;
+  }
+
+}
+
+//_____________________________________________________________________________
+void AliTRDgtuTrack::CookLabel()
+{
+
+  //
+  // Cook the track label from tracklets labels
+  //
+
+  AliTRDltuTracklet *trk;
+
+  const Int_t kMaxTracks = 10;
+  Int_t trackLabel[kMaxTracks];
+  Int_t trackCount[kMaxTracks];
+  for (Int_t it = 0; it < kMaxTracks; it++) {
+    trackLabel[it] = -1;
+    trackCount[it] = 0;
+  }
+
+  Bool_t counted;
+  Int_t label, nTracks = 0;
+  for (Int_t itrk = 0; itrk < fNtracklets; itrk++) {
+
+    trk = GetTracklet(itrk);
+
+    if (trk->GetLabel() == -1) continue;
+
+    label = trk->GetLabel();
+
+    counted = kFALSE;
+    for (Int_t it = 0; it < nTracks; it++) {
+      if (label == trackLabel[it]) {
+       trackCount[it]++;
+       counted = kTRUE;
+       break;
+      }
+    }
+    if (!counted) {
+      trackLabel[nTracks] = label;
+      trackCount[nTracks]++;
+      nTracks++;
+      if (nTracks == kMaxTracks) {
+       Warning("CookLabel","Too many tracks for this tracklet.");
+       nTracks--;
+       break;
+      }
+    }
+    
+  }
+
+  Float_t frac = 4.0/5.0;
+  for (Int_t it = 0; it < kMaxTracks; it++) {
+    if (trackCount[it] >= (Int_t)(frac*fNtracklets)) {
+      fLabel = trackLabel[it];
+      break;
+    }
+  }
+
+}
+
+//_____________________________________________________________________________
+AliTRDmodule::AliTRDmodule(AliTRDtrigParam *trigp) 
+{
+
+  //
+  // AliTRDmodule default constructor
+  //
+
+  fDeltaY     = trigp->GetDeltaY();
+  fDeltaS     = trigp->GetDeltaS();
+  fXprojPlane = trigp->GetXprojPlane();
+  fField      = trigp->GetField();
+  fLTUtrk     = 0;
+  fGTUtrk     = 0;
+  fTracklets  = new TObjArray(400);
+  fTracks     = new TObjArray(400);
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::Reset() 
+{
+
+  ResetTracklets();
+  ResetTracks();
+
+  fLTUtrk     = 0;
+  fGTUtrk     = 0;
+  fTracklets  = new TObjArray(400);
+  fTracks     = new TObjArray(400);
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::ResetTracks() 
+{
+
+  if (fTracks) {
+
+    AliTRDgtuTrack *trk;
+    for (Int_t i = 0; i < GetNtracks(); i++) {
+      
+      trk = GetTrack(i);
+      trk->Reset();
+      
+    }
+
+    fTracks->Delete();
+
+  }
+
+}
+
+//_____________________________________________________________________________
+AliTRDgtuTrack* AliTRDmodule::GetTrack(Int_t pos)
+{
+
+  if (fTracks == 0) return 0;
+  void * trk = fTracks->UncheckedAt(pos);
+  if (trk == 0) return 0;
+
+  return (AliTRDgtuTrack*)trk;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::RemoveTrack(Int_t pos)
+{
+
+  if (fTracks == 0) return;
+  fTracks->RemoveAt(pos);
+  fTracks->Compress();
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::AddTracklet(Int_t det, 
+                              Int_t row, 
+                              Float_t rowz,
+                              Float_t slope, 
+                              Float_t offset, 
+                              Float_t time, 
+                              Int_t ncl,
+                              Int_t label,
+                              Float_t q) 
+{
+  
+  fLTUtrk = new AliTRDltuTracklet(det,row,rowz,slope,offset,time,ncl,label,q);
+  
+  Tracklets()->Add(fLTUtrk);
+
+}
+
+//_____________________________________________________________________________
+AliTRDltuTracklet* AliTRDmodule::GetTracklet(Int_t pos)
+{
+
+  if (fTracklets == 0) return 0;
+  void * trk = fTracklets->UncheckedAt(pos);
+  if (trk == 0) return 0;
+
+  return (AliTRDltuTracklet*)trk;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::RemoveTracklet(Int_t pos)
+{
+
+  if (fTracklets == 0) return;
+  fTracklets->RemoveAt(pos);
+  fTracklets->Compress();
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::RemoveMultipleTracklets()
+{
+
+  Float_t OffDiffMin = 0.5;  // [cm]
+
+  AliTRDltuTracklet *trk;
+  Int_t Det1, Det2, Row1, Row2, Ncl1, Ncl2, Label1, Label2;
+  Float_t Off1, Off2;
+  Int_t itrk = 0;
+  while (itrk < (GetNtracklets()-1)) {
+
+    trk = GetTracklet(itrk  );
+
+    Det1 = trk->GetDetector();
+    Row1 = trk->GetRow();
+    Off1 = trk->GetOffset();
+    Ncl1 = trk->GetNclusters();
+    Label1 = trk->GetLabel();
+
+    trk = GetTracklet(itrk+1);
+
+    Det2 = trk->GetDetector();
+    Row2 = trk->GetRow();
+    Off2 = trk->GetOffset();
+    Ncl2 = trk->GetNclusters();
+    Label2 = trk->GetLabel();
+
+    if (Det1 == Det2 && Row1 == Row2) {
+      if ((Off2-Off1) < OffDiffMin) {
+       if (Ncl1 < Ncl2) {
+         RemoveTracklet(itrk  );
+       } else {
+         RemoveTracklet(itrk+1);
+       }
+      }
+    }
+
+    itrk++;
+
+  }
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::SortZ(Int_t cha)
+{
+
+  InitZLUT();
+
+  AliTRDltuTracklet *trk;
+  Int_t row, pla, det;
+  for (Int_t iTrk = 0; iTrk < GetNtracklets(); iTrk++) {
+
+    trk = GetTracklet(iTrk);
+
+    row = trk->GetRow();
+    det = trk->GetDetector();
+    pla = trk->GetPlane(det);
+
+    for (Int_t iZchan = 0; iZchan < kNsubZchan; iZchan++) {
+      if (fZChannelMap[cha][iZchan][pla][row] == 1) {
+       fZtrkid[pla][fZnchan[pla][iZchan]][iZchan] = iTrk;
+       fZnchan[pla][iZchan]++;
+      }
+    }
+
+  }
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::InitZLUT()
+{
+
+  for (Int_t iPlan = 0; iPlan < AliTRDgeometry::Nplan(); iPlan++) {
+    for (Int_t i = 0; i < kNsubZchan; i++) {
+      fZnchan[iPlan][i] = 0;
+      for (Int_t j = 0; j < kNmaxZchan; j++) {
+        fZtrkid[iPlan][j][i] = -1;
+      }
+    }
+  }
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::FindTracks() 
+{
+
+  for (Int_t iZchan = 0; iZchan < kNsubZchan; iZchan++) {
+    FindTracksCombi(iZchan);
+  }
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::FindTracksCombi(Int_t zchan) 
+{
+
+  //
+  // find tracks by pure combinatorics...
+  //
+  
+  static Int_t TrkTrack[12];
+  
+  Int_t nTracklets, nPlanes;
+  Int_t Ntrk1, TrkId1, Ntrk2, TrkId2;
+  Float_t Y1, Y1min, Y1max, S1, Z1, S1min, S1max, Y2, S2, Z2;
+  AliTRDltuTracklet *Trk1;
+  AliTRDltuTracklet *Trk2;
+  AliTRDltuTracklet *Trk ;
+
+  Bool_t IsPlane[kNplan];
+
+  for (Int_t iPlan1 = 0; iPlan1 < kNplan; iPlan1++) {
+
+    Ntrk1 = fZnchan[iPlan1][zchan];
+
+    for (Int_t iTrk1 = 0; iTrk1 < Ntrk1; iTrk1++) {
+
+      for (Int_t iPlan = 0; iPlan < kNplan; iPlan++) IsPlane[iPlan] = kFALSE;
+
+      TrkId1 = fZtrkid[iPlan1][iTrk1][zchan];
+
+      nTracklets = 0;
+      for (Int_t iList = 0; iList < kNmaxTrk; iList++) {
+       TrkTrack[iList] = -1;
+      }
+
+      TrkTrack[nTracklets++] = TrkId1;
+
+      IsPlane[iPlan1] = kTRUE;
+
+      Trk1 = GetTracklet(TrkId1);
+
+      Y1    = Trk1->GetYproj(fXprojPlane);
+      Y1min = Y1 - fDeltaY;
+      Y1max = Y1 + fDeltaY;
+      S1    = Trk1->GetSlope();
+      S1min = S1 - fDeltaS;
+      S1max = S1 + fDeltaS;
+      Z1    = Trk1->GetZproj(fXprojPlane);      
+
+      for (Int_t iPlan2 = 0; iPlan2 < kNplan; iPlan2++) {
+
+       if (iPlan2 == iPlan1) continue;
+
+       Ntrk2 = fZnchan[iPlan2][zchan];
+
+       for (Int_t iTrk2 = 0; iTrk2 < Ntrk2; iTrk2++) {
+
+         TrkId2 = fZtrkid[iPlan2][iTrk2][zchan];
+
+         if (TrkId2 == TrkId1) continue;
+
+         Trk2 = GetTracklet(TrkId2);
+
+         Y2 = Trk2->GetYproj(fXprojPlane);
+         S2 = Trk2->GetSlope();
+         Z2 = Trk2->GetZproj(fXprojPlane);
+
+         if ((Y1min < Y2 && Y2 < Y1max) && 
+             (S1min < S2 && S2 < S1max)) {
+
+           if (nTracklets >= kNmaxTrk) {
+             Warning("FindTracksCombi","Too many tracklets for this track.");
+           } else {
+             TrkTrack[nTracklets++] = TrkId2;
+             IsPlane[iPlan2] = kTRUE;
+           }
+
+         }
+
+       }  // end trk 2
+
+      }  // end plan 2
+
+      nPlanes = 0;
+      for (Int_t iPlan = 0; iPlan < kNplan; iPlan++) {
+       nPlanes += (Int_t)IsPlane[iPlan];
+      }
+      
+      if (nPlanes >= 4) {
+
+       Int_t Cha1, Cha2, Npoints1, Npoints2;
+       for (Int_t iList = 0; iList < (nTracklets-1); iList++) {
+
+         if (TrkTrack[iList] == -1 || TrkTrack[iList+1] == -1) continue;
+         Trk1 = GetTracklet(TrkTrack[iList  ]);
+         Trk2 = GetTracklet(TrkTrack[iList+1]);
+
+         Cha1 = Trk1->GetDetector();
+         Cha2 = Trk2->GetDetector();
+         if (Cha1 != Cha2) continue;
+
+         Npoints1 = Trk1->GetNclusters();
+         Npoints2 = Trk2->GetNclusters();
+
+         if (Npoints1 == Npoints2) {
+           TrkTrack[iList] = -1;
+         } else {
+           if (Npoints1 > Npoints2) TrkTrack[iList+1] = -1;
+           if (Npoints1 < Npoints2) TrkTrack[iList  ] = -1;
+         }
+
+       }
+
+       fGTUtrk = new AliTRDgtuTrack();
+       for (Int_t iList = 0; iList < nTracklets; iList++) {
+         if (TrkTrack[iList] == -1) continue;
+         Trk = GetTracklet(TrkTrack[iList]);
+         fGTUtrk->AddTracklet(Trk);
+       }
+       fGTUtrk->Track(fXprojPlane,fField);
+       AddTrack();
+      }
+           
+    }  // end trk 1
+
+  }  // end plan 1
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::AddTrack() 
+{
+  
+  Tracks()->Add(fGTUtrk);
+
+}
+
+//_____________________________________________________________________________
+void AliTRDmodule::RemoveMultipleTracks()
+{
+
+  AliTRDgtuTrack *trk1;
+  AliTRDgtuTrack *trk2;
+
+  Float_t Yproj1, Yproj2, Alpha1, Alpha2;
+  Int_t ntrk1, ntrk2;
+  Int_t iTrack = 0;
+
+  while (iTrack < (GetNtracks()-1)) {
+
+    trk1 = GetTrack(iTrack  );
+    trk2 = GetTrack(iTrack+1);
+
+    ntrk1  = trk1->GetNtracklets();
+    Yproj1 = trk1->GetYproj();
+    Alpha1 = trk1->GetSlope();
+    ntrk2  = trk2->GetNtracklets();
+    Yproj2 = trk2->GetYproj();
+    Alpha2 = trk2->GetSlope();
+
+    if (TMath::Abs(Yproj1-Yproj2) < fDeltaY && TMath::Abs(Alpha1-Alpha2) < fDeltaS) {
+      if (ntrk1 < ntrk2) {
+       RemoveTrack(iTrack  );
+      } else {
+       RemoveTrack(iTrack+1);
+      }
+    } else {
+      iTrack++;
+    }
+    
+  }
+
+}
+
+//_____________________________________________________________________________
+AliTRDtrigger::AliTRDtrigger():
+  TNamed(),
+  fTracks("AliTRDgtuTrack",0)
+{
+  //
+  // AliTRDtrigger default constructor
+  //
+
+  fDigitsManager = NULL;
+  fTrackletTree = NULL;
+  fTracklets     = NULL;
+
+  fNROB = 0;
+  fTrigParam = NULL;
+  fMCM = NULL;
+  fTrk = NULL;
+  fGTUtrk = NULL;
+
+  fNtracklets = 0;
+
+  fDigits = NULL;
+  fTrack0 = NULL;
+  fTrack1 = NULL;
+  fTrack2 = NULL;
+
+  fModule = NULL;
+
+  fNPrimary = 0;
+
+}
+
+//_____________________________________________________________________________
+AliTRDtrigger::AliTRDtrigger(const Text_t *name, const Text_t *title):
+  TNamed(name,title),
+  fTracks("AliTRDgtuTrack",1000)
+{
+  //
+  // AliTRDtrigger constructor
+  //
+
+  fDigitsManager = new AliTRDdigitsManager();
+  fTrackletTree = NULL;
+  fTracklets = new TObjArray(400);
+
+  fNROB = 0;
+  fTrigParam = NULL;
+  fMCM = NULL;
+  fTrk = NULL;
+  fGTUtrk = NULL;
+
+  fNtracklets = 0;
+
+  fDigits = NULL;
+  fTrack0 = NULL;
+  fTrack1 = NULL;
+  fTrack2 = NULL;
+
+  fModule = NULL;
+
+  fNPrimary = 0;
+
+}
+
+//_____________________________________________________________________________
+AliTRDtrigger::AliTRDtrigger(const AliTRDtrigger &p):TNamed(p)
+{
+  //
+  // AliTRDtrigger copy constructor
+  //
+
+  ((AliTRDtrigger &) p).Copy(*this);
+
+}
+
+///_____________________________________________________________________________
+AliTRDtrigger::~AliTRDtrigger()
+{
+  //
+  // AliTRDtrigger destructor
+  //
+
+  if (fTracklets) {
+    fTracklets->Delete();
+    delete fTracklets;
+  }
+
+  fTracks.Delete();
+
+}
+
+//_____________________________________________________________________________
+AliTRDtrigger &AliTRDtrigger::operator=(const AliTRDtrigger &p)
+{
+  //
+  // Assignment operator
+  //
+
+  if (this != &p) ((AliTRDtrigger &) p).Copy(*this);
+  return *this;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDtrigger::Copy(TObject &) const
+{
+  //
+  // Copy function
+  //
+
+  AliFatal("Not implemented");
+
+}
+
+//_____________________________________________________________________________
+void AliTRDtrigger::Init()
+{
+
+  fModule = new AliTRDmodule(fTrigParam); 
+  /*
+  AliHeader *header = fRunLoader->GetHeader();
+  fNPrimary = header->GetNprimary();
+  */
+  fTracks.Clear();
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrigger::Open(const Char_t *name, Int_t nEvent)
+{
+  //
+  // Opens the AliROOT file.
+  //
+
+  TString evfoldname = AliConfig::GetDefaultEventFolderName();
+  fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
+
+  if (!fRunLoader)
+    fRunLoader = AliRunLoader::Open(name);
+
+  if (!fRunLoader) {
+    Error("Open","Can not open session for file %s.",name);
+    return kFALSE;
+  }
+
+  // Open input
+
+  if (fRunLoader->GetAliRun() == 0x0) fRunLoader->LoadgAlice();
+  gAlice = fRunLoader->GetAliRun();
+
+  if (!(gAlice)) {
+    fRunLoader->LoadgAlice();
+    gAlice = fRunLoader->GetAliRun();
+    if (!(gAlice)) {
+      Error("Open","Could not find AliRun object.");
+      return kFALSE;
+    }
+  }
+
+  // Import the Trees for the event nEvent in the file
+  fRunLoader->GetEvent(nEvent);
+
+  // Open output
+
+  TObjArray *ioArray = 0;
+
+  AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
+  loader->MakeTree("T");
+  fTrackletTree = loader->TreeT();
+  fTrackletTree->Branch("TRDmcmTracklet","TObjArray",&ioArray,32000,0);
+
+  fRunLoader->LoadHeader();
+
+  Init();
+
+  return kTRUE;
+
+}
+
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrigger::ReadDigits() 
+{
+  //
+  // Reads the digits arrays from the input aliroot file
+  //
+
+  if (!fRunLoader) {
+    Error("ReadDigits","Can not find the Run Loader");
+    return kFALSE;
+  }
+
+  AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
+  if (!loader->TreeD()) loader->LoadDigits();
+
+  return (fDigitsManager->ReadDigits(loader->TreeD()));
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrigger::ReadDigits(AliRawReader* rawReader)
+{
+  //
+  // Reads the digits arrays from the ddl file
+  //
+
+  AliTRDrawData *raw = new AliTRDrawData();
+  raw->SetDebug(1);
+
+  fDigitsManager = raw->Raw2Digits(rawReader);
+
+  return kTRUE;
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrigger::ReadTracklets(AliRunLoader *rl) 
+{
+  //
+  // Reads the tracklets find the tracks
+  //
+
+  Int_t idet;
+
+  AliLoader *loader = rl->GetLoader("TRDLoader");
+  loader->LoadTracks();
+  fTrackletTree = loader->TreeT();
+
+  TBranch *branch = fTrackletTree->GetBranch("TRDmcmTracklet");
+  if (!branch) {
+    Error("ReadTracklets","Can't get the branch !");
+    return kFALSE;
+  }
+  TObjArray *tracklets = new TObjArray(400);
+  branch->SetAddress(&tracklets);
+
+  Int_t nEntries = (Int_t) fTrackletTree->GetEntries();
+  Int_t iEntry, itrk;
+  Int_t iStack, iStackPrev = -1;
+  
+  for (iEntry = 0; iEntry < nEntries; iEntry++) {    
+    fTrackletTree->GetEvent(iEntry);
+    
+    for (itrk = 0; itrk < tracklets->GetEntriesFast(); itrk++){
+
+      fTrk = (AliTRDmcmTracklet*)tracklets->UncheckedAt(itrk);
+      
+      idet = fTrk->GetDetector();
+
+      iStack = idet / (AliTRDgeometry::Nplan());
+      if (iStackPrev != iStack) {
+       if (iStackPrev == -1) {
+         iStackPrev = iStack;
+       } else {
+         MakeTracks(idet-AliTRDgeometry::Nplan());
+         ResetTracklets();
+         iStackPrev = iStack;
+       }
+      }
+      
+      Tracklets()->Add(fTrk);
+
+      if (iEntry == (nEntries-1) && itrk == (tracklets->GetEntriesFast()-1)) {
+       idet++;
+       MakeTracks(idet-AliTRDgeometry::Nplan());
+       ResetTracklets();
+      }
+
+    }
+
+  }
+
+  loader->UnloadTracks();
+
+  return kTRUE;
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrigger::MakeTracklets()
+{
+
+  AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
+  if (!calibration)
+  {
+    Error("MakeTracklets","No instance of AliTRDcalibDB.");
+    return kFALSE;  
+  }
+  
+  AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
+  if (!commonParam)
+  {
+    Error("MakeTracklets","No common params.");
+    return kFALSE;
+  }
+    
+  AliTRDgeometry *geo = AliTRDgeometry::GetGeometry(fRunLoader);
+
+  Int_t    chamBeg = 0;
+  Int_t    chamEnd = AliTRDgeometry::Ncham();
+  Int_t    planBeg = 0;
+  Int_t    planEnd = AliTRDgeometry::Nplan();
+  Int_t    sectBeg = 0;
+  Int_t    sectEnd = AliTRDgeometry::Nsect();
+
+  fMCM = new AliTRDmcm(fTrigParam,0);
+
+  Int_t time, col, row, col1, col2;
+  Float_t amp;
+  Int_t idet, iStack, iStackPrev;
+  iStack     = -1;
+  iStackPrev = -1;
+  for (Int_t isect = sectBeg; isect < sectEnd; isect++) {
+
+    for (Int_t icham = chamBeg; icham < chamEnd; icham++) {
+
+      // number of ROBs in the chamber
+      if( icham == 2 ) {
+       fNROB = 6;
+      } else {
+       fNROB = 8;
+      }
+
+      for (Int_t iplan = planBeg; iplan < planEnd; iplan++) {
+
+        idet = geo->GetDetector(iplan,icham,isect);
+       ResetTracklets();
+       /*
+       iStack = idet / (AliTRDgeometry::Nplan());
+       if (iStackPrev != iStack) {
+         if (iStackPrev == -1) {
+           iStackPrev = iStack;
+         } else {
+           MakeTracks(idet-AliTRDgeometry::Nplan());
+           ResetTracklets();
+           iStackPrev = iStack;
+         }
+       }
+       */
+        Int_t    nRowMax     = commonParam->GetRowMax(iplan,icham,isect);
+       Int_t    nColMax     = commonParam->GetColMax(iplan);
+        Int_t    nTimeTotal  = calibration->GetNumberOfTimeBins();
+
+        // Get the digits
+        fDigits = fDigitsManager->GetDigits(idet);
+        fDigits->Expand();
+        fTrack0 = fDigitsManager->GetDictionary(idet,0);
+        fTrack0->Expand();
+        fTrack1 = fDigitsManager->GetDictionary(idet,1);
+        fTrack1->Expand();
+        fTrack2 = fDigitsManager->GetDictionary(idet,2); 
+        fTrack2->Expand();
+
+
+       for (Int_t iRob = 0; iRob < fNROB; iRob++) {
+
+         for (Int_t iMcm = 0; iMcm < kNMCM; iMcm++) {
+
+           fMCM->Reset();
+
+           fMCM->SetRobId(iRob);
+           fMCM->SetChaId(idet);
+
+           SetMCMcoordinates(iMcm);
+
+           row = fMCM->GetRow();
+
+           if (row < 0 || row > nRowMax) {
+             Error("MakeTracklets","MCM row number out of range.");
+           }
+
+           fMCM->GetColRange(col1,col2);
+           
+            for (time = 0; time < nTimeTotal; time++) {
+             for (col = col1; col < col2; col++) {
+               if (col >= 0 && col < nColMax) {
+                 amp = TMath::Abs(fDigits->GetDataUnchecked(row,col,time));
+               } else {
+                 amp = 0.0;
+               }
+               fMCM->SetADC(col-col1,time,amp);
+
+             }
+           }
+
+           if (fTrigParam->GetTailCancelation()) {
+             fMCM->Filter(fTrigParam->GetNexponential(),fTrigParam->GetFilterType());
+           }
+           
+           if (fMCM->Run()) {
+
+             for (Int_t iSeed = 0; iSeed < kMaxTrackletsPerMCM; iSeed++) {
+               
+               if (fMCM->GetSeedCol()[iSeed] < 0) continue;
+
+               if ( fTrigParam->GetDebugLevel() > 1 ) 
+                 printf("Add tracklet %d in col %02d \n",fNtracklets,fMCM->GetSeedCol()[iSeed]);
+
+               if ( fTrigParam->GetDebugLevel() == -1 ) {
+                 printf("Add tracklet %d in col %02d \n",fNtracklets,fMCM->GetSeedCol()[iSeed]);
+                 for (time = 0; time < nTimeTotal; time++) {
+                   for (col = 0; col < kMcmCol; col++) {                   
+                     printf("%03.0f  ",fMCM->GetADC(col,time));
+                   }
+                   printf("\n");
+                 }
+               }
+
+               AddTracklet(idet,row,iSeed,fNtracklets++);
+
+             }
+
+           }
+
+         }
+
+      
+       }
+
+       // Compress the arrays
+        fDigits->Compress(1,0);
+        fTrack0->Compress(1,0);
+        fTrack1->Compress(1,0);
+        fTrack2->Compress(1,0);
+
+       WriteTracklets(idet);
+
+     }
+    }
+  }
+  /*
+  idet++;
+  MakeTracks(idet-AliTRDgeometry::Nplan());
+  ResetTracklets();
+  */
+  return kTRUE;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDtrigger::SetMCMcoordinates(Int_t imcm)
+{
+
+  Int_t robid = fMCM->GetRobId();
+
+  // setting the Row and Col range
+
+  const Int_t kNcolRob = 2;  // number of ROBs per chamber in column direction
+  const Int_t kNmcmRob = 4;  // number of MCMs per ROB in column/row direction
+
+  Int_t mcmid = imcm%(kNmcmRob*kNmcmRob);
+
+  if (robid%kNcolRob == 0) {
+
+    if ( mcmid%kNmcmRob == 0 ) {
+      fMCM->SetColRange(18*0-1,18*1-1+2+1);
+    }
+    if ( mcmid%kNmcmRob == 1 ) {
+      fMCM->SetColRange(18*1-1,18*2-1+2+1);
+    }
+    if ( mcmid%kNmcmRob == 2 ) {
+      fMCM->SetColRange(18*2-1,18*3-1+2+1);
+    }
+    if ( mcmid%kNmcmRob == 3 ) {
+      fMCM->SetColRange(18*3-1,18*4-1+2+1);
+    }
+
+  } else {
+
+    if ( mcmid%kNmcmRob == 0 ) {
+      fMCM->SetColRange(18*4-1,18*5-1+2+1);
+    }
+    if ( mcmid%kNmcmRob == 1 ) {
+      fMCM->SetColRange(18*5-1,18*6-1+2+1);
+    }
+    if ( mcmid%kNmcmRob == 2 ) {
+      fMCM->SetColRange(18*6-1,18*7-1+2+1);
+    }
+    if ( mcmid%kNmcmRob == 3 ) {
+      fMCM->SetColRange(18*7-1,18*8-1+2+1);
+    }
+
+  } 
+
+  fMCM->SetRow(kNmcmRob*(robid/kNcolRob)+mcmid/kNmcmRob);
+
+}
+
+//_____________________________________________________________________________
+void AliTRDtrigger::AddTracklet(Int_t det, Int_t row, Int_t seed, Int_t n)
+{
+
+  Float_t field = fTrigParam->GetField();
+  AliTRDgeometry *geo = (AliTRDgeometry*)AliTRDgeometry::GetGeometry(fRunLoader);
+
+  AliTRDcalibDB* calibration = AliTRDcalibDB::Instance();
+  if (!calibration)
+  {
+    Error("AddTracklets","No instance of AliTRDcalibDB.");
+    return;  
+  }
+  
+  Int_t nTimeTotal  = calibration->GetNumberOfTimeBins();
+
+  fTrk = new AliTRDmcmTracklet(det,row,n);
+
+  Int_t iCol, iCol1, iCol2, track[3];
+  iCol = fMCM->GetSeedCol()[seed];  // 0....20 (MCM)
+  fMCM->GetColRange(iCol1,iCol2);   // range in the pad plane
+           
+  Float_t Amp[3];
+  for (Int_t iTime = 0; iTime < nTimeTotal; iTime++) {
+
+    Amp[0] = fMCM->GetADC(iCol-1,iTime);
+    Amp[1] = fMCM->GetADC(iCol  ,iTime);
+    Amp[2] = fMCM->GetADC(iCol+1,iTime);
+
+    // extract track contribution only from the central pad
+    track[0] = fTrack0->GetDataUnchecked(row,iCol+iCol1,iTime);
+    track[1] = fTrack1->GetDataUnchecked(row,iCol+iCol1,iTime);
+    track[2] = fTrack2->GetDataUnchecked(row,iCol+iCol1,iTime);
+
+    if (fMCM->IsCluster(iCol,iTime)) {
+
+      fTrk->AddCluster(iCol+iCol1,iTime,Amp,track);
+
+    } else if ((iCol+1+1) < kMcmCol) {
+
+      Amp[0] = fMCM->GetADC(iCol-1+1,iTime);
+      Amp[1] = fMCM->GetADC(iCol  +1,iTime);
+      Amp[2] = fMCM->GetADC(iCol+1+1,iTime);
+
+      if (fMCM->IsCluster(iCol+1,iTime)) {
+
+       // extract track contribution only from the central pad
+       track[0] = fTrack0->GetDataUnchecked(row,iCol+1+iCol1,iTime);
+       track[1] = fTrack1->GetDataUnchecked(row,iCol+1+iCol1,iTime);
+       track[2] = fTrack2->GetDataUnchecked(row,iCol+1+iCol1,iTime);
+
+       fTrk->AddCluster(iCol+1+iCol1,iTime,Amp,track);
+
+      }
+
+    } else {
+    }
+
+  }
+
+  fTrk->CookLabel(0.8);  
+  /*
+  if (fTrk->GetLabel() >= fNPrimary) {
+    Info("AddTracklet","Only primaries are stored!");
+    return;
+  }
+  */
+  // LTU Pt cut
+  fTrk->MakeTrackletGraph(geo,field);
+  fTrk->MakeClusAmpGraph();
+  if (TMath::Abs(fTrk->GetPt()) < fTrigParam->GetLtuPtCut()) return;
+      
+  Tracklets()->Add(fTrk);
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrigger::WriteTracklets(Int_t det) 
+{
+  //
+  // Fills TRDmcmTracklet branch in the tree with the Tracklets 
+  // found in detector = det. For det=-1 writes the tree. 
+  //
+
+  if ((det < -1) || (det >= AliTRDgeometry::Ndet())) {
+    Error("WriteTracklets","Unexpected detector index %d.",det);
+    return kFALSE;
+  }
+
+  TBranch *branch = fTrackletTree->GetBranch("TRDmcmTracklet");
+  if (!branch) {
+    TObjArray *ioArray = 0;
+    branch = fTrackletTree->Branch("TRDmcmTracklet","TObjArray",&ioArray,32000,0);
+  }
+
+  if ((det >= 0) && (det < AliTRDgeometry::Ndet())) {
+
+    Int_t nTracklets = Tracklets()->GetEntriesFast();
+    TObjArray *detTracklets = new TObjArray(400);
+
+    for (Int_t i = 0; i < nTracklets; i++) {
+      AliTRDmcmTracklet *trk = (AliTRDmcmTracklet *) Tracklets()->UncheckedAt(i);
+      
+      if (det == trk->GetDetector()) {
+        detTracklets->AddLast(trk);
+      }
+      else {
+      }
+    }
+
+    branch->SetAddress(&detTracklets);
+    fTrackletTree->Fill();
+
+    delete detTracklets;
+
+    return kTRUE;
+
+  }
+
+  if (det == -1) {
+
+    Info("WriteTracklets","Writing the Tracklet tree %s for event %d."
+        ,fTrackletTree->GetName(),fRunLoader->GetEventNumber());
+
+    AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
+    loader->WriteTracks("OVERWRITE");
+    
+    return kTRUE;  
+
+  }
+
+  return kFALSE;
+
+}
+
+//_____________________________________________________________________________
+void AliTRDtrigger::MakeTracks(Int_t det)
+{
+  //
+  // Create GTU tracks per module (stack of 6 chambers)
+  //
+  
+  fModule->Reset();
+
+  AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance();
+  if (!commonParam)
+  {
+    Error("MakeTracks","No common params.");
+    return;
+  }
+    
+  Int_t nRowMax, iplan, icham, isect, row;
+
+  AliTRDgeometry *geo = (AliTRDgeometry*)AliTRDgeometry::GetGeometry(fRunLoader);
+
+  if ((det < 0) || (det >= AliTRDgeometry::Ndet())) {
+    Error("MakeTracks","Unexpected detector index %d.",det);
+    return;
+  }
+  
+  Int_t nTracklets = Tracklets()->GetEntriesFast();
+  
+  AliTRDmcmTracklet *trk;
+  for (Int_t i = 0; i < nTracklets; i++) {
+    
+    trk = (AliTRDmcmTracklet *) Tracklets()->UncheckedAt(i);
+    
+    iplan = geo->GetPlane(trk->GetDetector());
+    icham = geo->GetChamber(trk->GetDetector());
+    isect = geo->GetSector(trk->GetDetector());
+
+    nRowMax = commonParam->GetRowMax(iplan,icham,isect);
+    row = trk->GetRow();
+
+    fModule->AddTracklet(trk->GetDetector(),
+                        row,
+                        trk->GetRowz(),
+                        trk->GetSlope(),
+                        trk->GetOffset(),
+                        trk->GetTime0(),
+                        trk->GetNclusters(),
+                        trk->GetLabel(),
+                        trk->GetdQdl());
+    
+  }
+
+  fModule->SortTracklets();
+  fModule->RemoveMultipleTracklets();
+  fModule->SortZ((Int_t)geo->GetChamber(det));
+  fModule->FindTracks();
+  fModule->SortTracks();
+  fModule->RemoveMultipleTracks();
+
+  Int_t nModTracks = fModule->GetNtracks();
+  AliTRDgtuTrack *gtutrk;
+  for (Int_t i = 0; i < nModTracks; i++) {
+    gtutrk = (AliTRDgtuTrack*)fModule->GetTrack(i);
+    if (TMath::Abs(gtutrk->GetPt()) < fTrigParam->GetGtuPtCut()) continue;
+    gtutrk->CookLabel();
+    gtutrk->MakePID();
+    AddTrack(gtutrk,det);
+  }
+  
+}
+
+
diff --git a/TRD/AliTRDtrigger.h b/TRD/AliTRDtrigger.h
new file mode 100644 (file)
index 0000000..672dd4b
--- /dev/null
@@ -0,0 +1,311 @@
+#ifndef ALITRDTRIGGER_H
+#define ALITRDTRIGGER_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+//  TRD trigger class                                                        //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#include <TObjArray.h>
+#include <TClonesArray.h>
+#include <TNamed.h>
+#include <TFile.h>
+
+#include "AliTRDzmaps.h"
+#include "AliRunLoader.h"
+#include "AliLoader.h"
+
+const Int_t kNplan     =   6;
+const Int_t kNmaxZchan = 100;       // max number of tracklets per subchannel
+const Int_t kNsubZchan =  16;       // total number of subchannels
+const Int_t kNmaxTrk   =  12;       // max number of tracklets in one track (6*2)
+
+class AliTRDltuTracklet : public TObject {
+  
+ public:
+
+  AliTRDltuTracklet(Int_t det, 
+                   Int_t row, 
+                   Float_t rowz,
+                   Float_t slope, 
+                   Float_t offset, 
+                   Float_t time, 
+                   Int_t ncl,
+                   Int_t label,
+                   Float_t q);
+  ~AliTRDltuTracklet(){};
+
+  Bool_t  IsSortable() const { return kTRUE; }
+  virtual Int_t   Compare(const TObject *o) const;
+  Int_t   GetDetector() { return fDetector; };
+  Int_t   GetPlane(Int_t det) { return ((Int_t) (det % kNplan)); };
+  Int_t   GetRow()      { return fRow; };
+  Int_t   GetNclusters(){ return fNclusters; };
+  Float_t GetSlope()    { return fSlope; };
+  Float_t GetOffset()   { return fY; };
+  Float_t GetTime0()    { return fX; };
+  Float_t GetRowz()     { return fRowz; };
+  virtual Float_t GetYproj(Float_t xpl);
+  virtual Float_t GetZproj(Float_t xpl);
+  Int_t   GetLabel()    { return fLabel; };
+  Float_t GetPt(Float_t field);
+  Float_t GetQ() { return fQ; };
+
+ protected:
+
+  Float_t fX;                              // distance vertex to entrance window
+  Float_t fY;                              // tracklet offset at entrance window
+  Float_t fSlope;
+  Float_t fRowz;
+  Int_t   fDetector;
+  Int_t   fRow;
+  Int_t   fNclusters;
+  Int_t   fLabel;
+  Float_t fQ;                              // charge sum divided by number of clusters
+
+  ClassDef(AliTRDltuTracklet,1)
+
+};
+
+class AliTRDltuTracklet;
+
+class AliTRDgtuTrack : public TObject {
+
+ public:
+
+  AliTRDgtuTrack();
+  AliTRDgtuTrack(const AliTRDgtuTrack& track);
+  ~AliTRDgtuTrack(){};
+
+  Bool_t  IsSortable() const { return kTRUE; }
+  virtual Int_t   Compare(const TObject *o) const;
+
+  virtual void Reset();
+  void  ResetTracklets() { if(fTracklets) fTracklets->Delete(); };
+  virtual void AddTracklet(AliTRDltuTracklet *trk);
+  virtual AliTRDltuTracklet *GetTracklet(Int_t pos);
+  TObjArray     *Tracklets() { 
+    if(!fTracklets) fTracklets = new TObjArray(400); return fTracklets; 
+  };
+  Int_t          GetNtracklets() {
+    if (fTracklets) return fTracklets->GetEntriesFast();
+    return 0;
+  };
+  Float_t GetYproj()     { return fYproj; };
+  Float_t GetZproj()     { return fZproj; };
+  Float_t GetSlope()     { return fSlope; };
+  Int_t   GetTracklets() { return fNtracklets; };
+  Int_t   GetPlanes()    { return fNplanes; };
+  Int_t   GetClusters()  { return fNclusters; };
+  Float_t GetPt()        { return fPt; };
+  Float_t GetPhi()       { return fPhi; };
+  Float_t GetEta()       { return fEta; };
+  Int_t   GetLabel()     { return fLabel; };
+
+  virtual void Track(Float_t xpl, Float_t field);
+
+  virtual void CookLabel();
+
+  void  SetDetector(Int_t det) { fDetector = det; };
+  Int_t GetDetector() { return fDetector; };
+
+  virtual void MakePID();
+  Float_t GetPID() { return fPID; };
+
+  Bool_t  IsElectron() { return fIsElectron; };
+
+ protected:
+
+  TObjArray          *fTracklets;                   //! Array of LTU tracklets
+
+  Float_t fYproj;                                   // Average values calculated
+  Float_t fZproj;                                   // from the tracklets 
+  Float_t fSlope;
+
+  Int_t   fDetector;                                // First detector in the module
+
+  Int_t   fNtracklets;                              // Number of tracklets
+  Int_t   fNplanes;                                 // Number of TRD planes
+  Int_t   fNclusters;                               // Total number of clusters
+
+  Float_t fPt;                                      // Transverse momentum
+  Float_t fPhi;                                     // Phi angle at the vertex
+  Float_t fEta;                                     // Eta at the vertex
+  Int_t   fLabel;                                   // Track label
+  Float_t fPID;                                     // PID electron likelihood
+  Bool_t  fIsElectron;                              // Electron flag
+
+  ClassDef(AliTRDgtuTrack,1)
+
+};
+
+class AliTRDgtuTrack;
+class AliTRDtrigParam;
+
+class AliTRDmodule : public TObject {
+
+ public:
+
+  AliTRDmodule(AliTRDtrigParam *trigp);
+
+  virtual void   Reset();
+
+  virtual void   AddTracklet(Int_t det, 
+                            Int_t row, 
+                            Float_t rowz,
+                            Float_t slope, 
+                            Float_t offset, 
+                            Float_t time, 
+                            Int_t ncl,
+                            Int_t label,
+                            Float_t q);
+
+  TObjArray     *Tracklets() { 
+    if(!fTracklets) fTracklets = new TObjArray(400); return fTracklets; 
+  };
+
+  void           ResetTracklets() { if(fTracklets) fTracklets->Delete(); };
+  void           SortTracklets()  { if(fTracklets) fTracklets->Sort(); };
+  virtual AliTRDltuTracklet *GetTracklet(Int_t pos);
+  virtual void   RemoveMultipleTracklets();
+  virtual void   RemoveTracklet(Int_t pos);
+  Int_t          GetNtracklets() {
+    if (fTracklets) return fTracklets->GetEntriesFast();
+    return 0;
+  };
+
+  virtual void   AddTrack();
+
+  TObjArray     *Tracks() { 
+    if(!fTracks) fTracks = new TObjArray(400); return fTracks; 
+  };
+
+  virtual void   ResetTracks();
+  void           SortTracks()  { if(fTracks) fTracks->Sort(); };
+  virtual AliTRDgtuTrack *GetTrack(Int_t pos);
+  virtual void   RemoveMultipleTracks();
+  virtual void   RemoveTrack(Int_t pos);
+  Int_t          GetNtracks() {
+    if (fTracks) return fTracks->GetEntriesFast();
+    return 0;
+  };
+
+  virtual void   SortZ(Int_t cha);
+  virtual void   InitZLUT();
+  virtual void   FindTracks();
+  virtual void   FindTracksCombi(Int_t zchan);
+
+ protected:
+
+  Float_t             fXprojPlane;                  //! X (time) coordinate of the
+                                                    //  projection plane
+  Float_t             fField;                       //! Magnetic field
+  TObjArray          *fTracklets;                   //! Array of LTU tracklets
+  TObjArray          *fTracks;                      //! Array of GTU tracks
+
+  Int_t fZnchan[kNplan][kNsubZchan];                //! number of LTU tracklets in each 
+                                                    //  subchannel
+  Int_t fZtrkid[kNplan][kNmaxZchan][kNsubZchan];    //! list of LTU tracklet id's for 
+                                                    //  each subchannel
+
+  Float_t  fDeltaY;                        // Y (offset) matching window in the GTU
+  Float_t  fDeltaS;                        // Slope matching window in the GTU
+
+  AliTRDltuTracklet  *fLTUtrk;                      //! Current LTU tracklet
+  AliTRDgtuTrack     *fGTUtrk;                      //! Current GTU track
+
+  ClassDef(AliTRDmodule,1)
+
+};
+
+class AliTRDdigitsManager;
+class AliTRDdataArrayI;
+
+class AliRunLoader;
+class AliRawReader;
+
+class AliTRDmcmTracklet;
+class AliTRDmcm;
+class AliTRDmodule;
+
+class TTree;
+
+class AliTRDtrigger : public TNamed {
+
+ public:  
+
+  enum { kNMCM = 16 };
+
+  AliTRDtrigger();
+  AliTRDtrigger(const Text_t* name, const Text_t* title);
+  AliTRDtrigger(const AliTRDtrigger &p);   
+  virtual ~AliTRDtrigger();
+
+  AliTRDtrigger &operator=(const AliTRDtrigger &p); 
+  virtual void Copy(TObject &p) const;
+
+  virtual void Init();
+
+  void SetRunLoader(AliRunLoader *rl) { fRunLoader = rl; };
+  virtual Bool_t Open(const Char_t *name, Int_t nEvent = 0);
+  virtual Bool_t ReadDigits();
+  virtual Bool_t ReadDigits(AliRawReader* rawReader);
+  virtual Bool_t MakeTracklets();
+  virtual Bool_t WriteTracklets(Int_t det);
+  virtual Bool_t ReadTracklets(AliRunLoader *rl);
+
+  virtual void   AddTracklet(Int_t det, Int_t row, Int_t seed, Int_t n);
+  TObjArray     *Tracklets() { 
+    if(!fTracklets) fTracklets = new TObjArray(400); return fTracklets; 
+  };
+  void           ResetTracklets() { if(fTracklets) fTracklets->Delete(); };
+  virtual void   SetMCMcoordinates(Int_t imcm);
+  virtual void   SetParameter(AliTRDtrigParam *trigp) { fTrigParam = trigp; };
+  AliTRDtrigParam *GetParameter() { return fTrigParam; };
+
+  virtual void   MakeTracks(Int_t det);
+
+  AliTRDgtuTrack *GetTrack(Int_t i) const {
+    return (AliTRDgtuTrack *)fTracks.UncheckedAt(i);
+  }
+  void AddTrack(const AliTRDgtuTrack *t, Int_t det) {
+    AliTRDgtuTrack * track = new(fTracks[fTracks.GetEntriesFast()]) AliTRDgtuTrack(*t);
+    track->SetDetector(det);
+  }
+  Int_t GetNumberOfTracks() const {return fTracks.GetEntriesFast();}
+
+  Int_t GetNPrimary() { return fNPrimary; };
+
+ protected:
+
+  AliTRDtrigParam       *fTrigParam;                   //! Trigger class parameters
+  AliRunLoader          *fRunLoader;                   //! Run Loader
+  AliTRDdigitsManager   *fDigitsManager;               //! TRD digits manager
+  TTree                 *fTrackletTree;                //! Tree with tracklets
+  TObjArray             *fTracklets;                   //! Array of tracklets
+
+  Int_t                  fNROB;                        //! Number of ROBs in the current chamber
+  AliTRDmcm             *fMCM;                         //! Current MCM
+  AliTRDmcmTracklet     *fTrk;                         //! Current tracklet
+  AliTRDmodule          *fModule;                      //! Current module
+  AliTRDgtuTrack        *fGTUtrk;                      //! Current GTU track
+
+  Int_t                  fNtracklets;                  //! Tracklets counter
+
+  AliTRDdataArrayI *fDigits;                           //! Array with digits
+  AliTRDdataArrayI *fTrack0;                           //! Track dictionary 0
+  AliTRDdataArrayI *fTrack1;                           //! Track dictionary 1
+  AliTRDdataArrayI *fTrack2;                           //! Track dictionary 2
+
+  Int_t fNPrimary;                                     //! Number of primary tracks
+
+  TClonesArray           fTracks;                      //! Array of GTU tracks
+
+  ClassDef(AliTRDtrigger,1)                            //  TRD trigger class
+
+};
+
+#endif
diff --git a/TRD/AliTRDzmaps.h b/TRD/AliTRDzmaps.h
new file mode 100644 (file)
index 0000000..03b1f8d
--- /dev/null
@@ -0,0 +1,1146 @@
+#ifndef ALITRDZMAPS_H
+#define ALITRDZMAPS_H
+
+///////////////////////////////////////////////////////
+//  Z maps for Z-sorting channels                    //
+///////////////////////////////////////////////////////
+
+/* This file has been generated by zChannelGen.cxx */
+
+/* Access as: ZChannelMap[chamber][channel][plane][row] */
+
+const Int_t fZChannelMap[5][16][6][16] = {
+
+{  /* --- Chamber 0 --- */
+
+/*  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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 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 . . . . . . . . . . . . . . .  */
+
+{{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},
+ {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, 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, 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 . . . . . . . . . . . . .  */
+
+{{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, 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}},
+
+/*  . . . 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, 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, 1, 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, 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, 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 . . . . . . . . . .  */
+
+{{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, 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 . . . . . . . . .  */
+
+{{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, 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 . . . . . . . .  */
+
+{{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, 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, 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 . . . . . . .  */
+
+{{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, 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, 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 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, 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, 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 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, 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, 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 . . . .  */
+
+{{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, 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, 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 . . .  */
+
+{{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, 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, 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 . .  */
+
+{{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, 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, 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, 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, 1, 1, 0}}},
+
+{  /* --- Chamber 1 --- */
+
+/*  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, 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},
+ {0, 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 . . . . . . . . . . . . . . .  */
+
+{{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, 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 . . . . . . . . . . . . . .  */
+
+{{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, 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 . . . . . . . . . . . . .  */
+
+{{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, 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 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, 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, 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 . . . . . . . . . .  */
+
+{{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, 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 . . . . . . . . .  */
+
+{{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, 1, 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, 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, 1, 1, 1, 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, 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, 1, 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, 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, 1, 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, 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, 1, 1, 1, 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, 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, 1, 1, 1, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . . . . 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, 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, 1, 1, 1, 0, 0, 0}},
+
+/*  . . . . . . . . . . . . . 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, 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, 1, 1, 1, 0, 0}},
+
+/*  . . . . . . . . . . . . . . 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, 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, 1, 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, 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, 1, 1, 1}}},
+
+{  /* --- Chamber 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}}},
+
+{  /* --- Chamber 3 --- */
+
+/*  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, 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, 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 . . . . . . . . . . . .  */
+
+{{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, 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 . . . . . . . . . . .  */
+
+{{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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+
+/*  . . x 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, 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, 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, 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, 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, 1, 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, 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, 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, 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, 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, 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, 1, 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, 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, 1, 0, 0, 0, 0}},
+
+/*  . . . . . . . . . x 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, 1, 0, 0, 0}},
+
+/*  . . . . . . . . . . x 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, 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, 1, 0, 0}},
+
+/*  . . . . . . . . . . . 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, 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, 0, 1, 1, 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, 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, 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 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, 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, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
+
+/*  . . . . . . . . . . . . . . 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, 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, 0, 0}}},
+
+{  /* --- Chamber 4 --- */
+
+/*  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},
+ {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},
+ {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 . . . . . . . . . . . .  */
+
+{{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},
+ {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, 0, 0, 0, 0, 0, 0}},
+
+/*  . 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, 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, 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, 0, 0, 0, 0, 0}},
+
+/*  . . 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, 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, 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, 0, 0, 0, 0}},
+
+/*  . . . 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, 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, 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, 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, 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}},
+
+/*  . . . . . 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, 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}},
+
+/*  . . . . . . 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, 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}},
+
+/*  . . . . . . . x x x . . . . . .  */
+/*  . . . . . . . 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, 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, 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}},
+
+/*  . . . . . . . . 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, 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, 0, 1, 1, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 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, 0, 1, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 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, 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, 0, 1, 1, 1, 0}},
+
+/*  . . . . . . . . . . . . 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, 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, 0, 1, 1, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 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, 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  */
+/*  . . . . . . . . . . . . . . . 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, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
+
+/*  . . . . . . . . . . . . . . . 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, 0, 1},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}
+
+};
+
+#endif
diff --git a/TRD/Calib/PIDLQ/Run0_0_v0_s1.root b/TRD/Calib/PIDLQ/Run0_0_v0_s1.root
new file mode 100644 (file)
index 0000000..fdb2891
Binary files /dev/null and b/TRD/Calib/PIDLQ/Run0_0_v0_s1.root differ
diff --git a/TRD/TRDdEdxHistogramsV1_BV.root b/TRD/TRDdEdxHistogramsV1_BV.root
new file mode 100644 (file)
index 0000000..dad1c19
Binary files /dev/null and b/TRD/TRDdEdxHistogramsV1_BV.root differ
index e4c9663..8871a3a 100644 (file)
 #pragma link C++ class  AliTRDReconstructor+;
 #pragma link C++ class  AliTRDRecParam+;
 
+#pragma link C++ class  AliTRDtrigger+;
+#pragma link C++ class  AliTRDtrigParam+;
+#pragma link C++ class  AliTRDmcmTracklet+;
+#pragma link C++ class  AliTRDmcm+;
+#pragma link C++ class  AliTRDltuTracklet+;
+#pragma link C++ class  AliTRDgtuTrack+;
+#pragma link C++ class  AliTRDmodule+;
+
 #endif
index 7b58537..c59179b 100644 (file)
@@ -13,7 +13,11 @@ SRCS= AliTRDpixel.cxx \
       AliTRDPartID.cxx \
       AliTRDpidESD.cxx \
       AliTRDRecParam.cxx \
-      AliTRDReconstructor.cxx
+      AliTRDReconstructor.cxx \
+      AliTRDmcmTracklet.cxx \
+      AliTRDmcm.cxx \
+      AliTRDtrigParam.cxx \
+      AliTRDtrigger.cxx
 
 HDRS= $(SRCS:.cxx=.h)