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(AliTRDReconstructor *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, AliTRDReconstructor *rec)
127 ,fDigitsManager(new AliTRDdigitsManager())
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();
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];
650 AliTRDrawStreamBase *input = AliTRDrawStreamBase::GetRawStream(rawReader);
652 AliInfo(Form("Stream version: %s", input->IsA()->GetName()));
655 while ((det = input->NextChamber(fDigitsManager,fTrackletContainer)) >= 0){
656 Bool_t iclusterBranch = kFALSE;
657 if (fDigitsManager->GetIndexes(det)->HasEntry()){
658 iclusterBranch = MakeClusters(det);
661 fDigitsManager->RemoveDigits(det);
662 fDigitsManager->RemoveDictionaries(det);
663 fDigitsManager->ClearIndexes(det);
665 if (!fReconstructor->IsWritingTracklets()) continue;
666 if (*(fTrackletContainer[0]) > 0 || *(fTrackletContainer[1]) > 0) WriteTracklets(det);
668 if (fReconstructor->IsWritingTracklets()){
669 delete [] fTrackletContainer[0];
670 delete [] fTrackletContainer[1];
671 delete [] fTrackletContainer;
672 fTrackletContainer = NULL;
675 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
677 delete fDigitsManager;
678 fDigitsManager = NULL;
683 AliInfo(Form("Number of found clusters : %d", RecPoints()->GetEntriesFast()));
688 //_____________________________________________________________________________
689 UChar_t AliTRDclusterizer::GetStatus(Short_t &signal)
692 // Check if a pad is masked
697 if(signal>0 && TESTBIT(signal, 10)){
699 for(int ibit=0; ibit<4; ibit++){
700 if(TESTBIT(signal, 11+ibit)){
701 SETBIT(status, ibit);
702 CLRBIT(signal, 11+ibit);
709 //_____________________________________________________________________________
710 void AliTRDclusterizer::SetPadStatus(const UChar_t status, UChar_t &out){
712 // Set the pad status into out
713 // First three bits are needed for the position encoding
718 //_____________________________________________________________________________
719 UChar_t AliTRDclusterizer::GetPadStatus(UChar_t encoding) const {
721 // return the staus encoding of the corrupted pad
723 return static_cast<UChar_t>(encoding >> 3);
726 //_____________________________________________________________________________
727 Int_t AliTRDclusterizer::GetCorruption(UChar_t encoding) const {
729 // Return the position of the corruption
734 //_____________________________________________________________________________
735 Bool_t AliTRDclusterizer::MakeClusters(Int_t det)
738 // Generates the cluster.
742 // digits should be expanded beforehand!
743 // digitsIn->Expand();
744 fDigitsIn = (AliTRDarrayADC *) fDigitsManager->GetDigits(det); //mod
746 // This is to take care of switched off super modules
747 if (!fDigitsIn->HasData())
752 fIndexes = fDigitsManager->GetIndexes(det);
753 if (fIndexes->IsAllocated() == kFALSE)
755 AliError("Indexes do not exist!");
759 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
762 AliFatal("No AliTRDcalibDB instance available\n");
768 if (!fReconstructor){
769 AliError("Reconstructor not set\n");
773 TTreeSRedirector *fDebugStream = fReconstructor->GetDebugStream(AliTRDReconstructor::kClusterizer);
775 fMaxThresh = fReconstructor->GetRecoParam()->GetClusMaxThresh();
776 fSigThresh = fReconstructor->GetRecoParam()->GetClusSigThresh();
777 fMinMaxCutSigma = fReconstructor->GetRecoParam()->GetMinMaxCutSigma();
778 fMinLeftRightCutSigma = fReconstructor->GetRecoParam()->GetMinLeftRightCutSigma();
780 Int_t istack = fIndexes->GetStack();
781 fLayer = fIndexes->GetLayer();
782 Int_t isector = fIndexes->GetSM();
784 // Start clustering in the chamber
786 fDet = AliTRDgeometry::GetDetector(fLayer,istack,isector);
788 AliError("Strange Detector number Missmatch!");
792 // TRD space point transformation
793 fTransform->SetDetector(det);
795 Int_t iGeoLayer = AliGeomManager::kTRD1 + fLayer;
796 Int_t iGeoModule = istack + AliTRDgeometry::Nstack() * isector;
797 fVolid = AliGeomManager::LayerToVolUID(iGeoLayer,iGeoModule);
799 fColMax = fDigitsIn->GetNcol();
800 Int_t nRowMax = fDigitsIn->GetNrow();
801 fTimeTotal = fDigitsIn->GetNtime();
803 // Detector wise calibration object for the gain factors
804 const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
805 // Calibration object with pad wise values for the gain factors
806 fCalGainFactorROC = calibration->GetGainFactorROC(fDet);
807 // Calibration value for chamber wise gain factor
808 fCalGainFactorDetValue = calGainFactorDet->GetValue(fDet);
810 // Detector wise calibration object for the noise
811 const AliTRDCalDet *calNoiseDet = calibration->GetNoiseDet();
812 // Calibration object with pad wise values for the noise
813 fCalNoiseROC = calibration->GetNoiseROC(fDet);
814 // Calibration value for chamber wise noise
815 fCalNoiseDetValue = calNoiseDet->GetValue(fDet);
817 if(fDigitsOut) delete fDigitsOut;
818 fDigitsOut = new AliTRDarraySignal(nRowMax, fColMax, fTimeTotal);
820 firstClusterROC = -1;
823 // Apply the gain and the tail cancelation via digital filter
826 ClusterizerStruct curr, last;
828 Int_t nMaximas = 0, nCorrupted = 0;
831 // Here the clusterfining is happening
833 for(curr.Time = 0; curr.Time < fTimeTotal; curr.Time++)
834 while(fIndexes->NextRCIndex(curr.Row, curr.Col))
835 if(IsMaximum(curr.Row, curr.Col, curr.Time, curr.padStatus, &curr.Signals[0]))
839 last.Signals[0] *= Ratio;
840 if(curr.Row==last.Row && curr.Col==last.Col+2)
842 if(IsFivePadCluster(last.Row, last.Col, last.Time, &last.Signals[0], &curr.Signals[0], Ratio))
844 last.Signals[2] *= Ratio;
848 CreateCluster(last.Row, last.Col, last.Time, &last.Signals[0], last.padStatus);
854 last.Signals[0] *= Ratio;
855 CreateCluster(last.Row, last.Col, last.Time, &last.Signals[0], last.padStatus);
858 if(fReconstructor->GetStreamLevel(AliTRDReconstructor::kClusterizer) > 2){
859 (*fDebugStream) << "MakeClusters"
860 << "Detector=" << det
861 << "NMaxima=" << nMaximas
862 << "NClusters=" << fClusterROC
863 << "NCorrupted=" << nCorrupted
868 AddLabels(fDet,firstClusterROC,fClusterROC);
875 //_____________________________________________________________________________
876 Bool_t AliTRDclusterizer::IsMaximum(const Int_t row, const Int_t col, const Int_t time,
877 UChar_t &pasStatus, Double_t *const Signals)
880 // Returns true if this row,col,time combination is a maximum.
881 // Gives back the padStatus and the signals of the center pad and the two neighbouring pads.
884 Signals[1] = fDigitsOut->GetData(row,col,time);
885 if(Signals[1] < fMaxThresh) return kFALSE;
887 Float_t noiseMiddleThresh = fMinMaxCutSigma*fCalNoiseDetValue*fCalNoiseROC->GetValue(col,row);
888 if (Signals[1] < noiseMiddleThresh) return kFALSE;
890 if (col + 1 >= fColMax || col < 1) return kFALSE;
891 UChar_t status[3]={0, 0, 0};
894 status[1] = fDigitsIn->GetPadStatus(row,col,time);
895 //if(status[1]) SETBIT(pasStatus, AliTRDcluster::kMaskedCenter);//TR: mod: this is already done by SetPadStatus
897 Signals[2] = fDigitsOut->GetData(row,col+1,time);
898 status[2] = fDigitsIn->GetPadStatus(row,col+1,time);
899 //if(status[2]) SETBIT(pasStatus, AliTRDcluster::kMaskedLeft);//TR: mod: this is already done by SetPadStatus
901 Signals[0] = fDigitsOut->GetData(row,col-1,time);
902 status[0] = fDigitsIn->GetPadStatus(row,col-1,time);
903 //if(status[0]) SETBIT(pasStatus, AliTRDcluster::kMaskedRight);//TR: mod: this is already done by SetPadStatus
905 // reject candidates with more than 1 problematic pad
906 if(pasStatus >= 3) return kFALSE;
908 if (!status[1]) { // good central pad
909 if (!pasStatus) { // all pads are OK
910 if ((Signals[2] <= Signals[1]) && (Signals[0] < Signals[1])) {
911 if ((Signals[2] >= fSigThresh) || (Signals[0] >= fSigThresh)) {
912 Float_t noiseSumThresh = fMinLeftRightCutSigma
914 * fCalNoiseROC->GetValue(col,row);
915 if ((Signals[2]+Signals[0]+Signals[1]) >= noiseSumThresh)
919 } else { // one of the neighbouring pads are bad
920 if (status[2] && Signals[0] < Signals[1] && Signals[0] >= fSigThresh) {
921 fDigitsOut->SetData(row, col+1, time, 0.);//TR: mod: was: SetData(row, col, time+1, 0.)
922 SetPadStatus(status[2], pasStatus);
925 else if (status[0] && Signals[2] <= Signals[1] && Signals[2] >= fSigThresh) {
926 fDigitsOut->SetData(row, col-1, time, 0.);//TR: mod: was: SetData(row, col, time-1, 0.)
927 SetPadStatus(status[0], pasStatus);
932 else { // wrong maximum pad
933 if ((Signals[2] >= fSigThresh) || (Signals[0] >= fSigThresh)) {
934 fDigitsOut->SetData(row,col,time,fMaxThresh);
935 SetPadStatus(status[1], pasStatus);
942 //_____________________________________________________________________________
943 Bool_t AliTRDclusterizer::IsFivePadCluster(const Int_t row, const Int_t col, const Int_t time,
944 Double_t *SignalsThisMax, Double_t *SignalsNeighbourMax, Double_t &ratio)
947 // Look for 5 pad cluster with minimum in the middle
948 // Gives back the ratio
951 if (col < fColMax - 3){
952 if (col < fColMax - 5){
953 if (fDigitsOut->GetData(row,col+4,time) >= fSigThresh)
957 if (fDigitsOut->GetData(row,col-2,time) >= fSigThresh)
961 //if (fSignalsThisMax[1] >= 0){ //TR: mod
963 const Float_t kEpsilon = 0.01;
964 Double_t padSignal[5] = {SignalsThisMax[0],SignalsThisMax[1],SignalsThisMax[2],
965 SignalsNeighbourMax[1], SignalsNeighbourMax[2]};
967 // Unfold the two maxima and set the signal on
968 // the overlapping pad to the ratio
969 ratio = Unfold(kEpsilon,fLayer,padSignal);
975 //_____________________________________________________________________________
976 void AliTRDclusterizer::CreateCluster(const Int_t row, const Int_t col, const Int_t time,
977 const Double_t* const clusterSignal, const UChar_t pasStatus)
980 // Creates a cluster at the given position and saves it in fRecPoint
983 const Int_t kNsig = 5;
984 Double_t padSignal[kNsig];
986 // The position of the cluster in COL direction relative to the center pad (pad units)
987 Double_t clusterPosCol = 0.0;
988 if (fReconstructor->GetRecoParam()->IsLUT()) {
989 // Calculate the position of the cluster by using the
990 // lookup table method
991 clusterPosCol = LUTposition(fLayer,clusterSignal[0]
996 // Calculate the position of the cluster by using the
997 // center of gravity method
998 padSignal[1] = clusterSignal[0];
999 padSignal[2] = clusterSignal[1];
1000 padSignal[3] = clusterSignal[2];
1002 padSignal[0] = fDigitsOut->GetData(row,col-2,time);
1003 if(padSignal[0]>= padSignal[1])
1006 if(col < fColMax - 3){
1007 padSignal[4] = fDigitsOut->GetData(row,col+2,time);
1008 if(padSignal[4]>= padSignal[3])
1011 clusterPosCol = GetCOG(padSignal);
1014 // Count the number of pads in the cluster
1015 Int_t nPadCount = 1;
1016 // Look to the right
1018 while (fDigitsOut->GetData(row, col-ii, time) >= fSigThresh) {
1021 if (col-ii < 0) break;
1025 while (fDigitsOut->GetData(row, col+ii, time) >= fSigThresh) {
1028 if (col+ii >= fColMax) break;
1031 // Store the amplitudes of the pads in the cluster for later analysis
1032 // and check whether one of these pads is masked in the database
1033 Short_t signals[7] = { 0, 0, 0, 0, 0, 0, 0 };
1034 for(Int_t i = 0; i++; i<3)
1035 signals[i+2] = TMath::Nint(clusterSignal[i]);
1036 for(Int_t i = 0; i++; i<2)
1039 signals[i] = TMath::Nint(fDigitsOut->GetData(row,col-3+i,time));
1040 if(col+3-i < fColMax)
1041 signals[7-i] = TMath::Nint(fDigitsOut->GetData(row,col+3-i,time));
1043 /*for (Int_t jPad = col-3; jPad <= col+3; jPad++) {
1044 if ((jPad >= 0) && (jPad < fColMax))
1045 signals[jPad-col+3] = TMath::Nint(fDigitsOut->GetData(row,jPad,time));
1048 // Transform the local cluster coordinates into calibrated
1049 // space point positions defined in the local tracking system.
1050 // Here the calibration for T0, Vdrift and ExB is applied as well.
1051 Double_t clusterXYZ[6];
1052 clusterXYZ[0] = clusterPosCol;
1053 clusterXYZ[1] = clusterSignal[2];
1054 clusterXYZ[2] = clusterSignal[1];
1055 clusterXYZ[3] = clusterSignal[0];
1056 clusterXYZ[4] = 0.0;
1057 clusterXYZ[5] = 0.0;
1058 Int_t clusterRCT[3];
1059 clusterRCT[0] = row;
1060 clusterRCT[1] = col;
1064 if (fTransform->Transform(clusterXYZ,clusterRCT,((UInt_t) time),out,0)) {
1066 // Add the cluster to the output array
1067 // The track indices will be stored later
1068 Float_t clusterPos[3];
1069 clusterPos[0] = clusterXYZ[0];
1070 clusterPos[1] = clusterXYZ[1];
1071 clusterPos[2] = clusterXYZ[2];
1072 Float_t clusterSig[2];
1073 clusterSig[0] = clusterXYZ[4];
1074 clusterSig[1] = clusterXYZ[5];
1075 Double_t clusterCharge = clusterXYZ[3];
1076 Char_t clusterTimeBin = ((Char_t) clusterRCT[2]);
1078 Int_t n = RecPoints()->GetEntriesFast();
1079 AliTRDcluster *cluster = new((*RecPoints())[n]) AliTRDcluster(
1081 clusterCharge, clusterPos, clusterSig,
1083 ((Char_t) nPadCount),
1085 ((UChar_t) col), ((UChar_t) row), ((UChar_t) time),
1086 clusterTimeBin, clusterPosCol,
1088 cluster->SetInChamber(!out);
1090 UChar_t maskPosition = GetCorruption(pasStatus);
1091 UChar_t padstatus = GetPadStatus(pasStatus);
1093 cluster->SetPadMaskedPosition(maskPosition);
1094 cluster->SetPadMaskedStatus(padstatus);
1097 // Temporarily store the row, column and time bin of the center pad
1098 // Used to later on assign the track indices
1099 cluster->SetLabel(row, 0);
1100 cluster->SetLabel(col, 1);
1101 cluster->SetLabel(time,2);
1103 // Store the index of the first cluster in the current ROC
1104 if (firstClusterROC < 0) {
1105 firstClusterROC = RecPoints()->GetEntriesFast() - 1;
1108 // Count the number of cluster in the current ROC
1114 //_____________________________________________________________________________
1115 Bool_t AliTRDclusterizer::AddLabels(const Int_t idet, const Int_t firstClusterROC, const Int_t nClusterROC)
1118 // Add the track indices to the found clusters
1121 const Int_t kNclus = 3;
1122 const Int_t kNdict = AliTRDdigitsManager::kNDict;
1123 const Int_t kNtrack = kNdict * kNclus;
1125 Int_t iClusterROC = 0;
1132 // Temporary array to collect the track indices
1133 Int_t *idxTracks = new Int_t[kNtrack*nClusterROC];
1135 // Loop through the dictionary arrays one-by-one
1136 // to keep memory consumption low
1137 AliTRDarrayDictionary *tracksIn = 0; //mod
1138 for (Int_t iDict = 0; iDict < kNdict; iDict++) {
1140 // tracksIn should be expanded beforehand!
1141 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(idet,iDict);
1143 // Loop though the clusters found in this ROC
1144 for (iClusterROC = 0; iClusterROC < nClusterROC; iClusterROC++) {
1146 AliTRDcluster *cluster = (AliTRDcluster *)
1147 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
1148 row = cluster->GetLabel(0);
1149 col = cluster->GetLabel(1);
1150 time = cluster->GetLabel(2);
1152 for (iPad = 0; iPad < kNclus; iPad++) {
1153 Int_t iPadCol = col - 1 + iPad;
1154 Int_t index = tracksIn->GetData(row,iPadCol,time); //Modification of -1 in Track
1155 idxTracks[3*iPad+iDict + iClusterROC*kNtrack] = index;
1162 // Copy the track indices into the cluster
1163 // Loop though the clusters found in this ROC
1164 for (iClusterROC = 0; iClusterROC < nClusterROC; iClusterROC++) {
1166 AliTRDcluster *cluster = (AliTRDcluster *)
1167 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
1168 cluster->SetLabel(-9999,0);
1169 cluster->SetLabel(-9999,1);
1170 cluster->SetLabel(-9999,2);
1172 cluster->AddTrackIndex(&idxTracks[iClusterROC*kNtrack]);
1176 delete [] idxTracks;
1182 //_____________________________________________________________________________
1183 Double_t AliTRDclusterizer::GetCOG(Double_t signal[5]) const
1187 // Used for clusters with more than 3 pads - where LUT not applicable
1190 Double_t sum = signal[0]
1197 // Go to 3 pad COG ????
1199 Double_t res = (0.0 * (-signal[0] + signal[4])
1200 + (-signal[1] + signal[3])) / sum;
1206 //_____________________________________________________________________________
1207 Double_t AliTRDclusterizer::Unfold(Double_t eps, Int_t layer, Double_t *padSignal) const
1210 // Method to unfold neighbouring maxima.
1211 // The charge ratio on the overlapping pad is calculated
1212 // until there is no more change within the range given by eps.
1213 // The resulting ratio is then returned to the calling method.
1216 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
1218 AliError("No AliTRDcalibDB instance available\n");
1223 Int_t itStep = 0; // Count iteration steps
1225 Double_t ratio = 0.5; // Start value for ratio
1226 Double_t prevRatio = 0.0; // Store previous ratio
1228 Double_t newLeftSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store left cluster signal
1229 Double_t newRightSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store right cluster signal
1230 Double_t newSignal[3] = { 0.0, 0.0, 0.0 };
1232 // Start the iteration
1233 while ((TMath::Abs(prevRatio - ratio) > eps) && (itStep < 10)) {
1238 // Cluster position according to charge ratio
1239 Double_t maxLeft = (ratio*padSignal[2] - padSignal[0])
1240 / (padSignal[0] + padSignal[1] + ratio * padSignal[2]);
1241 Double_t maxRight = (padSignal[4] - (1-ratio)*padSignal[2])
1242 / ((1.0 - ratio)*padSignal[2] + padSignal[3] + padSignal[4]);
1244 // Set cluster charge ratio
1245 irc = calibration->PadResponse(1.0, maxLeft, layer, newSignal);
1246 Double_t ampLeft = padSignal[1] / newSignal[1];
1247 irc = calibration->PadResponse(1.0, maxRight, layer, newSignal);
1248 Double_t ampRight = padSignal[3] / newSignal[1];
1250 // Apply pad response to parameters
1251 irc = calibration->PadResponse(ampLeft ,maxLeft ,layer,newLeftSignal );
1252 irc = calibration->PadResponse(ampRight,maxRight,layer,newRightSignal);
1254 // Calculate new overlapping ratio
1255 ratio = TMath::Min((Double_t) 1.0
1256 ,newLeftSignal[2] / (newLeftSignal[2] + newRightSignal[0]));
1264 //_____________________________________________________________________________
1265 void AliTRDclusterizer::TailCancelation()
1268 // Applies the tail cancelation and gain factors:
1269 // Transform fDigitsIn to fDigitsOut
1276 Double_t *inADC = new Double_t[fTimeTotal]; // ADC data before tail cancellation
1277 Double_t *outADC = new Double_t[fTimeTotal]; // ADC data after tail cancellation
1278 fIndexes->ResetCounters();
1279 TTreeSRedirector *fDebugStream = fReconstructor->GetDebugStream(AliTRDReconstructor::kClusterizer);
1280 while(fIndexes->NextRCIndex(iRow, iCol))
1282 Float_t fCalGainFactorROCValue = fCalGainFactorROC->GetValue(iCol,iRow);
1283 Double_t gain = fCalGainFactorDetValue
1284 * fCalGainFactorROCValue;
1286 Bool_t corrupted = kFALSE;
1287 for (iTime = 0; iTime < fTimeTotal; iTime++)
1289 // Apply gain gain factor
1290 inADC[iTime] = fDigitsIn->GetDataB(iRow,iCol,iTime);
1291 if (fDigitsIn->GetPadStatus(iRow, iCol, iTime)) corrupted = kTRUE;
1292 inADC[iTime] /= gain;
1293 outADC[iTime] = inADC[iTime];
1294 if(fReconstructor->GetStreamLevel(AliTRDReconstructor::kClusterizer) > 7){
1295 (*fDebugStream) << "TailCancellation"
1299 << "inADC=" << inADC[iTime]
1301 << "outADC=" << outADC[iTime]
1302 << "corrupted=" << corrupted
1308 // Apply the tail cancelation via the digital filter
1309 // (only for non-coorupted pads)
1310 if (fReconstructor->GetRecoParam()->IsTailCancelation())
1311 DeConvExp(inADC,outADC,fTimeTotal,fReconstructor->GetRecoParam() ->GetTCnexp());
1314 for(iTime = 0; iTime < fTimeTotal; iTime++)//while (fIndexes->NextTbinIndex(iTime))
1316 // Store the amplitude of the digit if above threshold
1317 if (outADC[iTime] > fADCthresh)
1318 fDigitsOut->SetData(iRow,iCol,iTime,outADC[iTime]);
1321 } // while irow icol
1330 //_____________________________________________________________________________
1331 void AliTRDclusterizer::DeConvExp(const Double_t *const source, Double_t *const target
1332 ,const Int_t n, const Int_t nexp)
1335 // Tail cancellation by deconvolution for PASA v4 TRF
1339 Double_t coefficients[2];
1341 // Initialization (coefficient = alpha, rates = lambda)
1347 if (nexp == 1) { // 1 Exponentials
1353 if (nexp == 2) { // 2 Exponentials
1355 fReconstructor->GetTCParams(par);
1356 r1 = par[0];//1.156;
1357 r2 = par[1];//0.130;
1358 c1 = par[2];//0.114;
1359 c2 = par[3];//0.624;
1362 coefficients[0] = c1;
1363 coefficients[1] = c2;
1367 rates[0] = TMath::Exp(-dt/(r1));
1368 rates[1] = TMath::Exp(-dt/(r2));
1373 Double_t reminder[2];
1374 Double_t correction = 0.0;
1375 Double_t result = 0.0;
1377 // Attention: computation order is important
1378 for (k = 0; k < nexp; k++) {
1382 for (i = 0; i < n; i++) {
1384 result = (source[i] - correction); // No rescaling
1387 for (k = 0; k < nexp; k++) {
1388 reminder[k] = rates[k] * (reminder[k] + coefficients[k] * result);
1392 for (k = 0; k < nexp; k++) {
1393 correction += reminder[k];
1400 //_____________________________________________________________________________
1401 void AliTRDclusterizer::ResetRecPoints()
1404 // Resets the list of rec points
1408 fRecPoints->Delete();
1413 //_____________________________________________________________________________
1414 TClonesArray *AliTRDclusterizer::RecPoints()
1417 // Returns the list of rec points
1421 if(!(fRecPoints = AliTRDReconstructor::GetClusters())){
1422 // determine number of clusters which has to be allocated
1423 Float_t nclusters = fReconstructor->GetRecoParam()->GetNClusters();
1424 if(fReconstructor->IsHLT()) nclusters /= AliTRDgeometry::kNsector;
1426 fRecPoints = new TClonesArray("AliTRDcluster", Int_t(nclusters));
1428 //SetClustersOwner(kTRUE);
1429 AliTRDReconstructor::SetClusters(0x0);
1435 //_____________________________________________________________________________
1436 void AliTRDclusterizer::FillLUT()
1442 const Int_t kNlut = 128;
1444 fLUTbin = AliTRDgeometry::kNlayer * kNlut;
1446 // The lookup table from Bogdan
1447 Float_t lut[AliTRDgeometry::kNlayer][kNlut] = {
1449 0.0070, 0.0150, 0.0224, 0.0298, 0.0374, 0.0454, 0.0533, 0.0611,
1450 0.0684, 0.0755, 0.0827, 0.0900, 0.0975, 0.1049, 0.1120, 0.1187,
1451 0.1253, 0.1318, 0.1385, 0.1453, 0.1519, 0.1584, 0.1646, 0.1704,
1452 0.1762, 0.1821, 0.1879, 0.1938, 0.1996, 0.2053, 0.2108, 0.2160,
1453 0.2210, 0.2260, 0.2310, 0.2361, 0.2411, 0.2461, 0.2509, 0.2557,
1454 0.2602, 0.2646, 0.2689, 0.2732, 0.2774, 0.2816, 0.2859, 0.2901,
1455 0.2942, 0.2983, 0.3022, 0.3061, 0.3099, 0.3136, 0.3172, 0.3207,
1456 0.3242, 0.3278, 0.3312, 0.3347, 0.3382, 0.3416, 0.3450, 0.3483,
1457 0.3515, 0.3547, 0.3579, 0.3609, 0.3639, 0.3669, 0.3698, 0.3727,
1458 0.3756, 0.3785, 0.3813, 0.3842, 0.3870, 0.3898, 0.3926, 0.3952,
1459 0.3979, 0.4005, 0.4032, 0.4057, 0.4082, 0.4108, 0.4132, 0.4157,
1460 0.4181, 0.4205, 0.4228, 0.4252, 0.4275, 0.4299, 0.4322, 0.4345,
1461 0.4367, 0.4390, 0.4412, 0.4434, 0.4456, 0.4478, 0.4499, 0.4520,
1462 0.4541, 0.4562, 0.4583, 0.4603, 0.4623, 0.4643, 0.4663, 0.4683,
1463 0.4702, 0.4722, 0.4741, 0.4758, 0.4774, 0.4790, 0.4805, 0.4824,
1464 0.4844, 0.4863, 0.4883, 0.4902, 0.4921, 0.4940, 0.4959, 0.4978
1467 0.0072, 0.0156, 0.0235, 0.0313, 0.0394, 0.0478, 0.0561, 0.0642,
1468 0.0718, 0.0792, 0.0868, 0.0947, 0.1025, 0.1101, 0.1172, 0.1241,
1469 0.1309, 0.1378, 0.1449, 0.1518, 0.1586, 0.1650, 0.1710, 0.1770,
1470 0.1830, 0.1891, 0.1952, 0.2011, 0.2070, 0.2125, 0.2177, 0.2229,
1471 0.2280, 0.2332, 0.2383, 0.2435, 0.2484, 0.2533, 0.2581, 0.2627,
1472 0.2670, 0.2714, 0.2757, 0.2799, 0.2842, 0.2884, 0.2927, 0.2968,
1473 0.3008, 0.3048, 0.3086, 0.3123, 0.3159, 0.3195, 0.3231, 0.3266,
1474 0.3301, 0.3335, 0.3370, 0.3404, 0.3438, 0.3471, 0.3504, 0.3536,
1475 0.3567, 0.3598, 0.3628, 0.3657, 0.3686, 0.3715, 0.3744, 0.3772,
1476 0.3800, 0.3828, 0.3856, 0.3884, 0.3911, 0.3938, 0.3965, 0.3991,
1477 0.4016, 0.4042, 0.4067, 0.4092, 0.4116, 0.4140, 0.4164, 0.4187,
1478 0.4211, 0.4234, 0.4257, 0.4280, 0.4302, 0.4325, 0.4347, 0.4369,
1479 0.4391, 0.4413, 0.4434, 0.4456, 0.4477, 0.4497, 0.4518, 0.4538,
1480 0.4558, 0.4578, 0.4598, 0.4618, 0.4637, 0.4656, 0.4675, 0.4694,
1481 0.4713, 0.4732, 0.4750, 0.4766, 0.4781, 0.4797, 0.4813, 0.4832,
1482 0.4851, 0.4870, 0.4888, 0.4906, 0.4925, 0.4942, 0.4960, 0.4978
1485 0.0075, 0.0163, 0.0246, 0.0328, 0.0415, 0.0504, 0.0592, 0.0674,
1486 0.0753, 0.0832, 0.0914, 0.0996, 0.1077, 0.1154, 0.1225, 0.1296,
1487 0.1369, 0.1442, 0.1515, 0.1585, 0.1652, 0.1714, 0.1776, 0.1839,
1488 0.1902, 0.1965, 0.2025, 0.2085, 0.2141, 0.2194, 0.2247, 0.2299,
1489 0.2352, 0.2405, 0.2457, 0.2507, 0.2557, 0.2604, 0.2649, 0.2693,
1490 0.2737, 0.2780, 0.2823, 0.2867, 0.2909, 0.2951, 0.2992, 0.3033,
1491 0.3072, 0.3110, 0.3146, 0.3182, 0.3218, 0.3253, 0.3288, 0.3323,
1492 0.3357, 0.3392, 0.3426, 0.3459, 0.3492, 0.3524, 0.3555, 0.3586,
1493 0.3616, 0.3645, 0.3674, 0.3703, 0.3731, 0.3759, 0.3787, 0.3815,
1494 0.3843, 0.3870, 0.3897, 0.3925, 0.3950, 0.3976, 0.4002, 0.4027,
1495 0.4052, 0.4076, 0.4101, 0.4124, 0.4148, 0.4171, 0.4194, 0.4217,
1496 0.4239, 0.4262, 0.4284, 0.4306, 0.4328, 0.4350, 0.4371, 0.4393,
1497 0.4414, 0.4435, 0.4455, 0.4476, 0.4496, 0.4516, 0.4536, 0.4555,
1498 0.4575, 0.4594, 0.4613, 0.4632, 0.4650, 0.4669, 0.4687, 0.4705,
1499 0.4723, 0.4741, 0.4758, 0.4773, 0.4789, 0.4804, 0.4821, 0.4839,
1500 0.4857, 0.4875, 0.4893, 0.4910, 0.4928, 0.4945, 0.4961, 0.4978
1503 0.0078, 0.0171, 0.0258, 0.0345, 0.0438, 0.0532, 0.0624, 0.0708,
1504 0.0791, 0.0875, 0.0962, 0.1048, 0.1130, 0.1206, 0.1281, 0.1356,
1505 0.1432, 0.1508, 0.1582, 0.1651, 0.1716, 0.1780, 0.1845, 0.1910,
1506 0.1975, 0.2038, 0.2099, 0.2155, 0.2210, 0.2263, 0.2317, 0.2371,
1507 0.2425, 0.2477, 0.2528, 0.2578, 0.2626, 0.2671, 0.2715, 0.2759,
1508 0.2803, 0.2846, 0.2890, 0.2933, 0.2975, 0.3016, 0.3056, 0.3095,
1509 0.3132, 0.3168, 0.3204, 0.3239, 0.3274, 0.3309, 0.3344, 0.3378,
1510 0.3412, 0.3446, 0.3479, 0.3511, 0.3543, 0.3574, 0.3603, 0.3633,
1511 0.3662, 0.3690, 0.3718, 0.3747, 0.3774, 0.3802, 0.3829, 0.3857,
1512 0.3883, 0.3910, 0.3936, 0.3962, 0.3987, 0.4012, 0.4037, 0.4061,
1513 0.4085, 0.4109, 0.4132, 0.4155, 0.4177, 0.4200, 0.4222, 0.4244,
1514 0.4266, 0.4288, 0.4309, 0.4331, 0.4352, 0.4373, 0.4394, 0.4414,
1515 0.4435, 0.4455, 0.4475, 0.4494, 0.4514, 0.4533, 0.4552, 0.4571,
1516 0.4590, 0.4608, 0.4626, 0.4645, 0.4662, 0.4680, 0.4698, 0.4715,
1517 0.4733, 0.4750, 0.4766, 0.4781, 0.4796, 0.4812, 0.4829, 0.4846,
1518 0.4863, 0.4880, 0.4897, 0.4914, 0.4930, 0.4946, 0.4963, 0.4979
1521 0.0081, 0.0178, 0.0270, 0.0364, 0.0463, 0.0562, 0.0656, 0.0744,
1522 0.0831, 0.0921, 0.1013, 0.1102, 0.1183, 0.1261, 0.1339, 0.1419,
1523 0.1499, 0.1576, 0.1648, 0.1715, 0.1782, 0.1849, 0.1917, 0.1984,
1524 0.2048, 0.2110, 0.2167, 0.2223, 0.2278, 0.2333, 0.2389, 0.2444,
1525 0.2497, 0.2548, 0.2598, 0.2645, 0.2691, 0.2735, 0.2780, 0.2824,
1526 0.2868, 0.2912, 0.2955, 0.2997, 0.3038, 0.3078, 0.3116, 0.3152,
1527 0.3188, 0.3224, 0.3259, 0.3294, 0.3329, 0.3364, 0.3398, 0.3432,
1528 0.3465, 0.3497, 0.3529, 0.3561, 0.3591, 0.3620, 0.3649, 0.3677,
1529 0.3705, 0.3733, 0.3761, 0.3788, 0.3816, 0.3843, 0.3869, 0.3896,
1530 0.3922, 0.3948, 0.3973, 0.3998, 0.4022, 0.4047, 0.4070, 0.4094,
1531 0.4117, 0.4139, 0.4162, 0.4184, 0.4206, 0.4227, 0.4249, 0.4270,
1532 0.4291, 0.4313, 0.4334, 0.4354, 0.4375, 0.4395, 0.4415, 0.4435,
1533 0.4455, 0.4474, 0.4493, 0.4512, 0.4531, 0.4550, 0.4568, 0.4586,
1534 0.4604, 0.4622, 0.4639, 0.4657, 0.4674, 0.4691, 0.4708, 0.4725,
1535 0.4742, 0.4758, 0.4773, 0.4788, 0.4803, 0.4819, 0.4836, 0.4852,
1536 0.4869, 0.4885, 0.4901, 0.4917, 0.4933, 0.4948, 0.4964, 0.4979
1539 0.0085, 0.0189, 0.0288, 0.0389, 0.0497, 0.0603, 0.0699, 0.0792,
1540 0.0887, 0.0985, 0.1082, 0.1170, 0.1253, 0.1336, 0.1421, 0.1505,
1541 0.1587, 0.1662, 0.1733, 0.1803, 0.1874, 0.1945, 0.2014, 0.2081,
1542 0.2143, 0.2201, 0.2259, 0.2316, 0.2374, 0.2431, 0.2487, 0.2541,
1543 0.2593, 0.2642, 0.2689, 0.2735, 0.2781, 0.2826, 0.2872, 0.2917,
1544 0.2961, 0.3003, 0.3045, 0.3086, 0.3125, 0.3162, 0.3198, 0.3235,
1545 0.3270, 0.3306, 0.3342, 0.3377, 0.3411, 0.3446, 0.3479, 0.3511,
1546 0.3543, 0.3575, 0.3605, 0.3634, 0.3663, 0.3691, 0.3720, 0.3748,
1547 0.3775, 0.3803, 0.3830, 0.3857, 0.3884, 0.3911, 0.3937, 0.3962,
1548 0.3987, 0.4012, 0.4036, 0.4060, 0.4084, 0.4107, 0.4129, 0.4152,
1549 0.4174, 0.4196, 0.4218, 0.4239, 0.4261, 0.4282, 0.4303, 0.4324,
1550 0.4344, 0.4365, 0.4385, 0.4405, 0.4425, 0.4445, 0.4464, 0.4483,
1551 0.4502, 0.4521, 0.4539, 0.4558, 0.4576, 0.4593, 0.4611, 0.4629,
1552 0.4646, 0.4663, 0.4680, 0.4697, 0.4714, 0.4730, 0.4747, 0.4759,
1553 0.4769, 0.4780, 0.4790, 0.4800, 0.4811, 0.4827, 0.4843, 0.4859,
1554 0.4874, 0.4889, 0.4905, 0.4920, 0.4935, 0.4950, 0.4965, 0.4979
1561 fLUT = new Double_t[fLUTbin];
1563 for (Int_t ilayer = 0; ilayer < AliTRDgeometry::kNlayer; ilayer++) {
1564 for (Int_t ilut = 0; ilut < kNlut; ilut++ ) {
1565 fLUT[ilayer*kNlut+ilut] = lut[ilayer][ilut];
1571 //_____________________________________________________________________________
1572 Double_t AliTRDclusterizer::LUTposition(Int_t ilayer
1575 , Double_t ampR) const
1578 // Calculates the cluster position using the lookup table.
1579 // Method provided by Bogdan Vulpescu.
1582 const Int_t kNlut = 128;
1593 Double_t xMin[AliTRDgeometry::kNlayer] = { 0.006492, 0.006377, 0.006258
1594 , 0.006144, 0.006030, 0.005980 };
1595 Double_t xMax[AliTRDgeometry::kNlayer] = { 0.960351, 0.965870, 0.970445
1596 , 0.974352, 0.977667, 0.996101 };
1599 x = (ampL - ampR) / ampC;
1602 else if (ampL < ampR) {
1603 x = (ampR - ampL) / ampC;
1609 xmin = xMin[ilayer] + 0.000005;
1610 xmax = xMax[ilayer] - 0.000005;
1611 xwid = (xmax - xmin) / 127.0;
1616 else if (x > xmax) {
1617 pos = side * 0.5000;
1620 ix = (Int_t) ((x - xmin) / xwid);
1621 pos = side * fLUT[ilayer*kNlut+ix];