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