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