]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDclusterizer.cxx
Don't use shared pads in HLT and some code clean-up
[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
66f6bfd9 24#include <TClonesArray.h>
6d50f529 25#include <TObjArray.h>
f7336fa3 26
88cb7938 27#include "AliRunLoader.h"
28#include "AliLoader.h"
3fe61b77 29#include "AliAlignObj.h"
88cb7938 30
f7336fa3 31#include "AliTRDclusterizer.h"
3e1a3ad8 32#include "AliTRDcluster.h"
fc546d21 33#include "AliTRDReconstructor.h"
793ff80c 34#include "AliTRDgeometry.h"
b65e5048 35#include "AliTRDarrayDictionary.h"
36#include "AliTRDarrayADC.h"
3fe61b77 37#include "AliTRDdigitsManager.h"
38#include "AliTRDrawData.h"
3551db50 39#include "AliTRDcalibDB.h"
3fe61b77 40#include "AliTRDtransform.h"
41#include "AliTRDSignalIndex.h"
dfbb4bb9 42#include "AliTRDrawStreamBase.h"
3fe61b77 43#include "AliTRDfeeParam.h"
a5b99acd 44#include "AliTRDtrackletWord.h"
3fe61b77 45
29f95561 46#include "TTreeStream.h"
47
3fe61b77 48#include "Cal/AliTRDCalROC.h"
49#include "Cal/AliTRDCalDet.h"
0e09df31 50#include "Cal/AliTRDCalSingleChamberStatus.h"
f7336fa3 51
52ClassImp(AliTRDclusterizer)
53
54//_____________________________________________________________________________
486c2339 55AliTRDclusterizer::AliTRDclusterizer(const AliTRDReconstructor *const rec)
6d50f529 56 :TNamed()
3a039a31 57 ,fReconstructor(rec)
6d50f529 58 ,fRunLoader(NULL)
59 ,fClusterTree(NULL)
60 ,fRecPoints(NULL)
a5b99acd 61 ,fTracklets(NULL)
9c7c9ec1 62 ,fTrackletTree(NULL)
3d0c7d6d 63 ,fDigitsManager(new AliTRDdigitsManager())
9c7c9ec1 64 ,fTrackletContainer(NULL)
3fe61b77 65 ,fRawVersion(2)
dfbb4bb9 66 ,fTransform(new AliTRDtransform(0))
1b3a719f 67 ,fDigits(NULL)
064d808d 68 ,fIndexes(NULL)
064d808d 69 ,fMaxThresh(0)
70 ,fSigThresh(0)
71 ,fMinMaxCutSigma(0)
72 ,fMinLeftRightCutSigma(0)
73 ,fLayer(0)
74 ,fDet(0)
75 ,fVolid(0)
76 ,fColMax(0)
77 ,fTimeTotal(0)
78 ,fCalGainFactorROC(NULL)
79 ,fCalGainFactorDetValue(0)
80 ,fCalNoiseROC(NULL)
81 ,fCalNoiseDetValue(0)
1b3a719f 82 ,fCalPadStatusROC(NULL)
064d808d 83 ,fClusterROC(0)
84 ,firstClusterROC(0)
3d0c7d6d 85 ,fNoOfClusters(0)
f7336fa3 86{
87 //
88 // AliTRDclusterizer default constructor
89 //
90
b72f4eaf 91 SetBit(kLabels, kTRUE);
3d0c7d6d 92
a7ac01d2 93 AliTRDcalibDB *trd = 0x0;
94 if (!(trd = AliTRDcalibDB::Instance())) {
95 AliFatal("Could not get calibration object");
96 }
97
3fe61b77 98 fRawVersion = AliTRDfeeParam::Instance()->GetRAWversion();
99
3a039a31 100 // Initialize debug stream
101 if(fReconstructor){
102 if(fReconstructor->GetStreamLevel(AliTRDReconstructor::kClusterizer) > 1){
103 TDirectory *savedir = gDirectory;
29f95561 104 //fgGetDebugStream = new TTreeSRedirector("TRD.ClusterizerDebug.root");
3a039a31 105 savedir->cd();
106 }
107 }
eb52b657 108
f7336fa3 109}
110
111//_____________________________________________________________________________
486c2339 112AliTRDclusterizer::AliTRDclusterizer(const Text_t *name, const Text_t *title, const AliTRDReconstructor *const rec)
6d50f529 113 :TNamed(name,title)
3a039a31 114 ,fReconstructor(rec)
6d50f529 115 ,fRunLoader(NULL)
116 ,fClusterTree(NULL)
117 ,fRecPoints(NULL)
a5b99acd 118 ,fTracklets(NULL)
9c7c9ec1 119 ,fTrackletTree(NULL)
3d0c7d6d 120 ,fDigitsManager(new AliTRDdigitsManager())
9c7c9ec1 121 ,fTrackletContainer(NULL)
3fe61b77 122 ,fRawVersion(2)
3fe61b77 123 ,fTransform(new AliTRDtransform(0))
1b3a719f 124 ,fDigits(NULL)
064d808d 125 ,fIndexes(NULL)
064d808d 126 ,fMaxThresh(0)
127 ,fSigThresh(0)
128 ,fMinMaxCutSigma(0)
129 ,fMinLeftRightCutSigma(0)
130 ,fLayer(0)
131 ,fDet(0)
132 ,fVolid(0)
133 ,fColMax(0)
134 ,fTimeTotal(0)
135 ,fCalGainFactorROC(NULL)
136 ,fCalGainFactorDetValue(0)
137 ,fCalNoiseROC(NULL)
138 ,fCalNoiseDetValue(0)
1b3a719f 139 ,fCalPadStatusROC(NULL)
064d808d 140 ,fClusterROC(0)
141 ,firstClusterROC(0)
3d0c7d6d 142 ,fNoOfClusters(0)
f7336fa3 143{
144 //
6d50f529 145 // AliTRDclusterizer constructor
f7336fa3 146 //
147
b72f4eaf 148 SetBit(kLabels, kTRUE);
3d0c7d6d 149
a7ac01d2 150 AliTRDcalibDB *trd = 0x0;
151 if (!(trd = AliTRDcalibDB::Instance())) {
152 AliFatal("Could not get calibration object");
153 }
154
3fe61b77 155 fDigitsManager->CreateArrays();
156
157 fRawVersion = AliTRDfeeParam::Instance()->GetRAWversion();
158
b72f4eaf 159 //FillLUT();
023b669c 160
f7336fa3 161}
162
8230f242 163//_____________________________________________________________________________
6d50f529 164AliTRDclusterizer::AliTRDclusterizer(const AliTRDclusterizer &c)
165 :TNamed(c)
3a039a31 166 ,fReconstructor(c.fReconstructor)
6d50f529 167 ,fRunLoader(NULL)
168 ,fClusterTree(NULL)
169 ,fRecPoints(NULL)
a5b99acd 170 ,fTracklets(NULL)
9c7c9ec1 171 ,fTrackletTree(NULL)
3fe61b77 172 ,fDigitsManager(NULL)
66f6bfd9 173 ,fTrackletContainer(NULL)
3fe61b77 174 ,fRawVersion(2)
3fe61b77 175 ,fTransform(NULL)
1b3a719f 176 ,fDigits(NULL)
064d808d 177 ,fIndexes(NULL)
064d808d 178 ,fMaxThresh(0)
179 ,fSigThresh(0)
180 ,fMinMaxCutSigma(0)
181 ,fMinLeftRightCutSigma(0)
182 ,fLayer(0)
183 ,fDet(0)
184 ,fVolid(0)
185 ,fColMax(0)
186 ,fTimeTotal(0)
187 ,fCalGainFactorROC(NULL)
188 ,fCalGainFactorDetValue(0)
189 ,fCalNoiseROC(NULL)
190 ,fCalNoiseDetValue(0)
1b3a719f 191 ,fCalPadStatusROC(NULL)
064d808d 192 ,fClusterROC(0)
193 ,firstClusterROC(0)
3d0c7d6d 194 ,fNoOfClusters(0)
8230f242 195{
196 //
197 // AliTRDclusterizer copy constructor
198 //
199
b72f4eaf 200 SetBit(kLabels, kTRUE);
3d0c7d6d 201
b72f4eaf 202 //FillLUT();
fc546d21 203
8230f242 204}
205
f7336fa3 206//_____________________________________________________________________________
207AliTRDclusterizer::~AliTRDclusterizer()
208{
8230f242 209 //
210 // AliTRDclusterizer destructor
211 //
f7336fa3 212
48f8adf3 213 if (fRecPoints/* && IsClustersOwner()*/){
66f6bfd9 214 fRecPoints->Delete();
215 delete fRecPoints;
216 }
3fe61b77 217
a5b99acd 218 if (fTracklets){
219 fTracklets->Delete();
220 delete fTracklets;
221 }
222
66f6bfd9 223 if (fDigitsManager) {
224 delete fDigitsManager;
225 fDigitsManager = NULL;
226 }
9c7c9ec1 227
66f6bfd9 228 if (fTrackletContainer){
229 delete fTrackletContainer;
230 fTrackletContainer = NULL;
231 }
3fe61b77 232
66f6bfd9 233 if (fTransform){
234 delete fTransform;
235 fTransform = NULL;
236 }
fc546d21 237
f7336fa3 238}
239
8230f242 240//_____________________________________________________________________________
dd9a6ee3 241AliTRDclusterizer &AliTRDclusterizer::operator=(const AliTRDclusterizer &c)
242{
243 //
244 // Assignment operator
245 //
246
3fe61b77 247 if (this != &c)
248 {
249 ((AliTRDclusterizer &) c).Copy(*this);
250 }
053767a4 251
dd9a6ee3 252 return *this;
253
254}
255
256//_____________________________________________________________________________
e0d47c25 257void AliTRDclusterizer::Copy(TObject &c) const
8230f242 258{
259 //
260 // Copy function
261 //
262
3fe61b77 263 ((AliTRDclusterizer &) c).fClusterTree = NULL;
264 ((AliTRDclusterizer &) c).fRecPoints = NULL;
9c7c9ec1 265 ((AliTRDclusterizer &) c).fTrackletTree = NULL;
3fe61b77 266 ((AliTRDclusterizer &) c).fDigitsManager = NULL;
9c7c9ec1 267 ((AliTRDclusterizer &) c).fTrackletContainer = NULL;
3fe61b77 268 ((AliTRDclusterizer &) c).fRawVersion = fRawVersion;
3fe61b77 269 ((AliTRDclusterizer &) c).fTransform = NULL;
1b3a719f 270 ((AliTRDclusterizer &) c).fDigits = NULL;
064d808d 271 ((AliTRDclusterizer &) c).fIndexes = NULL;
064d808d 272 ((AliTRDclusterizer &) c).fMaxThresh = 0;
273 ((AliTRDclusterizer &) c).fSigThresh = 0;
274 ((AliTRDclusterizer &) c).fMinMaxCutSigma= 0;
275 ((AliTRDclusterizer &) c).fMinLeftRightCutSigma = 0;
276 ((AliTRDclusterizer &) c).fLayer = 0;
277 ((AliTRDclusterizer &) c).fDet = 0;
278 ((AliTRDclusterizer &) c).fVolid = 0;
279 ((AliTRDclusterizer &) c).fColMax = 0;
280 ((AliTRDclusterizer &) c).fTimeTotal = 0;
281 ((AliTRDclusterizer &) c).fCalGainFactorROC = NULL;
282 ((AliTRDclusterizer &) c).fCalGainFactorDetValue = 0;
283 ((AliTRDclusterizer &) c).fCalNoiseROC = NULL;
284 ((AliTRDclusterizer &) c).fCalNoiseDetValue = 0;
1b3a719f 285 ((AliTRDclusterizer &) c).fCalPadStatusROC = NULL;
064d808d 286 ((AliTRDclusterizer &) c).fClusterROC = 0;
287 ((AliTRDclusterizer &) c).firstClusterROC= 0;
3d0c7d6d 288 ((AliTRDclusterizer &) c).fNoOfClusters = 0;
8230f242 289}
290
f7336fa3 291//_____________________________________________________________________________
3e1a3ad8 292Bool_t AliTRDclusterizer::Open(const Char_t *name, Int_t nEvent)
f7336fa3 293{
294 //
3e1a3ad8 295 // Opens the AliROOT file. Output and input are in the same file
f7336fa3 296 //
6d50f529 297
e191bb57 298 TString evfoldname = AliConfig::GetDefaultEventFolderName();
6d50f529 299 fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
300
301 if (!fRunLoader) {
19dd5b2f 302 fRunLoader = AliRunLoader::Open(name);
6d50f529 303 }
304
305 if (!fRunLoader) {
306 AliError(Form("Can not open session for file %s.",name));
307 return kFALSE;
308 }
88cb7938 309
310 OpenInput(nEvent);
311 OpenOutput();
6d50f529 312
3e1a3ad8 313 return kTRUE;
f7336fa3 314
6d50f529 315}
3e1a3ad8 316
317//_____________________________________________________________________________
88cb7938 318Bool_t AliTRDclusterizer::OpenOutput()
3e1a3ad8 319{
320 //
321 // Open the output file
322 //
323
66f6bfd9 324 if (!fReconstructor->IsWritingClusters()) return kTRUE;
325
326 TObjArray *ioArray = 0x0;
88cb7938 327
328 AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
329 loader->MakeTree("R");
6d50f529 330
88cb7938 331 fClusterTree = loader->TreeR();
66f6bfd9 332 fClusterTree->Branch("TRDcluster", "TObjArray", &ioArray, 32000, 0);
3e1a3ad8 333
3e1a3ad8 334 return kTRUE;
335
336}
337
25ca55ce 338//_____________________________________________________________________________
e7295a3a 339Bool_t AliTRDclusterizer::OpenOutput(TTree *const clusterTree)
25ca55ce 340{
341 //
342 // Connect the output tree
343 //
344
66f6bfd9 345 // clusters writing
346 if (fReconstructor->IsWritingClusters()){
347 TObjArray *ioArray = 0x0;
348 fClusterTree = clusterTree;
349 fClusterTree->Branch("TRDcluster", "TObjArray", &ioArray, 32000, 0);
350 }
11d0be11 351 return kTRUE;
352}
353
354//_____________________________________________________________________________
355Bool_t AliTRDclusterizer::OpenTrackletOutput()
356{
357 //
358 // Tracklet writing
359 //
9c7c9ec1 360
3a039a31 361 if (fReconstructor->IsWritingTracklets()){
9c7c9ec1 362 TString evfoldname = AliConfig::GetDefaultEventFolderName();
363 fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
364
365 if (!fRunLoader) {
366 fRunLoader = AliRunLoader::Open("galice.root");
367 }
368 if (!fRunLoader) {
369 AliError(Form("Can not open session for file galice.root."));
370 return kFALSE;
371 }
372
373 UInt_t **leaves = new UInt_t *[2];
374 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
375 if (!dl) {
376 AliError("Could not get the tracklets data loader!");
90cf7133 377 dl = new AliDataLoader("TRD.Tracklets.root","tracklets", "tracklets");
9c7c9ec1 378 fRunLoader->GetLoader("TRDLoader")->AddDataLoader(dl);
379 }
11d0be11 380 fTrackletTree = dl->Tree();
381 if (!fTrackletTree)
382 {
383 dl->MakeTree();
384 fTrackletTree = dl->Tree();
385 }
386 TBranch *trkbranch = fTrackletTree->GetBranch("trkbranch");
387 if (!trkbranch)
388 fTrackletTree->Branch("trkbranch",leaves[0],"det/i:side/i:tracklets[256]/i");
9c7c9ec1 389 }
390
25ca55ce 391 return kTRUE;
25ca55ce 392}
393
3e1a3ad8 394//_____________________________________________________________________________
88cb7938 395Bool_t AliTRDclusterizer::OpenInput(Int_t nEvent)
f7336fa3 396{
397 //
398 // Opens a ROOT-file with TRD-hits and reads in the digits-tree
399 //
400
f7336fa3 401 // Import the Trees for the event nEvent in the file
bdbb05bb 402 fRunLoader->GetEvent(nEvent);
88cb7938 403
f7336fa3 404 return kTRUE;
405
406}
407
408//_____________________________________________________________________________
793ff80c 409Bool_t AliTRDclusterizer::WriteClusters(Int_t det)
f7336fa3 410{
411 //
3e1a3ad8 412 // Fills TRDcluster branch in the tree with the clusters
793ff80c 413 // found in detector = det. For det=-1 writes the tree.
a3c76cdc 414 //
793ff80c 415
6d50f529 416 if ((det < -1) ||
417 (det >= AliTRDgeometry::Ndet())) {
418 AliError(Form("Unexpected detector index %d.\n",det));
3e1a3ad8 419 return kFALSE;
793ff80c 420 }
317b5644 421
66f6bfd9 422 TObjArray *ioArray = new TObjArray(400);
3e1a3ad8 423 TBranch *branch = fClusterTree->GetBranch("TRDcluster");
424 if (!branch) {
3e1a3ad8 425 branch = fClusterTree->Branch("TRDcluster","TObjArray",&ioArray,32000,0);
66f6bfd9 426 } else branch->SetAddress(&ioArray);
66f6bfd9 427
428 Int_t nRecPoints = RecPoints()->GetEntriesFast();
429 if(det >= 0){
3e1a3ad8 430 for (Int_t i = 0; i < nRecPoints; i++) {
bdbb05bb 431 AliTRDcluster *c = (AliTRDcluster *) RecPoints()->UncheckedAt(i);
66f6bfd9 432 if(det != c->GetDetector()) continue;
433 ioArray->AddLast(c);
793ff80c 434 }
3e1a3ad8 435 fClusterTree->Fill();
66f6bfd9 436 } else {
eb52b657 437
66f6bfd9 438 Int_t detOld = -1;
439 for (Int_t i = 0; i < nRecPoints; i++) {
440 AliTRDcluster *c = (AliTRDcluster *) RecPoints()->UncheckedAt(i);
441 if(c->GetDetector() != detOld){
442 fClusterTree->Fill();
443 ioArray->Clear();
444 detOld = c->GetDetector();
445 }
446 ioArray->AddLast(c);
a6dd11e9 447 }
793ff80c 448 }
66f6bfd9 449 delete ioArray;
6d50f529 450
66f6bfd9 451 return kTRUE;
eb52b657 452
f7336fa3 453}
793ff80c 454
9c7c9ec1 455//_____________________________________________________________________________
456Bool_t AliTRDclusterizer::WriteTracklets(Int_t det)
457{
eb52b657 458 //
459 // Write the raw data tracklets into seperate file
460 //
9c7c9ec1 461
462 UInt_t **leaves = new UInt_t *[2];
463 for (Int_t i=0; i<2 ;i++){
317b5644 464 leaves[i] = new UInt_t[258];
465 leaves[i][0] = det; // det
466 leaves[i][1] = i; // side
467 memcpy(leaves[i]+2, fTrackletContainer[i], sizeof(UInt_t) * 256);
9c7c9ec1 468 }
469
9c7c9ec1 470 if (!fTrackletTree){
471 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
472 dl->MakeTree();
473 fTrackletTree = dl->Tree();
474 }
475
476 TBranch *trkbranch = fTrackletTree->GetBranch("trkbranch");
477 if (!trkbranch) {
478 trkbranch = fTrackletTree->Branch("trkbranch",leaves[0],"det/i:side/i:tracklets[256]/i");
479 }
480
481 for (Int_t i=0; i<2; i++){
317b5644 482 if (leaves[i][2]>0) {
483 trkbranch->SetAddress(leaves[i]);
484 fTrackletTree->Fill();
485 }
9c7c9ec1 486 }
487
488 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
489 dl->WriteData("OVERWRITE");
490 //dl->Unload();
491 delete [] leaves;
492
eb52b657 493 return kTRUE;
494
9c7c9ec1 495}
496
3fe61b77 497//_____________________________________________________________________________
498Bool_t AliTRDclusterizer::ReadDigits()
499{
500 //
501 // Reads the digits arrays from the input aliroot file
502 //
503
504 if (!fRunLoader) {
505 AliError("No run loader available");
506 return kFALSE;
507 }
508
509 AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
510 if (!loader->TreeD()) {
511 loader->LoadDigits();
512 }
513
514 // Read in the digit arrays
515 return (fDigitsManager->ReadDigits(loader->TreeD()));
516
517}
518
519//_____________________________________________________________________________
520Bool_t AliTRDclusterizer::ReadDigits(TTree *digitsTree)
521{
522 //
523 // Reads the digits arrays from the input tree
524 //
525
526 // Read in the digit arrays
527 return (fDigitsManager->ReadDigits(digitsTree));
528
529}
530
531//_____________________________________________________________________________
532Bool_t AliTRDclusterizer::ReadDigits(AliRawReader *rawReader)
533{
534 //
535 // Reads the digits arrays from the ddl file
536 //
537
538 AliTRDrawData raw;
539 fDigitsManager = raw.Raw2Digits(rawReader);
540
541 return kTRUE;
542
543}
544
545//_____________________________________________________________________________
546Bool_t AliTRDclusterizer::MakeClusters()
547{
548 //
549 // Creates clusters from digits
550 //
551
552 // Propagate info from the digits manager
b72f4eaf 553 if (TestBit(kLabels)){
554 SetBit(kLabels, fDigitsManager->UsesDictionaries());
66f6bfd9 555 }
556
3fe61b77 557 Bool_t fReturn = kTRUE;
66f6bfd9 558 for (Int_t i = 0; i < AliTRDgeometry::kNdet; i++){
559
b65e5048 560 AliTRDarrayADC *digitsIn = (AliTRDarrayADC*) fDigitsManager->GetDigits(i); //mod
66f6bfd9 561 // This is to take care of switched off super modules
562 if (!digitsIn->HasData()) continue;
563 digitsIn->Expand();
0d64b05f 564 digitsIn->DeleteNegatives(); // Restore digits array to >=0 values
66f6bfd9 565 AliTRDSignalIndex* indexes = fDigitsManager->GetIndexes(i);
566 if (indexes->IsAllocated() == kFALSE){
567 fDigitsManager->BuildIndexes(i);
568 }
569
570 Bool_t fR = kFALSE;
571 if (indexes->HasEntry()){
b72f4eaf 572 if (TestBit(kLabels)){
66f6bfd9 573 for (Int_t iDict = 0; iDict < AliTRDdigitsManager::kNDict; iDict++){
b65e5048 574 AliTRDarrayDictionary *tracksIn = 0; //mod
575 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(i,iDict); //mod
66f6bfd9 576 tracksIn->Expand();
3fe61b77 577 }
66f6bfd9 578 }
579 fR = MakeClusters(i);
580 fReturn = fR && fReturn;
3fe61b77 581 }
66f6bfd9 582
583 //if (fR == kFALSE){
584 // if(IsWritingClusters()) WriteClusters(i);
585 // ResetRecPoints();
586 //}
587
588 // No compress just remove
589 fDigitsManager->RemoveDigits(i);
590 fDigitsManager->RemoveDictionaries(i);
591 fDigitsManager->ClearIndexes(i);
592 }
593
594 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
3fe61b77 595
66f6bfd9 596 AliInfo(Form("Number of found clusters : %d", RecPoints()->GetEntriesFast()));
3fe61b77 597
66f6bfd9 598 return fReturn;
eb52b657 599
3fe61b77 600}
601
602//_____________________________________________________________________________
603Bool_t AliTRDclusterizer::Raw2Clusters(AliRawReader *rawReader)
604{
605 //
606 // Creates clusters from raw data
607 //
608
fc546d21 609 return Raw2ClustersChamber(rawReader);
3fe61b77 610
3fe61b77 611}
612
613//_____________________________________________________________________________
614Bool_t AliTRDclusterizer::Raw2ClustersChamber(AliRawReader *rawReader)
615{
616 //
617 // Creates clusters from raw data
618 //
619
620 // Create the digits manager
66f6bfd9 621 if (!fDigitsManager){
3d0c7d6d 622 fDigitsManager = new AliTRDdigitsManager(kTRUE);
66f6bfd9 623 fDigitsManager->CreateArrays();
624 }
3fe61b77 625
b72f4eaf 626 fDigitsManager->SetUseDictionaries(TestBit(kLabels));
3fe61b77 627
317b5644 628 // tracklet container for raw tracklet writing
a5b99acd 629 if (!fTrackletContainer && ( fReconstructor->IsWritingTracklets() || fReconstructor->IsProcessingTracklets() )) {
317b5644 630 // maximum tracklets for one HC
631 const Int_t kTrackletChmb=256;
632 fTrackletContainer = new UInt_t *[2];
633 fTrackletContainer[0] = new UInt_t[kTrackletChmb];
634 fTrackletContainer[1] = new UInt_t[kTrackletChmb];
635 }
636
064d808d 637 AliTRDrawStreamBase *input = AliTRDrawStreamBase::GetRawStream(rawReader);
6b0d4ad5 638 if(fReconstructor->IsHLT())
639 input->SetSharedPadReadout(kFALSE);
3fe61b77 640
064d808d 641 AliInfo(Form("Stream version: %s", input->IsA()->GetName()));
3fe61b77 642
643 Int_t det = 0;
064d808d 644 while ((det = input->NextChamber(fDigitsManager,fTrackletContainer)) >= 0){
66f6bfd9 645 Bool_t iclusterBranch = kFALSE;
646 if (fDigitsManager->GetIndexes(det)->HasEntry()){
486c2339 647 iclusterBranch = MakeClusters(det);
3fe61b77 648 }
66f6bfd9 649
486c2339 650 fDigitsManager->ResetArrays(det);
651
317b5644 652 if (!fReconstructor->IsWritingTracklets()) continue;
653 if (*(fTrackletContainer[0]) > 0 || *(fTrackletContainer[1]) > 0) WriteTracklets(det);
9c7c9ec1 654 }
486c2339 655
a5b99acd 656 if (fTrackletContainer){
317b5644 657 delete [] fTrackletContainer[0];
658 delete [] fTrackletContainer[1];
659 delete [] fTrackletContainer;
660 fTrackletContainer = NULL;
661 }
662
66f6bfd9 663 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
3fe61b77 664
665 delete fDigitsManager;
666 fDigitsManager = NULL;
dfbb4bb9 667
064d808d 668 delete input;
669 input = NULL;
3fe61b77 670
3d0c7d6d 671 AliInfo(Form("Number of found clusters : %d", fNoOfClusters));
66f6bfd9 672 return kTRUE;
eb52b657 673
3fe61b77 674}
675
fa7427d0 676//_____________________________________________________________________________
677UChar_t AliTRDclusterizer::GetStatus(Short_t &signal)
678{
023b669c 679 //
680 // Check if a pad is masked
681 //
682
317b5644 683 UChar_t status = 0;
684
685 if(signal>0 && TESTBIT(signal, 10)){
686 CLRBIT(signal, 10);
687 for(int ibit=0; ibit<4; ibit++){
688 if(TESTBIT(signal, 11+ibit)){
689 SETBIT(status, ibit);
690 CLRBIT(signal, 11+ibit);
691 }
692 }
693 }
694 return status;
fa7427d0 695}
696
6d9e79cc 697//_____________________________________________________________________________
e7295a3a 698void AliTRDclusterizer::SetPadStatus(const UChar_t status, UChar_t &out) const {
6d9e79cc 699 //
700 // Set the pad status into out
701 // First three bits are needed for the position encoding
702 //
064d808d 703 out |= status << 3;
6d9e79cc 704}
705
706//_____________________________________________________________________________
064d808d 707UChar_t AliTRDclusterizer::GetPadStatus(UChar_t encoding) const {
6d9e79cc 708 //
709 // return the staus encoding of the corrupted pad
710 //
711 return static_cast<UChar_t>(encoding >> 3);
712}
713
714//_____________________________________________________________________________
064d808d 715Int_t AliTRDclusterizer::GetCorruption(UChar_t encoding) const {
6d9e79cc 716 //
717 // Return the position of the corruption
718 //
719 return encoding & 7;
720}
721
3fe61b77 722//_____________________________________________________________________________
723Bool_t AliTRDclusterizer::MakeClusters(Int_t det)
724{
725 //
726 // Generates the cluster.
727 //
728
729 // Get the digits
064d808d 730 // digits should be expanded beforehand!
3fe61b77 731 // digitsIn->Expand();
1b3a719f 732 fDigits = (AliTRDarrayADC *) fDigitsManager->GetDigits(det); //mod
f5375dcb 733
3fe61b77 734 // This is to take care of switched off super modules
b72f4eaf 735 if (!fDigits->HasData()) return kFALSE;
3fe61b77 736
064d808d 737 fIndexes = fDigitsManager->GetIndexes(det);
b72f4eaf 738 if (fIndexes->IsAllocated() == kFALSE) {
739 AliError("Indexes do not exist!");
740 return kFALSE;
741 }
064d808d 742
3fe61b77 743 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
b72f4eaf 744 if (!calibration) {
745 AliFatal("No AliTRDcalibDB instance available\n");
746 return kFALSE;
747 }
3fe61b77 748
3a039a31 749 if (!fReconstructor){
750 AliError("Reconstructor not set\n");
751 return kFALSE;
752 }
c5f589b9 753
064d808d 754 fMaxThresh = fReconstructor->GetRecoParam()->GetClusMaxThresh();
755 fSigThresh = fReconstructor->GetRecoParam()->GetClusSigThresh();
756 fMinMaxCutSigma = fReconstructor->GetRecoParam()->GetMinMaxCutSigma();
757 fMinLeftRightCutSigma = fReconstructor->GetRecoParam()->GetMinLeftRightCutSigma();
3fe61b77 758
064d808d 759 Int_t istack = fIndexes->GetStack();
760 fLayer = fIndexes->GetLayer();
761 Int_t isector = fIndexes->GetSM();
3fe61b77 762
763 // Start clustering in the chamber
764
064d808d 765 fDet = AliTRDgeometry::GetDetector(fLayer,istack,isector);
766 if (fDet != det) {
b65e5048 767 AliError("Strange Detector number Missmatch!");
768 return kFALSE;
769 }
3fe61b77 770
771 // TRD space point transformation
772 fTransform->SetDetector(det);
773
064d808d 774 Int_t iGeoLayer = AliGeomManager::kTRD1 + fLayer;
053767a4 775 Int_t iGeoModule = istack + AliTRDgeometry::Nstack() * isector;
064d808d 776 fVolid = AliGeomManager::LayerToVolUID(iGeoLayer,iGeoModule);
3fe61b77 777
a5b99acd 778 if(fReconstructor->IsProcessingTracklets() && fTrackletContainer)
779 AddTrackletsToArray();
780
1b3a719f 781 fColMax = fDigits->GetNcol();
782 //Int_t nRowMax = fDigits->GetNrow();
783 fTimeTotal = fDigits->GetNtime();
3fe61b77 784
785 // Detector wise calibration object for the gain factors
064d808d 786 const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
3fe61b77 787 // Calibration object with pad wise values for the gain factors
064d808d 788 fCalGainFactorROC = calibration->GetGainFactorROC(fDet);
3fe61b77 789 // Calibration value for chamber wise gain factor
064d808d 790 fCalGainFactorDetValue = calGainFactorDet->GetValue(fDet);
0e09df31 791
df83a620 792 // Detector wise calibration object for the noise
064d808d 793 const AliTRDCalDet *calNoiseDet = calibration->GetNoiseDet();
df83a620 794 // Calibration object with pad wise values for the noise
064d808d 795 fCalNoiseROC = calibration->GetNoiseROC(fDet);
df83a620 796 // Calibration value for chamber wise noise
064d808d 797 fCalNoiseDetValue = calNoiseDet->GetValue(fDet);
1b3a719f 798
799 // Calibration object with the pad status
800 fCalPadStatusROC = calibration->GetPadStatusROC(fDet);
6b0d4ad5 801
b72f4eaf 802 SetBit(kLUT, fReconstructor->UseLUT());
803 SetBit(kGAUS, fReconstructor->UseGAUS());
804 SetBit(kHLT, fReconstructor->IsHLT());
6b0d4ad5 805
064d808d 806 firstClusterROC = -1;
807 fClusterROC = 0;
3fe61b77 808
b72f4eaf 809 // Apply the gain and the tail cancelation via digital filter
810 if(fReconstructor->UseTailCancelation()) TailCancelation();
023b669c 811
486c2339 812 MaxStruct curr, last;
064d808d 813 Int_t nMaximas = 0, nCorrupted = 0;
f5375dcb 814
064d808d 815 // Here the clusterfining is happening
816
b72f4eaf 817 for(curr.Time = 0; curr.Time < fTimeTotal; curr.Time++){
818 while(fIndexes->NextRCIndex(curr.Row, curr.Col)){
819 //printf("\nCHECK r[%2d] c[%3d] t[%d]\n", curr.Row, curr.Col, curr.Time);
820 if(IsMaximum(curr, curr.padStatus, &curr.Signals[0])){
c96d03ba 821 //printf("\tMAX s[%d %d %d]\n", curr.Signals[0], curr.Signals[1], curr.Signals[2]);
b72f4eaf 822 if(last.Row>-1){
823 if(curr.Time==last.Time && curr.Row==last.Row && curr.Col==last.Col+2) FivePadCluster(last, curr);
824 CreateCluster(last);
825 }
826 last=curr; curr.FivePad=kFALSE;
827 }
c96d03ba 828 //printf("\t--- s[%d %d %d]\n", curr.Signals[0], curr.Signals[1], curr.Signals[2]);
b72f4eaf 829 }
830 }
831 if(last.Row>-1) CreateCluster(last);
df83a620 832
064d808d 833 if(fReconstructor->GetStreamLevel(AliTRDReconstructor::kClusterizer) > 2){
6b0d4ad5 834 TTreeSRedirector* fDebugStream = fReconstructor->GetDebugStream(AliTRDReconstructor::kClusterizer);
064d808d 835 (*fDebugStream) << "MakeClusters"
b72f4eaf 836 << "Detector=" << det
837 << "NMaxima=" << nMaximas
838 << "NClusters=" << fClusterROC
839 << "NCorrupted=" << nCorrupted
840 << "\n";
df83a620 841 }
b72f4eaf 842 if (TestBit(kLabels)) AddLabels();
f5375dcb 843
064d808d 844 return kTRUE;
f5375dcb 845
064d808d 846}
3fe61b77 847
064d808d 848//_____________________________________________________________________________
1b3a719f 849Bool_t AliTRDclusterizer::IsMaximum(const MaxStruct &Max, UChar_t &padStatus, Short_t *const Signals)
064d808d 850{
851 //
852 // Returns true if this row,col,time combination is a maximum.
853 // Gives back the padStatus and the signals of the center pad and the two neighbouring pads.
854 //
c96d03ba 855
856 Signals[1] = fDigits->GetData(Max.Row, Max.Col, Max.Time);
857 if(Signals[1] < fMaxThresh) return kFALSE;
3fe61b77 858
486c2339 859 Float_t noiseMiddleThresh = fMinMaxCutSigma*fCalNoiseDetValue*fCalNoiseROC->GetValue(Max.Col, Max.Row);
c96d03ba 860 if (Signals[1] < noiseMiddleThresh) return kFALSE;
f5375dcb 861
486c2339 862 if (Max.Col + 1 >= fColMax || Max.Col < 1) return kFALSE;
3fe61b77 863
b72f4eaf 864 UChar_t status[3]={
865 fCalPadStatusROC->GetStatus(Max.Col-1, Max.Row)
866 ,fCalPadStatusROC->GetStatus(Max.Col, Max.Row)
867 ,fCalPadStatusROC->GetStatus(Max.Col+1, Max.Row)
868 };
486c2339 869
c96d03ba 870 Signals[0] = fDigits->GetData(Max.Row, Max.Col-1, Max.Time);
871 Signals[2] = fDigits->GetData(Max.Row, Max.Col+1, Max.Time);
872
486c2339 873 if(!(status[0] | status[1] | status[2])) {//all pads are good
c96d03ba 874 if ((Signals[2] <= Signals[1]) && (Signals[0] < Signals[1])) {
875 if ((Signals[2] >= fSigThresh) || (Signals[0] >= fSigThresh)) {
b72f4eaf 876 Float_t noiseSumThresh = fMinLeftRightCutSigma
877 * fCalNoiseDetValue
878 * fCalNoiseROC->GetValue(Max.Col, Max.Row);
c96d03ba 879 if ((Signals[2]+Signals[0]+Signals[1]) < noiseSumThresh) return kFALSE;
b72f4eaf 880 padStatus = 0;
881 return kTRUE;
eb52b657 882 }
064d808d 883 }
b72f4eaf 884 } else { // at least one of the pads is bad, and reject candidates with more than 1 problematic pad
c96d03ba 885 if (status[2] && (!(status[0] || status[1])) && Signals[1] > Signals[0] && Signals[0] >= fSigThresh) {
886 Signals[2]=0;
486c2339 887 SetPadStatus(status[2], padStatus);
888 return kTRUE;
889 }
c96d03ba 890 else if (status[0] && (!(status[1] || status[2])) && Signals[1] >= Signals[2] && Signals[2] >= fSigThresh) {
891 Signals[0]=0;
486c2339 892 SetPadStatus(status[0], padStatus);
893 return kTRUE;
894 }
c96d03ba 895 else if (status[1] && (!(status[0] || status[2])) && ((Signals[2] >= fSigThresh) || (Signals[0] >= fSigThresh))) {
896 Signals[1]=TMath::Nint(fMaxThresh);
486c2339 897 SetPadStatus(status[1], padStatus);
064d808d 898 return kTRUE;
899 }
900 }
901 return kFALSE;
902}
3fe61b77 903
064d808d 904//_____________________________________________________________________________
1b3a719f 905Bool_t AliTRDclusterizer::FivePadCluster(MaxStruct &ThisMax, MaxStruct &NeighbourMax)
064d808d 906{
907 //
908 // Look for 5 pad cluster with minimum in the middle
909 // Gives back the ratio
910 //
486c2339 911 if (ThisMax.Col >= fColMax - 3) return kFALSE;
912 if (ThisMax.Col < fColMax - 5){
1b3a719f 913 if (fDigits->GetData(ThisMax.Row, ThisMax.Col+4, ThisMax.Time) >= fSigThresh)
486c2339 914 return kFALSE;
064d808d 915 }
486c2339 916 if (ThisMax.Col > 1) {
1b3a719f 917 if (fDigits->GetData(ThisMax.Row, ThisMax.Col-2, ThisMax.Time) >= fSigThresh)
486c2339 918 return kFALSE;
919 }
920
486c2339 921 const Float_t kEpsilon = 0.01;
c96d03ba 922 Double_t padSignal[5] = {ThisMax.Signals[0], ThisMax.Signals[1], ThisMax.Signals[2],
923 NeighbourMax.Signals[1], NeighbourMax.Signals[2]};
486c2339 924
925 // Unfold the two maxima and set the signal on
926 // the overlapping pad to the ratio
1b3a719f 927 Float_t ratio = Unfold(kEpsilon,fLayer,padSignal);
c96d03ba 928 ThisMax.Signals[2] = TMath::Nint(ThisMax.Signals[2]*ratio);
929 NeighbourMax.Signals[0] = TMath::Nint(NeighbourMax.Signals[0]*(1-ratio));
1b3a719f 930 ThisMax.FivePad=kTRUE;
931 NeighbourMax.FivePad=kTRUE;
486c2339 932 return kTRUE;
c96d03ba 933
064d808d 934}
eb52b657 935
064d808d 936//_____________________________________________________________________________
486c2339 937void AliTRDclusterizer::CreateCluster(const MaxStruct &Max)
064d808d 938{
939 //
3d0c7d6d 940 // Creates a cluster at the given position and saves it in fRecPoints
064d808d 941 //
eb52b657 942
c96d03ba 943 Int_t nPadCount = 1;
944 Short_t signals[7] = { 0, 0, Max.Signals[0], Max.Signals[1], Max.Signals[2], 0, 0 };
945 if(!TestBit(kHLT)) CalcAdditionalInfo(Max, signals, nPadCount);
946
947 AliTRDcluster cluster(fDet, ((UChar_t) Max.Col), ((UChar_t) Max.Row), ((UChar_t) Max.Time), signals, fVolid);
948 cluster.SetNPads(nPadCount);
b72f4eaf 949 if(TestBit(kLUT)) cluster.SetRPhiMethod(AliTRDcluster::kLUT);
950 else if(TestBit(kGAUS)) cluster.SetRPhiMethod(AliTRDcluster::kGAUS);
951 else cluster.SetRPhiMethod(AliTRDcluster::kCOG);
3fe61b77 952
b72f4eaf 953 cluster.SetFivePad(Max.FivePad);
954 // set pads status for the cluster
955 UChar_t maskPosition = GetCorruption(Max.padStatus);
956 if (maskPosition) {
957 cluster.SetPadMaskedPosition(maskPosition);
958 cluster.SetPadMaskedStatus(GetPadStatus(Max.padStatus));
959 }
064d808d 960
961 // Transform the local cluster coordinates into calibrated
962 // space point positions defined in the local tracking system.
963 // Here the calibration for T0, Vdrift and ExB is applied as well.
b72f4eaf 964 if(!fTransform->Transform(&cluster)) return;
965 // Temporarily store the Max.Row, column and time bin of the center pad
966 // Used to later on assign the track indices
967 cluster.SetLabel(Max.Row, 0);
968 cluster.SetLabel(Max.Col, 1);
969 cluster.SetLabel(Max.Time,2);
c96d03ba 970
b72f4eaf 971 //needed for HLT reconstruction
972 AddClusterToArray(&cluster);
973
974 // Store the index of the first cluster in the current ROC
975 if (firstClusterROC < 0) firstClusterROC = fNoOfClusters;
976
977 fNoOfClusters++;
978 fClusterROC++;
3fe61b77 979}
980
3d0c7d6d 981//_____________________________________________________________________________
982void AliTRDclusterizer::CalcAdditionalInfo(const MaxStruct &Max, Short_t *const signals, Int_t &nPadCount)
983{
984 // Look to the right
985 Int_t ii = 1;
986 while (fDigits->GetData(Max.Row, Max.Col-ii, Max.Time) >= fSigThresh) {
987 nPadCount++;
988 ii++;
989 if (Max.Col < ii) break;
990 }
991 // Look to the left
992 ii = 1;
993 while (fDigits->GetData(Max.Row, Max.Col+ii, Max.Time) >= fSigThresh) {
994 nPadCount++;
995 ii++;
996 if (Max.Col+ii >= fColMax) break;
997 }
998
999 // Store the amplitudes of the pads in the cluster for later analysis
1000 // and check whether one of these pads is masked in the database
1001 signals[2]=Max.Signals[0];
1002 signals[3]=Max.Signals[1];
1003 signals[4]=Max.Signals[2];
1004 for(Int_t i = 0; i<2; i++)
1005 {
1006 if(Max.Col+i >= 3)
1007 signals[i] = fDigits->GetData(Max.Row, Max.Col-3+i, Max.Time);
1008 if(Max.Col+3-i < fColMax)
1009 signals[6-i] = fDigits->GetData(Max.Row, Max.Col+3-i, Max.Time);
1010 }
1011 /*for (Int_t jPad = Max.Col-3; jPad <= Max.Col+3; jPad++) {
1012 if ((jPad >= 0) && (jPad < fColMax))
1013 signals[jPad-Max.Col+3] = TMath::Nint(fDigits->GetData(Max.Row,jPad,Max.Time));
1014 }*/
1015}
1016
1017//_____________________________________________________________________________
e7295a3a 1018void AliTRDclusterizer::AddClusterToArray(AliTRDcluster* cluster)
3d0c7d6d 1019{
1020 //
1021 // Add a cluster to the array
1022 //
1023
1024 Int_t n = RecPoints()->GetEntriesFast();
1025 if(n!=fNoOfClusters)AliError(Form("fNoOfClusters != RecPoints()->GetEntriesFast %i != %i \n", fNoOfClusters, n));
1026 new((*RecPoints())[n]) AliTRDcluster(*cluster);
1027}
1028
a5b99acd 1029//_____________________________________________________________________________
1030void AliTRDclusterizer::AddTrackletsToArray()
1031{
1032 //
1033 // Add the online tracklets of this chamber to the array
1034 //
1035
1036 UInt_t* trackletword;
1037 for(Int_t side=0; side<2; side++)
1038 {
1039 Int_t trkl=0;
1040 trackletword=fTrackletContainer[side];
97be9934 1041 while(trackletword[trkl]>0){
a5b99acd 1042 Int_t n = TrackletsArray()->GetEntriesFast();
35943b1e 1043 AliTRDtrackletWord tmp(trackletword[trkl]);
1044 new((*TrackletsArray())[n]) AliTRDcluster(&tmp,fDet,fVolid);
a5b99acd 1045 trkl++;
97be9934 1046 }
a5b99acd 1047 }
1048}
1049
3fe61b77 1050//_____________________________________________________________________________
6cd9a21f 1051Bool_t AliTRDclusterizer::AddLabels()
3551db50 1052{
1053 //
3fe61b77 1054 // Add the track indices to the found clusters
3551db50 1055 //
1056
3fe61b77 1057 const Int_t kNclus = 3;
1058 const Int_t kNdict = AliTRDdigitsManager::kNDict;
1059 const Int_t kNtrack = kNdict * kNclus;
1060
1061 Int_t iClusterROC = 0;
1062
1063 Int_t row = 0;
1064 Int_t col = 0;
1065 Int_t time = 0;
1066 Int_t iPad = 0;
1067
1068 // Temporary array to collect the track indices
6cd9a21f 1069 Int_t *idxTracks = new Int_t[kNtrack*fClusterROC];
3fe61b77 1070
1071 // Loop through the dictionary arrays one-by-one
1072 // to keep memory consumption low
b65e5048 1073 AliTRDarrayDictionary *tracksIn = 0; //mod
3fe61b77 1074 for (Int_t iDict = 0; iDict < kNdict; iDict++) {
1075
1076 // tracksIn should be expanded beforehand!
6cd9a21f 1077 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(fDet,iDict);
3fe61b77 1078
1079 // Loop though the clusters found in this ROC
6cd9a21f 1080 for (iClusterROC = 0; iClusterROC < fClusterROC; iClusterROC++) {
317b5644 1081
3fe61b77 1082 AliTRDcluster *cluster = (AliTRDcluster *)
b65e5048 1083 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
3fe61b77 1084 row = cluster->GetLabel(0);
1085 col = cluster->GetLabel(1);
1086 time = cluster->GetLabel(2);
1087
1088 for (iPad = 0; iPad < kNclus; iPad++) {
b65e5048 1089 Int_t iPadCol = col - 1 + iPad;
1090 Int_t index = tracksIn->GetData(row,iPadCol,time); //Modification of -1 in Track
1091 idxTracks[3*iPad+iDict + iClusterROC*kNtrack] = index;
3fe61b77 1092 }
1093
1094 }
1095
1096 }
1097
1098 // Copy the track indices into the cluster
1099 // Loop though the clusters found in this ROC
6cd9a21f 1100 for (iClusterROC = 0; iClusterROC < fClusterROC; iClusterROC++) {
317b5644 1101
3fe61b77 1102 AliTRDcluster *cluster = (AliTRDcluster *)
1103 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
1104 cluster->SetLabel(-9999,0);
1105 cluster->SetLabel(-9999,1);
1106 cluster->SetLabel(-9999,2);
1107
1108 cluster->AddTrackIndex(&idxTracks[iClusterROC*kNtrack]);
1109
1110 }
1111
1112 delete [] idxTracks;
1113
1114 return kTRUE;
1115
1116}
1117
3fe61b77 1118//_____________________________________________________________________________
e7295a3a 1119Float_t AliTRDclusterizer::Unfold(Double_t eps, Int_t layer, const Double_t *const padSignal) const
3fe61b77 1120{
1121 //
1122 // Method to unfold neighbouring maxima.
1123 // The charge ratio on the overlapping pad is calculated
1124 // until there is no more change within the range given by eps.
1125 // The resulting ratio is then returned to the calling method.
1126 //
1127
1128 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
6d50f529 1129 if (!calibration) {
3fe61b77 1130 AliError("No AliTRDcalibDB instance available\n");
1131 return kFALSE;
6d50f529 1132 }
3fe61b77 1133
1134 Int_t irc = 0;
1135 Int_t itStep = 0; // Count iteration steps
1136
1137 Double_t ratio = 0.5; // Start value for ratio
1138 Double_t prevRatio = 0.0; // Store previous ratio
1139
1140 Double_t newLeftSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store left cluster signal
1141 Double_t newRightSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store right cluster signal
1142 Double_t newSignal[3] = { 0.0, 0.0, 0.0 };
1143
1144 // Start the iteration
1145 while ((TMath::Abs(prevRatio - ratio) > eps) && (itStep < 10)) {
1146
1147 itStep++;
1148 prevRatio = ratio;
1149
1150 // Cluster position according to charge ratio
1151 Double_t maxLeft = (ratio*padSignal[2] - padSignal[0])
064d808d 1152 / (padSignal[0] + padSignal[1] + ratio * padSignal[2]);
3fe61b77 1153 Double_t maxRight = (padSignal[4] - (1-ratio)*padSignal[2])
1154 / ((1.0 - ratio)*padSignal[2] + padSignal[3] + padSignal[4]);
1155
1156 // Set cluster charge ratio
064d808d 1157 irc = calibration->PadResponse(1.0, maxLeft, layer, newSignal);
3fe61b77 1158 Double_t ampLeft = padSignal[1] / newSignal[1];
064d808d 1159 irc = calibration->PadResponse(1.0, maxRight, layer, newSignal);
3fe61b77 1160 Double_t ampRight = padSignal[3] / newSignal[1];
1161
1162 // Apply pad response to parameters
053767a4 1163 irc = calibration->PadResponse(ampLeft ,maxLeft ,layer,newLeftSignal );
1164 irc = calibration->PadResponse(ampRight,maxRight,layer,newRightSignal);
3fe61b77 1165
1166 // Calculate new overlapping ratio
1167 ratio = TMath::Min((Double_t) 1.0
1168 ,newLeftSignal[2] / (newLeftSignal[2] + newRightSignal[0]));
1169
b43a3e17 1170 }
88719a08 1171
3fe61b77 1172 return ratio;
1173
1174}
88719a08 1175
3fe61b77 1176//_____________________________________________________________________________
064d808d 1177void AliTRDclusterizer::TailCancelation()
3fe61b77 1178{
1179 //
1180 // Applies the tail cancelation and gain factors:
1b3a719f 1181 // Transform fDigits to fDigits
3fe61b77 1182 //
1183
1184 Int_t iRow = 0;
1185 Int_t iCol = 0;
1186 Int_t iTime = 0;
1187
1b3a719f 1188 Double_t *inADC = new Double_t[fTimeTotal]; // ADC data before tail cancellation
064d808d 1189 Double_t *outADC = new Double_t[fTimeTotal]; // ADC data after tail cancellation
1b3a719f 1190
064d808d 1191 fIndexes->ResetCounters();
29f95561 1192 TTreeSRedirector *fDebugStream = fReconstructor->GetDebugStream(AliTRDReconstructor::kClusterizer);
064d808d 1193 while(fIndexes->NextRCIndex(iRow, iCol))
3fe61b77 1194 {
064d808d 1195 Float_t fCalGainFactorROCValue = fCalGainFactorROC->GetValue(iCol,iRow);
1196 Double_t gain = fCalGainFactorDetValue
1197 * fCalGainFactorROCValue;
3fe61b77 1198
f5375dcb 1199 Bool_t corrupted = kFALSE;
064d808d 1200 for (iTime = 0; iTime < fTimeTotal; iTime++)
b65e5048 1201 {
1202 // Apply gain gain factor
1b3a719f 1203 inADC[iTime] = fDigits->GetData(iRow,iCol,iTime);
1204 if (fCalPadStatusROC->GetStatus(iCol, iRow)) corrupted = kTRUE;
b65e5048 1205 inADC[iTime] /= gain;
1206 outADC[iTime] = inADC[iTime];
29f95561 1207 if(fReconstructor->GetStreamLevel(AliTRDReconstructor::kClusterizer) > 7){
1208 (*fDebugStream) << "TailCancellation"
1209 << "col=" << iCol
1210 << "row=" << iRow
1211 << "time=" << iTime
1212 << "inADC=" << inADC[iTime]
1213 << "gain=" << gain
1214 << "outADC=" << outADC[iTime]
1215 << "corrupted=" << corrupted
1216 << "\n";
1217 }
b65e5048 1218 }
1219 if (!corrupted)
1220 {
1221 // Apply the tail cancelation via the digital filter
1222 // (only for non-coorupted pads)
1b3a719f 1223 DeConvExp(&inADC[0],&outADC[0],fTimeTotal,fReconstructor->GetRecoParam() ->GetTCnexp());
b65e5048 1224 }
3fe61b77 1225
064d808d 1226 for(iTime = 0; iTime < fTimeTotal; iTime++)//while (fIndexes->NextTbinIndex(iTime))
b65e5048 1227 {
1228 // Store the amplitude of the digit if above threshold
6b0d4ad5 1229 if (outADC[iTime] > 0)
1b3a719f 1230 fDigits->SetData(iRow,iCol,iTime,TMath::Nint(outADC[iTime]));
1231 else
1232 fDigits->SetData(iRow,iCol,iTime,0);
b65e5048 1233 } // while itime
3fe61b77 1234
1235 } // while irow icol
1b3a719f 1236
3fe61b77 1237 delete [] inADC;
1238 delete [] outADC;
1239
1240 return;
1241
1242}
1243
1244//_____________________________________________________________________________
064d808d 1245void AliTRDclusterizer::DeConvExp(const Double_t *const source, Double_t *const target
1246 ,const Int_t n, const Int_t nexp)
3fe61b77 1247{
1248 //
1249 // Tail cancellation by deconvolution for PASA v4 TRF
1250 //
1251
1252 Double_t rates[2];
1253 Double_t coefficients[2];
1254
1255 // Initialization (coefficient = alpha, rates = lambda)
1256 Double_t r1 = 1.0;
1257 Double_t r2 = 1.0;
1258 Double_t c1 = 0.5;
1259 Double_t c2 = 0.5;
1260
1261 if (nexp == 1) { // 1 Exponentials
1262 r1 = 1.156;
1263 r2 = 0.130;
1264 c1 = 0.066;
1265 c2 = 0.000;
1266 }
1267 if (nexp == 2) { // 2 Exponentials
181c7f7e 1268 Double_t par[4];
1269 fReconstructor->GetTCParams(par);
1270 r1 = par[0];//1.156;
1271 r2 = par[1];//0.130;
1272 c1 = par[2];//0.114;
1273 c2 = par[3];//0.624;
3fe61b77 1274 }
1275
1276 coefficients[0] = c1;
1277 coefficients[1] = c2;
1278
1279 Double_t dt = 0.1;
1280
1281 rates[0] = TMath::Exp(-dt/(r1));
1282 rates[1] = TMath::Exp(-dt/(r2));
1283
1284 Int_t i = 0;
1285 Int_t k = 0;
1286
1287 Double_t reminder[2];
1288 Double_t correction = 0.0;
1289 Double_t result = 0.0;
1290
1291 // Attention: computation order is important
1292 for (k = 0; k < nexp; k++) {
1293 reminder[k] = 0.0;
1294 }
1295
1296 for (i = 0; i < n; i++) {
1297
1298 result = (source[i] - correction); // No rescaling
1299 target[i] = result;
1300
1301 for (k = 0; k < nexp; k++) {
1302 reminder[k] = rates[k] * (reminder[k] + coefficients[k] * result);
1303 }
1304
1305 correction = 0.0;
1306 for (k = 0; k < nexp; k++) {
1307 correction += reminder[k];
1308 }
1309
1310 }
6d50f529 1311
1312}
1313
1314//_____________________________________________________________________________
1315void AliTRDclusterizer::ResetRecPoints()
1316{
1317 //
1318 // Resets the list of rec points
1319 //
1320
1321 if (fRecPoints) {
1322 fRecPoints->Delete();
48f8adf3 1323 delete fRecPoints;
6d50f529 1324 }
6d50f529 1325}
1326
1327//_____________________________________________________________________________
66f6bfd9 1328TClonesArray *AliTRDclusterizer::RecPoints()
6d50f529 1329{
1330 //
1331 // Returns the list of rec points
1332 //
1333
1334 if (!fRecPoints) {
48f8adf3 1335 if(!(fRecPoints = AliTRDReconstructor::GetClusters())){
8ae98148 1336 // determine number of clusters which has to be allocated
1337 Float_t nclusters = fReconstructor->GetRecoParam()->GetNClusters();
8ae98148 1338
1339 fRecPoints = new TClonesArray("AliTRDcluster", Int_t(nclusters));
48f8adf3 1340 }
1341 //SetClustersOwner(kTRUE);
1342 AliTRDReconstructor::SetClusters(0x0);
6d50f529 1343 }
6d50f529 1344 return fRecPoints;
eb52b657 1345
3551db50 1346}
fc546d21 1347
a5b99acd 1348//_____________________________________________________________________________
1349TClonesArray *AliTRDclusterizer::TrackletsArray()
1350{
1351 //
1352 // Returns the list of rec points
1353 //
1354
1355 if (!fTracklets && fReconstructor->IsProcessingTracklets()) {
94ac01ef 1356 fTracklets = new TClonesArray("AliTRDcluster", 2*MAXTRACKLETSPERHC);
a5b99acd 1357 //SetClustersOwner(kTRUE);
1358 //AliTRDReconstructor::SetTracklets(0x0);
1359 }
1360 return fTracklets;
1361
1362}
1363