]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDclusterizer.cxx
-1. Possibility to call FindMultiMC in the debug mode AliTPCReconstructor::StreamLeve...
[u/mrichter/AliRoot.git] / TRD / AliTRDclusterizer.cxx
CommitLineData
f7336fa3 1/**************************************************************************
317b5644 2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
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**************************************************************************/
f7336fa3 15
88cb7938 16/* $Id$ */
f7336fa3 17
18///////////////////////////////////////////////////////////////////////////////
19// //
3fe61b77 20// TRD cluster finder //
f7336fa3 21// //
22///////////////////////////////////////////////////////////////////////////////
23
3fe61b77 24#include <TF1.h>
94de3818 25#include <TTree.h>
3fe61b77 26#include <TH1.h>
793ff80c 27#include <TFile.h>
66f6bfd9 28#include <TClonesArray.h>
6d50f529 29#include <TObjArray.h>
f7336fa3 30
88cb7938 31#include "AliRunLoader.h"
32#include "AliLoader.h"
3fe61b77 33#include "AliRawReader.h"
6d50f529 34#include "AliLog.h"
3fe61b77 35#include "AliAlignObj.h"
88cb7938 36
f7336fa3 37#include "AliTRDclusterizer.h"
3e1a3ad8 38#include "AliTRDcluster.h"
fc546d21 39#include "AliTRDReconstructor.h"
793ff80c 40#include "AliTRDgeometry.h"
b65e5048 41#include "AliTRDarraySignal.h"
42#include "AliTRDarrayDictionary.h"
43#include "AliTRDarrayADC.h"
3fe61b77 44#include "AliTRDdigitsManager.h"
45#include "AliTRDrawData.h"
3551db50 46#include "AliTRDcalibDB.h"
fc546d21 47#include "AliTRDrecoParam.h"
b43a3e17 48#include "AliTRDCommonParam.h"
3fe61b77 49#include "AliTRDtransform.h"
50#include "AliTRDSignalIndex.h"
dfbb4bb9 51#include "AliTRDrawStreamBase.h"
3fe61b77 52#include "AliTRDfeeParam.h"
53
54#include "Cal/AliTRDCalROC.h"
55#include "Cal/AliTRDCalDet.h"
0e09df31 56#include "Cal/AliTRDCalSingleChamberStatus.h"
f7336fa3 57
58ClassImp(AliTRDclusterizer)
59
60//_____________________________________________________________________________
3a039a31 61AliTRDclusterizer::AliTRDclusterizer(AliTRDReconstructor *rec)
6d50f529 62 :TNamed()
3a039a31 63 ,fReconstructor(rec)
6d50f529 64 ,fRunLoader(NULL)
65 ,fClusterTree(NULL)
66 ,fRecPoints(NULL)
9c7c9ec1 67 ,fTrackletTree(NULL)
3fe61b77 68 ,fDigitsManager(NULL)
9c7c9ec1 69 ,fTrackletContainer(NULL)
3fe61b77 70 ,fAddLabels(kTRUE)
71 ,fRawVersion(2)
72 ,fIndexesOut(NULL)
73 ,fIndexesMaxima(NULL)
dfbb4bb9 74 ,fTransform(new AliTRDtransform(0))
fc546d21 75 ,fLUTbin(0)
76 ,fLUT(NULL)
f7336fa3 77{
78 //
79 // AliTRDclusterizer default constructor
80 //
81
a7ac01d2 82 AliTRDcalibDB *trd = 0x0;
83 if (!(trd = AliTRDcalibDB::Instance())) {
84 AliFatal("Could not get calibration object");
85 }
86
3fe61b77 87 fRawVersion = AliTRDfeeParam::Instance()->GetRAWversion();
88
3a039a31 89 // Initialize debug stream
90 if(fReconstructor){
91 if(fReconstructor->GetStreamLevel(AliTRDReconstructor::kClusterizer) > 1){
92 TDirectory *savedir = gDirectory;
93 //fgDebugStreamer = new TTreeSRedirector("TRD.ClusterizerDebug.root");
94 savedir->cd();
95 }
96 }
eb52b657 97
f7336fa3 98}
99
100//_____________________________________________________________________________
3a039a31 101AliTRDclusterizer::AliTRDclusterizer(const Text_t *name, const Text_t *title, AliTRDReconstructor *rec)
6d50f529 102 :TNamed(name,title)
3a039a31 103 ,fReconstructor(rec)
6d50f529 104 ,fRunLoader(NULL)
105 ,fClusterTree(NULL)
106 ,fRecPoints(NULL)
9c7c9ec1 107 ,fTrackletTree(NULL)
3fe61b77 108 ,fDigitsManager(new AliTRDdigitsManager())
9c7c9ec1 109 ,fTrackletContainer(NULL)
3fe61b77 110 ,fAddLabels(kTRUE)
111 ,fRawVersion(2)
112 ,fIndexesOut(NULL)
113 ,fIndexesMaxima(NULL)
114 ,fTransform(new AliTRDtransform(0))
fc546d21 115 ,fLUTbin(0)
116 ,fLUT(NULL)
f7336fa3 117{
118 //
6d50f529 119 // AliTRDclusterizer constructor
f7336fa3 120 //
121
a7ac01d2 122 AliTRDcalibDB *trd = 0x0;
123 if (!(trd = AliTRDcalibDB::Instance())) {
124 AliFatal("Could not get calibration object");
125 }
126
3a039a31 127 // Initialize debug stream
eb52b657 128 if (fReconstructor){
129 if (fReconstructor->GetStreamLevel(AliTRDReconstructor::kClusterizer) > 1){
3a039a31 130 TDirectory *savedir = gDirectory;
131 //fgDebugStreamer = new TTreeSRedirector("TRD.ClusterizerDebug.root");
132 savedir->cd();
133 }
134 }
135
3fe61b77 136 fDigitsManager->CreateArrays();
137
138 fRawVersion = AliTRDfeeParam::Instance()->GetRAWversion();
139
fc546d21 140 FillLUT();
023b669c 141
f7336fa3 142}
143
8230f242 144//_____________________________________________________________________________
6d50f529 145AliTRDclusterizer::AliTRDclusterizer(const AliTRDclusterizer &c)
146 :TNamed(c)
3a039a31 147 ,fReconstructor(c.fReconstructor)
6d50f529 148 ,fRunLoader(NULL)
149 ,fClusterTree(NULL)
150 ,fRecPoints(NULL)
9c7c9ec1 151 ,fTrackletTree(NULL)
3fe61b77 152 ,fDigitsManager(NULL)
66f6bfd9 153 ,fTrackletContainer(NULL)
3fe61b77 154 ,fAddLabels(kTRUE)
155 ,fRawVersion(2)
156 ,fIndexesOut(NULL)
157 ,fIndexesMaxima(NULL)
158 ,fTransform(NULL)
fc546d21 159 ,fLUTbin(0)
160 ,fLUT(0)
8230f242 161{
162 //
163 // AliTRDclusterizer copy constructor
164 //
165
fc546d21 166 FillLUT();
167
8230f242 168}
169
f7336fa3 170//_____________________________________________________________________________
171AliTRDclusterizer::~AliTRDclusterizer()
172{
8230f242 173 //
174 // AliTRDclusterizer destructor
175 //
f7336fa3 176
48f8adf3 177 if (fRecPoints/* && IsClustersOwner()*/){
66f6bfd9 178 fRecPoints->Delete();
179 delete fRecPoints;
180 }
3fe61b77 181
66f6bfd9 182 if (fDigitsManager) {
183 delete fDigitsManager;
184 fDigitsManager = NULL;
185 }
9c7c9ec1 186
66f6bfd9 187 if (fTrackletContainer){
188 delete fTrackletContainer;
189 fTrackletContainer = NULL;
190 }
3fe61b77 191
66f6bfd9 192 if (fIndexesOut){
193 delete fIndexesOut;
194 fIndexesOut = NULL;
195 }
3fe61b77 196
66f6bfd9 197 if (fIndexesMaxima){
198 delete fIndexesMaxima;
199 fIndexesMaxima = NULL;
200 }
6d50f529 201
66f6bfd9 202 if (fTransform){
203 delete fTransform;
204 fTransform = NULL;
205 }
fc546d21 206
66f6bfd9 207 if (fLUT) {
208 delete [] fLUT;
209 fLUT = NULL;
210 }
eb52b657 211
f7336fa3 212}
213
8230f242 214//_____________________________________________________________________________
dd9a6ee3 215AliTRDclusterizer &AliTRDclusterizer::operator=(const AliTRDclusterizer &c)
216{
217 //
218 // Assignment operator
219 //
220
3fe61b77 221 if (this != &c)
222 {
223 ((AliTRDclusterizer &) c).Copy(*this);
224 }
053767a4 225
dd9a6ee3 226 return *this;
227
228}
229
230//_____________________________________________________________________________
e0d47c25 231void AliTRDclusterizer::Copy(TObject &c) const
8230f242 232{
233 //
234 // Copy function
235 //
236
3fe61b77 237 ((AliTRDclusterizer &) c).fClusterTree = NULL;
238 ((AliTRDclusterizer &) c).fRecPoints = NULL;
9c7c9ec1 239 ((AliTRDclusterizer &) c).fTrackletTree = NULL;
3fe61b77 240 ((AliTRDclusterizer &) c).fDigitsManager = NULL;
9c7c9ec1 241 ((AliTRDclusterizer &) c).fTrackletContainer = NULL;
3fe61b77 242 ((AliTRDclusterizer &) c).fAddLabels = fAddLabels;
243 ((AliTRDclusterizer &) c).fRawVersion = fRawVersion;
244 ((AliTRDclusterizer &) c).fIndexesOut = NULL;
245 ((AliTRDclusterizer &) c).fIndexesMaxima = NULL;
246 ((AliTRDclusterizer &) c).fTransform = NULL;
fc546d21 247 ((AliTRDclusterizer &) c).fLUTbin = 0;
248 ((AliTRDclusterizer &) c).fLUT = NULL;
8230f242 249
250}
251
f7336fa3 252//_____________________________________________________________________________
3e1a3ad8 253Bool_t AliTRDclusterizer::Open(const Char_t *name, Int_t nEvent)
f7336fa3 254{
255 //
3e1a3ad8 256 // Opens the AliROOT file. Output and input are in the same file
f7336fa3 257 //
6d50f529 258
e191bb57 259 TString evfoldname = AliConfig::GetDefaultEventFolderName();
6d50f529 260 fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
261
262 if (!fRunLoader) {
19dd5b2f 263 fRunLoader = AliRunLoader::Open(name);
6d50f529 264 }
265
266 if (!fRunLoader) {
267 AliError(Form("Can not open session for file %s.",name));
268 return kFALSE;
269 }
88cb7938 270
271 OpenInput(nEvent);
272 OpenOutput();
6d50f529 273
3e1a3ad8 274 return kTRUE;
f7336fa3 275
6d50f529 276}
3e1a3ad8 277
278//_____________________________________________________________________________
88cb7938 279Bool_t AliTRDclusterizer::OpenOutput()
3e1a3ad8 280{
281 //
282 // Open the output file
283 //
284
66f6bfd9 285 if (!fReconstructor->IsWritingClusters()) return kTRUE;
286
287 TObjArray *ioArray = 0x0;
88cb7938 288
289 AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
290 loader->MakeTree("R");
6d50f529 291
88cb7938 292 fClusterTree = loader->TreeR();
66f6bfd9 293 fClusterTree->Branch("TRDcluster", "TObjArray", &ioArray, 32000, 0);
3e1a3ad8 294
3e1a3ad8 295 return kTRUE;
296
297}
298
25ca55ce 299//_____________________________________________________________________________
300Bool_t AliTRDclusterizer::OpenOutput(TTree *clusterTree)
301{
302 //
303 // Connect the output tree
304 //
305
66f6bfd9 306 // clusters writing
307 if (fReconstructor->IsWritingClusters()){
308 TObjArray *ioArray = 0x0;
309 fClusterTree = clusterTree;
310 fClusterTree->Branch("TRDcluster", "TObjArray", &ioArray, 32000, 0);
311 }
9c7c9ec1 312
313 // tracklet writing
3a039a31 314 if (fReconstructor->IsWritingTracklets()){
9c7c9ec1 315 TString evfoldname = AliConfig::GetDefaultEventFolderName();
316 fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
317
318 if (!fRunLoader) {
319 fRunLoader = AliRunLoader::Open("galice.root");
320 }
321 if (!fRunLoader) {
322 AliError(Form("Can not open session for file galice.root."));
323 return kFALSE;
324 }
325
326 UInt_t **leaves = new UInt_t *[2];
327 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
328 if (!dl) {
329 AliError("Could not get the tracklets data loader!");
90cf7133 330 dl = new AliDataLoader("TRD.Tracklets.root","tracklets", "tracklets");
9c7c9ec1 331 fRunLoader->GetLoader("TRDLoader")->AddDataLoader(dl);
332 }
333 else {
334 fTrackletTree = dl->Tree();
335 if (!fTrackletTree)
336 {
317b5644 337 dl->MakeTree();
338 fTrackletTree = dl->Tree();
9c7c9ec1 339 }
340 TBranch *trkbranch = fTrackletTree->GetBranch("trkbranch");
341 if (!trkbranch)
342 fTrackletTree->Branch("trkbranch",leaves[0],"det/i:side/i:tracklets[256]/i");
343 }
344 }
345
25ca55ce 346 return kTRUE;
347
348}
349
3e1a3ad8 350//_____________________________________________________________________________
88cb7938 351Bool_t AliTRDclusterizer::OpenInput(Int_t nEvent)
f7336fa3 352{
353 //
354 // Opens a ROOT-file with TRD-hits and reads in the digits-tree
355 //
356
f7336fa3 357 // Import the Trees for the event nEvent in the file
bdbb05bb 358 fRunLoader->GetEvent(nEvent);
88cb7938 359
f7336fa3 360 return kTRUE;
361
362}
363
364//_____________________________________________________________________________
793ff80c 365Bool_t AliTRDclusterizer::WriteClusters(Int_t det)
f7336fa3 366{
367 //
3e1a3ad8 368 // Fills TRDcluster branch in the tree with the clusters
793ff80c 369 // found in detector = det. For det=-1 writes the tree.
a3c76cdc 370 //
793ff80c 371
6d50f529 372 if ((det < -1) ||
373 (det >= AliTRDgeometry::Ndet())) {
374 AliError(Form("Unexpected detector index %d.\n",det));
3e1a3ad8 375 return kFALSE;
793ff80c 376 }
317b5644 377
66f6bfd9 378 TObjArray *ioArray = new TObjArray(400);
3e1a3ad8 379 TBranch *branch = fClusterTree->GetBranch("TRDcluster");
380 if (!branch) {
3e1a3ad8 381 branch = fClusterTree->Branch("TRDcluster","TObjArray",&ioArray,32000,0);
66f6bfd9 382 } else branch->SetAddress(&ioArray);
66f6bfd9 383
384 Int_t nRecPoints = RecPoints()->GetEntriesFast();
385 if(det >= 0){
3e1a3ad8 386 for (Int_t i = 0; i < nRecPoints; i++) {
bdbb05bb 387 AliTRDcluster *c = (AliTRDcluster *) RecPoints()->UncheckedAt(i);
66f6bfd9 388 if(det != c->GetDetector()) continue;
389 ioArray->AddLast(c);
793ff80c 390 }
3e1a3ad8 391 fClusterTree->Fill();
66f6bfd9 392 } else {
eb52b657 393
66f6bfd9 394 Int_t detOld = -1;
395 for (Int_t i = 0; i < nRecPoints; i++) {
396 AliTRDcluster *c = (AliTRDcluster *) RecPoints()->UncheckedAt(i);
397 if(c->GetDetector() != detOld){
398 fClusterTree->Fill();
399 ioArray->Clear();
400 detOld = c->GetDetector();
401 }
402 ioArray->AddLast(c);
a6dd11e9 403 }
793ff80c 404 }
66f6bfd9 405 delete ioArray;
6d50f529 406
66f6bfd9 407 return kTRUE;
eb52b657 408
f7336fa3 409}
793ff80c 410
9c7c9ec1 411//_____________________________________________________________________________
412Bool_t AliTRDclusterizer::WriteTracklets(Int_t det)
413{
eb52b657 414 //
415 // Write the raw data tracklets into seperate file
416 //
9c7c9ec1 417
418 UInt_t **leaves = new UInt_t *[2];
419 for (Int_t i=0; i<2 ;i++){
317b5644 420 leaves[i] = new UInt_t[258];
421 leaves[i][0] = det; // det
422 leaves[i][1] = i; // side
423 memcpy(leaves[i]+2, fTrackletContainer[i], sizeof(UInt_t) * 256);
9c7c9ec1 424 }
425
9c7c9ec1 426 if (!fTrackletTree){
427 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
428 dl->MakeTree();
429 fTrackletTree = dl->Tree();
430 }
431
432 TBranch *trkbranch = fTrackletTree->GetBranch("trkbranch");
433 if (!trkbranch) {
434 trkbranch = fTrackletTree->Branch("trkbranch",leaves[0],"det/i:side/i:tracklets[256]/i");
435 }
436
437 for (Int_t i=0; i<2; i++){
317b5644 438 if (leaves[i][2]>0) {
439 trkbranch->SetAddress(leaves[i]);
440 fTrackletTree->Fill();
441 }
9c7c9ec1 442 }
443
444 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
445 dl->WriteData("OVERWRITE");
446 //dl->Unload();
447 delete [] leaves;
448
eb52b657 449 return kTRUE;
450
9c7c9ec1 451}
452
3551db50 453//_____________________________________________________________________________
3fe61b77 454void AliTRDclusterizer::ResetHelperIndexes(AliTRDSignalIndex *indexesIn)
455{
456 //
457 // Reset the helper indexes
458 //
459
460 if (fIndexesOut)
461 {
462 // carefull here - we assume that only row number may change - most probable
463 if (indexesIn->GetNrow() <= fIndexesOut->GetNrow())
317b5644 464 fIndexesOut->ResetContent();
3fe61b77 465 else
317b5644 466 fIndexesOut->ResetContentConditional(indexesIn->GetNrow()
467 , indexesIn->GetNcol()
468 , indexesIn->GetNtime());
3fe61b77 469 }
470 else
471 {
472 fIndexesOut = new AliTRDSignalIndex(indexesIn->GetNrow()
473 , indexesIn->GetNcol()
474 , indexesIn->GetNtime());
475 }
476
477 if (fIndexesMaxima)
478 {
479 // carefull here - we assume that only row number may change - most probable
480 if (indexesIn->GetNrow() <= fIndexesMaxima->GetNrow())
481 {
317b5644 482 fIndexesMaxima->ResetContent();
483 }
3fe61b77 484 else
317b5644 485 {
486 fIndexesMaxima->ResetContentConditional(indexesIn->GetNrow()
3fe61b77 487 , indexesIn->GetNcol()
488 , indexesIn->GetNtime());
317b5644 489 }
3fe61b77 490 }
491 else
492 {
493 fIndexesMaxima = new AliTRDSignalIndex(indexesIn->GetNrow()
317b5644 494 , indexesIn->GetNcol()
495 , indexesIn->GetNtime());
3fe61b77 496 }
497
498}
499
500//_____________________________________________________________________________
501Bool_t AliTRDclusterizer::ReadDigits()
502{
503 //
504 // Reads the digits arrays from the input aliroot file
505 //
506
507 if (!fRunLoader) {
508 AliError("No run loader available");
509 return kFALSE;
510 }
511
512 AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
513 if (!loader->TreeD()) {
514 loader->LoadDigits();
515 }
516
517 // Read in the digit arrays
518 return (fDigitsManager->ReadDigits(loader->TreeD()));
519
520}
521
522//_____________________________________________________________________________
523Bool_t AliTRDclusterizer::ReadDigits(TTree *digitsTree)
524{
525 //
526 // Reads the digits arrays from the input tree
527 //
528
529 // Read in the digit arrays
530 return (fDigitsManager->ReadDigits(digitsTree));
531
532}
533
534//_____________________________________________________________________________
535Bool_t AliTRDclusterizer::ReadDigits(AliRawReader *rawReader)
536{
537 //
538 // Reads the digits arrays from the ddl file
539 //
540
541 AliTRDrawData raw;
542 fDigitsManager = raw.Raw2Digits(rawReader);
543
544 return kTRUE;
545
546}
547
548//_____________________________________________________________________________
549Bool_t AliTRDclusterizer::MakeClusters()
550{
551 //
552 // Creates clusters from digits
553 //
554
555 // Propagate info from the digits manager
66f6bfd9 556 if (fAddLabels == kTRUE){
557 fAddLabels = fDigitsManager->UsesDictionaries();
558 }
559
3fe61b77 560 Bool_t fReturn = kTRUE;
66f6bfd9 561 for (Int_t i = 0; i < AliTRDgeometry::kNdet; i++){
562
b65e5048 563 AliTRDarrayADC *digitsIn = (AliTRDarrayADC*) fDigitsManager->GetDigits(i); //mod
66f6bfd9 564 // This is to take care of switched off super modules
565 if (!digitsIn->HasData()) continue;
566 digitsIn->Expand();
567 AliTRDSignalIndex* indexes = fDigitsManager->GetIndexes(i);
568 if (indexes->IsAllocated() == kFALSE){
569 fDigitsManager->BuildIndexes(i);
570 }
571
572 Bool_t fR = kFALSE;
573 if (indexes->HasEntry()){
574 if (fAddLabels){
575 for (Int_t iDict = 0; iDict < AliTRDdigitsManager::kNDict; iDict++){
b65e5048 576 AliTRDarrayDictionary *tracksIn = 0; //mod
577 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(i,iDict); //mod
66f6bfd9 578 tracksIn->Expand();
3fe61b77 579 }
66f6bfd9 580 }
581 fR = MakeClusters(i);
582 fReturn = fR && fReturn;
3fe61b77 583 }
66f6bfd9 584
585 //if (fR == kFALSE){
586 // if(IsWritingClusters()) WriteClusters(i);
587 // ResetRecPoints();
588 //}
589
590 // No compress just remove
591 fDigitsManager->RemoveDigits(i);
592 fDigitsManager->RemoveDictionaries(i);
593 fDigitsManager->ClearIndexes(i);
594 }
595
596 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
3fe61b77 597
66f6bfd9 598 AliInfo(Form("Number of found clusters : %d", RecPoints()->GetEntriesFast()));
3fe61b77 599
66f6bfd9 600 return fReturn;
eb52b657 601
3fe61b77 602}
603
604//_____________________________________________________________________________
605Bool_t AliTRDclusterizer::Raw2Clusters(AliRawReader *rawReader)
606{
607 //
608 // Creates clusters from raw data
609 //
610
fc546d21 611 return Raw2ClustersChamber(rawReader);
3fe61b77 612
3fe61b77 613}
614
615//_____________________________________________________________________________
616Bool_t AliTRDclusterizer::Raw2ClustersChamber(AliRawReader *rawReader)
617{
618 //
619 // Creates clusters from raw data
620 //
621
622 // Create the digits manager
66f6bfd9 623 if (!fDigitsManager){
624 fDigitsManager = new AliTRDdigitsManager();
625 fDigitsManager->CreateArrays();
626 }
3fe61b77 627
628 fDigitsManager->SetUseDictionaries(fAddLabels);
629
317b5644 630 // tracklet container for raw tracklet writing
631 if (!fTrackletContainer && fReconstructor->IsWritingTracklets()) {
632 // maximum tracklets for one HC
633 const Int_t kTrackletChmb=256;
634 fTrackletContainer = new UInt_t *[2];
635 fTrackletContainer[0] = new UInt_t[kTrackletChmb];
636 fTrackletContainer[1] = new UInt_t[kTrackletChmb];
637 }
638
639
dfbb4bb9 640 AliTRDrawStreamBase *pinput = AliTRDrawStreamBase::GetRawStream(rawReader);
641 AliTRDrawStreamBase &input = *pinput;
3fe61b77 642
643 AliInfo(Form("Stream version: %s", input.IsA()->GetName()));
644
645 Int_t det = 0;
317b5644 646 while ((det = input.NextChamber(fDigitsManager,fTrackletContainer)) >= 0){
66f6bfd9 647 Bool_t iclusterBranch = kFALSE;
648 if (fDigitsManager->GetIndexes(det)->HasEntry()){
649 iclusterBranch = MakeClusters(det);
3fe61b77 650 }
66f6bfd9 651
652 fDigitsManager->RemoveDigits(det);
653 fDigitsManager->RemoveDictionaries(det);
654 fDigitsManager->ClearIndexes(det);
317b5644 655
656 if (!fReconstructor->IsWritingTracklets()) continue;
657 if (*(fTrackletContainer[0]) > 0 || *(fTrackletContainer[1]) > 0) WriteTracklets(det);
9c7c9ec1 658 }
317b5644 659 if (fReconstructor->IsWritingTracklets()){
660 delete [] fTrackletContainer[0];
661 delete [] fTrackletContainer[1];
662 delete [] fTrackletContainer;
663 fTrackletContainer = NULL;
664 }
665
66f6bfd9 666 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
3fe61b77 667
668 delete fDigitsManager;
669 fDigitsManager = NULL;
dfbb4bb9 670
671 delete pinput;
672 pinput = NULL;
3fe61b77 673
66f6bfd9 674 AliInfo(Form("Number of found clusters : %d", RecPoints()->GetEntriesFast()));
675 return kTRUE;
eb52b657 676
3fe61b77 677}
678
fa7427d0 679//_____________________________________________________________________________
680UChar_t AliTRDclusterizer::GetStatus(Short_t &signal)
681{
023b669c 682 //
683 // Check if a pad is masked
684 //
685
317b5644 686 UChar_t status = 0;
687
688 if(signal>0 && TESTBIT(signal, 10)){
689 CLRBIT(signal, 10);
690 for(int ibit=0; ibit<4; ibit++){
691 if(TESTBIT(signal, 11+ibit)){
692 SETBIT(status, ibit);
693 CLRBIT(signal, 11+ibit);
694 }
695 }
696 }
697 return status;
fa7427d0 698}
699
3fe61b77 700//_____________________________________________________________________________
701Bool_t AliTRDclusterizer::MakeClusters(Int_t det)
702{
703 //
704 // Generates the cluster.
705 //
706
707 // Get the digits
708 // digits should be expanded beforehand!
709 // digitsIn->Expand();
b65e5048 710 AliTRDarrayADC *digitsIn = (AliTRDarrayADC *) fDigitsManager->GetDigits(det); //mod
f5375dcb 711
3fe61b77 712 // This is to take care of switched off super modules
625f5260 713 if (!digitsIn->HasData())
3fe61b77 714 {
715 return kFALSE;
716 }
717
718 AliTRDSignalIndex *indexesIn = fDigitsManager->GetIndexes(det);
719 if (indexesIn->IsAllocated() == kFALSE)
720 {
721 AliError("Indexes do not exist!");
722 return kFALSE;
723 }
724
725 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
726 if (!calibration)
727 {
728 AliFatal("No AliTRDcalibDB instance available\n");
729 return kFALSE;
730 }
731
3fe61b77 732 // ADC thresholds
733 // There is no ADC threshold anymore, and simParam should not be used in clusterizer. KO
acc49af9 734 Float_t adcThreshold = 0;
3fe61b77 735
3a039a31 736 if (!fReconstructor){
737 AliError("Reconstructor not set\n");
738 return kFALSE;
739 }
c5f589b9 740
3fe61b77 741 // Threshold value for the maximum
eb52b657 742 Float_t maxThresh = fReconstructor->GetRecoParam()->GetClusMaxThresh();
3fe61b77 743 // Threshold value for the digit signal
eb52b657 744 Float_t sigThresh = fReconstructor->GetRecoParam()->GetClusSigThresh();
3fe61b77 745
df83a620 746 // Threshold value for the maximum ( cut noise)
eb52b657 747 Float_t minMaxCutSigma = fReconstructor->GetRecoParam()->GetMinMaxCutSigma();
df83a620 748 // Threshold value for the sum pad ( cut noise)
eb52b657 749 Float_t minLeftRightCutSigma = fReconstructor->GetRecoParam()->GetMinLeftRightCutSigma();
df83a620 750
3fe61b77 751 // Iteration limit for unfolding procedure
752 const Float_t kEpsilon = 0.01;
753 const Int_t kNclus = 3;
754 const Int_t kNsig = 5;
755
756 Int_t iUnfold = 0;
757 Double_t ratioLeft = 1.0;
758 Double_t ratioRight = 1.0;
759
760 Double_t padSignal[kNsig];
761 Double_t clusterSignal[kNclus];
762
053767a4 763 Int_t istack = indexesIn->GetStack();
764 Int_t ilayer = indexesIn->GetLayer();
765 Int_t isector = indexesIn->GetSM();
3fe61b77 766
767 // Start clustering in the chamber
768
053767a4 769 Int_t idet = AliTRDgeometry::GetDetector(ilayer,istack,isector);
b65e5048 770 if (idet != det) {
771 AliError("Strange Detector number Missmatch!");
772 return kFALSE;
773 }
3fe61b77 774
775 // TRD space point transformation
776 fTransform->SetDetector(det);
777
053767a4 778 Int_t iGeoLayer = AliGeomManager::kTRD1 + ilayer;
779 Int_t iGeoModule = istack + AliTRDgeometry::Nstack() * isector;
780 UShort_t volid = AliGeomManager::LayerToVolUID(iGeoLayer,iGeoModule);
3fe61b77 781
782 Int_t nColMax = digitsIn->GetNcol();
fa7427d0 783 Int_t nRowMax = digitsIn->GetNrow();
3fe61b77 784 Int_t nTimeTotal = digitsIn->GetNtime();
785
786 // Detector wise calibration object for the gain factors
0e09df31 787 const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
3fe61b77 788 // Calibration object with pad wise values for the gain factors
0e09df31 789 AliTRDCalROC *calGainFactorROC = calibration->GetGainFactorROC(idet);
3fe61b77 790 // Calibration value for chamber wise gain factor
0e09df31 791 Float_t calGainFactorDetValue = calGainFactorDet->GetValue(idet);
792
df83a620 793 // Detector wise calibration object for the noise
794 const AliTRDCalDet *calNoiseDet = calibration->GetNoiseDet();
795 // Calibration object with pad wise values for the noise
796 AliTRDCalROC *calNoiseROC = calibration->GetNoiseROC(idet);
797 // Calibration value for chamber wise noise
798 Float_t calNoiseDetValue = calNoiseDet->GetValue(idet);
799
3fe61b77 800 Int_t nClusters = 0;
801
b65e5048 802 AliTRDarraySignal *digitsOut = new AliTRDarraySignal(nRowMax, nColMax, nTimeTotal);
803 AliTRDarrayADC padStatus(nRowMax, nColMax, nTimeTotal);
3fe61b77 804
805 ResetHelperIndexes(indexesIn);
806
807 // Apply the gain and the tail cancelation via digital filter
808 TailCancelation(digitsIn
b65e5048 809 ,digitsOut
810 ,indexesIn
811 ,fIndexesOut
812 ,nTimeTotal
813 ,adcThreshold
814 ,calGainFactorROC
815 ,calGainFactorDetValue);
317b5644 816
3fe61b77 817 Int_t row = 0;
818 Int_t col = 0;
819 Int_t time = 0;
820 Int_t iPad = 0;
821
f5375dcb 822 UChar_t status[3]={0, 0, 0}, ipos = 0;
3fe61b77 823 fIndexesOut->ResetCounters();
eb52b657 824 while (fIndexesOut->NextRCTbinIndex(row, col, time)) {
023b669c 825
b65e5048 826 Float_t signalM = TMath::Abs(digitsOut->GetData(row,col,time));
f5375dcb 827 status[1] = digitsIn->GetPadStatus(row,col,time);
828 if(status[1]) SETBIT(ipos, AliTRDcluster::kMaskedCenter);
829
df83a620 830 if(signalM < maxThresh) continue;
831
832 Float_t noiseMiddleThresh = minMaxCutSigma*calNoiseDetValue*calNoiseROC->GetValue(col,row);
833 if (signalM < noiseMiddleThresh) continue;
834
835 if (col + 1 >= nColMax || col-1 < 0) continue;
f5375dcb 836
b65e5048 837 Float_t signalL = TMath::Abs(digitsOut->GetData(row,col+1,time));
df83a620 838 status[0] = digitsIn->GetPadStatus(row,col+1,time);
839 if(status[0]) SETBIT(ipos, AliTRDcluster::kMaskedLeft);
f5375dcb 840
b65e5048 841 Float_t signalR = TMath::Abs(digitsOut->GetData(row,col-1,time));
df83a620 842 status[2] = digitsIn->GetPadStatus(row,col-1,time);
843 if(status[2]) SETBIT(ipos, AliTRDcluster::kMaskedRight);
f5375dcb 844
df83a620 845 // reject candidates with more than 1 problematic pad
846 if(ipos == 3 || ipos > 4) continue;
f5375dcb 847
b65e5048 848 if (!status[1]) { // good central pad
849 if (!ipos) { // all pads are OK
850 if ((signalL <= signalM) && (signalR < signalM)) {
851 if ((signalL >= sigThresh) || (signalR >= sigThresh)) {
852 Float_t noiseSumThresh = minLeftRightCutSigma
853 * calNoiseDetValue
854 * calNoiseROC->GetValue(col,row);
855 if ((signalL+signalR+signalM) >= noiseSumThresh) {
856 // Maximum found, mark the position by a negative signal
857 digitsOut->SetData(row,col,time,-signalM);
858 fIndexesMaxima->AddIndexTBin(row,col,time);
859 padStatus.SetData(row, col, time, ipos);
860 }
861 }
862 }
863 }
864 else { // one of the neighbouring pads are bad
865 if (status[0] && signalR < signalM && signalR >= sigThresh) {
866 digitsOut->SetData(row,col,time,-signalM);
867 digitsOut->SetData(row, col, time+1, 0.);
023b669c 868 fIndexesMaxima->AddIndexTBin(row,col,time);
b65e5048 869 padStatus.SetData(row, col, time, ipos);
870 }
871 else if (status[2] && signalL <= signalM && signalL >= sigThresh) {
872 digitsOut->SetData(row,col,time,-signalM);
873 digitsOut->SetData(row, col, time-1, 0.);
874 fIndexesMaxima->AddIndexTBin(row,col,time);
875 padStatus.SetData(row, col, time, ipos);
876 }
df83a620 877 }
b65e5048 878 }
879 else { // wrong maximum pad
df83a620 880 if ((signalL >= sigThresh) || (signalR >= sigThresh)) {
b65e5048 881 // Maximum found, mark the position by a negative signal
882 digitsOut->SetData(row,col,time,-maxThresh);
883 fIndexesMaxima->AddIndexTBin(row,col,time);
884 padStatus.SetData(row, col, time, ipos);
f5375dcb 885 }
886 }
b65e5048 887
df83a620 888 }
f5375dcb 889
eb52b657 890 // The index to the first cluster of a given ROC
df83a620 891 Int_t firstClusterROC = -1;
eb52b657 892 // The number of cluster in a given ROC
893 Int_t nClusterROC = 0;
f5375dcb 894
eb52b657 895 // Now check the maxima and calculate the cluster position
896 fIndexesMaxima->ResetCounters();
897 while (fIndexesMaxima->NextRCTbinIndex(row, col, time)) {
3fe61b77 898
eb52b657 899 // Maximum found ?
b65e5048 900 if (digitsOut->GetData(row,col,time) < 0.0) {
023b669c 901
eb52b657 902 for (iPad = 0; iPad < kNclus; iPad++) {
903 Int_t iPadCol = col - 1 + iPad;
b65e5048 904 clusterSignal[iPad] = TMath::Abs(digitsOut->GetData(row,iPadCol,time));
eb52b657 905 }
3fe61b77 906
eb52b657 907 // Count the number of pads in the cluster
908 Int_t nPadCount = 0;
909 Int_t ii;
910 // Look to the right
911 ii = 0;
b65e5048 912 while (TMath::Abs(digitsOut->GetData(row,col-ii ,time)) >= sigThresh) {
eb52b657 913 nPadCount++;
914 ii++;
915 if (col-ii < 0) break;
916 }
917 // Look to the left
918 ii = 0;
b65e5048 919 while (TMath::Abs(digitsOut->GetData(row,col+ii+1,time)) >= sigThresh) {
eb52b657 920 nPadCount++;
921 ii++;
922 if (col+ii+1 >= nColMax) break;
923 }
924 nClusters++;
f5375dcb 925
eb52b657 926 // Look for 5 pad cluster with minimum in the middle
927 Bool_t fivePadCluster = kFALSE;
928 if (col < (nColMax - 3)){
b65e5048 929 if (digitsOut->GetData(row,col+2,time) < 0) {
eb52b657 930 fivePadCluster = kTRUE;
931 }
932 if ((fivePadCluster) && (col < (nColMax - 5))) {
b65e5048 933 if (digitsOut->GetData(row,col+4,time) >= sigThresh) {
eb52b657 934 fivePadCluster = kFALSE;
f5375dcb 935 }
eb52b657 936 }
937 if ((fivePadCluster) && (col > 1)) {
b65e5048 938 if (digitsOut->GetData(row,col-2,time) >= sigThresh) {
eb52b657 939 fivePadCluster = kFALSE;
f5375dcb 940 }
941 }
eb52b657 942 }
3fe61b77 943
eb52b657 944 // 5 pad cluster
945 // Modify the signal of the overlapping pad for the left part
946 // of the cluster which remains from a previous unfolding
947 if (iUnfold) {
948 clusterSignal[0] *= ratioLeft;
949 iUnfold = 0;
950 }
3fe61b77 951
eb52b657 952 // Unfold the 5 pad cluster
b65e5048 953 if (fivePadCluster) {
eb52b657 954 for (iPad = 0; iPad < kNsig; iPad++) {
b65e5048 955 padSignal[iPad] = TMath::Abs(digitsOut->GetData(row
956 ,col-1+iPad
957 ,time));
f5375dcb 958 }
eb52b657 959 // Unfold the two maxima and set the signal on
960 // the overlapping pad to the ratio
961 ratioRight = Unfold(kEpsilon,ilayer,padSignal);
962 ratioLeft = 1.0 - ratioRight;
963 clusterSignal[2] *= ratioRight;
964 iUnfold = 1;
965 }
3fe61b77 966
eb52b657 967 // The position of the cluster in COL direction relative to the center pad (pad units)
968 Double_t clusterPosCol = 0.0;
969 if (fReconstructor->GetRecoParam()->IsLUT()) {
970 // Calculate the position of the cluster by using the
971 // lookup table method
972 clusterPosCol = LUTposition(ilayer,clusterSignal[0]
973 ,clusterSignal[1]
974 ,clusterSignal[2]);
975 }
976 else {
977 // Calculate the position of the cluster by using the
978 // center of gravity method
979 for (Int_t i = 0; i < kNsig; i++) {
980 padSignal[i] = 0.0;
981 }
b65e5048 982 padSignal[2] = TMath::Abs(digitsOut->GetData(row,col ,time)); // Central pad
983 padSignal[3] = TMath::Abs(digitsOut->GetData(row,col+1,time)); // Left pad
984 padSignal[1] = TMath::Abs(digitsOut->GetData(row,col-1,time)); // Right pad
eb52b657 985 if ((col > 2) &&
b65e5048 986 (TMath::Abs(digitsOut->GetData(row,col-2,time)) < padSignal[1])) {
987 padSignal[4] = TMath::Abs(digitsOut->GetData(row,col-2,time));
f5375dcb 988 }
eb52b657 989 if ((col < nColMax - 3) &&
b65e5048 990 (TMath::Abs(digitsOut->GetData(row,col+2,time)) < padSignal[3])) {
991 padSignal[0] = TMath::Abs(digitsOut->GetData(row,col+2,time));
eb52b657 992 }
993 clusterPosCol = GetCOG(padSignal);
994 }
3fe61b77 995
eb52b657 996 // Store the amplitudes of the pads in the cluster for later analysis
997 // and check whether one of these pads is masked in the database
998 Short_t signals[7] = { 0, 0, 0, 0, 0, 0, 0 };
999 for (Int_t jPad = col-3; jPad <= col+3; jPad++) {
1000 if ((jPad < 0) ||
1001 (jPad >= nColMax-1)) {
1002 continue;
f5375dcb 1003 }
b65e5048 1004 signals[jPad-col+3] = TMath::Nint(TMath::Abs(digitsOut->GetData(row,jPad,time)));
eb52b657 1005 }
3fe61b77 1006
eb52b657 1007 // Transform the local cluster coordinates into calibrated
1008 // space point positions defined in the local tracking system.
1009 // Here the calibration for T0, Vdrift and ExB is applied as well.
1010 Double_t clusterXYZ[6];
1011 clusterXYZ[0] = clusterPosCol;
1012 clusterXYZ[1] = clusterSignal[2];
1013 clusterXYZ[2] = clusterSignal[1];
1014 clusterXYZ[3] = clusterSignal[0];
1015 clusterXYZ[4] = 0.0;
1016 clusterXYZ[5] = 0.0;
1017 Int_t clusterRCT[3];
1018 clusterRCT[0] = row;
1019 clusterRCT[1] = col;
1020 clusterRCT[2] = 0;
1021
1022 Bool_t out = kTRUE;
1023 if (fTransform->Transform(clusterXYZ,clusterRCT,((UInt_t) time),out,0)) {
f5375dcb 1024
1025 // Add the cluster to the output array
1026 // The track indices will be stored later
1027 Float_t clusterPos[3];
1028 clusterPos[0] = clusterXYZ[0];
1029 clusterPos[1] = clusterXYZ[1];
1030 clusterPos[2] = clusterXYZ[2];
1031 Float_t clusterSig[2];
1032 clusterSig[0] = clusterXYZ[4];
1033 clusterSig[1] = clusterXYZ[5];
1034 Double_t clusterCharge = clusterXYZ[3];
1035 Char_t clusterTimeBin = ((Char_t) clusterRCT[2]);
66f6bfd9 1036
1037 Int_t n = RecPoints()->GetEntriesFast();
1038 AliTRDcluster *cluster = new((*RecPoints())[n]) AliTRDcluster(idet
b65e5048 1039 ,clusterCharge
1040 ,clusterPos
1041 ,clusterSig
1042 ,0x0
1043 ,((Char_t) nPadCount)
1044 ,signals
1045 ,((UChar_t) col)
1046 ,((UChar_t) row)
1047 ,((UChar_t) time)
1048 ,clusterTimeBin
1049 ,clusterPosCol
1050 ,volid);
f5375dcb 1051 cluster->SetInChamber(!out);
023b669c 1052
b65e5048 1053 UChar_t maskPosition = padStatus.GetData(row, col, time);
023b669c 1054 if (maskPosition) {
f5375dcb 1055 cluster->SetPadMaskedPosition(maskPosition);
eb52b657 1056 if (maskPosition & AliTRDcluster::kMaskedLeft) {
023b669c 1057 cluster->SetPadMaskedStatus(status[0]);
b65e5048 1058 }
eb52b657 1059 else if (maskPosition & AliTRDcluster::kMaskedCenter) {
023b669c 1060 cluster->SetPadMaskedStatus(status[1]);
b65e5048 1061 }
023b669c 1062 else {
1063 cluster->SetPadMaskedStatus(status[2]);
b65e5048 1064 }
f5375dcb 1065 }
3fe61b77 1066
f5375dcb 1067 // Temporarily store the row, column and time bin of the center pad
1068 // Used to later on assign the track indices
1069 cluster->SetLabel( row,0);
1070 cluster->SetLabel( col,1);
1071 cluster->SetLabel(time,2);
3fe61b77 1072
f5375dcb 1073 // Store the index of the first cluster in the current ROC
1074 if (firstClusterROC < 0) {
1075 firstClusterROC = RecPoints()->GetEntriesFast() - 1;
1076 }
1077
1078 // Count the number of cluster in the current ROC
1079 nClusterROC++;
1080
1081 } // if: Transform ok ?
eb52b657 1082
f5375dcb 1083 } // if: Maximum found ?
eb52b657 1084
f5375dcb 1085 }
3fe61b77 1086
1087 delete digitsOut;
1088
eb52b657 1089 if (fAddLabels) {
1090 AddLabels(idet,firstClusterROC,nClusterROC);
1091 }
3fe61b77 1092
1093 return kTRUE;
1094
1095}
1096
1097//_____________________________________________________________________________
1098Bool_t AliTRDclusterizer::AddLabels(Int_t idet, Int_t firstClusterROC, Int_t nClusterROC)
3551db50 1099{
1100 //
3fe61b77 1101 // Add the track indices to the found clusters
3551db50 1102 //
1103
3fe61b77 1104 const Int_t kNclus = 3;
1105 const Int_t kNdict = AliTRDdigitsManager::kNDict;
1106 const Int_t kNtrack = kNdict * kNclus;
1107
1108 Int_t iClusterROC = 0;
1109
1110 Int_t row = 0;
1111 Int_t col = 0;
1112 Int_t time = 0;
1113 Int_t iPad = 0;
1114
1115 // Temporary array to collect the track indices
1116 Int_t *idxTracks = new Int_t[kNtrack*nClusterROC];
1117
1118 // Loop through the dictionary arrays one-by-one
1119 // to keep memory consumption low
b65e5048 1120 AliTRDarrayDictionary *tracksIn = 0; //mod
3fe61b77 1121 for (Int_t iDict = 0; iDict < kNdict; iDict++) {
1122
1123 // tracksIn should be expanded beforehand!
b65e5048 1124 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(idet,iDict);
3fe61b77 1125
1126 // Loop though the clusters found in this ROC
1127 for (iClusterROC = 0; iClusterROC < nClusterROC; iClusterROC++) {
317b5644 1128
3fe61b77 1129 AliTRDcluster *cluster = (AliTRDcluster *)
b65e5048 1130 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
3fe61b77 1131 row = cluster->GetLabel(0);
1132 col = cluster->GetLabel(1);
1133 time = cluster->GetLabel(2);
1134
1135 for (iPad = 0; iPad < kNclus; iPad++) {
b65e5048 1136 Int_t iPadCol = col - 1 + iPad;
1137 Int_t index = tracksIn->GetData(row,iPadCol,time); //Modification of -1 in Track
1138 idxTracks[3*iPad+iDict + iClusterROC*kNtrack] = index;
3fe61b77 1139 }
1140
1141 }
1142
1143 }
1144
1145 // Copy the track indices into the cluster
1146 // Loop though the clusters found in this ROC
1147 for (iClusterROC = 0; iClusterROC < nClusterROC; iClusterROC++) {
317b5644 1148
3fe61b77 1149 AliTRDcluster *cluster = (AliTRDcluster *)
1150 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
1151 cluster->SetLabel(-9999,0);
1152 cluster->SetLabel(-9999,1);
1153 cluster->SetLabel(-9999,2);
1154
1155 cluster->AddTrackIndex(&idxTracks[iClusterROC*kNtrack]);
1156
1157 }
1158
1159 delete [] idxTracks;
1160
1161 return kTRUE;
1162
1163}
1164
1165//_____________________________________________________________________________
acc49af9 1166Double_t AliTRDclusterizer::GetCOG(Double_t signal[5]) const
3fe61b77 1167{
1168 //
1169 // Get COG position
1170 // Used for clusters with more than 3 pads - where LUT not applicable
1171 //
1172
1173 Double_t sum = signal[0]
317b5644 1174 + signal[1]
1175 + signal[2]
1176 + signal[3]
1177 + signal[4];
3fe61b77 1178
eb52b657 1179 // ???????????? CBL
1180 // Go to 3 pad COG ????
023b669c 1181 // ???????????? CBL
3fe61b77 1182 Double_t res = (0.0 * (-signal[0] + signal[4])
1183 + (-signal[1] + signal[3])) / sum;
1184
1185 return res;
1186
1187}
1188
1189//_____________________________________________________________________________
053767a4 1190Double_t AliTRDclusterizer::Unfold(Double_t eps, Int_t layer, Double_t *padSignal)
3fe61b77 1191{
1192 //
1193 // Method to unfold neighbouring maxima.
1194 // The charge ratio on the overlapping pad is calculated
1195 // until there is no more change within the range given by eps.
1196 // The resulting ratio is then returned to the calling method.
1197 //
1198
1199 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
6d50f529 1200 if (!calibration) {
3fe61b77 1201 AliError("No AliTRDcalibDB instance available\n");
1202 return kFALSE;
6d50f529 1203 }
3fe61b77 1204
1205 Int_t irc = 0;
1206 Int_t itStep = 0; // Count iteration steps
1207
1208 Double_t ratio = 0.5; // Start value for ratio
1209 Double_t prevRatio = 0.0; // Store previous ratio
1210
1211 Double_t newLeftSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store left cluster signal
1212 Double_t newRightSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store right cluster signal
1213 Double_t newSignal[3] = { 0.0, 0.0, 0.0 };
1214
1215 // Start the iteration
1216 while ((TMath::Abs(prevRatio - ratio) > eps) && (itStep < 10)) {
1217
1218 itStep++;
1219 prevRatio = ratio;
1220
1221 // Cluster position according to charge ratio
1222 Double_t maxLeft = (ratio*padSignal[2] - padSignal[0])
1223 / (padSignal[0] + padSignal[1] + ratio*padSignal[2]);
1224 Double_t maxRight = (padSignal[4] - (1-ratio)*padSignal[2])
1225 / ((1.0 - ratio)*padSignal[2] + padSignal[3] + padSignal[4]);
1226
1227 // Set cluster charge ratio
053767a4 1228 irc = calibration->PadResponse(1.0,maxLeft ,layer,newSignal);
3fe61b77 1229 Double_t ampLeft = padSignal[1] / newSignal[1];
053767a4 1230 irc = calibration->PadResponse(1.0,maxRight,layer,newSignal);
3fe61b77 1231 Double_t ampRight = padSignal[3] / newSignal[1];
1232
1233 // Apply pad response to parameters
053767a4 1234 irc = calibration->PadResponse(ampLeft ,maxLeft ,layer,newLeftSignal );
1235 irc = calibration->PadResponse(ampRight,maxRight,layer,newRightSignal);
3fe61b77 1236
1237 // Calculate new overlapping ratio
1238 ratio = TMath::Min((Double_t) 1.0
1239 ,newLeftSignal[2] / (newLeftSignal[2] + newRightSignal[0]));
1240
b43a3e17 1241 }
88719a08 1242
3fe61b77 1243 return ratio;
1244
1245}
88719a08 1246
3fe61b77 1247//_____________________________________________________________________________
b65e5048 1248void AliTRDclusterizer::TailCancelation(AliTRDarrayADC *digitsIn
1249 , AliTRDarraySignal *digitsOut
1250 , AliTRDSignalIndex *indexesIn
1251 , AliTRDSignalIndex *indexesOut
1252 , Int_t nTimeTotal
1253 , Float_t adcThreshold
1254 , AliTRDCalROC *calGainFactorROC
1255 , Float_t calGainFactorDetValue)
3fe61b77 1256{
1257 //
1258 // Applies the tail cancelation and gain factors:
1259 // Transform digitsIn to digitsOut
1260 //
1261
1262 Int_t iRow = 0;
1263 Int_t iCol = 0;
1264 Int_t iTime = 0;
1265
3fe61b77 1266 Double_t *inADC = new Double_t[nTimeTotal]; // ADC data before tail cancellation
1267 Double_t *outADC = new Double_t[nTimeTotal]; // ADC data after tail cancellation
1268 indexesIn->ResetCounters();
1269 while (indexesIn->NextRCIndex(iRow, iCol))
1270 {
1271 Float_t calGainFactorROCValue = calGainFactorROC->GetValue(iCol,iRow);
1272 Double_t gain = calGainFactorDetValue
317b5644 1273 * calGainFactorROCValue;
3fe61b77 1274
f5375dcb 1275 Bool_t corrupted = kFALSE;
3fe61b77 1276 for (iTime = 0; iTime < nTimeTotal; iTime++)
b65e5048 1277 {
1278 // Apply gain gain factor
ce1fb7da 1279 inADC[iTime] = digitsIn->GetDataB(iRow,iCol,iTime);
b65e5048 1280 if (digitsIn->GetPadStatus(iRow, iCol, iTime)) corrupted = kTRUE;
1281 inADC[iTime] /= gain;
1282 outADC[iTime] = inADC[iTime];
1283 }
1284 if (!corrupted)
1285 {
1286 // Apply the tail cancelation via the digital filter
1287 // (only for non-coorupted pads)
1288 if (fReconstructor->GetRecoParam() ->IsTailCancelation())
1289 {
1290 DeConvExp(inADC,outADC,nTimeTotal,fReconstructor->GetRecoParam() ->GetTCnexp());
ce1fb7da 1291 }
b65e5048 1292 }
3fe61b77 1293
1294 indexesIn->ResetTbinCounter();
b65e5048 1295
3fe61b77 1296 while (indexesIn->NextTbinIndex(iTime))
b65e5048 1297 {
1298 // Store the amplitude of the digit if above threshold
1299 if (outADC[iTime] > adcThreshold)
1300 {
1301 digitsOut->SetData(iRow,iCol,iTime,outADC[iTime]);
1302 indexesOut->AddIndexTBin(iRow,iCol,iTime);
1303 }
1304 } // while itime
3fe61b77 1305
1306 } // while irow icol
1307
1308 delete [] inADC;
1309 delete [] outADC;
1310
1311 return;
1312
1313}
1314
1315//_____________________________________________________________________________
1316void AliTRDclusterizer::DeConvExp(Double_t *source, Double_t *target
b65e5048 1317 , Int_t n, Int_t nexp)
3fe61b77 1318{
1319 //
1320 // Tail cancellation by deconvolution for PASA v4 TRF
1321 //
1322
1323 Double_t rates[2];
1324 Double_t coefficients[2];
1325
1326 // Initialization (coefficient = alpha, rates = lambda)
1327 Double_t r1 = 1.0;
1328 Double_t r2 = 1.0;
1329 Double_t c1 = 0.5;
1330 Double_t c2 = 0.5;
1331
1332 if (nexp == 1) { // 1 Exponentials
1333 r1 = 1.156;
1334 r2 = 0.130;
1335 c1 = 0.066;
1336 c2 = 0.000;
1337 }
1338 if (nexp == 2) { // 2 Exponentials
181c7f7e 1339 Double_t par[4];
1340 fReconstructor->GetTCParams(par);
1341 r1 = par[0];//1.156;
1342 r2 = par[1];//0.130;
1343 c1 = par[2];//0.114;
1344 c2 = par[3];//0.624;
3fe61b77 1345 }
1346
1347 coefficients[0] = c1;
1348 coefficients[1] = c2;
1349
1350 Double_t dt = 0.1;
1351
1352 rates[0] = TMath::Exp(-dt/(r1));
1353 rates[1] = TMath::Exp(-dt/(r2));
1354
1355 Int_t i = 0;
1356 Int_t k = 0;
1357
1358 Double_t reminder[2];
1359 Double_t correction = 0.0;
1360 Double_t result = 0.0;
1361
1362 // Attention: computation order is important
1363 for (k = 0; k < nexp; k++) {
1364 reminder[k] = 0.0;
1365 }
1366
1367 for (i = 0; i < n; i++) {
1368
1369 result = (source[i] - correction); // No rescaling
1370 target[i] = result;
1371
1372 for (k = 0; k < nexp; k++) {
1373 reminder[k] = rates[k] * (reminder[k] + coefficients[k] * result);
1374 }
1375
1376 correction = 0.0;
1377 for (k = 0; k < nexp; k++) {
1378 correction += reminder[k];
1379 }
1380
1381 }
6d50f529 1382
1383}
1384
1385//_____________________________________________________________________________
1386void AliTRDclusterizer::ResetRecPoints()
1387{
1388 //
1389 // Resets the list of rec points
1390 //
1391
1392 if (fRecPoints) {
1393 fRecPoints->Delete();
48f8adf3 1394 delete fRecPoints;
6d50f529 1395 }
6d50f529 1396}
1397
1398//_____________________________________________________________________________
66f6bfd9 1399TClonesArray *AliTRDclusterizer::RecPoints()
6d50f529 1400{
1401 //
1402 // Returns the list of rec points
1403 //
1404
1405 if (!fRecPoints) {
48f8adf3 1406 if(!(fRecPoints = AliTRDReconstructor::GetClusters())){
8ae98148 1407 // determine number of clusters which has to be allocated
1408 Float_t nclusters = fReconstructor->GetRecoParam()->GetNClusters();
1409 if(fReconstructor->IsHLT()) nclusters /= AliTRDgeometry::kNsector;
1410
1411 fRecPoints = new TClonesArray("AliTRDcluster", Int_t(nclusters));
48f8adf3 1412 }
1413 //SetClustersOwner(kTRUE);
1414 AliTRDReconstructor::SetClusters(0x0);
6d50f529 1415 }
6d50f529 1416 return fRecPoints;
eb52b657 1417
3551db50 1418}
fc546d21 1419
1420//_____________________________________________________________________________
1421void AliTRDclusterizer::FillLUT()
1422{
1423 //
1424 // Create the LUT
1425 //
1426
1427 const Int_t kNlut = 128;
1428
053767a4 1429 fLUTbin = AliTRDgeometry::kNlayer * kNlut;
fc546d21 1430
1431 // The lookup table from Bogdan
053767a4 1432 Float_t lut[AliTRDgeometry::kNlayer][kNlut] = {
fc546d21 1433 {
1434 0.0070, 0.0150, 0.0224, 0.0298, 0.0374, 0.0454, 0.0533, 0.0611,
1435 0.0684, 0.0755, 0.0827, 0.0900, 0.0975, 0.1049, 0.1120, 0.1187,
1436 0.1253, 0.1318, 0.1385, 0.1453, 0.1519, 0.1584, 0.1646, 0.1704,
1437 0.1762, 0.1821, 0.1879, 0.1938, 0.1996, 0.2053, 0.2108, 0.2160,
1438 0.2210, 0.2260, 0.2310, 0.2361, 0.2411, 0.2461, 0.2509, 0.2557,
1439 0.2602, 0.2646, 0.2689, 0.2732, 0.2774, 0.2816, 0.2859, 0.2901,
1440 0.2942, 0.2983, 0.3022, 0.3061, 0.3099, 0.3136, 0.3172, 0.3207,
1441 0.3242, 0.3278, 0.3312, 0.3347, 0.3382, 0.3416, 0.3450, 0.3483,
1442 0.3515, 0.3547, 0.3579, 0.3609, 0.3639, 0.3669, 0.3698, 0.3727,
1443 0.3756, 0.3785, 0.3813, 0.3842, 0.3870, 0.3898, 0.3926, 0.3952,
1444 0.3979, 0.4005, 0.4032, 0.4057, 0.4082, 0.4108, 0.4132, 0.4157,
1445 0.4181, 0.4205, 0.4228, 0.4252, 0.4275, 0.4299, 0.4322, 0.4345,
1446 0.4367, 0.4390, 0.4412, 0.4434, 0.4456, 0.4478, 0.4499, 0.4520,
1447 0.4541, 0.4562, 0.4583, 0.4603, 0.4623, 0.4643, 0.4663, 0.4683,
1448 0.4702, 0.4722, 0.4741, 0.4758, 0.4774, 0.4790, 0.4805, 0.4824,
1449 0.4844, 0.4863, 0.4883, 0.4902, 0.4921, 0.4940, 0.4959, 0.4978
1450 },
1451 {
1452 0.0072, 0.0156, 0.0235, 0.0313, 0.0394, 0.0478, 0.0561, 0.0642,
1453 0.0718, 0.0792, 0.0868, 0.0947, 0.1025, 0.1101, 0.1172, 0.1241,
1454 0.1309, 0.1378, 0.1449, 0.1518, 0.1586, 0.1650, 0.1710, 0.1770,
1455 0.1830, 0.1891, 0.1952, 0.2011, 0.2070, 0.2125, 0.2177, 0.2229,
1456 0.2280, 0.2332, 0.2383, 0.2435, 0.2484, 0.2533, 0.2581, 0.2627,
1457 0.2670, 0.2714, 0.2757, 0.2799, 0.2842, 0.2884, 0.2927, 0.2968,
1458 0.3008, 0.3048, 0.3086, 0.3123, 0.3159, 0.3195, 0.3231, 0.3266,
1459 0.3301, 0.3335, 0.3370, 0.3404, 0.3438, 0.3471, 0.3504, 0.3536,
1460 0.3567, 0.3598, 0.3628, 0.3657, 0.3686, 0.3715, 0.3744, 0.3772,
1461 0.3800, 0.3828, 0.3856, 0.3884, 0.3911, 0.3938, 0.3965, 0.3991,
1462 0.4016, 0.4042, 0.4067, 0.4092, 0.4116, 0.4140, 0.4164, 0.4187,
1463 0.4211, 0.4234, 0.4257, 0.4280, 0.4302, 0.4325, 0.4347, 0.4369,
1464 0.4391, 0.4413, 0.4434, 0.4456, 0.4477, 0.4497, 0.4518, 0.4538,
1465 0.4558, 0.4578, 0.4598, 0.4618, 0.4637, 0.4656, 0.4675, 0.4694,
1466 0.4713, 0.4732, 0.4750, 0.4766, 0.4781, 0.4797, 0.4813, 0.4832,
1467 0.4851, 0.4870, 0.4888, 0.4906, 0.4925, 0.4942, 0.4960, 0.4978
1468 },
1469 {
1470 0.0075, 0.0163, 0.0246, 0.0328, 0.0415, 0.0504, 0.0592, 0.0674,
1471 0.0753, 0.0832, 0.0914, 0.0996, 0.1077, 0.1154, 0.1225, 0.1296,
1472 0.1369, 0.1442, 0.1515, 0.1585, 0.1652, 0.1714, 0.1776, 0.1839,
1473 0.1902, 0.1965, 0.2025, 0.2085, 0.2141, 0.2194, 0.2247, 0.2299,
1474 0.2352, 0.2405, 0.2457, 0.2507, 0.2557, 0.2604, 0.2649, 0.2693,
1475 0.2737, 0.2780, 0.2823, 0.2867, 0.2909, 0.2951, 0.2992, 0.3033,
1476 0.3072, 0.3110, 0.3146, 0.3182, 0.3218, 0.3253, 0.3288, 0.3323,
1477 0.3357, 0.3392, 0.3426, 0.3459, 0.3492, 0.3524, 0.3555, 0.3586,
1478 0.3616, 0.3645, 0.3674, 0.3703, 0.3731, 0.3759, 0.3787, 0.3815,
1479 0.3843, 0.3870, 0.3897, 0.3925, 0.3950, 0.3976, 0.4002, 0.4027,
1480 0.4052, 0.4076, 0.4101, 0.4124, 0.4148, 0.4171, 0.4194, 0.4217,
1481 0.4239, 0.4262, 0.4284, 0.4306, 0.4328, 0.4350, 0.4371, 0.4393,
1482 0.4414, 0.4435, 0.4455, 0.4476, 0.4496, 0.4516, 0.4536, 0.4555,
1483 0.4575, 0.4594, 0.4613, 0.4632, 0.4650, 0.4669, 0.4687, 0.4705,
1484 0.4723, 0.4741, 0.4758, 0.4773, 0.4789, 0.4804, 0.4821, 0.4839,
1485 0.4857, 0.4875, 0.4893, 0.4910, 0.4928, 0.4945, 0.4961, 0.4978
1486 },
1487 {
1488 0.0078, 0.0171, 0.0258, 0.0345, 0.0438, 0.0532, 0.0624, 0.0708,
1489 0.0791, 0.0875, 0.0962, 0.1048, 0.1130, 0.1206, 0.1281, 0.1356,
1490 0.1432, 0.1508, 0.1582, 0.1651, 0.1716, 0.1780, 0.1845, 0.1910,
1491 0.1975, 0.2038, 0.2099, 0.2155, 0.2210, 0.2263, 0.2317, 0.2371,
1492 0.2425, 0.2477, 0.2528, 0.2578, 0.2626, 0.2671, 0.2715, 0.2759,
1493 0.2803, 0.2846, 0.2890, 0.2933, 0.2975, 0.3016, 0.3056, 0.3095,
1494 0.3132, 0.3168, 0.3204, 0.3239, 0.3274, 0.3309, 0.3344, 0.3378,
1495 0.3412, 0.3446, 0.3479, 0.3511, 0.3543, 0.3574, 0.3603, 0.3633,
1496 0.3662, 0.3690, 0.3718, 0.3747, 0.3774, 0.3802, 0.3829, 0.3857,
1497 0.3883, 0.3910, 0.3936, 0.3962, 0.3987, 0.4012, 0.4037, 0.4061,
1498 0.4085, 0.4109, 0.4132, 0.4155, 0.4177, 0.4200, 0.4222, 0.4244,
1499 0.4266, 0.4288, 0.4309, 0.4331, 0.4352, 0.4373, 0.4394, 0.4414,
1500 0.4435, 0.4455, 0.4475, 0.4494, 0.4514, 0.4533, 0.4552, 0.4571,
1501 0.4590, 0.4608, 0.4626, 0.4645, 0.4662, 0.4680, 0.4698, 0.4715,
1502 0.4733, 0.4750, 0.4766, 0.4781, 0.4796, 0.4812, 0.4829, 0.4846,
1503 0.4863, 0.4880, 0.4897, 0.4914, 0.4930, 0.4946, 0.4963, 0.4979
1504 },
1505 {
1506 0.0081, 0.0178, 0.0270, 0.0364, 0.0463, 0.0562, 0.0656, 0.0744,
1507 0.0831, 0.0921, 0.1013, 0.1102, 0.1183, 0.1261, 0.1339, 0.1419,
1508 0.1499, 0.1576, 0.1648, 0.1715, 0.1782, 0.1849, 0.1917, 0.1984,
1509 0.2048, 0.2110, 0.2167, 0.2223, 0.2278, 0.2333, 0.2389, 0.2444,
1510 0.2497, 0.2548, 0.2598, 0.2645, 0.2691, 0.2735, 0.2780, 0.2824,
1511 0.2868, 0.2912, 0.2955, 0.2997, 0.3038, 0.3078, 0.3116, 0.3152,
1512 0.3188, 0.3224, 0.3259, 0.3294, 0.3329, 0.3364, 0.3398, 0.3432,
1513 0.3465, 0.3497, 0.3529, 0.3561, 0.3591, 0.3620, 0.3649, 0.3677,
1514 0.3705, 0.3733, 0.3761, 0.3788, 0.3816, 0.3843, 0.3869, 0.3896,
1515 0.3922, 0.3948, 0.3973, 0.3998, 0.4022, 0.4047, 0.4070, 0.4094,
1516 0.4117, 0.4139, 0.4162, 0.4184, 0.4206, 0.4227, 0.4249, 0.4270,
1517 0.4291, 0.4313, 0.4334, 0.4354, 0.4375, 0.4395, 0.4415, 0.4435,
1518 0.4455, 0.4474, 0.4493, 0.4512, 0.4531, 0.4550, 0.4568, 0.4586,
1519 0.4604, 0.4622, 0.4639, 0.4657, 0.4674, 0.4691, 0.4708, 0.4725,
1520 0.4742, 0.4758, 0.4773, 0.4788, 0.4803, 0.4819, 0.4836, 0.4852,
1521 0.4869, 0.4885, 0.4901, 0.4917, 0.4933, 0.4948, 0.4964, 0.4979
1522 },
1523 {
1524 0.0085, 0.0189, 0.0288, 0.0389, 0.0497, 0.0603, 0.0699, 0.0792,
1525 0.0887, 0.0985, 0.1082, 0.1170, 0.1253, 0.1336, 0.1421, 0.1505,
1526 0.1587, 0.1662, 0.1733, 0.1803, 0.1874, 0.1945, 0.2014, 0.2081,
1527 0.2143, 0.2201, 0.2259, 0.2316, 0.2374, 0.2431, 0.2487, 0.2541,
1528 0.2593, 0.2642, 0.2689, 0.2735, 0.2781, 0.2826, 0.2872, 0.2917,
1529 0.2961, 0.3003, 0.3045, 0.3086, 0.3125, 0.3162, 0.3198, 0.3235,
1530 0.3270, 0.3306, 0.3342, 0.3377, 0.3411, 0.3446, 0.3479, 0.3511,
1531 0.3543, 0.3575, 0.3605, 0.3634, 0.3663, 0.3691, 0.3720, 0.3748,
1532 0.3775, 0.3803, 0.3830, 0.3857, 0.3884, 0.3911, 0.3937, 0.3962,
1533 0.3987, 0.4012, 0.4036, 0.4060, 0.4084, 0.4107, 0.4129, 0.4152,
1534 0.4174, 0.4196, 0.4218, 0.4239, 0.4261, 0.4282, 0.4303, 0.4324,
1535 0.4344, 0.4365, 0.4385, 0.4405, 0.4425, 0.4445, 0.4464, 0.4483,
1536 0.4502, 0.4521, 0.4539, 0.4558, 0.4576, 0.4593, 0.4611, 0.4629,
1537 0.4646, 0.4663, 0.4680, 0.4697, 0.4714, 0.4730, 0.4747, 0.4759,
1538 0.4769, 0.4780, 0.4790, 0.4800, 0.4811, 0.4827, 0.4843, 0.4859,
1539 0.4874, 0.4889, 0.4905, 0.4920, 0.4935, 0.4950, 0.4965, 0.4979
1540 }
1541 };
1542
1543 if (fLUT) {
1544 delete [] fLUT;
1545 }
1546 fLUT = new Double_t[fLUTbin];
1547
053767a4 1548 for (Int_t ilayer = 0; ilayer < AliTRDgeometry::kNlayer; ilayer++) {
fc546d21 1549 for (Int_t ilut = 0; ilut < kNlut; ilut++ ) {
053767a4 1550 fLUT[ilayer*kNlut+ilut] = lut[ilayer][ilut];
fc546d21 1551 }
1552 }
1553
1554}
1555
1556//_____________________________________________________________________________
eb52b657 1557Double_t AliTRDclusterizer::LUTposition(Int_t ilayer
1558 , Double_t ampL
1559 , Double_t ampC
1560 , Double_t ampR) const
fc546d21 1561{
1562 //
1563 // Calculates the cluster position using the lookup table.
1564 // Method provided by Bogdan Vulpescu.
1565 //
1566
1567 const Int_t kNlut = 128;
1568
1569 Double_t pos;
1570 Double_t x = 0.0;
1571 Double_t xmin;
1572 Double_t xmax;
1573 Double_t xwid;
1574
1575 Int_t side = 0;
1576 Int_t ix;
1577
053767a4 1578 Double_t xMin[AliTRDgeometry::kNlayer] = { 0.006492, 0.006377, 0.006258
317b5644 1579 , 0.006144, 0.006030, 0.005980 };
053767a4 1580 Double_t xMax[AliTRDgeometry::kNlayer] = { 0.960351, 0.965870, 0.970445
317b5644 1581 , 0.974352, 0.977667, 0.996101 };
fc546d21 1582
1583 if (ampL > ampR) {
1584 x = (ampL - ampR) / ampC;
1585 side = -1;
1586 }
1587 else if (ampL < ampR) {
1588 x = (ampR - ampL) / ampC;
1589 side = +1;
1590 }
1591
1592 if (ampL != ampR) {
1593
053767a4 1594 xmin = xMin[ilayer] + 0.000005;
1595 xmax = xMax[ilayer] - 0.000005;
fc546d21 1596 xwid = (xmax - xmin) / 127.0;
1597
1598 if (x < xmin) {
1599 pos = 0.0000;
1600 }
1601 else if (x > xmax) {
1602 pos = side * 0.5000;
1603 }
1604 else {
1605 ix = (Int_t) ((x - xmin) / xwid);
053767a4 1606 pos = side * fLUT[ilayer*kNlut+ix];
fc546d21 1607 }
317b5644 1608
fc546d21 1609 }
1610 else {
1611
1612 pos = 0.0;
1613
1614 }
1615
1616 return pos;
1617
1618}