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