1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // TRD cluster finder //
22 ///////////////////////////////////////////////////////////////////////////////
28 #include <TClonesArray.h>
29 #include <TObjArray.h>
31 #include "AliRunLoader.h"
32 #include "AliLoader.h"
33 #include "AliRawReader.h"
35 #include "AliAlignObj.h"
37 #include "AliTRDclusterizer.h"
38 #include "AliTRDcluster.h"
39 #include "AliTRDReconstructor.h"
40 #include "AliTRDgeometry.h"
41 #include "AliTRDarraySignal.h"
42 #include "AliTRDarrayDictionary.h"
43 #include "AliTRDarrayADC.h"
44 #include "AliTRDdigitsManager.h"
45 #include "AliTRDrawData.h"
46 #include "AliTRDcalibDB.h"
47 #include "AliTRDrecoParam.h"
48 #include "AliTRDCommonParam.h"
49 #include "AliTRDtransform.h"
50 #include "AliTRDSignalIndex.h"
51 #include "AliTRDrawStreamBase.h"
52 #include "AliTRDfeeParam.h"
54 #include "TTreeStream.h"
56 #include "Cal/AliTRDCalROC.h"
57 #include "Cal/AliTRDCalDet.h"
58 #include "Cal/AliTRDCalSingleChamberStatus.h"
60 ClassImp(AliTRDclusterizer)
62 //_____________________________________________________________________________
63 AliTRDclusterizer::AliTRDclusterizer(const AliTRDReconstructor *const rec)
70 ,fDigitsManager(new AliTRDdigitsManager(rec))
71 ,fTrackletContainer(NULL)
74 ,fTransform(new AliTRDtransform(0))
83 ,fMinLeftRightCutSigma(0)
89 ,fCalGainFactorROC(NULL)
90 ,fCalGainFactorDetValue(0)
98 // AliTRDclusterizer default constructor
101 AliTRDcalibDB *trd = 0x0;
102 if (!(trd = AliTRDcalibDB::Instance())) {
103 AliFatal("Could not get calibration object");
106 fRawVersion = AliTRDfeeParam::Instance()->GetRAWversion();
108 // Initialize debug stream
110 if(fReconstructor->GetStreamLevel(AliTRDReconstructor::kClusterizer) > 1){
111 TDirectory *savedir = gDirectory;
112 //fgGetDebugStream = new TTreeSRedirector("TRD.ClusterizerDebug.root");
119 //_____________________________________________________________________________
120 AliTRDclusterizer::AliTRDclusterizer(const Text_t *name, const Text_t *title, const AliTRDReconstructor *const rec)
127 ,fDigitsManager(new AliTRDdigitsManager(rec))
128 ,fTrackletContainer(NULL)
131 ,fTransform(new AliTRDtransform(0))
140 ,fMinLeftRightCutSigma(0)
146 ,fCalGainFactorROC(NULL)
147 ,fCalGainFactorDetValue(0)
149 ,fCalNoiseDetValue(0)
155 // AliTRDclusterizer constructor
158 AliTRDcalibDB *trd = 0x0;
159 if (!(trd = AliTRDcalibDB::Instance())) {
160 AliFatal("Could not get calibration object");
163 fDigitsManager->CreateArrays();
165 fRawVersion = AliTRDfeeParam::Instance()->GetRAWversion();
171 //_____________________________________________________________________________
172 AliTRDclusterizer::AliTRDclusterizer(const AliTRDclusterizer &c)
174 ,fReconstructor(c.fReconstructor)
179 ,fDigitsManager(NULL)
180 ,fTrackletContainer(NULL)
192 ,fMinLeftRightCutSigma(0)
198 ,fCalGainFactorROC(NULL)
199 ,fCalGainFactorDetValue(0)
201 ,fCalNoiseDetValue(0)
207 // AliTRDclusterizer copy constructor
214 //_____________________________________________________________________________
215 AliTRDclusterizer::~AliTRDclusterizer()
218 // AliTRDclusterizer destructor
221 if (fRecPoints/* && IsClustersOwner()*/){
222 fRecPoints->Delete();
226 if (fDigitsManager) {
227 delete fDigitsManager;
228 fDigitsManager = NULL;
231 if (fTrackletContainer){
232 delete fTrackletContainer;
233 fTrackletContainer = NULL;
253 //_____________________________________________________________________________
254 AliTRDclusterizer &AliTRDclusterizer::operator=(const AliTRDclusterizer &c)
257 // Assignment operator
262 ((AliTRDclusterizer &) c).Copy(*this);
269 //_____________________________________________________________________________
270 void AliTRDclusterizer::Copy(TObject &c) const
276 ((AliTRDclusterizer &) c).fClusterTree = NULL;
277 ((AliTRDclusterizer &) c).fRecPoints = NULL;
278 ((AliTRDclusterizer &) c).fTrackletTree = NULL;
279 ((AliTRDclusterizer &) c).fDigitsManager = NULL;
280 ((AliTRDclusterizer &) c).fTrackletContainer = NULL;
281 ((AliTRDclusterizer &) c).fAddLabels = fAddLabels;
282 ((AliTRDclusterizer &) c).fRawVersion = fRawVersion;
283 ((AliTRDclusterizer &) c).fTransform = NULL;
284 ((AliTRDclusterizer &) c).fLUTbin = 0;
285 ((AliTRDclusterizer &) c).fLUT = NULL;
286 ((AliTRDclusterizer &) c).fDigitsIn = NULL;
287 ((AliTRDclusterizer &) c).fIndexes = NULL;
288 ((AliTRDclusterizer &) c).fADCthresh = 0;
289 ((AliTRDclusterizer &) c).fMaxThresh = 0;
290 ((AliTRDclusterizer &) c).fSigThresh = 0;
291 ((AliTRDclusterizer &) c).fMinMaxCutSigma= 0;
292 ((AliTRDclusterizer &) c).fMinLeftRightCutSigma = 0;
293 ((AliTRDclusterizer &) c).fLayer = 0;
294 ((AliTRDclusterizer &) c).fDet = 0;
295 ((AliTRDclusterizer &) c).fVolid = 0;
296 ((AliTRDclusterizer &) c).fColMax = 0;
297 ((AliTRDclusterizer &) c).fTimeTotal = 0;
298 ((AliTRDclusterizer &) c).fCalGainFactorROC = NULL;
299 ((AliTRDclusterizer &) c).fCalGainFactorDetValue = 0;
300 ((AliTRDclusterizer &) c).fCalNoiseROC = NULL;
301 ((AliTRDclusterizer &) c).fCalNoiseDetValue = 0;
302 ((AliTRDclusterizer &) c).fDigitsOut = NULL;
303 ((AliTRDclusterizer &) c).fClusterROC = 0;
304 ((AliTRDclusterizer &) c).firstClusterROC= 0;
308 //_____________________________________________________________________________
309 Bool_t AliTRDclusterizer::Open(const Char_t *name, Int_t nEvent)
312 // Opens the AliROOT file. Output and input are in the same file
315 TString evfoldname = AliConfig::GetDefaultEventFolderName();
316 fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
319 fRunLoader = AliRunLoader::Open(name);
323 AliError(Form("Can not open session for file %s.",name));
334 //_____________________________________________________________________________
335 Bool_t AliTRDclusterizer::OpenOutput()
338 // Open the output file
341 if (!fReconstructor->IsWritingClusters()) return kTRUE;
343 TObjArray *ioArray = 0x0;
345 AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
346 loader->MakeTree("R");
348 fClusterTree = loader->TreeR();
349 fClusterTree->Branch("TRDcluster", "TObjArray", &ioArray, 32000, 0);
355 //_____________________________________________________________________________
356 Bool_t AliTRDclusterizer::OpenOutput(TTree *clusterTree)
359 // Connect the output tree
363 if (fReconstructor->IsWritingClusters()){
364 TObjArray *ioArray = 0x0;
365 fClusterTree = clusterTree;
366 fClusterTree->Branch("TRDcluster", "TObjArray", &ioArray, 32000, 0);
370 if (fReconstructor->IsWritingTracklets()){
371 TString evfoldname = AliConfig::GetDefaultEventFolderName();
372 fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
375 fRunLoader = AliRunLoader::Open("galice.root");
378 AliError(Form("Can not open session for file galice.root."));
382 UInt_t **leaves = new UInt_t *[2];
383 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
385 AliError("Could not get the tracklets data loader!");
386 dl = new AliDataLoader("TRD.Tracklets.root","tracklets", "tracklets");
387 fRunLoader->GetLoader("TRDLoader")->AddDataLoader(dl);
390 fTrackletTree = dl->Tree();
394 fTrackletTree = dl->Tree();
396 TBranch *trkbranch = fTrackletTree->GetBranch("trkbranch");
398 fTrackletTree->Branch("trkbranch",leaves[0],"det/i:side/i:tracklets[256]/i");
406 //_____________________________________________________________________________
407 Bool_t AliTRDclusterizer::OpenInput(Int_t nEvent)
410 // Opens a ROOT-file with TRD-hits and reads in the digits-tree
413 // Import the Trees for the event nEvent in the file
414 fRunLoader->GetEvent(nEvent);
420 //_____________________________________________________________________________
421 Bool_t AliTRDclusterizer::WriteClusters(Int_t det)
424 // Fills TRDcluster branch in the tree with the clusters
425 // found in detector = det. For det=-1 writes the tree.
429 (det >= AliTRDgeometry::Ndet())) {
430 AliError(Form("Unexpected detector index %d.\n",det));
434 TObjArray *ioArray = new TObjArray(400);
435 TBranch *branch = fClusterTree->GetBranch("TRDcluster");
437 branch = fClusterTree->Branch("TRDcluster","TObjArray",&ioArray,32000,0);
438 } else branch->SetAddress(&ioArray);
440 Int_t nRecPoints = RecPoints()->GetEntriesFast();
442 for (Int_t i = 0; i < nRecPoints; i++) {
443 AliTRDcluster *c = (AliTRDcluster *) RecPoints()->UncheckedAt(i);
444 if(det != c->GetDetector()) continue;
447 fClusterTree->Fill();
451 for (Int_t i = 0; i < nRecPoints; i++) {
452 AliTRDcluster *c = (AliTRDcluster *) RecPoints()->UncheckedAt(i);
453 if(c->GetDetector() != detOld){
454 fClusterTree->Fill();
456 detOld = c->GetDetector();
467 //_____________________________________________________________________________
468 Bool_t AliTRDclusterizer::WriteTracklets(Int_t det)
471 // Write the raw data tracklets into seperate file
474 UInt_t **leaves = new UInt_t *[2];
475 for (Int_t i=0; i<2 ;i++){
476 leaves[i] = new UInt_t[258];
477 leaves[i][0] = det; // det
478 leaves[i][1] = i; // side
479 memcpy(leaves[i]+2, fTrackletContainer[i], sizeof(UInt_t) * 256);
483 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
485 fTrackletTree = dl->Tree();
488 TBranch *trkbranch = fTrackletTree->GetBranch("trkbranch");
490 trkbranch = fTrackletTree->Branch("trkbranch",leaves[0],"det/i:side/i:tracklets[256]/i");
493 for (Int_t i=0; i<2; i++){
494 if (leaves[i][2]>0) {
495 trkbranch->SetAddress(leaves[i]);
496 fTrackletTree->Fill();
500 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
501 dl->WriteData("OVERWRITE");
509 //_____________________________________________________________________________
510 Bool_t AliTRDclusterizer::ReadDigits()
513 // Reads the digits arrays from the input aliroot file
517 AliError("No run loader available");
521 AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
522 if (!loader->TreeD()) {
523 loader->LoadDigits();
526 // Read in the digit arrays
527 return (fDigitsManager->ReadDigits(loader->TreeD()));
531 //_____________________________________________________________________________
532 Bool_t AliTRDclusterizer::ReadDigits(TTree *digitsTree)
535 // Reads the digits arrays from the input tree
538 // Read in the digit arrays
539 return (fDigitsManager->ReadDigits(digitsTree));
543 //_____________________________________________________________________________
544 Bool_t AliTRDclusterizer::ReadDigits(AliRawReader *rawReader)
547 // Reads the digits arrays from the ddl file
551 fDigitsManager = raw.Raw2Digits(rawReader);
557 //_____________________________________________________________________________
558 Bool_t AliTRDclusterizer::MakeClusters()
561 // Creates clusters from digits
564 // Propagate info from the digits manager
565 if (fAddLabels == kTRUE){
566 fAddLabels = fDigitsManager->UsesDictionaries();
569 Bool_t fReturn = kTRUE;
570 for (Int_t i = 0; i < AliTRDgeometry::kNdet; i++){
572 AliTRDarrayADC *digitsIn = (AliTRDarrayADC*) fDigitsManager->GetDigits(i); //mod
573 // This is to take care of switched off super modules
574 if (!digitsIn->HasData()) continue;
576 digitsIn->DeleteNegatives(); // Restore digits array to >=0 values
577 AliTRDSignalIndex* indexes = fDigitsManager->GetIndexes(i);
578 if (indexes->IsAllocated() == kFALSE){
579 fDigitsManager->BuildIndexes(i);
583 if (indexes->HasEntry()){
585 for (Int_t iDict = 0; iDict < AliTRDdigitsManager::kNDict; iDict++){
586 AliTRDarrayDictionary *tracksIn = 0; //mod
587 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(i,iDict); //mod
591 fR = MakeClusters(i);
592 fReturn = fR && fReturn;
596 // if(IsWritingClusters()) WriteClusters(i);
600 // No compress just remove
601 fDigitsManager->RemoveDigits(i);
602 fDigitsManager->RemoveDictionaries(i);
603 fDigitsManager->ClearIndexes(i);
606 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
608 AliInfo(Form("Number of found clusters : %d", RecPoints()->GetEntriesFast()));
614 //_____________________________________________________________________________
615 Bool_t AliTRDclusterizer::Raw2Clusters(AliRawReader *rawReader)
618 // Creates clusters from raw data
621 return Raw2ClustersChamber(rawReader);
625 //_____________________________________________________________________________
626 Bool_t AliTRDclusterizer::Raw2ClustersChamber(AliRawReader *rawReader)
629 // Creates clusters from raw data
632 // Create the digits manager
633 if (!fDigitsManager){
634 fDigitsManager = new AliTRDdigitsManager(fReconstructor);
635 fDigitsManager->CreateArrays();
638 fDigitsManager->SetUseDictionaries(fAddLabels);
640 // tracklet container for raw tracklet writing
641 if (!fTrackletContainer && fReconstructor->IsWritingTracklets()) {
642 // maximum tracklets for one HC
643 const Int_t kTrackletChmb=256;
644 fTrackletContainer = new UInt_t *[2];
645 fTrackletContainer[0] = new UInt_t[kTrackletChmb];
646 fTrackletContainer[1] = new UInt_t[kTrackletChmb];
649 AliTRDrawStreamBase *input = AliTRDrawStreamBase::GetRawStream(rawReader);
651 AliInfo(Form("Stream version: %s", input->IsA()->GetName()));
654 while ((det = input->NextChamber(fDigitsManager,fTrackletContainer)) >= 0){
655 Bool_t iclusterBranch = kFALSE;
656 if (fDigitsManager->GetIndexes(det)->HasEntry()){
657 iclusterBranch = MakeClusters(det);
660 fDigitsManager->ResetArrays(det);
662 if (!fReconstructor->IsWritingTracklets()) continue;
663 if (*(fTrackletContainer[0]) > 0 || *(fTrackletContainer[1]) > 0) WriteTracklets(det);
666 if (fReconstructor->IsWritingTracklets()){
667 delete [] fTrackletContainer[0];
668 delete [] fTrackletContainer[1];
669 delete [] fTrackletContainer;
670 fTrackletContainer = NULL;
673 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
675 delete fDigitsManager;
676 fDigitsManager = NULL;
681 AliInfo(Form("Number of found clusters : %d", RecPoints()->GetEntriesFast()));
686 //_____________________________________________________________________________
687 UChar_t AliTRDclusterizer::GetStatus(Short_t &signal)
690 // Check if a pad is masked
695 if(signal>0 && TESTBIT(signal, 10)){
697 for(int ibit=0; ibit<4; ibit++){
698 if(TESTBIT(signal, 11+ibit)){
699 SETBIT(status, ibit);
700 CLRBIT(signal, 11+ibit);
707 //_____________________________________________________________________________
708 void AliTRDclusterizer::SetPadStatus(const UChar_t status, UChar_t &out){
710 // Set the pad status into out
711 // First three bits are needed for the position encoding
716 //_____________________________________________________________________________
717 UChar_t AliTRDclusterizer::GetPadStatus(UChar_t encoding) const {
719 // return the staus encoding of the corrupted pad
721 return static_cast<UChar_t>(encoding >> 3);
724 //_____________________________________________________________________________
725 Int_t AliTRDclusterizer::GetCorruption(UChar_t encoding) const {
727 // Return the position of the corruption
732 //_____________________________________________________________________________
733 Bool_t AliTRDclusterizer::MakeClusters(Int_t det)
736 // Generates the cluster.
740 // digits should be expanded beforehand!
741 // digitsIn->Expand();
742 fDigitsIn = (AliTRDarrayADC *) fDigitsManager->GetDigits(det); //mod
744 // This is to take care of switched off super modules
745 if (!fDigitsIn->HasData())
750 fIndexes = fDigitsManager->GetIndexes(det);
751 if (fIndexes->IsAllocated() == kFALSE)
753 AliError("Indexes do not exist!");
757 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
760 AliFatal("No AliTRDcalibDB instance available\n");
766 if (!fReconstructor){
767 AliError("Reconstructor not set\n");
771 TTreeSRedirector *fDebugStream = fReconstructor->GetDebugStream(AliTRDReconstructor::kClusterizer);
773 fMaxThresh = fReconstructor->GetRecoParam()->GetClusMaxThresh();
774 fSigThresh = fReconstructor->GetRecoParam()->GetClusSigThresh();
775 fMinMaxCutSigma = fReconstructor->GetRecoParam()->GetMinMaxCutSigma();
776 fMinLeftRightCutSigma = fReconstructor->GetRecoParam()->GetMinLeftRightCutSigma();
778 Int_t istack = fIndexes->GetStack();
779 fLayer = fIndexes->GetLayer();
780 Int_t isector = fIndexes->GetSM();
782 // Start clustering in the chamber
784 fDet = AliTRDgeometry::GetDetector(fLayer,istack,isector);
786 AliError("Strange Detector number Missmatch!");
790 // TRD space point transformation
791 fTransform->SetDetector(det);
793 Int_t iGeoLayer = AliGeomManager::kTRD1 + fLayer;
794 Int_t iGeoModule = istack + AliTRDgeometry::Nstack() * isector;
795 fVolid = AliGeomManager::LayerToVolUID(iGeoLayer,iGeoModule);
797 fColMax = fDigitsIn->GetNcol();
798 Int_t nRowMax = fDigitsIn->GetNrow();
799 fTimeTotal = fDigitsIn->GetNtime();
801 // Detector wise calibration object for the gain factors
802 const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
803 // Calibration object with pad wise values for the gain factors
804 fCalGainFactorROC = calibration->GetGainFactorROC(fDet);
805 // Calibration value for chamber wise gain factor
806 fCalGainFactorDetValue = calGainFactorDet->GetValue(fDet);
808 // Detector wise calibration object for the noise
809 const AliTRDCalDet *calNoiseDet = calibration->GetNoiseDet();
810 // Calibration object with pad wise values for the noise
811 fCalNoiseROC = calibration->GetNoiseROC(fDet);
812 // Calibration value for chamber wise noise
813 fCalNoiseDetValue = calNoiseDet->GetValue(fDet);
815 if(fDigitsOut) delete fDigitsOut;
816 fDigitsOut = new AliTRDarraySignal(nRowMax, fColMax, fTimeTotal);
818 firstClusterROC = -1;
821 // Apply the gain and the tail cancelation via digital filter
824 MaxStruct curr, last;
826 Int_t nMaximas = 0, nCorrupted = 0;
829 // Here the clusterfining is happening
831 for(curr.Time = 0; curr.Time < fTimeTotal; curr.Time++)
832 while(fIndexes->NextRCIndex(curr.Row, curr.Col))
833 if(IsMaximum(curr, curr.padStatus, &curr.Signals[0]))
837 last.Signals[0] *= Ratio;
838 if(curr.Row==last.Row && curr.Col==last.Col+2)
840 if(IsFivePadCluster(last, curr, Ratio))
842 last.Signals[2] *= Ratio;
852 last.Signals[0] *= Ratio;
856 if(fReconstructor->GetStreamLevel(AliTRDReconstructor::kClusterizer) > 2){
857 (*fDebugStream) << "MakeClusters"
858 << "Detector=" << det
859 << "NMaxima=" << nMaximas
860 << "NClusters=" << fClusterROC
861 << "NCorrupted=" << nCorrupted
866 AddLabels(fDet,firstClusterROC,fClusterROC);
873 //_____________________________________________________________________________
874 Bool_t AliTRDclusterizer::IsMaximum(const MaxStruct &Max, UChar_t &padStatus, Float_t *const Signals)
877 // Returns true if this row,col,time combination is a maximum.
878 // Gives back the padStatus and the signals of the center pad and the two neighbouring pads.
881 Signals[1] = fDigitsOut->GetData(Max.Row, Max.Col, Max.Time);
882 if(Signals[1] < fMaxThresh) return kFALSE;
884 Float_t noiseMiddleThresh = fMinMaxCutSigma*fCalNoiseDetValue*fCalNoiseROC->GetValue(Max.Col, Max.Row);
885 if (Signals[1] < noiseMiddleThresh) return kFALSE;
887 if (Max.Col + 1 >= fColMax || Max.Col < 1) return kFALSE;
889 UChar_t status[3]={fDigitsIn->GetPadStatus(Max.Row, Max.Col-1, Max.Time),
890 fDigitsIn->GetPadStatus(Max.Row, Max.Col, Max.Time),
891 fDigitsIn->GetPadStatus(Max.Row, Max.Col+1, Max.Time)};
893 Signals[0] = fDigitsOut->GetData(Max.Row, Max.Col-1, Max.Time);
894 Signals[2] = fDigitsOut->GetData(Max.Row, Max.Col+1, Max.Time);
896 if(!(status[0] | status[1] | status[2])) {//all pads are good
897 if ((Signals[2] <= Signals[1]) && (Signals[0] < Signals[1])) {
898 if ((Signals[2] >= fSigThresh) || (Signals[0] >= fSigThresh)) {
899 Float_t noiseSumThresh = fMinLeftRightCutSigma
901 * fCalNoiseROC->GetValue(Max.Col, Max.Row);
902 if ((Signals[2]+Signals[0]+Signals[1]) < noiseSumThresh) return kFALSE;
908 else { // at least one of the pads is bad, and reject candidates with more than 1 problematic pad
909 if (status[2] && (!(status[0] || status[1])) && Signals[1] > Signals[0] && Signals[0] >= fSigThresh) {
910 fDigitsOut->SetData(Max.Row, Max.Col+1, Max.Time, 0.);
911 SetPadStatus(status[2], padStatus);
914 else if (status[0] && (!(status[1] || status[2])) && Signals[1] >= Signals[2] && Signals[2] >= fSigThresh) {
915 fDigitsOut->SetData(Max.Row, Max.Col-1, Max.Time, 0.);
916 SetPadStatus(status[0], padStatus);
919 else if (status[1] && (!(status[0] || status[2])) && ((Signals[2] >= fSigThresh) || (Signals[0] >= fSigThresh))) {
920 fDigitsOut->SetData(Max.Row, Max.Col, Max.Time, fMaxThresh);
921 SetPadStatus(status[1], padStatus);
928 //_____________________________________________________________________________
929 Bool_t AliTRDclusterizer::IsFivePadCluster(const MaxStruct &ThisMax, const MaxStruct &NeighbourMax, Float_t &ratio)
932 // Look for 5 pad cluster with minimum in the middle
933 // Gives back the ratio
936 if (ThisMax.Col >= fColMax - 3) return kFALSE;
937 if (ThisMax.Col < fColMax - 5){
938 if (fDigitsOut->GetData(ThisMax.Row, ThisMax.Col+4, ThisMax.Time) >= fSigThresh)
941 if (ThisMax.Col > 1) {
942 if (fDigitsOut->GetData(ThisMax.Row, ThisMax.Col-2, ThisMax.Time) >= fSigThresh)
946 //if (fSignalsThisMax[1] >= 0){ //TR: mod
948 const Float_t kEpsilon = 0.01;
949 Double_t padSignal[5] = {ThisMax.Signals[0], ThisMax.Signals[1], ThisMax.Signals[2],
950 NeighbourMax.Signals[1], NeighbourMax.Signals[2]};
952 // Unfold the two maxima and set the signal on
953 // the overlapping pad to the ratio
954 ratio = Unfold(kEpsilon,fLayer,padSignal);
958 //_____________________________________________________________________________
959 void AliTRDclusterizer::CreateCluster(const MaxStruct &Max)
962 // Creates a cluster at the given position and saves it in fRecPoint
965 const Int_t kNsig = 5;
966 Double_t padSignal[kNsig];
968 // The position of the cluster in COL direction relative to the center pad (pad units)
969 Double_t clusterPosCol = 0.0;
970 if (fReconstructor->GetRecoParam()->IsLUT()) {
971 // Calculate the position of the cluster by using the
972 // lookup table method
973 clusterPosCol = LUTposition(fLayer,Max.Signals[0]
978 // Calculate the position of the cluster by using the
979 // center of gravity method
980 padSignal[1] = Max.Signals[0];
981 padSignal[2] = Max.Signals[1];
982 padSignal[3] = Max.Signals[2];
984 padSignal[0] = fDigitsOut->GetData(Max.Row, Max.Col-2, Max.Time);
985 if(padSignal[0]>= padSignal[1])
988 if(Max.Col < fColMax - 3){
989 padSignal[4] = fDigitsOut->GetData(Max.Row, Max.Col+2, Max.Time);
990 if(padSignal[4]>= padSignal[3])
993 clusterPosCol = GetCOG(padSignal);
996 // Count the number of pads in the cluster
1000 while (fDigitsOut->GetData(Max.Row, Max.Col-ii, Max.Time) >= fSigThresh) {
1003 if (Max.Col < ii) break;
1007 while (fDigitsOut->GetData(Max.Row, Max.Col+ii, Max.Time) >= fSigThresh) {
1010 if (Max.Col+ii >= fColMax) break;
1013 // Store the amplitudes of the pads in the cluster for later analysis
1014 // and check whether one of these pads is masked in the database
1015 Short_t signals[7] = { 0, 0, TMath::Nint(Max.Signals[0]),
1016 TMath::Nint(Max.Signals[1]),
1017 TMath::Nint(Max.Signals[2]), 0, 0 };
1018 for(Int_t i = 0; i<2; i++)
1021 signals[i] = TMath::Nint(fDigitsOut->GetData(Max.Row, Max.Col-3+i, Max.Time));
1022 if(Max.Col+3-i < fColMax)
1023 signals[6-i] = TMath::Nint(fDigitsOut->GetData(Max.Row, Max.Col+3-i, Max.Time));
1025 /*for (Int_t jPad = Max.Col-3; jPad <= Max.Col+3; jPad++) {
1026 if ((jPad >= 0) && (jPad < fColMax))
1027 signals[jPad-Max.Col+3] = TMath::Nint(fDigitsOut->GetData(Max.Row,jPad,Max.Time));
1030 // Transform the local cluster coordinates into calibrated
1031 // space point positions defined in the local tracking system.
1032 // Here the calibration for T0, Vdrift and ExB is applied as well.
1033 Double_t clusterXYZ[6];
1034 clusterXYZ[0] = clusterPosCol;
1035 clusterXYZ[1] = Max.Signals[2];
1036 clusterXYZ[2] = Max.Signals[1];
1037 clusterXYZ[3] = Max.Signals[0];
1038 clusterXYZ[4] = 0.0;
1039 clusterXYZ[5] = 0.0;
1040 Int_t clusterRCT[3];
1041 clusterRCT[0] = Max.Row;
1042 clusterRCT[1] = Max.Col;
1046 if (fTransform->Transform(clusterXYZ,clusterRCT,((UInt_t) Max.Time),out,0)) {
1048 // Add the cluster to the output array
1049 // The track indices will be stored later
1050 Float_t clusterPos[3];
1051 clusterPos[0] = clusterXYZ[0];
1052 clusterPos[1] = clusterXYZ[1];
1053 clusterPos[2] = clusterXYZ[2];
1054 Float_t clusterSig[2];
1055 clusterSig[0] = clusterXYZ[4];
1056 clusterSig[1] = clusterXYZ[5];
1057 Double_t clusterCharge = clusterXYZ[3];
1058 Char_t clusterTimeBin = ((Char_t) clusterRCT[2]);
1060 Int_t n = RecPoints()->GetEntriesFast();
1061 AliTRDcluster *cluster = new((*RecPoints())[n]) AliTRDcluster(
1063 clusterCharge, clusterPos, clusterSig,
1065 ((Char_t) nPadCount),
1067 ((UChar_t) Max.Col), ((UChar_t) Max.Row), ((UChar_t) Max.Time),
1068 clusterTimeBin, clusterPosCol,
1070 cluster->SetInChamber(!out);
1072 UChar_t maskPosition = GetCorruption(Max.padStatus);
1074 cluster->SetPadMaskedPosition(maskPosition);
1075 cluster->SetPadMaskedStatus(GetPadStatus(Max.padStatus));
1078 // Temporarily store the Max.Row, column and time bin of the center pad
1079 // Used to later on assign the track indices
1080 cluster->SetLabel(Max.Row, 0);
1081 cluster->SetLabel(Max.Col, 1);
1082 cluster->SetLabel(Max.Time,2);
1084 // Store the index of the first cluster in the current ROC
1085 if (firstClusterROC < 0) {
1086 firstClusterROC = RecPoints()->GetEntriesFast() - 1;
1089 // Count the number of cluster in the current ROC
1095 //_____________________________________________________________________________
1096 Bool_t AliTRDclusterizer::AddLabels(const Int_t idet, const Int_t firstClusterROC, const Int_t nClusterROC)
1099 // Add the track indices to the found clusters
1102 const Int_t kNclus = 3;
1103 const Int_t kNdict = AliTRDdigitsManager::kNDict;
1104 const Int_t kNtrack = kNdict * kNclus;
1106 Int_t iClusterROC = 0;
1113 // Temporary array to collect the track indices
1114 Int_t *idxTracks = new Int_t[kNtrack*nClusterROC];
1116 // Loop through the dictionary arrays one-by-one
1117 // to keep memory consumption low
1118 AliTRDarrayDictionary *tracksIn = 0; //mod
1119 for (Int_t iDict = 0; iDict < kNdict; iDict++) {
1121 // tracksIn should be expanded beforehand!
1122 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(idet,iDict);
1124 // Loop though the clusters found in this ROC
1125 for (iClusterROC = 0; iClusterROC < nClusterROC; iClusterROC++) {
1127 AliTRDcluster *cluster = (AliTRDcluster *)
1128 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
1129 row = cluster->GetLabel(0);
1130 col = cluster->GetLabel(1);
1131 time = cluster->GetLabel(2);
1133 for (iPad = 0; iPad < kNclus; iPad++) {
1134 Int_t iPadCol = col - 1 + iPad;
1135 Int_t index = tracksIn->GetData(row,iPadCol,time); //Modification of -1 in Track
1136 idxTracks[3*iPad+iDict + iClusterROC*kNtrack] = index;
1143 // Copy the track indices into the cluster
1144 // Loop though the clusters found in this ROC
1145 for (iClusterROC = 0; iClusterROC < nClusterROC; iClusterROC++) {
1147 AliTRDcluster *cluster = (AliTRDcluster *)
1148 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
1149 cluster->SetLabel(-9999,0);
1150 cluster->SetLabel(-9999,1);
1151 cluster->SetLabel(-9999,2);
1153 cluster->AddTrackIndex(&idxTracks[iClusterROC*kNtrack]);
1157 delete [] idxTracks;
1163 //_____________________________________________________________________________
1164 Double_t AliTRDclusterizer::GetCOG(Double_t signal[5]) const
1168 // Used for clusters with more than 3 pads - where LUT not applicable
1171 Double_t sum = signal[0]
1178 // Go to 3 pad COG ????
1180 Double_t res = (0.0 * (-signal[0] + signal[4])
1181 + (-signal[1] + signal[3])) / sum;
1187 //_____________________________________________________________________________
1188 Float_t AliTRDclusterizer::Unfold(Double_t eps, Int_t layer, Double_t *padSignal) const
1191 // Method to unfold neighbouring maxima.
1192 // The charge ratio on the overlapping pad is calculated
1193 // until there is no more change within the range given by eps.
1194 // The resulting ratio is then returned to the calling method.
1197 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
1199 AliError("No AliTRDcalibDB instance available\n");
1204 Int_t itStep = 0; // Count iteration steps
1206 Double_t ratio = 0.5; // Start value for ratio
1207 Double_t prevRatio = 0.0; // Store previous ratio
1209 Double_t newLeftSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store left cluster signal
1210 Double_t newRightSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store right cluster signal
1211 Double_t newSignal[3] = { 0.0, 0.0, 0.0 };
1213 // Start the iteration
1214 while ((TMath::Abs(prevRatio - ratio) > eps) && (itStep < 10)) {
1219 // Cluster position according to charge ratio
1220 Double_t maxLeft = (ratio*padSignal[2] - padSignal[0])
1221 / (padSignal[0] + padSignal[1] + ratio * padSignal[2]);
1222 Double_t maxRight = (padSignal[4] - (1-ratio)*padSignal[2])
1223 / ((1.0 - ratio)*padSignal[2] + padSignal[3] + padSignal[4]);
1225 // Set cluster charge ratio
1226 irc = calibration->PadResponse(1.0, maxLeft, layer, newSignal);
1227 Double_t ampLeft = padSignal[1] / newSignal[1];
1228 irc = calibration->PadResponse(1.0, maxRight, layer, newSignal);
1229 Double_t ampRight = padSignal[3] / newSignal[1];
1231 // Apply pad response to parameters
1232 irc = calibration->PadResponse(ampLeft ,maxLeft ,layer,newLeftSignal );
1233 irc = calibration->PadResponse(ampRight,maxRight,layer,newRightSignal);
1235 // Calculate new overlapping ratio
1236 ratio = TMath::Min((Double_t) 1.0
1237 ,newLeftSignal[2] / (newLeftSignal[2] + newRightSignal[0]));
1245 //_____________________________________________________________________________
1246 void AliTRDclusterizer::TailCancelation()
1249 // Applies the tail cancelation and gain factors:
1250 // Transform fDigitsIn to fDigitsOut
1257 Double_t *inADC = new Double_t[fTimeTotal]; // ADC data before tail cancellation
1258 Double_t *outADC = new Double_t[fTimeTotal]; // ADC data after tail cancellation
1259 fIndexes->ResetCounters();
1260 TTreeSRedirector *fDebugStream = fReconstructor->GetDebugStream(AliTRDReconstructor::kClusterizer);
1261 while(fIndexes->NextRCIndex(iRow, iCol))
1263 Float_t fCalGainFactorROCValue = fCalGainFactorROC->GetValue(iCol,iRow);
1264 Double_t gain = fCalGainFactorDetValue
1265 * fCalGainFactorROCValue;
1267 Bool_t corrupted = kFALSE;
1268 for (iTime = 0; iTime < fTimeTotal; iTime++)
1270 // Apply gain gain factor
1271 inADC[iTime] = fDigitsIn->GetDataB(iRow,iCol,iTime);
1272 if (fDigitsIn->GetPadStatus(iRow, iCol, iTime)) corrupted = kTRUE;
1273 inADC[iTime] /= gain;
1274 outADC[iTime] = inADC[iTime];
1275 if(fReconstructor->GetStreamLevel(AliTRDReconstructor::kClusterizer) > 7){
1276 (*fDebugStream) << "TailCancellation"
1280 << "inADC=" << inADC[iTime]
1282 << "outADC=" << outADC[iTime]
1283 << "corrupted=" << corrupted
1289 // Apply the tail cancelation via the digital filter
1290 // (only for non-coorupted pads)
1291 if (fReconstructor->GetRecoParam()->IsTailCancelation())
1292 DeConvExp(inADC,outADC,fTimeTotal,fReconstructor->GetRecoParam() ->GetTCnexp());
1295 for(iTime = 0; iTime < fTimeTotal; iTime++)//while (fIndexes->NextTbinIndex(iTime))
1297 // Store the amplitude of the digit if above threshold
1298 if (outADC[iTime] > fADCthresh)
1299 fDigitsOut->SetData(iRow,iCol,iTime,outADC[iTime]);
1302 } // while irow icol
1311 //_____________________________________________________________________________
1312 void AliTRDclusterizer::DeConvExp(const Double_t *const source, Double_t *const target
1313 ,const Int_t n, const Int_t nexp)
1316 // Tail cancellation by deconvolution for PASA v4 TRF
1320 Double_t coefficients[2];
1322 // Initialization (coefficient = alpha, rates = lambda)
1328 if (nexp == 1) { // 1 Exponentials
1334 if (nexp == 2) { // 2 Exponentials
1336 fReconstructor->GetTCParams(par);
1337 r1 = par[0];//1.156;
1338 r2 = par[1];//0.130;
1339 c1 = par[2];//0.114;
1340 c2 = par[3];//0.624;
1343 coefficients[0] = c1;
1344 coefficients[1] = c2;
1348 rates[0] = TMath::Exp(-dt/(r1));
1349 rates[1] = TMath::Exp(-dt/(r2));
1354 Double_t reminder[2];
1355 Double_t correction = 0.0;
1356 Double_t result = 0.0;
1358 // Attention: computation order is important
1359 for (k = 0; k < nexp; k++) {
1363 for (i = 0; i < n; i++) {
1365 result = (source[i] - correction); // No rescaling
1368 for (k = 0; k < nexp; k++) {
1369 reminder[k] = rates[k] * (reminder[k] + coefficients[k] * result);
1373 for (k = 0; k < nexp; k++) {
1374 correction += reminder[k];
1381 //_____________________________________________________________________________
1382 void AliTRDclusterizer::ResetRecPoints()
1385 // Resets the list of rec points
1389 fRecPoints->Delete();
1394 //_____________________________________________________________________________
1395 TClonesArray *AliTRDclusterizer::RecPoints()
1398 // Returns the list of rec points
1402 if(!(fRecPoints = AliTRDReconstructor::GetClusters())){
1403 // determine number of clusters which has to be allocated
1404 Float_t nclusters = fReconstructor->GetRecoParam()->GetNClusters();
1405 if(fReconstructor->IsHLT()) nclusters /= AliTRDgeometry::kNsector;
1407 fRecPoints = new TClonesArray("AliTRDcluster", Int_t(nclusters));
1409 //SetClustersOwner(kTRUE);
1410 AliTRDReconstructor::SetClusters(0x0);
1416 //_____________________________________________________________________________
1417 void AliTRDclusterizer::FillLUT()
1423 const Int_t kNlut = 128;
1425 fLUTbin = AliTRDgeometry::kNlayer * kNlut;
1427 // The lookup table from Bogdan
1428 Float_t lut[AliTRDgeometry::kNlayer][kNlut] = {
1430 0.0070, 0.0150, 0.0224, 0.0298, 0.0374, 0.0454, 0.0533, 0.0611,
1431 0.0684, 0.0755, 0.0827, 0.0900, 0.0975, 0.1049, 0.1120, 0.1187,
1432 0.1253, 0.1318, 0.1385, 0.1453, 0.1519, 0.1584, 0.1646, 0.1704,
1433 0.1762, 0.1821, 0.1879, 0.1938, 0.1996, 0.2053, 0.2108, 0.2160,
1434 0.2210, 0.2260, 0.2310, 0.2361, 0.2411, 0.2461, 0.2509, 0.2557,
1435 0.2602, 0.2646, 0.2689, 0.2732, 0.2774, 0.2816, 0.2859, 0.2901,
1436 0.2942, 0.2983, 0.3022, 0.3061, 0.3099, 0.3136, 0.3172, 0.3207,
1437 0.3242, 0.3278, 0.3312, 0.3347, 0.3382, 0.3416, 0.3450, 0.3483,
1438 0.3515, 0.3547, 0.3579, 0.3609, 0.3639, 0.3669, 0.3698, 0.3727,
1439 0.3756, 0.3785, 0.3813, 0.3842, 0.3870, 0.3898, 0.3926, 0.3952,
1440 0.3979, 0.4005, 0.4032, 0.4057, 0.4082, 0.4108, 0.4132, 0.4157,
1441 0.4181, 0.4205, 0.4228, 0.4252, 0.4275, 0.4299, 0.4322, 0.4345,
1442 0.4367, 0.4390, 0.4412, 0.4434, 0.4456, 0.4478, 0.4499, 0.4520,
1443 0.4541, 0.4562, 0.4583, 0.4603, 0.4623, 0.4643, 0.4663, 0.4683,
1444 0.4702, 0.4722, 0.4741, 0.4758, 0.4774, 0.4790, 0.4805, 0.4824,
1445 0.4844, 0.4863, 0.4883, 0.4902, 0.4921, 0.4940, 0.4959, 0.4978
1448 0.0072, 0.0156, 0.0235, 0.0313, 0.0394, 0.0478, 0.0561, 0.0642,
1449 0.0718, 0.0792, 0.0868, 0.0947, 0.1025, 0.1101, 0.1172, 0.1241,
1450 0.1309, 0.1378, 0.1449, 0.1518, 0.1586, 0.1650, 0.1710, 0.1770,
1451 0.1830, 0.1891, 0.1952, 0.2011, 0.2070, 0.2125, 0.2177, 0.2229,
1452 0.2280, 0.2332, 0.2383, 0.2435, 0.2484, 0.2533, 0.2581, 0.2627,
1453 0.2670, 0.2714, 0.2757, 0.2799, 0.2842, 0.2884, 0.2927, 0.2968,
1454 0.3008, 0.3048, 0.3086, 0.3123, 0.3159, 0.3195, 0.3231, 0.3266,
1455 0.3301, 0.3335, 0.3370, 0.3404, 0.3438, 0.3471, 0.3504, 0.3536,
1456 0.3567, 0.3598, 0.3628, 0.3657, 0.3686, 0.3715, 0.3744, 0.3772,
1457 0.3800, 0.3828, 0.3856, 0.3884, 0.3911, 0.3938, 0.3965, 0.3991,
1458 0.4016, 0.4042, 0.4067, 0.4092, 0.4116, 0.4140, 0.4164, 0.4187,
1459 0.4211, 0.4234, 0.4257, 0.4280, 0.4302, 0.4325, 0.4347, 0.4369,
1460 0.4391, 0.4413, 0.4434, 0.4456, 0.4477, 0.4497, 0.4518, 0.4538,
1461 0.4558, 0.4578, 0.4598, 0.4618, 0.4637, 0.4656, 0.4675, 0.4694,
1462 0.4713, 0.4732, 0.4750, 0.4766, 0.4781, 0.4797, 0.4813, 0.4832,
1463 0.4851, 0.4870, 0.4888, 0.4906, 0.4925, 0.4942, 0.4960, 0.4978
1466 0.0075, 0.0163, 0.0246, 0.0328, 0.0415, 0.0504, 0.0592, 0.0674,
1467 0.0753, 0.0832, 0.0914, 0.0996, 0.1077, 0.1154, 0.1225, 0.1296,
1468 0.1369, 0.1442, 0.1515, 0.1585, 0.1652, 0.1714, 0.1776, 0.1839,
1469 0.1902, 0.1965, 0.2025, 0.2085, 0.2141, 0.2194, 0.2247, 0.2299,
1470 0.2352, 0.2405, 0.2457, 0.2507, 0.2557, 0.2604, 0.2649, 0.2693,
1471 0.2737, 0.2780, 0.2823, 0.2867, 0.2909, 0.2951, 0.2992, 0.3033,
1472 0.3072, 0.3110, 0.3146, 0.3182, 0.3218, 0.3253, 0.3288, 0.3323,
1473 0.3357, 0.3392, 0.3426, 0.3459, 0.3492, 0.3524, 0.3555, 0.3586,
1474 0.3616, 0.3645, 0.3674, 0.3703, 0.3731, 0.3759, 0.3787, 0.3815,
1475 0.3843, 0.3870, 0.3897, 0.3925, 0.3950, 0.3976, 0.4002, 0.4027,
1476 0.4052, 0.4076, 0.4101, 0.4124, 0.4148, 0.4171, 0.4194, 0.4217,
1477 0.4239, 0.4262, 0.4284, 0.4306, 0.4328, 0.4350, 0.4371, 0.4393,
1478 0.4414, 0.4435, 0.4455, 0.4476, 0.4496, 0.4516, 0.4536, 0.4555,
1479 0.4575, 0.4594, 0.4613, 0.4632, 0.4650, 0.4669, 0.4687, 0.4705,
1480 0.4723, 0.4741, 0.4758, 0.4773, 0.4789, 0.4804, 0.4821, 0.4839,
1481 0.4857, 0.4875, 0.4893, 0.4910, 0.4928, 0.4945, 0.4961, 0.4978
1484 0.0078, 0.0171, 0.0258, 0.0345, 0.0438, 0.0532, 0.0624, 0.0708,
1485 0.0791, 0.0875, 0.0962, 0.1048, 0.1130, 0.1206, 0.1281, 0.1356,
1486 0.1432, 0.1508, 0.1582, 0.1651, 0.1716, 0.1780, 0.1845, 0.1910,
1487 0.1975, 0.2038, 0.2099, 0.2155, 0.2210, 0.2263, 0.2317, 0.2371,
1488 0.2425, 0.2477, 0.2528, 0.2578, 0.2626, 0.2671, 0.2715, 0.2759,
1489 0.2803, 0.2846, 0.2890, 0.2933, 0.2975, 0.3016, 0.3056, 0.3095,
1490 0.3132, 0.3168, 0.3204, 0.3239, 0.3274, 0.3309, 0.3344, 0.3378,
1491 0.3412, 0.3446, 0.3479, 0.3511, 0.3543, 0.3574, 0.3603, 0.3633,
1492 0.3662, 0.3690, 0.3718, 0.3747, 0.3774, 0.3802, 0.3829, 0.3857,
1493 0.3883, 0.3910, 0.3936, 0.3962, 0.3987, 0.4012, 0.4037, 0.4061,
1494 0.4085, 0.4109, 0.4132, 0.4155, 0.4177, 0.4200, 0.4222, 0.4244,
1495 0.4266, 0.4288, 0.4309, 0.4331, 0.4352, 0.4373, 0.4394, 0.4414,
1496 0.4435, 0.4455, 0.4475, 0.4494, 0.4514, 0.4533, 0.4552, 0.4571,
1497 0.4590, 0.4608, 0.4626, 0.4645, 0.4662, 0.4680, 0.4698, 0.4715,
1498 0.4733, 0.4750, 0.4766, 0.4781, 0.4796, 0.4812, 0.4829, 0.4846,
1499 0.4863, 0.4880, 0.4897, 0.4914, 0.4930, 0.4946, 0.4963, 0.4979
1502 0.0081, 0.0178, 0.0270, 0.0364, 0.0463, 0.0562, 0.0656, 0.0744,
1503 0.0831, 0.0921, 0.1013, 0.1102, 0.1183, 0.1261, 0.1339, 0.1419,
1504 0.1499, 0.1576, 0.1648, 0.1715, 0.1782, 0.1849, 0.1917, 0.1984,
1505 0.2048, 0.2110, 0.2167, 0.2223, 0.2278, 0.2333, 0.2389, 0.2444,
1506 0.2497, 0.2548, 0.2598, 0.2645, 0.2691, 0.2735, 0.2780, 0.2824,
1507 0.2868, 0.2912, 0.2955, 0.2997, 0.3038, 0.3078, 0.3116, 0.3152,
1508 0.3188, 0.3224, 0.3259, 0.3294, 0.3329, 0.3364, 0.3398, 0.3432,
1509 0.3465, 0.3497, 0.3529, 0.3561, 0.3591, 0.3620, 0.3649, 0.3677,
1510 0.3705, 0.3733, 0.3761, 0.3788, 0.3816, 0.3843, 0.3869, 0.3896,
1511 0.3922, 0.3948, 0.3973, 0.3998, 0.4022, 0.4047, 0.4070, 0.4094,
1512 0.4117, 0.4139, 0.4162, 0.4184, 0.4206, 0.4227, 0.4249, 0.4270,
1513 0.4291, 0.4313, 0.4334, 0.4354, 0.4375, 0.4395, 0.4415, 0.4435,
1514 0.4455, 0.4474, 0.4493, 0.4512, 0.4531, 0.4550, 0.4568, 0.4586,
1515 0.4604, 0.4622, 0.4639, 0.4657, 0.4674, 0.4691, 0.4708, 0.4725,
1516 0.4742, 0.4758, 0.4773, 0.4788, 0.4803, 0.4819, 0.4836, 0.4852,
1517 0.4869, 0.4885, 0.4901, 0.4917, 0.4933, 0.4948, 0.4964, 0.4979
1520 0.0085, 0.0189, 0.0288, 0.0389, 0.0497, 0.0603, 0.0699, 0.0792,
1521 0.0887, 0.0985, 0.1082, 0.1170, 0.1253, 0.1336, 0.1421, 0.1505,
1522 0.1587, 0.1662, 0.1733, 0.1803, 0.1874, 0.1945, 0.2014, 0.2081,
1523 0.2143, 0.2201, 0.2259, 0.2316, 0.2374, 0.2431, 0.2487, 0.2541,
1524 0.2593, 0.2642, 0.2689, 0.2735, 0.2781, 0.2826, 0.2872, 0.2917,
1525 0.2961, 0.3003, 0.3045, 0.3086, 0.3125, 0.3162, 0.3198, 0.3235,
1526 0.3270, 0.3306, 0.3342, 0.3377, 0.3411, 0.3446, 0.3479, 0.3511,
1527 0.3543, 0.3575, 0.3605, 0.3634, 0.3663, 0.3691, 0.3720, 0.3748,
1528 0.3775, 0.3803, 0.3830, 0.3857, 0.3884, 0.3911, 0.3937, 0.3962,
1529 0.3987, 0.4012, 0.4036, 0.4060, 0.4084, 0.4107, 0.4129, 0.4152,
1530 0.4174, 0.4196, 0.4218, 0.4239, 0.4261, 0.4282, 0.4303, 0.4324,
1531 0.4344, 0.4365, 0.4385, 0.4405, 0.4425, 0.4445, 0.4464, 0.4483,
1532 0.4502, 0.4521, 0.4539, 0.4558, 0.4576, 0.4593, 0.4611, 0.4629,
1533 0.4646, 0.4663, 0.4680, 0.4697, 0.4714, 0.4730, 0.4747, 0.4759,
1534 0.4769, 0.4780, 0.4790, 0.4800, 0.4811, 0.4827, 0.4843, 0.4859,
1535 0.4874, 0.4889, 0.4905, 0.4920, 0.4935, 0.4950, 0.4965, 0.4979
1542 fLUT = new Double_t[fLUTbin];
1544 for (Int_t ilayer = 0; ilayer < AliTRDgeometry::kNlayer; ilayer++) {
1545 for (Int_t ilut = 0; ilut < kNlut; ilut++ ) {
1546 fLUT[ilayer*kNlut+ilut] = lut[ilayer][ilut];
1552 //_____________________________________________________________________________
1553 Double_t AliTRDclusterizer::LUTposition(Int_t ilayer
1556 , Double_t ampR) const
1559 // Calculates the cluster position using the lookup table.
1560 // Method provided by Bogdan Vulpescu.
1563 const Int_t kNlut = 128;
1574 Double_t xMin[AliTRDgeometry::kNlayer] = { 0.006492, 0.006377, 0.006258
1575 , 0.006144, 0.006030, 0.005980 };
1576 Double_t xMax[AliTRDgeometry::kNlayer] = { 0.960351, 0.965870, 0.970445
1577 , 0.974352, 0.977667, 0.996101 };
1580 x = (ampL - ampR) / ampC;
1583 else if (ampL < ampR) {
1584 x = (ampR - ampL) / ampC;
1590 xmin = xMin[ilayer] + 0.000005;
1591 xmax = xMax[ilayer] - 0.000005;
1592 xwid = (xmax - xmin) / 127.0;
1597 else if (x > xmax) {
1598 pos = side * 0.5000;
1601 ix = (Int_t) ((x - xmin) / xwid);
1602 pos = side * fLUT[ilayer*kNlut+ix];