]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDclusterizer.cxx
Obsolete functions of AliESDEvent removed from FillESD()
[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//_____________________________________________________________________________
0ab5ff49 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();
839f6b9b 456 ioArray->Clear();
66f6bfd9 457 } else {
839f6b9b 458 Int_t detOld = -1, nw(0);
66f6bfd9 459 for (Int_t i = 0; i < nRecPoints; i++) {
460 AliTRDcluster *c = (AliTRDcluster *) RecPoints()->UncheckedAt(i);
461 if(c->GetDetector() != detOld){
839f6b9b 462 nw += ioArray->GetEntriesFast();
66f6bfd9 463 fClusterTree->Fill();
464 ioArray->Clear();
465 detOld = c->GetDetector();
466 }
467 ioArray->AddLast(c);
a6dd11e9 468 }
839f6b9b 469 if(ioArray->GetEntriesFast()){
470 nw += ioArray->GetEntriesFast();
471 fClusterTree->Fill();
472 ioArray->Clear();
473 }
474 AliDebug(2, Form("Clusters FOUND[%d] WRITTEN[%d] STATUS[%s]", nRecPoints, nw, nw==nRecPoints?"OK":"FAILED"));
793ff80c 475 }
66f6bfd9 476 delete ioArray;
6d50f529 477
66f6bfd9 478 return kTRUE;
f7336fa3 479}
793ff80c 480
9c7c9ec1 481//_____________________________________________________________________________
482Bool_t AliTRDclusterizer::WriteTracklets(Int_t det)
483{
eb52b657 484 //
485 // Write the raw data tracklets into seperate file
486 //
9c7c9ec1 487
488 UInt_t **leaves = new UInt_t *[2];
489 for (Int_t i=0; i<2 ;i++){
317b5644 490 leaves[i] = new UInt_t[258];
491 leaves[i][0] = det; // det
492 leaves[i][1] = i; // side
493 memcpy(leaves[i]+2, fTrackletContainer[i], sizeof(UInt_t) * 256);
9c7c9ec1 494 }
495
9c7c9ec1 496 if (!fTrackletTree){
497 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
498 dl->MakeTree();
499 fTrackletTree = dl->Tree();
500 }
501
502 TBranch *trkbranch = fTrackletTree->GetBranch("trkbranch");
503 if (!trkbranch) {
504 trkbranch = fTrackletTree->Branch("trkbranch",leaves[0],"det/i:side/i:tracklets[256]/i");
505 }
506
507 for (Int_t i=0; i<2; i++){
317b5644 508 if (leaves[i][2]>0) {
509 trkbranch->SetAddress(leaves[i]);
510 fTrackletTree->Fill();
511 }
9c7c9ec1 512 }
513
514 AliDataLoader *dl = fRunLoader->GetLoader("TRDLoader")->GetDataLoader("tracklets");
515 dl->WriteData("OVERWRITE");
516 //dl->Unload();
517 delete [] leaves;
518
eb52b657 519 return kTRUE;
520
9c7c9ec1 521}
522
3fe61b77 523//_____________________________________________________________________________
524Bool_t AliTRDclusterizer::ReadDigits()
525{
526 //
527 // Reads the digits arrays from the input aliroot file
528 //
529
530 if (!fRunLoader) {
531 AliError("No run loader available");
532 return kFALSE;
533 }
534
535 AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
536 if (!loader->TreeD()) {
537 loader->LoadDigits();
538 }
539
540 // Read in the digit arrays
541 return (fDigitsManager->ReadDigits(loader->TreeD()));
542
543}
544
545//_____________________________________________________________________________
546Bool_t AliTRDclusterizer::ReadDigits(TTree *digitsTree)
547{
548 //
549 // Reads the digits arrays from the input tree
550 //
551
552 // Read in the digit arrays
553 return (fDigitsManager->ReadDigits(digitsTree));
554
555}
556
557//_____________________________________________________________________________
558Bool_t AliTRDclusterizer::ReadDigits(AliRawReader *rawReader)
559{
560 //
561 // Reads the digits arrays from the ddl file
562 //
563
564 AliTRDrawData raw;
565 fDigitsManager = raw.Raw2Digits(rawReader);
566
567 return kTRUE;
568
569}
570
571//_____________________________________________________________________________
572Bool_t AliTRDclusterizer::MakeClusters()
573{
574 //
575 // Creates clusters from digits
576 //
577
578 // Propagate info from the digits manager
b72f4eaf 579 if (TestBit(kLabels)){
580 SetBit(kLabels, fDigitsManager->UsesDictionaries());
66f6bfd9 581 }
582
3fe61b77 583 Bool_t fReturn = kTRUE;
66f6bfd9 584 for (Int_t i = 0; i < AliTRDgeometry::kNdet; i++){
585
b65e5048 586 AliTRDarrayADC *digitsIn = (AliTRDarrayADC*) fDigitsManager->GetDigits(i); //mod
66f6bfd9 587 // This is to take care of switched off super modules
588 if (!digitsIn->HasData()) continue;
589 digitsIn->Expand();
0d64b05f 590 digitsIn->DeleteNegatives(); // Restore digits array to >=0 values
66f6bfd9 591 AliTRDSignalIndex* indexes = fDigitsManager->GetIndexes(i);
592 if (indexes->IsAllocated() == kFALSE){
593 fDigitsManager->BuildIndexes(i);
594 }
595
596 Bool_t fR = kFALSE;
597 if (indexes->HasEntry()){
b72f4eaf 598 if (TestBit(kLabels)){
66f6bfd9 599 for (Int_t iDict = 0; iDict < AliTRDdigitsManager::kNDict; iDict++){
b65e5048 600 AliTRDarrayDictionary *tracksIn = 0; //mod
601 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(i,iDict); //mod
66f6bfd9 602 tracksIn->Expand();
3fe61b77 603 }
66f6bfd9 604 }
605 fR = MakeClusters(i);
606 fReturn = fR && fReturn;
3fe61b77 607 }
66f6bfd9 608
609 //if (fR == kFALSE){
610 // if(IsWritingClusters()) WriteClusters(i);
611 // ResetRecPoints();
612 //}
613
5127281e 614 // Clear arrays of this chamber, to prepare for next event
615 fDigitsManager->ClearArrays(i);
66f6bfd9 616 }
617
618 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
3fe61b77 619
66f6bfd9 620 AliInfo(Form("Number of found clusters : %d", RecPoints()->GetEntriesFast()));
3fe61b77 621
66f6bfd9 622 return fReturn;
eb52b657 623
3fe61b77 624}
625
626//_____________________________________________________________________________
627Bool_t AliTRDclusterizer::Raw2Clusters(AliRawReader *rawReader)
628{
629 //
630 // Creates clusters from raw data
631 //
632
fc546d21 633 return Raw2ClustersChamber(rawReader);
3fe61b77 634
3fe61b77 635}
636
637//_____________________________________________________________________________
638Bool_t AliTRDclusterizer::Raw2ClustersChamber(AliRawReader *rawReader)
639{
640 //
641 // Creates clusters from raw data
642 //
643
644 // Create the digits manager
66f6bfd9 645 if (!fDigitsManager){
8cbe253a 646 SetBit(knewDM, kTRUE);
3d0c7d6d 647 fDigitsManager = new AliTRDdigitsManager(kTRUE);
66f6bfd9 648 fDigitsManager->CreateArrays();
649 }
3fe61b77 650
b72f4eaf 651 fDigitsManager->SetUseDictionaries(TestBit(kLabels));
3fe61b77 652
317b5644 653 // tracklet container for raw tracklet writing
a5b99acd 654 if (!fTrackletContainer && ( fReconstructor->IsWritingTracklets() || fReconstructor->IsProcessingTracklets() )) {
317b5644 655 // maximum tracklets for one HC
656 const Int_t kTrackletChmb=256;
657 fTrackletContainer = new UInt_t *[2];
658 fTrackletContainer[0] = new UInt_t[kTrackletChmb];
659 fTrackletContainer[1] = new UInt_t[kTrackletChmb];
660 }
661
8dbc94c7 662 if(!fRawStream)
663 fRawStream = AliTRDrawStreamBase::GetRawStream(rawReader);
664 else
665 fRawStream->SetReader(rawReader);
666
c6f7c6cb 667 SetBit(kHLT, fReconstructor->IsHLT());
668
669 if(TestBit(kHLT)){
8dbc94c7 670 fRawStream->SetSharedPadReadout(kFALSE);
17e0e535 671 fRawStream->SetNoErrorWarning();
672 }
3fe61b77 673
17e0e535 674 AliDebug(1,Form("Stream version: %s", fRawStream->IsA()->GetName()));
3fe61b77 675
676 Int_t det = 0;
8dbc94c7 677 while ((det = fRawStream->NextChamber(fDigitsManager,fTrackletContainer)) >= 0){
c6f7c6cb 678 if (fDigitsManager->GetIndexes(det)->HasEntry())
679 MakeClusters(det);
66f6bfd9 680
66f68968 681 fDigitsManager->ClearArrays(det);
682
317b5644 683 if (!fReconstructor->IsWritingTracklets()) continue;
684 if (*(fTrackletContainer[0]) > 0 || *(fTrackletContainer[1]) > 0) WriteTracklets(det);
9c7c9ec1 685 }
486c2339 686
a5b99acd 687 if (fTrackletContainer){
317b5644 688 delete [] fTrackletContainer[0];
689 delete [] fTrackletContainer[1];
690 delete [] fTrackletContainer;
691 fTrackletContainer = NULL;
692 }
693
66f6bfd9 694 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
3fe61b77 695
8cbe253a 696 if(!TestBit(knewDM)){
697 delete fDigitsManager;
698 fDigitsManager = NULL;
ad808511 699 delete fRawStream;
700 fRawStream = NULL;
8cbe253a 701 }
dfbb4bb9 702
3d0c7d6d 703 AliInfo(Form("Number of found clusters : %d", fNoOfClusters));
66f6bfd9 704 return kTRUE;
eb52b657 705
3fe61b77 706}
707
fa7427d0 708//_____________________________________________________________________________
709UChar_t AliTRDclusterizer::GetStatus(Short_t &signal)
710{
023b669c 711 //
712 // Check if a pad is masked
713 //
714
317b5644 715 UChar_t status = 0;
716
717 if(signal>0 && TESTBIT(signal, 10)){
718 CLRBIT(signal, 10);
719 for(int ibit=0; ibit<4; ibit++){
720 if(TESTBIT(signal, 11+ibit)){
721 SETBIT(status, ibit);
722 CLRBIT(signal, 11+ibit);
723 }
724 }
725 }
726 return status;
fa7427d0 727}
728
6d9e79cc 729//_____________________________________________________________________________
e7295a3a 730void AliTRDclusterizer::SetPadStatus(const UChar_t status, UChar_t &out) const {
6d9e79cc 731 //
732 // Set the pad status into out
733 // First three bits are needed for the position encoding
734 //
064d808d 735 out |= status << 3;
6d9e79cc 736}
737
738//_____________________________________________________________________________
064d808d 739UChar_t AliTRDclusterizer::GetPadStatus(UChar_t encoding) const {
6d9e79cc 740 //
741 // return the staus encoding of the corrupted pad
742 //
743 return static_cast<UChar_t>(encoding >> 3);
744}
745
746//_____________________________________________________________________________
064d808d 747Int_t AliTRDclusterizer::GetCorruption(UChar_t encoding) const {
6d9e79cc 748 //
749 // Return the position of the corruption
750 //
751 return encoding & 7;
752}
753
3fe61b77 754//_____________________________________________________________________________
755Bool_t AliTRDclusterizer::MakeClusters(Int_t det)
756{
757 //
758 // Generates the cluster.
759 //
760
761 // Get the digits
615f0826 762 fDigits = (AliTRDarrayADC *) fDigitsManager->GetDigits(det); //mod
a0446ff1 763 fBaseline = fDigitsManager->GetDigitsParam()->GetADCbaseline(det);
f5375dcb 764
3fe61b77 765 // This is to take care of switched off super modules
b72f4eaf 766 if (!fDigits->HasData()) return kFALSE;
3fe61b77 767
064d808d 768 fIndexes = fDigitsManager->GetIndexes(det);
b72f4eaf 769 if (fIndexes->IsAllocated() == kFALSE) {
770 AliError("Indexes do not exist!");
771 return kFALSE;
772 }
064d808d 773
fc0882f3 774 AliTRDcalibDB* const calibration = AliTRDcalibDB::Instance();
b72f4eaf 775 if (!calibration) {
776 AliFatal("No AliTRDcalibDB instance available\n");
777 return kFALSE;
778 }
3fe61b77 779
3a039a31 780 if (!fReconstructor){
781 AliError("Reconstructor not set\n");
782 return kFALSE;
783 }
c5f589b9 784
c6f7c6cb 785 const AliTRDrecoParam *const recoParam = fReconstructor->GetRecoParam();
fc0882f3 786
787 fMaxThresh = recoParam->GetClusMaxThresh();
788 fSigThresh = recoParam->GetClusSigThresh();
789 fMinMaxCutSigma = recoParam->GetMinMaxCutSigma();
790 fMinLeftRightCutSigma = recoParam->GetMinLeftRightCutSigma();
3fe61b77 791
064d808d 792 Int_t istack = fIndexes->GetStack();
793 fLayer = fIndexes->GetLayer();
794 Int_t isector = fIndexes->GetSM();
3fe61b77 795
796 // Start clustering in the chamber
797
064d808d 798 fDet = AliTRDgeometry::GetDetector(fLayer,istack,isector);
799 if (fDet != det) {
828c6f80 800 AliError("Strange Detector number Missmatch!");
b65e5048 801 return kFALSE;
802 }
3fe61b77 803
839f6b9b 804 AliDebug(2, Form("Det[%d] @ Sec[%d] Stk[%d] Ly[%d]", fDet, isector, istack, fLayer));
805
3fe61b77 806 // TRD space point transformation
807 fTransform->SetDetector(det);
808
064d808d 809 Int_t iGeoLayer = AliGeomManager::kTRD1 + fLayer;
053767a4 810 Int_t iGeoModule = istack + AliTRDgeometry::Nstack() * isector;
064d808d 811 fVolid = AliGeomManager::LayerToVolUID(iGeoLayer,iGeoModule);
3fe61b77 812
a5b99acd 813 if(fReconstructor->IsProcessingTracklets() && fTrackletContainer)
814 AddTrackletsToArray();
815
1b3a719f 816 fColMax = fDigits->GetNcol();
8b8d2999 817 fTimeTotal = fDigitsManager->GetDigitsParam()->GetNTimeBins(det);
3fe61b77 818
69a850a0 819 // Check consistency between OCDB and raw data
4e6823c2 820 Int_t nTimeOCDB = calibration->GetNumberOfTimeBinsDCS();
c6f7c6cb 821 if(TestBit(kHLT)){
822 if((nTimeOCDB > -1) && (fTimeTotal != nTimeOCDB)){
823 AliWarning(Form("Number of timebins does not match OCDB value (RAW[%d] OCDB[%d]), using raw value"
824 ,fTimeTotal,nTimeOCDB));
825 }
826 }else{
827 if(nTimeOCDB == -1){
828 AliWarning("Undefined number of timebins in OCDB, using value from raw data.");
829 if(!fTimeTotal>0){
830 AliError("Number of timebins in raw data is negative, skipping chamber!");
831 return kFALSE;
832 }
833 }else if(nTimeOCDB == -2){
834 AliError("Mixed number of timebins in OCDB, no reconstruction of TRD data!");
835 return kFALSE;
836 }else if(fTimeTotal != nTimeOCDB){
837 AliError(Form("Number of timebins in raw data does not match OCDB value (RAW[%d] OCDB[%d]), skipping chamber!"
838 ,fTimeTotal,nTimeOCDB));
839 return kFALSE;
840 }
69a850a0 841 }
842
3fe61b77 843 // Detector wise calibration object for the gain factors
064d808d 844 const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
3fe61b77 845 // Calibration object with pad wise values for the gain factors
064d808d 846 fCalGainFactorROC = calibration->GetGainFactorROC(fDet);
3fe61b77 847 // Calibration value for chamber wise gain factor
064d808d 848 fCalGainFactorDetValue = calGainFactorDet->GetValue(fDet);
0e09df31 849
df83a620 850 // Detector wise calibration object for the noise
064d808d 851 const AliTRDCalDet *calNoiseDet = calibration->GetNoiseDet();
df83a620 852 // Calibration object with pad wise values for the noise
064d808d 853 fCalNoiseROC = calibration->GetNoiseROC(fDet);
df83a620 854 // Calibration value for chamber wise noise
064d808d 855 fCalNoiseDetValue = calNoiseDet->GetValue(fDet);
1b3a719f 856
857 // Calibration object with the pad status
858 fCalPadStatusROC = calibration->GetPadStatusROC(fDet);
6b0d4ad5 859
064d808d 860 firstClusterROC = -1;
861 fClusterROC = 0;
3fe61b77 862
c6f7c6cb 863 SetBit(kLUT, recoParam->UseLUT());
864 SetBit(kGAUS, recoParam->UseGAUS());
865
b72f4eaf 866 // Apply the gain and the tail cancelation via digital filter
fc0882f3 867 if(recoParam->UseTailCancelation()) TailCancelation(recoParam);
023b669c 868
486c2339 869 MaxStruct curr, last;
064d808d 870 Int_t nMaximas = 0, nCorrupted = 0;
f5375dcb 871
064d808d 872 // Here the clusterfining is happening
873
615f0826 874 for(curr.time = 0; curr.time < fTimeTotal; curr.time++){
875 while(fIndexes->NextRCIndex(curr.row, curr.col)){
876 if(IsMaximum(curr, curr.padStatus, &curr.signals[0])){
877 if(last.row>-1){
878 if(curr.time==last.time && curr.row==last.row && curr.col==last.col+2) FivePadCluster(last, curr);
b72f4eaf 879 CreateCluster(last);
880 }
615f0826 881 last=curr; curr.fivePad=kFALSE;
b72f4eaf 882 }
b72f4eaf 883 }
884 }
615f0826 885 if(last.row>-1) CreateCluster(last);
df83a620 886
fc0882f3 887 if(recoParam->GetStreamLevel(AliTRDrecoParam::kClusterizer) > 2 && fReconstructor->IsDebugStreaming()){
a2fbb6ec 888 TTreeSRedirector* fDebugStream = fReconstructor->GetDebugStream(AliTRDrecoParam::kClusterizer);
064d808d 889 (*fDebugStream) << "MakeClusters"
b72f4eaf 890 << "Detector=" << det
891 << "NMaxima=" << nMaximas
892 << "NClusters=" << fClusterROC
893 << "NCorrupted=" << nCorrupted
894 << "\n";
df83a620 895 }
b72f4eaf 896 if (TestBit(kLabels)) AddLabels();
f5375dcb 897
064d808d 898 return kTRUE;
f5375dcb 899
064d808d 900}
3fe61b77 901
064d808d 902//_____________________________________________________________________________
1b3a719f 903Bool_t AliTRDclusterizer::IsMaximum(const MaxStruct &Max, UChar_t &padStatus, Short_t *const Signals)
064d808d 904{
905 //
906 // Returns true if this row,col,time combination is a maximum.
907 // Gives back the padStatus and the signals of the center pad and the two neighbouring pads.
908 //
c96d03ba 909
615f0826 910 Float_t gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(Max.col,Max.row);
911 Signals[1] = (Short_t)((fDigits->GetData(Max.row, Max.col, Max.time) - fBaseline) / gain + 0.5f);
c96d03ba 912 if(Signals[1] < fMaxThresh) return kFALSE;
3fe61b77 913
615f0826 914 Float_t noiseMiddleThresh = fMinMaxCutSigma*fCalNoiseDetValue*fCalNoiseROC->GetValue(Max.col, Max.row);
c96d03ba 915 if (Signals[1] < noiseMiddleThresh) return kFALSE;
f5375dcb 916
615f0826 917 if (Max.col + 1 >= fColMax || Max.col < 1) return kFALSE;
3fe61b77 918
b72f4eaf 919 UChar_t status[3]={
615f0826 920 fCalPadStatusROC->GetStatus(Max.col-1, Max.row)
921 ,fCalPadStatusROC->GetStatus(Max.col, Max.row)
922 ,fCalPadStatusROC->GetStatus(Max.col+1, Max.row)
b72f4eaf 923 };
486c2339 924
615f0826 925 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(Max.col-1,Max.row);
19dd8eb9 926 Signals[0] = (Short_t)((fDigits->GetData(Max.row, Max.col-1, Max.time) - fBaseline) / gain + 0.5f);
927 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(Max.col+1,Max.row);
928 Signals[2] = (Short_t)((fDigits->GetData(Max.row, Max.col+1, Max.time) - fBaseline) / gain + 0.5f);
c96d03ba 929
486c2339 930 if(!(status[0] | status[1] | status[2])) {//all pads are good
c96d03ba 931 if ((Signals[2] <= Signals[1]) && (Signals[0] < Signals[1])) {
932 if ((Signals[2] >= fSigThresh) || (Signals[0] >= fSigThresh)) {
5a8db426 933 if(Signals[0]<0)Signals[0]=0;
934 if(Signals[2]<0)Signals[2]=0;
b72f4eaf 935 Float_t noiseSumThresh = fMinLeftRightCutSigma
936 * fCalNoiseDetValue
615f0826 937 * fCalNoiseROC->GetValue(Max.col, Max.row);
c96d03ba 938 if ((Signals[2]+Signals[0]+Signals[1]) < noiseSumThresh) return kFALSE;
b72f4eaf 939 padStatus = 0;
940 return kTRUE;
eb52b657 941 }
064d808d 942 }
b72f4eaf 943 } else { // at least one of the pads is bad, and reject candidates with more than 1 problematic pad
5a8db426 944 if(Signals[0]<0)Signals[0]=0;
945 if(Signals[2]<0)Signals[2]=0;
c96d03ba 946 if (status[2] && (!(status[0] || status[1])) && Signals[1] > Signals[0] && Signals[0] >= fSigThresh) {
947 Signals[2]=0;
486c2339 948 SetPadStatus(status[2], padStatus);
949 return kTRUE;
950 }
c96d03ba 951 else if (status[0] && (!(status[1] || status[2])) && Signals[1] >= Signals[2] && Signals[2] >= fSigThresh) {
952 Signals[0]=0;
486c2339 953 SetPadStatus(status[0], padStatus);
954 return kTRUE;
955 }
c96d03ba 956 else if (status[1] && (!(status[0] || status[2])) && ((Signals[2] >= fSigThresh) || (Signals[0] >= fSigThresh))) {
615f0826 957 Signals[1] = (Short_t)(fMaxThresh + 0.5f);
486c2339 958 SetPadStatus(status[1], padStatus);
064d808d 959 return kTRUE;
960 }
961 }
962 return kFALSE;
963}
3fe61b77 964
064d808d 965//_____________________________________________________________________________
1b3a719f 966Bool_t AliTRDclusterizer::FivePadCluster(MaxStruct &ThisMax, MaxStruct &NeighbourMax)
064d808d 967{
968 //
969 // Look for 5 pad cluster with minimum in the middle
970 // Gives back the ratio
971 //
615f0826 972
973 if (ThisMax.col >= fColMax - 3) return kFALSE;
974 Float_t gain;
975 if (ThisMax.col < fColMax - 5){
976 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(ThisMax.col+4,ThisMax.row);
977 if (fDigits->GetData(ThisMax.row, ThisMax.col+4, ThisMax.time) - fBaseline >= fSigThresh * gain)
486c2339 978 return kFALSE;
064d808d 979 }
615f0826 980 if (ThisMax.col > 1) {
981 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(ThisMax.col-2,ThisMax.row);
982 if (fDigits->GetData(ThisMax.row, ThisMax.col-2, ThisMax.time) - fBaseline >= fSigThresh * gain)
486c2339 983 return kFALSE;
984 }
985
486c2339 986 const Float_t kEpsilon = 0.01;
615f0826 987 Double_t padSignal[5] = {ThisMax.signals[0], ThisMax.signals[1], ThisMax.signals[2],
988 NeighbourMax.signals[1], NeighbourMax.signals[2]};
486c2339 989
990 // Unfold the two maxima and set the signal on
991 // the overlapping pad to the ratio
1b3a719f 992 Float_t ratio = Unfold(kEpsilon,fLayer,padSignal);
615f0826 993 ThisMax.signals[2] = (Short_t)(ThisMax.signals[2]*ratio + 0.5f);
994 NeighbourMax.signals[0] = (Short_t)(NeighbourMax.signals[0]*(1-ratio) + 0.5f);
995 ThisMax.fivePad=kTRUE;
996 NeighbourMax.fivePad=kTRUE;
486c2339 997 return kTRUE;
c96d03ba 998
064d808d 999}
eb52b657 1000
064d808d 1001//_____________________________________________________________________________
486c2339 1002void AliTRDclusterizer::CreateCluster(const MaxStruct &Max)
064d808d 1003{
1004 //
3d0c7d6d 1005 // Creates a cluster at the given position and saves it in fRecPoints
064d808d 1006 //
eb52b657 1007
c96d03ba 1008 Int_t nPadCount = 1;
615f0826 1009 Short_t signals[7] = { 0, 0, Max.signals[0], Max.signals[1], Max.signals[2], 0, 0 };
c96d03ba 1010 if(!TestBit(kHLT)) CalcAdditionalInfo(Max, signals, nPadCount);
1011
615f0826 1012 AliTRDcluster cluster(fDet, ((UChar_t) Max.col), ((UChar_t) Max.row), ((UChar_t) Max.time), signals, fVolid);
c96d03ba 1013 cluster.SetNPads(nPadCount);
b72f4eaf 1014 if(TestBit(kLUT)) cluster.SetRPhiMethod(AliTRDcluster::kLUT);
1015 else if(TestBit(kGAUS)) cluster.SetRPhiMethod(AliTRDcluster::kGAUS);
1016 else cluster.SetRPhiMethod(AliTRDcluster::kCOG);
3fe61b77 1017
615f0826 1018 cluster.SetFivePad(Max.fivePad);
b72f4eaf 1019 // set pads status for the cluster
1020 UChar_t maskPosition = GetCorruption(Max.padStatus);
1021 if (maskPosition) {
1022 cluster.SetPadMaskedPosition(maskPosition);
1023 cluster.SetPadMaskedStatus(GetPadStatus(Max.padStatus));
1024 }
064d808d 1025
1026 // Transform the local cluster coordinates into calibrated
1027 // space point positions defined in the local tracking system.
1028 // Here the calibration for T0, Vdrift and ExB is applied as well.
b72f4eaf 1029 if(!fTransform->Transform(&cluster)) return;
1030 // Temporarily store the Max.Row, column and time bin of the center pad
1031 // Used to later on assign the track indices
615f0826 1032 cluster.SetLabel(Max.row, 0);
1033 cluster.SetLabel(Max.col, 1);
1034 cluster.SetLabel(Max.time,2);
c96d03ba 1035
b72f4eaf 1036 //needed for HLT reconstruction
1037 AddClusterToArray(&cluster);
1038
1039 // Store the index of the first cluster in the current ROC
1040 if (firstClusterROC < 0) firstClusterROC = fNoOfClusters;
1041
1042 fNoOfClusters++;
1043 fClusterROC++;
3fe61b77 1044}
1045
3d0c7d6d 1046//_____________________________________________________________________________
1047void AliTRDclusterizer::CalcAdditionalInfo(const MaxStruct &Max, Short_t *const signals, Int_t &nPadCount)
1048{
1049 // Look to the right
1050 Int_t ii = 1;
615f0826 1051 while (fDigits->GetData(Max.row, Max.col-ii, Max.time) >= fSigThresh) {
3d0c7d6d 1052 nPadCount++;
1053 ii++;
615f0826 1054 if (Max.col < ii) break;
3d0c7d6d 1055 }
1056 // Look to the left
1057 ii = 1;
615f0826 1058 while (fDigits->GetData(Max.row, Max.col+ii, Max.time) >= fSigThresh) {
3d0c7d6d 1059 nPadCount++;
1060 ii++;
615f0826 1061 if (Max.col+ii >= fColMax) break;
3d0c7d6d 1062 }
1063
1064 // Store the amplitudes of the pads in the cluster for later analysis
1065 // and check whether one of these pads is masked in the database
615f0826 1066 signals[2]=Max.signals[0];
1067 signals[3]=Max.signals[1];
1068 signals[4]=Max.signals[2];
1069 Float_t gain;
3d0c7d6d 1070 for(Int_t i = 0; i<2; i++)
1071 {
615f0826 1072 if(Max.col+i >= 3){
1073 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(Max.col-3+i,Max.row);
1074 signals[i] = (Short_t)((fDigits->GetData(Max.row, Max.col-3+i, Max.time) - fBaseline) / gain + 0.5f);
1075 }
1076 if(Max.col+3-i < fColMax){
1077 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(Max.col+3-i,Max.row);
1078 signals[6-i] = (Short_t)((fDigits->GetData(Max.row, Max.col+3-i, Max.time) - fBaseline) / gain + 0.5f);
1079 }
3d0c7d6d 1080 }
1081 /*for (Int_t jPad = Max.Col-3; jPad <= Max.Col+3; jPad++) {
1082 if ((jPad >= 0) && (jPad < fColMax))
1083 signals[jPad-Max.Col+3] = TMath::Nint(fDigits->GetData(Max.Row,jPad,Max.Time));
1084 }*/
1085}
1086
1087//_____________________________________________________________________________
e7295a3a 1088void AliTRDclusterizer::AddClusterToArray(AliTRDcluster* cluster)
3d0c7d6d 1089{
1090 //
1091 // Add a cluster to the array
1092 //
1093
1094 Int_t n = RecPoints()->GetEntriesFast();
1095 if(n!=fNoOfClusters)AliError(Form("fNoOfClusters != RecPoints()->GetEntriesFast %i != %i \n", fNoOfClusters, n));
1096 new((*RecPoints())[n]) AliTRDcluster(*cluster);
1097}
1098
a5b99acd 1099//_____________________________________________________________________________
1100void AliTRDclusterizer::AddTrackletsToArray()
1101{
1102 //
1103 // Add the online tracklets of this chamber to the array
1104 //
1105
1106 UInt_t* trackletword;
1107 for(Int_t side=0; side<2; side++)
1108 {
1109 Int_t trkl=0;
1110 trackletword=fTrackletContainer[side];
97be9934 1111 while(trackletword[trkl]>0){
a5b99acd 1112 Int_t n = TrackletsArray()->GetEntriesFast();
35943b1e 1113 AliTRDtrackletWord tmp(trackletword[trkl]);
1114 new((*TrackletsArray())[n]) AliTRDcluster(&tmp,fDet,fVolid);
a5b99acd 1115 trkl++;
97be9934 1116 }
a5b99acd 1117 }
1118}
1119
3fe61b77 1120//_____________________________________________________________________________
6cd9a21f 1121Bool_t AliTRDclusterizer::AddLabels()
3551db50 1122{
1123 //
3fe61b77 1124 // Add the track indices to the found clusters
3551db50 1125 //
1126
3fe61b77 1127 const Int_t kNclus = 3;
1128 const Int_t kNdict = AliTRDdigitsManager::kNDict;
1129 const Int_t kNtrack = kNdict * kNclus;
1130
1131 Int_t iClusterROC = 0;
1132
1133 Int_t row = 0;
1134 Int_t col = 0;
1135 Int_t time = 0;
1136 Int_t iPad = 0;
1137
1138 // Temporary array to collect the track indices
6cd9a21f 1139 Int_t *idxTracks = new Int_t[kNtrack*fClusterROC];
3fe61b77 1140
1141 // Loop through the dictionary arrays one-by-one
1142 // to keep memory consumption low
b65e5048 1143 AliTRDarrayDictionary *tracksIn = 0; //mod
3fe61b77 1144 for (Int_t iDict = 0; iDict < kNdict; iDict++) {
1145
1146 // tracksIn should be expanded beforehand!
6cd9a21f 1147 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(fDet,iDict);
3fe61b77 1148
1149 // Loop though the clusters found in this ROC
6cd9a21f 1150 for (iClusterROC = 0; iClusterROC < fClusterROC; iClusterROC++) {
317b5644 1151
3fe61b77 1152 AliTRDcluster *cluster = (AliTRDcluster *)
b65e5048 1153 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
3fe61b77 1154 row = cluster->GetLabel(0);
1155 col = cluster->GetLabel(1);
1156 time = cluster->GetLabel(2);
1157
1158 for (iPad = 0; iPad < kNclus; iPad++) {
b65e5048 1159 Int_t iPadCol = col - 1 + iPad;
1160 Int_t index = tracksIn->GetData(row,iPadCol,time); //Modification of -1 in Track
1161 idxTracks[3*iPad+iDict + iClusterROC*kNtrack] = index;
3fe61b77 1162 }
1163
1164 }
1165
1166 }
1167
1168 // Copy the track indices into the cluster
1169 // Loop though the clusters found in this ROC
6cd9a21f 1170 for (iClusterROC = 0; iClusterROC < fClusterROC; iClusterROC++) {
317b5644 1171
3fe61b77 1172 AliTRDcluster *cluster = (AliTRDcluster *)
1173 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
1174 cluster->SetLabel(-9999,0);
1175 cluster->SetLabel(-9999,1);
1176 cluster->SetLabel(-9999,2);
1177
1178 cluster->AddTrackIndex(&idxTracks[iClusterROC*kNtrack]);
1179
1180 }
1181
1182 delete [] idxTracks;
1183
1184 return kTRUE;
1185
1186}
1187
3fe61b77 1188//_____________________________________________________________________________
e7295a3a 1189Float_t AliTRDclusterizer::Unfold(Double_t eps, Int_t layer, const Double_t *const padSignal) const
3fe61b77 1190{
1191 //
1192 // Method to unfold neighbouring maxima.
1193 // The charge ratio on the overlapping pad is calculated
1194 // until there is no more change within the range given by eps.
1195 // The resulting ratio is then returned to the calling method.
1196 //
1197
1198 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
6d50f529 1199 if (!calibration) {
3fe61b77 1200 AliError("No AliTRDcalibDB instance available\n");
1201 return kFALSE;
6d50f529 1202 }
3fe61b77 1203
1204 Int_t irc = 0;
1205 Int_t itStep = 0; // Count iteration steps
1206
1207 Double_t ratio = 0.5; // Start value for ratio
1208 Double_t prevRatio = 0.0; // Store previous ratio
1209
1210 Double_t newLeftSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store left cluster signal
1211 Double_t newRightSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store right cluster signal
1212 Double_t newSignal[3] = { 0.0, 0.0, 0.0 };
1213
1214 // Start the iteration
1215 while ((TMath::Abs(prevRatio - ratio) > eps) && (itStep < 10)) {
1216
1217 itStep++;
1218 prevRatio = ratio;
1219
1220 // Cluster position according to charge ratio
1221 Double_t maxLeft = (ratio*padSignal[2] - padSignal[0])
064d808d 1222 / (padSignal[0] + padSignal[1] + ratio * padSignal[2]);
3fe61b77 1223 Double_t maxRight = (padSignal[4] - (1-ratio)*padSignal[2])
1224 / ((1.0 - ratio)*padSignal[2] + padSignal[3] + padSignal[4]);
1225
1226 // Set cluster charge ratio
064d808d 1227 irc = calibration->PadResponse(1.0, maxLeft, layer, newSignal);
3fe61b77 1228 Double_t ampLeft = padSignal[1] / newSignal[1];
064d808d 1229 irc = calibration->PadResponse(1.0, maxRight, layer, newSignal);
3fe61b77 1230 Double_t ampRight = padSignal[3] / newSignal[1];
1231
1232 // Apply pad response to parameters
053767a4 1233 irc = calibration->PadResponse(ampLeft ,maxLeft ,layer,newLeftSignal );
1234 irc = calibration->PadResponse(ampRight,maxRight,layer,newRightSignal);
3fe61b77 1235
1236 // Calculate new overlapping ratio
1237 ratio = TMath::Min((Double_t) 1.0
1238 ,newLeftSignal[2] / (newLeftSignal[2] + newRightSignal[0]));
1239
b43a3e17 1240 }
88719a08 1241
3fe61b77 1242 return ratio;
1243
1244}
88719a08 1245
3fe61b77 1246//_____________________________________________________________________________
fc0882f3 1247void AliTRDclusterizer::TailCancelation(const AliTRDrecoParam* const recoParam)
3fe61b77 1248{
1249 //
fc0882f3 1250 // Applies the tail cancelation
3fe61b77 1251 //
1252
1253 Int_t iRow = 0;
1254 Int_t iCol = 0;
1255 Int_t iTime = 0;
1256
664030bc 1257 Float_t *arr = new Float_t[fTimeTotal]; // temp array containing the ADC signals
1b3a719f 1258
a2fbb6ec 1259 TTreeSRedirector *fDebugStream = fReconstructor->GetDebugStream(AliTRDrecoParam::kClusterizer);
fc0882f3 1260 Bool_t debugStreaming = recoParam->GetStreamLevel(AliTRDrecoParam::kClusterizer) > 7 && fReconstructor->IsDebugStreaming();
1261 Int_t nexp = recoParam->GetTCnexp();
064d808d 1262 while(fIndexes->NextRCIndex(iRow, iCol))
3fe61b77 1263 {
664030bc 1264 // if corrupted then don't make the tail cancallation
1265 if (fCalPadStatusROC->GetStatus(iCol, iRow)) continue;
5a8db426 1266
cb5522da 1267 // Save data into the temporary processing array and substract the baseline,
1268 // since DeConvExp does not expect a baseline
064d808d 1269 for (iTime = 0; iTime < fTimeTotal; iTime++)
664030bc 1270 arr[iTime] = fDigits->GetData(iRow,iCol,iTime)-fBaseline;
5a8db426 1271
cb5522da 1272 if(debugStreaming){
1273 for (iTime = 0; iTime < fTimeTotal; iTime++)
5a8db426 1274 (*fDebugStream) << "TailCancellation"
1275 << "col=" << iCol
1276 << "row=" << iRow
1277 << "time=" << iTime
664030bc 1278 << "arr=" << arr[iTime]
5a8db426 1279 << "\n";
cb5522da 1280 }
5a8db426 1281
664030bc 1282 // Apply the tail cancelation via the digital filter
1283 DeConvExp(arr,fTimeTotal,nexp);
3fe61b77 1284
cb5522da 1285 // Save tailcancalled data and add the baseline
5a8db426 1286 for(iTime = 0; iTime < fTimeTotal; iTime++)
664030bc 1287 fDigits->SetData(iRow,iCol,iTime,(Short_t)(arr[iTime] + fBaseline + 0.5f));
5a8db426 1288
3fe61b77 1289 } // while irow icol
1b3a719f 1290
664030bc 1291 delete [] arr;
3fe61b77 1292
1293 return;
1294
1295}
1296
1297//_____________________________________________________________________________
fc0882f3 1298void AliTRDclusterizer::DeConvExp(Float_t *const arr, const Int_t nTime, const Int_t nexp)
3fe61b77 1299{
1300 //
1301 // Tail cancellation by deconvolution for PASA v4 TRF
1302 //
1303
664030bc 1304 Float_t rates[2];
1305 Float_t coefficients[2];
3fe61b77 1306
1307 // Initialization (coefficient = alpha, rates = lambda)
664030bc 1308 Float_t r1 = 1.0;
1309 Float_t r2 = 1.0;
1310 Float_t c1 = 0.5;
1311 Float_t c2 = 0.5;
3fe61b77 1312
1313 if (nexp == 1) { // 1 Exponentials
1314 r1 = 1.156;
1315 r2 = 0.130;
1316 c1 = 0.066;
1317 c2 = 0.000;
1318 }
1319 if (nexp == 2) { // 2 Exponentials
181c7f7e 1320 Double_t par[4];
a2fbb6ec 1321 fReconstructor->GetRecoParam()->GetTCParams(par);
181c7f7e 1322 r1 = par[0];//1.156;
1323 r2 = par[1];//0.130;
1324 c1 = par[2];//0.114;
1325 c2 = par[3];//0.624;
3fe61b77 1326 }
1327
1328 coefficients[0] = c1;
1329 coefficients[1] = c2;
1330
fc0882f3 1331 Double_t dt = 0.1;
3fe61b77 1332
1333 rates[0] = TMath::Exp(-dt/(r1));
1334 rates[1] = TMath::Exp(-dt/(r2));
1335
1336 Int_t i = 0;
1337 Int_t k = 0;
1338
664030bc 1339 Float_t reminder[2];
1340 Float_t correction = 0.0;
1341 Float_t result = 0.0;
3fe61b77 1342
1343 // Attention: computation order is important
1344 for (k = 0; k < nexp; k++) {
1345 reminder[k] = 0.0;
1346 }
1347
fc0882f3 1348 for (i = 0; i < nTime; i++) {
3fe61b77 1349
664030bc 1350 result = (arr[i] - correction); // No rescaling
1351 arr[i] = result;
3fe61b77 1352
1353 for (k = 0; k < nexp; k++) {
1354 reminder[k] = rates[k] * (reminder[k] + coefficients[k] * result);
1355 }
1356
1357 correction = 0.0;
1358 for (k = 0; k < nexp; k++) {
1359 correction += reminder[k];
1360 }
1361
1362 }
6d50f529 1363
1364}
1365
1366//_____________________________________________________________________________
1367void AliTRDclusterizer::ResetRecPoints()
1368{
1369 //
1370 // Resets the list of rec points
1371 //
1372
1373 if (fRecPoints) {
1374 fRecPoints->Delete();
48f8adf3 1375 delete fRecPoints;
6d50f529 1376 }
6d50f529 1377}
1378
1379//_____________________________________________________________________________
66f6bfd9 1380TClonesArray *AliTRDclusterizer::RecPoints()
6d50f529 1381{
1382 //
1383 // Returns the list of rec points
1384 //
1385
1386 if (!fRecPoints) {
48f8adf3 1387 if(!(fRecPoints = AliTRDReconstructor::GetClusters())){
8ae98148 1388 // determine number of clusters which has to be allocated
1389 Float_t nclusters = fReconstructor->GetRecoParam()->GetNClusters();
8ae98148 1390
1391 fRecPoints = new TClonesArray("AliTRDcluster", Int_t(nclusters));
48f8adf3 1392 }
1393 //SetClustersOwner(kTRUE);
1394 AliTRDReconstructor::SetClusters(0x0);
6d50f529 1395 }
6d50f529 1396 return fRecPoints;
eb52b657 1397
3551db50 1398}
fc546d21 1399
a5b99acd 1400//_____________________________________________________________________________
1401TClonesArray *AliTRDclusterizer::TrackletsArray()
1402{
1403 //
1404 // Returns the list of rec points
1405 //
1406
1407 if (!fTracklets && fReconstructor->IsProcessingTracklets()) {
94ac01ef 1408 fTracklets = new TClonesArray("AliTRDcluster", 2*MAXTRACKLETSPERHC);
a5b99acd 1409 //SetClustersOwner(kTRUE);
1410 //AliTRDReconstructor::SetTracklets(0x0);
1411 }
1412 return fTracklets;
1413
1414}
1415