]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDclusterizer.cxx
Fix to apply pileup selection in MC performance
[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"
cc26f39c 29#include "AliTreeLoader.h"
3fe61b77 30#include "AliAlignObj.h"
88cb7938 31
f7336fa3 32#include "AliTRDclusterizer.h"
3e1a3ad8 33#include "AliTRDcluster.h"
fc546d21 34#include "AliTRDReconstructor.h"
793ff80c 35#include "AliTRDgeometry.h"
b65e5048 36#include "AliTRDarrayDictionary.h"
37#include "AliTRDarrayADC.h"
3fe61b77 38#include "AliTRDdigitsManager.h"
e570c2a5 39#include "AliTRDdigitsParam.h"
3fe61b77 40#include "AliTRDrawData.h"
3551db50 41#include "AliTRDcalibDB.h"
3fe61b77 42#include "AliTRDtransform.h"
43#include "AliTRDSignalIndex.h"
8dcbd181 44#include "AliTRDrawStream.h"
3fe61b77 45#include "AliTRDfeeParam.h"
a5b99acd 46#include "AliTRDtrackletWord.h"
cb8b99ee 47#include "AliTRDtrackletMCM.h"
48#include "AliTRDtrackGTU.h"
49#include "AliESDTrdTrack.h"
3fe61b77 50
29f95561 51#include "TTreeStream.h"
52
3fe61b77 53#include "Cal/AliTRDCalROC.h"
54#include "Cal/AliTRDCalDet.h"
0e09df31 55#include "Cal/AliTRDCalSingleChamberStatus.h"
e8e7f17e 56#include "Cal/AliTRDCalOnlineGainTableROC.h"
f7336fa3 57
58ClassImp(AliTRDclusterizer)
59
60//_____________________________________________________________________________
486c2339 61AliTRDclusterizer::AliTRDclusterizer(const AliTRDReconstructor *const rec)
6d50f529 62 :TNamed()
3a039a31 63 ,fReconstructor(rec)
6d50f529 64 ,fRunLoader(NULL)
65 ,fClusterTree(NULL)
66 ,fRecPoints(NULL)
a5b99acd 67 ,fTracklets(NULL)
a1c095f1 68 ,fTracks(NULL)
9c7c9ec1 69 ,fTrackletTree(NULL)
3d0c7d6d 70 ,fDigitsManager(new AliTRDdigitsManager())
9c7c9ec1 71 ,fTrackletContainer(NULL)
3fe61b77 72 ,fRawVersion(2)
dfbb4bb9 73 ,fTransform(new AliTRDtransform(0))
1b3a719f 74 ,fDigits(NULL)
07897df4 75 ,fDigitsRaw(NULL)
064d808d 76 ,fIndexes(NULL)
064d808d 77 ,fMaxThresh(0)
1ab4da8c 78 ,fMaxThreshTest(0)
064d808d 79 ,fSigThresh(0)
80 ,fMinMaxCutSigma(0)
81 ,fMinLeftRightCutSigma(0)
82 ,fLayer(0)
83 ,fDet(0)
84 ,fVolid(0)
85 ,fColMax(0)
86 ,fTimeTotal(0)
87 ,fCalGainFactorROC(NULL)
88 ,fCalGainFactorDetValue(0)
89 ,fCalNoiseROC(NULL)
90 ,fCalNoiseDetValue(0)
1b3a719f 91 ,fCalPadStatusROC(NULL)
893e2ec6 92 ,fCalOnlGainROC(NULL)
064d808d 93 ,fClusterROC(0)
94 ,firstClusterROC(0)
3d0c7d6d 95 ,fNoOfClusters(0)
615f0826 96 ,fBaseline(0)
8dbc94c7 97 ,fRawStream(NULL)
e2cea5e3 98 ,fTrgFlags()
f7336fa3 99{
100 //
101 // AliTRDclusterizer default constructor
102 //
103
b72f4eaf 104 SetBit(kLabels, kTRUE);
8cbe253a 105 SetBit(knewDM, kFALSE);
3d0c7d6d 106
3fe61b77 107 fRawVersion = AliTRDfeeParam::Instance()->GetRAWversion();
108
3a039a31 109 // Initialize debug stream
110 if(fReconstructor){
a2fbb6ec 111 if(fReconstructor->GetRecoParam()->GetStreamLevel(AliTRDrecoParam::kClusterizer) > 1){
3a039a31 112 TDirectory *savedir = gDirectory;
29f95561 113 //fgGetDebugStream = new TTreeSRedirector("TRD.ClusterizerDebug.root");
3a039a31 114 savedir->cd();
115 }
116 }
eb52b657 117
f7336fa3 118}
119
120//_____________________________________________________________________________
a987273c 121AliTRDclusterizer::AliTRDclusterizer(const Text_t *name
122 , const Text_t *title
123 , const AliTRDReconstructor *const rec)
6d50f529 124 :TNamed(name,title)
3a039a31 125 ,fReconstructor(rec)
6d50f529 126 ,fRunLoader(NULL)
127 ,fClusterTree(NULL)
128 ,fRecPoints(NULL)
a5b99acd 129 ,fTracklets(NULL)
a1c095f1 130 ,fTracks(NULL)
9c7c9ec1 131 ,fTrackletTree(NULL)
3d0c7d6d 132 ,fDigitsManager(new AliTRDdigitsManager())
9c7c9ec1 133 ,fTrackletContainer(NULL)
3fe61b77 134 ,fRawVersion(2)
3fe61b77 135 ,fTransform(new AliTRDtransform(0))
1b3a719f 136 ,fDigits(NULL)
07897df4 137 ,fDigitsRaw(NULL)
064d808d 138 ,fIndexes(NULL)
064d808d 139 ,fMaxThresh(0)
1ab4da8c 140 ,fMaxThreshTest(0)
064d808d 141 ,fSigThresh(0)
142 ,fMinMaxCutSigma(0)
143 ,fMinLeftRightCutSigma(0)
144 ,fLayer(0)
145 ,fDet(0)
146 ,fVolid(0)
147 ,fColMax(0)
148 ,fTimeTotal(0)
149 ,fCalGainFactorROC(NULL)
150 ,fCalGainFactorDetValue(0)
151 ,fCalNoiseROC(NULL)
152 ,fCalNoiseDetValue(0)
1b3a719f 153 ,fCalPadStatusROC(NULL)
893e2ec6 154 ,fCalOnlGainROC(NULL)
064d808d 155 ,fClusterROC(0)
156 ,firstClusterROC(0)
3d0c7d6d 157 ,fNoOfClusters(0)
615f0826 158 ,fBaseline(0)
8dbc94c7 159 ,fRawStream(NULL)
e2cea5e3 160 ,fTrgFlags()
f7336fa3 161{
162 //
6d50f529 163 // AliTRDclusterizer constructor
f7336fa3 164 //
165
b72f4eaf 166 SetBit(kLabels, kTRUE);
8cbe253a 167 SetBit(knewDM, kFALSE);
3d0c7d6d 168
3fe61b77 169 fDigitsManager->CreateArrays();
170
171 fRawVersion = AliTRDfeeParam::Instance()->GetRAWversion();
172
b72f4eaf 173 //FillLUT();
023b669c 174
f7336fa3 175}
176
8230f242 177//_____________________________________________________________________________
6d50f529 178AliTRDclusterizer::AliTRDclusterizer(const AliTRDclusterizer &c)
179 :TNamed(c)
3a039a31 180 ,fReconstructor(c.fReconstructor)
6d50f529 181 ,fRunLoader(NULL)
182 ,fClusterTree(NULL)
183 ,fRecPoints(NULL)
a5b99acd 184 ,fTracklets(NULL)
a1c095f1 185 ,fTracks(NULL)
9c7c9ec1 186 ,fTrackletTree(NULL)
3fe61b77 187 ,fDigitsManager(NULL)
66f6bfd9 188 ,fTrackletContainer(NULL)
3fe61b77 189 ,fRawVersion(2)
3fe61b77 190 ,fTransform(NULL)
1b3a719f 191 ,fDigits(NULL)
07897df4 192 ,fDigitsRaw(NULL)
064d808d 193 ,fIndexes(NULL)
064d808d 194 ,fMaxThresh(0)
1ab4da8c 195 ,fMaxThreshTest(0)
064d808d 196 ,fSigThresh(0)
197 ,fMinMaxCutSigma(0)
198 ,fMinLeftRightCutSigma(0)
199 ,fLayer(0)
200 ,fDet(0)
201 ,fVolid(0)
202 ,fColMax(0)
203 ,fTimeTotal(0)
204 ,fCalGainFactorROC(NULL)
205 ,fCalGainFactorDetValue(0)
206 ,fCalNoiseROC(NULL)
207 ,fCalNoiseDetValue(0)
1b3a719f 208 ,fCalPadStatusROC(NULL)
893e2ec6 209 ,fCalOnlGainROC(NULL)
064d808d 210 ,fClusterROC(0)
211 ,firstClusterROC(0)
3d0c7d6d 212 ,fNoOfClusters(0)
615f0826 213 ,fBaseline(0)
8dbc94c7 214 ,fRawStream(NULL)
e2cea5e3 215 ,fTrgFlags()
8230f242 216{
217 //
218 // AliTRDclusterizer copy constructor
219 //
220
b72f4eaf 221 SetBit(kLabels, kTRUE);
8cbe253a 222 SetBit(knewDM, kFALSE);
3d0c7d6d 223
b72f4eaf 224 //FillLUT();
fc546d21 225
8230f242 226}
227
f7336fa3 228//_____________________________________________________________________________
229AliTRDclusterizer::~AliTRDclusterizer()
230{
8230f242 231 //
232 // AliTRDclusterizer destructor
233 //
f7336fa3 234
66f6bfd9 235 if (fDigitsManager) {
236 delete fDigitsManager;
237 fDigitsManager = NULL;
238 }
9c7c9ec1 239
07897df4 240 if (fDigitsRaw) {
241 delete fDigitsRaw;
242 fDigitsRaw = NULL;
243 }
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 }
f7336fa3 254}
255
8230f242 256//_____________________________________________________________________________
dd9a6ee3 257AliTRDclusterizer &AliTRDclusterizer::operator=(const AliTRDclusterizer &c)
258{
259 //
260 // Assignment operator
261 //
262
3fe61b77 263 if (this != &c)
264 {
265 ((AliTRDclusterizer &) c).Copy(*this);
266 }
053767a4 267
dd9a6ee3 268 return *this;
269
270}
271
272//_____________________________________________________________________________
0ab5ff49 273void AliTRDclusterizer::Copy(TObject &c) const
8230f242 274{
275 //
276 // Copy function
277 //
278
3fe61b77 279 ((AliTRDclusterizer &) c).fClusterTree = NULL;
280 ((AliTRDclusterizer &) c).fRecPoints = NULL;
9c7c9ec1 281 ((AliTRDclusterizer &) c).fTrackletTree = NULL;
3fe61b77 282 ((AliTRDclusterizer &) c).fDigitsManager = NULL;
3fe61b77 283 ((AliTRDclusterizer &) c).fRawVersion = fRawVersion;
3fe61b77 284 ((AliTRDclusterizer &) c).fTransform = NULL;
07897df4 285 ((AliTRDclusterizer &) c).fDigits = NULL;
286 ((AliTRDclusterizer &) c).fDigitsRaw = NULL;
064d808d 287 ((AliTRDclusterizer &) c).fIndexes = NULL;
064d808d 288 ((AliTRDclusterizer &) c).fMaxThresh = 0;
1ab4da8c 289 ((AliTRDclusterizer &) c).fMaxThreshTest = 0;
064d808d 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
3e1a3ad8 374//_____________________________________________________________________________
88cb7938 375Bool_t AliTRDclusterizer::OpenInput(Int_t nEvent)
f7336fa3 376{
377 //
378 // Opens a ROOT-file with TRD-hits and reads in the digits-tree
379 //
380
f7336fa3 381 // Import the Trees for the event nEvent in the file
bdbb05bb 382 fRunLoader->GetEvent(nEvent);
88cb7938 383
f7336fa3 384 return kTRUE;
385
386}
387
388//_____________________________________________________________________________
793ff80c 389Bool_t AliTRDclusterizer::WriteClusters(Int_t det)
f7336fa3 390{
391 //
3e1a3ad8 392 // Fills TRDcluster branch in the tree with the clusters
793ff80c 393 // found in detector = det. For det=-1 writes the tree.
a3c76cdc 394 //
793ff80c 395
6d50f529 396 if ((det < -1) ||
397 (det >= AliTRDgeometry::Ndet())) {
398 AliError(Form("Unexpected detector index %d.\n",det));
3e1a3ad8 399 return kFALSE;
793ff80c 400 }
317b5644 401
66f6bfd9 402 TObjArray *ioArray = new TObjArray(400);
3e1a3ad8 403 TBranch *branch = fClusterTree->GetBranch("TRDcluster");
404 if (!branch) {
97b70082 405 fClusterTree->Branch("TRDcluster","TObjArray",&ioArray,32000,0);
66f6bfd9 406 } else branch->SetAddress(&ioArray);
66f6bfd9 407
408 Int_t nRecPoints = RecPoints()->GetEntriesFast();
409 if(det >= 0){
3e1a3ad8 410 for (Int_t i = 0; i < nRecPoints; i++) {
bdbb05bb 411 AliTRDcluster *c = (AliTRDcluster *) RecPoints()->UncheckedAt(i);
66f6bfd9 412 if(det != c->GetDetector()) continue;
413 ioArray->AddLast(c);
793ff80c 414 }
3e1a3ad8 415 fClusterTree->Fill();
839f6b9b 416 ioArray->Clear();
66f6bfd9 417 } else {
839f6b9b 418 Int_t detOld = -1, nw(0);
66f6bfd9 419 for (Int_t i = 0; i < nRecPoints; i++) {
420 AliTRDcluster *c = (AliTRDcluster *) RecPoints()->UncheckedAt(i);
421 if(c->GetDetector() != detOld){
839f6b9b 422 nw += ioArray->GetEntriesFast();
66f6bfd9 423 fClusterTree->Fill();
424 ioArray->Clear();
425 detOld = c->GetDetector();
426 }
427 ioArray->AddLast(c);
a6dd11e9 428 }
839f6b9b 429 if(ioArray->GetEntriesFast()){
430 nw += ioArray->GetEntriesFast();
431 fClusterTree->Fill();
432 ioArray->Clear();
433 }
434 AliDebug(2, Form("Clusters FOUND[%d] WRITTEN[%d] STATUS[%s]", nRecPoints, nw, nw==nRecPoints?"OK":"FAILED"));
793ff80c 435 }
66f6bfd9 436 delete ioArray;
6d50f529 437
66f6bfd9 438 return kTRUE;
f7336fa3 439}
793ff80c 440
3fe61b77 441//_____________________________________________________________________________
442Bool_t AliTRDclusterizer::ReadDigits()
443{
444 //
445 // Reads the digits arrays from the input aliroot file
446 //
447
448 if (!fRunLoader) {
449 AliError("No run loader available");
450 return kFALSE;
451 }
452
453 AliLoader* loader = fRunLoader->GetLoader("TRDLoader");
454 if (!loader->TreeD()) {
455 loader->LoadDigits();
456 }
457
458 // Read in the digit arrays
459 return (fDigitsManager->ReadDigits(loader->TreeD()));
460
461}
462
463//_____________________________________________________________________________
464Bool_t AliTRDclusterizer::ReadDigits(TTree *digitsTree)
465{
466 //
467 // Reads the digits arrays from the input tree
468 //
469
470 // Read in the digit arrays
471 return (fDigitsManager->ReadDigits(digitsTree));
472
473}
474
475//_____________________________________________________________________________
476Bool_t AliTRDclusterizer::ReadDigits(AliRawReader *rawReader)
477{
478 //
479 // Reads the digits arrays from the ddl file
480 //
481
482 AliTRDrawData raw;
483 fDigitsManager = raw.Raw2Digits(rawReader);
484
485 return kTRUE;
486
487}
488
cb8b99ee 489Bool_t AliTRDclusterizer::ReadTracklets()
490{
491 //
492 // Reads simulated tracklets from the input aliroot file
493 //
494
495 AliRunLoader *runLoader = AliRunLoader::Instance();
496 if (!runLoader) {
497 AliError("No run loader available");
498 return kFALSE;
499 }
500
501 AliLoader* loader = runLoader->GetLoader("TRDLoader");
502
503 AliDataLoader *trackletLoader = loader->GetDataLoader("tracklets");
504 if (!trackletLoader) {
505 return kFALSE;
506 }
507
508 // simulated tracklets
509 trackletLoader->Load();
510 TTree *trackletTree = trackletLoader->Tree();
511
d2eba04b 512 if (trackletTree) {
513 TBranch *trklbranch = trackletTree->GetBranch("mcmtrklbranch");
514 TClonesArray *trklArray = TrackletsArray("AliTRDtrackletMCM");
515 if (trklbranch && trklArray) {
516 AliTRDtrackletMCM *trkl = 0x0;
517 trklbranch->SetAddress(&trkl);
518 for (Int_t iTracklet = 0; iTracklet < trklbranch->GetEntries(); iTracklet++) {
519 trklbranch->GetEntry(iTracklet);
520 new ((*trklArray)[trklArray->GetEntries()]) AliTRDtrackletMCM(*trkl);
521 }
522 return kTRUE;
523 }
524 }
525 return kFALSE;
cb8b99ee 526}
527
528Bool_t AliTRDclusterizer::ReadTracks()
529{
530 //
531 // Reads simulated GTU tracks from the input aliroot file
532 //
533
534 AliRunLoader *runLoader = AliRunLoader::Instance();
535
536 if (!runLoader) {
537 AliError("No run loader available");
538 return kFALSE;
539 }
540
541 AliLoader* loader = runLoader->GetLoader("TRDLoader");
8eab6a01 542 if (!loader) {
543 return kFALSE;
544 }
cb8b99ee 545
546 AliDataLoader *trackLoader = loader->GetDataLoader("gtutracks");
547 if (!trackLoader) {
548 return kFALSE;
549 }
550
551 trackLoader->Load();
552
553 TTree *trackTree = trackLoader->Tree();
554 if (!trackTree) {
555 return kFALSE;
556 }
557
558 TClonesArray *trackArray = TracksArray();
559 AliTRDtrackGTU *trk = 0x0;
560 trackTree->SetBranchAddress("TRDtrackGTU", &trk);
561 for (Int_t iTrack = 0; iTrack < trackTree->GetEntries(); iTrack++) {
562 trackTree->GetEntry(iTrack);
563 new ((*trackArray)[trackArray->GetEntries()]) AliESDTrdTrack(*(trk->CreateTrdTrack()));
564 }
565
566 return kTRUE;
567}
568
3fe61b77 569//_____________________________________________________________________________
570Bool_t AliTRDclusterizer::MakeClusters()
571{
572 //
573 // Creates clusters from digits
574 //
575
576 // Propagate info from the digits manager
b72f4eaf 577 if (TestBit(kLabels)){
578 SetBit(kLabels, fDigitsManager->UsesDictionaries());
66f6bfd9 579 }
580
3fe61b77 581 Bool_t fReturn = kTRUE;
66f6bfd9 582 for (Int_t i = 0; i < AliTRDgeometry::kNdet; i++){
583
b65e5048 584 AliTRDarrayADC *digitsIn = (AliTRDarrayADC*) fDigitsManager->GetDigits(i); //mod
66f6bfd9 585 // This is to take care of switched off super modules
586 if (!digitsIn->HasData()) continue;
587 digitsIn->Expand();
0d64b05f 588 digitsIn->DeleteNegatives(); // Restore digits array to >=0 values
66f6bfd9 589 AliTRDSignalIndex* indexes = fDigitsManager->GetIndexes(i);
590 if (indexes->IsAllocated() == kFALSE){
591 fDigitsManager->BuildIndexes(i);
592 }
593
07897df4 594 Bool_t fR(kFALSE);
66f6bfd9 595 if (indexes->HasEntry()){
b72f4eaf 596 if (TestBit(kLabels)){
07897df4 597 Int_t nDict(0);
66f6bfd9 598 for (Int_t iDict = 0; iDict < AliTRDdigitsManager::kNDict; iDict++){
07897df4 599 AliTRDarrayDictionary *tracksIn(NULL); //mod
b65e5048 600 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(i,iDict); //mod
07897df4 601 // This is to take care of data reconstruction
602 if (!tracksIn->GetDim()) continue;
603 tracksIn->Expand(); nDict++;
604 }
605 if(!nDict){
606 AliDebug(1, "MC labels not available. Switch them off.");
607 SetUseLabels(kFALSE);
3fe61b77 608 }
66f6bfd9 609 }
610 fR = MakeClusters(i);
611 fReturn = fR && fReturn;
3fe61b77 612 }
66f6bfd9 613
614 //if (fR == kFALSE){
615 // if(IsWritingClusters()) WriteClusters(i);
616 // ResetRecPoints();
617 //}
618
5127281e 619 // Clear arrays of this chamber, to prepare for next event
620 fDigitsManager->ClearArrays(i);
66f6bfd9 621 }
622
623 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
3fe61b77 624
d2eba04b 625 AliInfo(Form("Found :: clusters[%d] tracklets[%d] tracks[%d]",
626 RecPoints()?RecPoints()->GetEntriesFast():0,
627 TrackletsArray()?TrackletsArray()->GetEntriesFast():0,
628 TracksArray()?TracksArray()->GetEntriesFast():0));
3fe61b77 629
66f6bfd9 630 return fReturn;
eb52b657 631
3fe61b77 632}
633
634//_____________________________________________________________________________
635Bool_t AliTRDclusterizer::Raw2Clusters(AliRawReader *rawReader)
636{
637 //
638 // Creates clusters from raw data
639 //
640
fc546d21 641 return Raw2ClustersChamber(rawReader);
3fe61b77 642
3fe61b77 643}
644
645//_____________________________________________________________________________
646Bool_t AliTRDclusterizer::Raw2ClustersChamber(AliRawReader *rawReader)
647{
648 //
649 // Creates clusters from raw data
650 //
651
652 // Create the digits manager
66f6bfd9 653 if (!fDigitsManager){
8cbe253a 654 SetBit(knewDM, kTRUE);
3d0c7d6d 655 fDigitsManager = new AliTRDdigitsManager(kTRUE);
66f6bfd9 656 fDigitsManager->CreateArrays();
657 }
3fe61b77 658
b72f4eaf 659 fDigitsManager->SetUseDictionaries(TestBit(kLabels));
3fe61b77 660
f2ab58d4 661 // ----- preparing tracklet output -----
662 if (fReconstructor->IsWritingTracklets()) {
663 AliDataLoader *trklLoader = AliRunLoader::Instance()->GetLoader("TRDLoader")->GetDataLoader("tracklets");
664 if (!trklLoader) {
cc26f39c 665 //AliInfo("Could not get the tracklets data loader, adding it now!");
f2ab58d4 666 trklLoader = new AliDataLoader("TRD.Tracklets.root","tracklets", "tracklets");
667 AliRunLoader::Instance()->GetLoader("TRDLoader")->AddDataLoader(trklLoader);
668 }
cc26f39c 669 AliTreeLoader *trklTreeLoader = dynamic_cast<AliTreeLoader*> (trklLoader->GetBaseLoader("tracklets-raw"));
670 if (!trklTreeLoader) {
671 trklTreeLoader = new AliTreeLoader("tracklets-raw", trklLoader);
672 trklLoader->AddBaseLoader(trklTreeLoader);
673 }
674 if (!trklTreeLoader->Tree())
675 trklTreeLoader->MakeTree();
f2ab58d4 676 }
677
8dbc94c7 678 if(!fRawStream)
8df1f8f5 679 fRawStream = new AliTRDrawStream(rawReader);
8dbc94c7 680 else
681 fRawStream->SetReader(rawReader);
682
9dcc64cc 683 //if(fReconstructor->IsHLT()){
a1c095f1 684 fRawStream->DisableErrorStorage();
9dcc64cc 685 //}
3fe61b77 686
a1c095f1 687 // register tracklet array for output
cb8b99ee 688 fRawStream->SetTrackletArray(TrackletsArray("AliTRDtrackletMCM"));
a1c095f1 689 fRawStream->SetTrackArray(TracksArray());
690
b14f2845 691 UInt_t det = 0;
a1c095f1 692 while ((det = fRawStream->NextChamber(fDigitsManager)) < AliTRDgeometry::kNdet){
dc4457f0 693 if (fDigitsManager->GetIndexes(det)->HasEntry()){
c6f7c6cb 694 MakeClusters(det);
dc4457f0 695 fDigitsManager->ClearArrays(det);
696 }
9c7c9ec1 697 }
a1c095f1 698
f2ab58d4 699 if (fReconstructor->IsWritingTracklets()) {
700 if (AliDataLoader *trklLoader = AliRunLoader::Instance()->GetLoader("TRDLoader")->GetDataLoader("tracklets")) {
cc26f39c 701 if (trklLoader) {
702 if (AliTreeLoader *trklTreeLoader = (AliTreeLoader*) trklLoader->GetBaseLoader("tracklets-raw"))
703 trklTreeLoader->WriteData("OVERWRITE");
704 trklLoader->UnloadAll();
705 }
f2ab58d4 706 }
707 }
708
e2cea5e3 709 for (Int_t iSector = 0; iSector < AliTRDgeometry::kNsector; iSector++) {
710 fTrgFlags[iSector] = fRawStream->GetTriggerFlags(iSector);
711 }
712
66f6bfd9 713 if(fReconstructor->IsWritingClusters()) WriteClusters(-1);
3fe61b77 714
8cbe253a 715 if(!TestBit(knewDM)){
716 delete fDigitsManager;
717 fDigitsManager = NULL;
ad808511 718 delete fRawStream;
719 fRawStream = NULL;
8cbe253a 720 }
dfbb4bb9 721
d2eba04b 722 AliInfo(Form("Found :: clusters[%d] tracklets[%d] tracks[%d]",
723 RecPoints()?RecPoints()->GetEntriesFast():0,
724 TrackletsArray()?TrackletsArray()->GetEntriesFast():0,
725 TracksArray()?TracksArray()->GetEntriesFast():0));
66f6bfd9 726 return kTRUE;
eb52b657 727
3fe61b77 728}
729
fa7427d0 730//_____________________________________________________________________________
731UChar_t AliTRDclusterizer::GetStatus(Short_t &signal)
732{
023b669c 733 //
734 // Check if a pad is masked
735 //
736
317b5644 737 UChar_t status = 0;
738
739 if(signal>0 && TESTBIT(signal, 10)){
740 CLRBIT(signal, 10);
741 for(int ibit=0; ibit<4; ibit++){
742 if(TESTBIT(signal, 11+ibit)){
743 SETBIT(status, ibit);
744 CLRBIT(signal, 11+ibit);
745 }
746 }
747 }
748 return status;
fa7427d0 749}
750
6d9e79cc 751//_____________________________________________________________________________
e7295a3a 752void AliTRDclusterizer::SetPadStatus(const UChar_t status, UChar_t &out) const {
6d9e79cc 753 //
754 // Set the pad status into out
755 // First three bits are needed for the position encoding
756 //
064d808d 757 out |= status << 3;
6d9e79cc 758}
759
760//_____________________________________________________________________________
064d808d 761UChar_t AliTRDclusterizer::GetPadStatus(UChar_t encoding) const {
6d9e79cc 762 //
763 // return the staus encoding of the corrupted pad
764 //
765 return static_cast<UChar_t>(encoding >> 3);
766}
767
768//_____________________________________________________________________________
064d808d 769Int_t AliTRDclusterizer::GetCorruption(UChar_t encoding) const {
6d9e79cc 770 //
771 // Return the position of the corruption
772 //
773 return encoding & 7;
774}
775
3fe61b77 776//_____________________________________________________________________________
777Bool_t AliTRDclusterizer::MakeClusters(Int_t det)
778{
779 //
780 // Generates the cluster.
781 //
782
783 // Get the digits
615f0826 784 fDigits = (AliTRDarrayADC *) fDigitsManager->GetDigits(det); //mod
a0446ff1 785 fBaseline = fDigitsManager->GetDigitsParam()->GetADCbaseline(det);
f5375dcb 786
3fe61b77 787 // This is to take care of switched off super modules
b72f4eaf 788 if (!fDigits->HasData()) return kFALSE;
3fe61b77 789
064d808d 790 fIndexes = fDigitsManager->GetIndexes(det);
b72f4eaf 791 if (fIndexes->IsAllocated() == kFALSE) {
792 AliError("Indexes do not exist!");
793 return kFALSE;
794 }
064d808d 795
fc0882f3 796 AliTRDcalibDB* const calibration = AliTRDcalibDB::Instance();
b72f4eaf 797 if (!calibration) {
798 AliFatal("No AliTRDcalibDB instance available\n");
799 return kFALSE;
800 }
3fe61b77 801
3a039a31 802 if (!fReconstructor){
803 AliError("Reconstructor not set\n");
804 return kFALSE;
805 }
c5f589b9 806
c6f7c6cb 807 const AliTRDrecoParam *const recoParam = fReconstructor->GetRecoParam();
fc0882f3 808
07897df4 809 fMaxThresh = recoParam->GetClusMaxThresh();
810 fMaxThreshTest = (recoParam->GetClusMaxThresh()/2+fBaseline);
811 fSigThresh = recoParam->GetClusSigThresh();
fc0882f3 812 fMinMaxCutSigma = recoParam->GetMinMaxCutSigma();
813 fMinLeftRightCutSigma = recoParam->GetMinLeftRightCutSigma();
8c499dbf 814 const Int_t iEveryNTB = recoParam->GetRecEveryNTB();
3fe61b77 815
064d808d 816 Int_t istack = fIndexes->GetStack();
817 fLayer = fIndexes->GetLayer();
818 Int_t isector = fIndexes->GetSM();
3fe61b77 819
820 // Start clustering in the chamber
821
064d808d 822 fDet = AliTRDgeometry::GetDetector(fLayer,istack,isector);
823 if (fDet != det) {
126991d9 824 AliError(Form("Detector number missmatch! Request[%03d] RAW[%03d]", det, fDet));
b65e5048 825 return kFALSE;
826 }
3fe61b77 827
839f6b9b 828 AliDebug(2, Form("Det[%d] @ Sec[%d] Stk[%d] Ly[%d]", fDet, isector, istack, fLayer));
829
3fe61b77 830 // TRD space point transformation
831 fTransform->SetDetector(det);
832
064d808d 833 Int_t iGeoLayer = AliGeomManager::kTRD1 + fLayer;
053767a4 834 Int_t iGeoModule = istack + AliTRDgeometry::Nstack() * isector;
064d808d 835 fVolid = AliGeomManager::LayerToVolUID(iGeoLayer,iGeoModule);
3fe61b77 836
1b3a719f 837 fColMax = fDigits->GetNcol();
8b8d2999 838 fTimeTotal = fDigitsManager->GetDigitsParam()->GetNTimeBins(det);
3fe61b77 839
126991d9 840 // Check consistency between Geometry and raw data
841 AliTRDpadPlane *pp(fTransform->GetPadPlane());
842 Int_t ncols(pp->GetNcols()), nrows(pp->GetNrows());
cf8adf20 843 if(ncols != fColMax) AliDebug(1, Form("N cols missmatch in Digits for Det[%3d] :: Geom[%3d] RAW[%3d]", fDet, ncols, fColMax));
844 if(nrows != fDigits->GetNrow()) AliDebug(1, Form("N rows missmatch in Digits for Det[%3d] :: Geom[%3d] RAW[%3d]", fDet, nrows, fDigits->GetNrow()));
845 if(ncols != fIndexes->GetNcol()) AliDebug(1, Form("N cols missmatch in Digits for Det[%3d] :: Geom[%3d] RAW[%3d]", fDet, ncols, fIndexes->GetNcol()));
846 if(nrows != fIndexes->GetNrow()) AliDebug(1, Form("N rows missmatch in Digits for Det[%3d] :: Geom[%3d] RAW[%3d]", fDet, nrows, fIndexes->GetNrow()));
126991d9 847
69a850a0 848 // Check consistency between OCDB and raw data
4e6823c2 849 Int_t nTimeOCDB = calibration->GetNumberOfTimeBinsDCS();
d03bfe2b 850 if(fReconstructor->IsHLT()){
c6f7c6cb 851 if((nTimeOCDB > -1) && (fTimeTotal != nTimeOCDB)){
852 AliWarning(Form("Number of timebins does not match OCDB value (RAW[%d] OCDB[%d]), using raw value"
853 ,fTimeTotal,nTimeOCDB));
854 }
855 }else{
856 if(nTimeOCDB == -1){
599bd95b 857 AliDebug(1, "Undefined number of timebins in OCDB, using value from raw data.");
c6f7c6cb 858 if(!fTimeTotal>0){
126991d9 859 AliError(Form("Number of timebins in raw data is negative, skipping chamber[%3d]!", fDet));
860 return kFALSE;
c6f7c6cb 861 }
862 }else if(nTimeOCDB == -2){
863 AliError("Mixed number of timebins in OCDB, no reconstruction of TRD data!");
864 return kFALSE;
865 }else if(fTimeTotal != nTimeOCDB){
126991d9 866 AliError(Form("Number of timebins in raw data does not match OCDB value (RAW[%d] OCDB[%d]), skipping chamber[%3d]!"
867 ,fTimeTotal,nTimeOCDB, fDet));
c6f7c6cb 868 return kFALSE;
869 }
69a850a0 870 }
599bd95b 871 AliDebug(1, Form("Using %2d number of timebins for Det[%03d].", fTimeTotal, fDet));
69a850a0 872
3fe61b77 873 // Detector wise calibration object for the gain factors
064d808d 874 const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
3fe61b77 875 // Calibration object with pad wise values for the gain factors
064d808d 876 fCalGainFactorROC = calibration->GetGainFactorROC(fDet);
3fe61b77 877 // Calibration value for chamber wise gain factor
064d808d 878 fCalGainFactorDetValue = calGainFactorDet->GetValue(fDet);
0e09df31 879
df83a620 880 // Detector wise calibration object for the noise
064d808d 881 const AliTRDCalDet *calNoiseDet = calibration->GetNoiseDet();
df83a620 882 // Calibration object with pad wise values for the noise
064d808d 883 fCalNoiseROC = calibration->GetNoiseROC(fDet);
df83a620 884 // Calibration value for chamber wise noise
064d808d 885 fCalNoiseDetValue = calNoiseDet->GetValue(fDet);
1b3a719f 886
887 // Calibration object with the pad status
888 fCalPadStatusROC = calibration->GetPadStatusROC(fDet);
e8e7f17e 889 // Calibration object of the online gain
893e2ec6 890 fCalOnlGainROC = 0x0;
c36ddf52 891 if (calibration->HasOnlineFilterGain()) {
893e2ec6 892 fCalOnlGainROC = calibration->GetOnlineGainTableROC(fDet);
c36ddf52 893 }
6b0d4ad5 894
064d808d 895 firstClusterROC = -1;
896 fClusterROC = 0;
3fe61b77 897
c6f7c6cb 898 SetBit(kLUT, recoParam->UseLUT());
899 SetBit(kGAUS, recoParam->UseGAUS());
900
b72f4eaf 901 // Apply the gain and the tail cancelation via digital filter
5f5f179e 902 // Use the configuration from the DCS to find out whether online
903 // tail cancellation was applied
07897df4 904 if(!calibration->HasOnlineTailCancellation()){
905 // save a copy of raw data
906 if(TestBit(kRawSignal)){
907 if(fDigitsRaw){
908 fDigitsRaw->~AliTRDarrayADC();
909 new(fDigitsRaw) AliTRDarrayADC(*fDigits);
910 } else fDigitsRaw = new AliTRDarrayADC(*fDigits);
911 }
912 TailCancelation(recoParam);
913 }
023b669c 914
486c2339 915 MaxStruct curr, last;
064d808d 916 Int_t nMaximas = 0, nCorrupted = 0;
f5375dcb 917
064d808d 918 // Here the clusterfining is happening
919
8c499dbf 920 for(curr.time = 0; curr.time < fTimeTotal; curr.time+=iEveryNTB){
615f0826 921 while(fIndexes->NextRCIndex(curr.row, curr.col)){
1ab4da8c 922 if(fDigits->GetData(curr.row, curr.col, curr.time) > fMaxThreshTest && IsMaximum(curr, curr.padStatus, &curr.signals[0])){
615f0826 923 if(last.row>-1){
634a1625 924 if(curr.col==last.col+2 && curr.row==last.row && curr.time==last.time) FivePadCluster(last, curr);
b72f4eaf 925 CreateCluster(last);
926 }
615f0826 927 last=curr; curr.fivePad=kFALSE;
b72f4eaf 928 }
b72f4eaf 929 }
930 }
615f0826 931 if(last.row>-1) CreateCluster(last);
df83a620 932
fc0882f3 933 if(recoParam->GetStreamLevel(AliTRDrecoParam::kClusterizer) > 2 && fReconstructor->IsDebugStreaming()){
a2fbb6ec 934 TTreeSRedirector* fDebugStream = fReconstructor->GetDebugStream(AliTRDrecoParam::kClusterizer);
064d808d 935 (*fDebugStream) << "MakeClusters"
b72f4eaf 936 << "Detector=" << det
937 << "NMaxima=" << nMaximas
938 << "NClusters=" << fClusterROC
939 << "NCorrupted=" << nCorrupted
940 << "\n";
df83a620 941 }
a0931654 942 if (TestBit(kLabels)) AddLabels();
f5375dcb 943
064d808d 944 return kTRUE;
f5375dcb 945
064d808d 946}
3fe61b77 947
064d808d 948//_____________________________________________________________________________
07897df4 949Bool_t AliTRDclusterizer::IsMaximum(const MaxStruct &Max, UChar_t &padStatus, Float_t *const Signals)
064d808d 950{
951 //
952 // Returns true if this row,col,time combination is a maximum.
953 // Gives back the padStatus and the signals of the center pad and the two neighbouring pads.
954 //
c96d03ba 955
615f0826 956 Float_t gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(Max.col,Max.row);
893e2ec6 957 Float_t onlcf = fCalOnlGainROC ? fCalOnlGainROC->GetGainCorrectionFactor(Max.row,Max.col) : 1;
958 Signals[1] = (fDigits->GetData(Max.row, Max.col, Max.time) - fBaseline) /(onlcf * gain) + 0.5f;
1ab4da8c 959 if(Signals[1] <= fMaxThresh) return kFALSE;
3fe61b77 960
634a1625 961 if(Max.col < 1 || Max.col + 1 >= fColMax) return kFALSE;
f5375dcb 962
07897df4 963 Float_t noiseMiddleThresh = fMinMaxCutSigma*fCalNoiseDetValue*fCalNoiseROC->GetValue(Max.col, Max.row);
634a1625 964 if (Signals[1] <= noiseMiddleThresh) return kFALSE;
3fe61b77 965
d2eba04b 966 Char_t status[3]={
615f0826 967 fCalPadStatusROC->GetStatus(Max.col-1, Max.row)
968 ,fCalPadStatusROC->GetStatus(Max.col, Max.row)
969 ,fCalPadStatusROC->GetStatus(Max.col+1, Max.row)
b72f4eaf 970 };
486c2339 971
c66dc420 972 Short_t signal(0);
973 if((signal = fDigits->GetData(Max.row, Max.col-1, Max.time))){
974 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(Max.col-1,Max.row);
893e2ec6 975 onlcf = fCalOnlGainROC ? fCalOnlGainROC->GetGainCorrectionFactor(Max.row,Max.col-1) : 1;
976 Signals[0] = (signal - fBaseline) /( onlcf * gain) + 0.5f;
07897df4 977 } else Signals[0] = 0.;
c66dc420 978 if((signal = fDigits->GetData(Max.row, Max.col+1, Max.time))){
979 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(Max.col+1,Max.row);
893e2ec6 980 onlcf = fCalOnlGainROC ? fCalOnlGainROC->GetGainCorrectionFactor(Max.row,Max.col+1) : 1;
981 Signals[2] = (signal - fBaseline) /( onlcf * gain) + 0.5f;
07897df4 982 } else Signals[2] = 0.;
c96d03ba 983
486c2339 984 if(!(status[0] | status[1] | status[2])) {//all pads are good
c96d03ba 985 if ((Signals[2] <= Signals[1]) && (Signals[0] < Signals[1])) {
1ab4da8c 986 if ((Signals[2] > fSigThresh) || (Signals[0] > fSigThresh)) {
07897df4 987 if(Signals[0]<0) Signals[0]=0.;
988 if(Signals[2]<0) Signals[2]=0.;
989 Float_t noiseSumThresh = fMinLeftRightCutSigma * fCalNoiseDetValue
990 * fCalNoiseROC->GetValue(Max.col, Max.row);
1ab4da8c 991 if ((Signals[2]+Signals[0]+Signals[1]) <= noiseSumThresh) return kFALSE;
b72f4eaf 992 padStatus = 0;
993 return kTRUE;
eb52b657 994 }
064d808d 995 }
b72f4eaf 996 } else { // at least one of the pads is bad, and reject candidates with more than 1 problematic pad
5a8db426 997 if(Signals[0]<0)Signals[0]=0;
998 if(Signals[2]<0)Signals[2]=0;
1ab4da8c 999 if (status[2] && (!(status[0] || status[1])) && Signals[1] > Signals[0] && Signals[0] > fSigThresh) {
c96d03ba 1000 Signals[2]=0;
486c2339 1001 SetPadStatus(status[2], padStatus);
1002 return kTRUE;
1003 }
1ab4da8c 1004 else if (status[0] && (!(status[1] || status[2])) && Signals[1] >= Signals[2] && Signals[2] > fSigThresh) {
c96d03ba 1005 Signals[0]=0;
486c2339 1006 SetPadStatus(status[0], padStatus);
1007 return kTRUE;
1008 }
1ab4da8c 1009 else if (status[1] && (!(status[0] || status[2])) && ((Signals[2] > fSigThresh) || (Signals[0] > fSigThresh))) {
1010 Signals[1] = fMaxThresh;
486c2339 1011 SetPadStatus(status[1], padStatus);
064d808d 1012 return kTRUE;
1013 }
1014 }
1015 return kFALSE;
1016}
3fe61b77 1017
064d808d 1018//_____________________________________________________________________________
1b3a719f 1019Bool_t AliTRDclusterizer::FivePadCluster(MaxStruct &ThisMax, MaxStruct &NeighbourMax)
064d808d 1020{
1021 //
1022 // Look for 5 pad cluster with minimum in the middle
1023 // Gives back the ratio
1024 //
615f0826 1025
1026 if (ThisMax.col >= fColMax - 3) return kFALSE;
1027 Float_t gain;
893e2ec6 1028 Float_t onlcf;
615f0826 1029 if (ThisMax.col < fColMax - 5){
1030 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(ThisMax.col+4,ThisMax.row);
893e2ec6 1031 onlcf = fCalOnlGainROC ? fCalOnlGainROC->GetGainCorrectionFactor(ThisMax.row,ThisMax.col+4) : 1;
1032 if (fDigits->GetData(ThisMax.row, ThisMax.col+4, ThisMax.time) - fBaseline >= fSigThresh * gain * onlcf)
486c2339 1033 return kFALSE;
064d808d 1034 }
615f0826 1035 if (ThisMax.col > 1) {
1036 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(ThisMax.col-2,ThisMax.row);
893e2ec6 1037 onlcf = fCalOnlGainROC ? fCalOnlGainROC->GetGainCorrectionFactor(ThisMax.row,ThisMax.col-2) : 1;
1038 if (fDigits->GetData(ThisMax.row, ThisMax.col-2, ThisMax.time) - fBaseline >= fSigThresh * gain * onlcf)
486c2339 1039 return kFALSE;
1040 }
1041
486c2339 1042 const Float_t kEpsilon = 0.01;
615f0826 1043 Double_t padSignal[5] = {ThisMax.signals[0], ThisMax.signals[1], ThisMax.signals[2],
1044 NeighbourMax.signals[1], NeighbourMax.signals[2]};
486c2339 1045
1046 // Unfold the two maxima and set the signal on
1047 // the overlapping pad to the ratio
1b3a719f 1048 Float_t ratio = Unfold(kEpsilon,fLayer,padSignal);
07897df4 1049 ThisMax.signals[2] = ThisMax.signals[2]*ratio + 0.5f;
1050 NeighbourMax.signals[0] = NeighbourMax.signals[0]*(1-ratio) + 0.5f;
615f0826 1051 ThisMax.fivePad=kTRUE;
1052 NeighbourMax.fivePad=kTRUE;
486c2339 1053 return kTRUE;
c96d03ba 1054
064d808d 1055}
eb52b657 1056
064d808d 1057//_____________________________________________________________________________
486c2339 1058void AliTRDclusterizer::CreateCluster(const MaxStruct &Max)
064d808d 1059{
1060 //
d2eba04b 1061 // Creates a cluster at the given position and saves it in RecPoints
064d808d 1062 //
eb52b657 1063
c96d03ba 1064 Int_t nPadCount = 1;
07897df4 1065 Short_t signals[7] = { 0, 0, (Short_t)Max.signals[0], (Short_t)Max.signals[1], (Short_t)Max.signals[2], 0, 0 };
d03bfe2b 1066 if(!fReconstructor->IsHLT()) CalcAdditionalInfo(Max, signals, nPadCount);
c96d03ba 1067
615f0826 1068 AliTRDcluster cluster(fDet, ((UChar_t) Max.col), ((UChar_t) Max.row), ((UChar_t) Max.time), signals, fVolid);
c96d03ba 1069 cluster.SetNPads(nPadCount);
07897df4 1070 cluster.SetQ(Max.signals[0]+Max.signals[1]+Max.signals[2]);
b72f4eaf 1071 if(TestBit(kLUT)) cluster.SetRPhiMethod(AliTRDcluster::kLUT);
1072 else if(TestBit(kGAUS)) cluster.SetRPhiMethod(AliTRDcluster::kGAUS);
1073 else cluster.SetRPhiMethod(AliTRDcluster::kCOG);
3fe61b77 1074
615f0826 1075 cluster.SetFivePad(Max.fivePad);
b72f4eaf 1076 // set pads status for the cluster
1077 UChar_t maskPosition = GetCorruption(Max.padStatus);
1078 if (maskPosition) {
1079 cluster.SetPadMaskedPosition(maskPosition);
1080 cluster.SetPadMaskedStatus(GetPadStatus(Max.padStatus));
1081 }
8fc736d7 1082 cluster.SetXcorr(fReconstructor->UseClusterRadialCorrection());
064d808d 1083
1084 // Transform the local cluster coordinates into calibrated
1085 // space point positions defined in the local tracking system.
1086 // Here the calibration for T0, Vdrift and ExB is applied as well.
d03bfe2b 1087 if(!TestBit(kSkipTrafo)) if(!fTransform->Transform(&cluster)) return;
07897df4 1088 // Store raw signals in cluster. This MUST be called after position reconstruction !
1089 // Xianguo Lu and Alex Bercuci 19.03.2012
1090 if(TestBit(kRawSignal) && fDigitsRaw){
19447c3c 1091 Float_t tmp(0.), kMaxShortVal(32767.); // protect against data overflow due to wrong gain calibration
1092 Short_t rawSignal[7] = {0};
1093 for(Int_t ipad(Max.col-3), iRawId(0); ipad<=Max.col+3; ipad++, iRawId++){
1094 if(ipad<0 || ipad>=fColMax) continue;
1095 if(!fCalOnlGainROC){
1096 rawSignal[iRawId] = fDigitsRaw->GetData(Max.row, ipad, Max.time);
1097 continue;
1098 }
1099 // Deconvolute online gain calibration when available
1100 // Alex Bercuci 27.04.2012
1101 tmp = (fDigitsRaw->GetData(Max.row, ipad, Max.time) - fBaseline)/fCalOnlGainROC->GetGainCorrectionFactor(Max.row, ipad) + 0.5f;
1102 rawSignal[iRawId] = (Short_t)TMath::Min(tmp, kMaxShortVal);
07897df4 1103 }
1104 cluster.SetSignals(rawSignal, kTRUE);
1105 }
b72f4eaf 1106 // Temporarily store the Max.Row, column and time bin of the center pad
1107 // Used to later on assign the track indices
615f0826 1108 cluster.SetLabel(Max.row, 0);
1109 cluster.SetLabel(Max.col, 1);
1110 cluster.SetLabel(Max.time,2);
c96d03ba 1111
b72f4eaf 1112 //needed for HLT reconstruction
8c499dbf 1113 AddClusterToArray(&cluster);
b72f4eaf 1114
1115 // Store the index of the first cluster in the current ROC
1116 if (firstClusterROC < 0) firstClusterROC = fNoOfClusters;
1117
1118 fNoOfClusters++;
1119 fClusterROC++;
3fe61b77 1120}
1121
3d0c7d6d 1122//_____________________________________________________________________________
1123void AliTRDclusterizer::CalcAdditionalInfo(const MaxStruct &Max, Short_t *const signals, Int_t &nPadCount)
1124{
c66dc420 1125// Calculate number of pads/cluster and
1126// ADC signals at position 0, 1, 5 and 6
1127
f05239f1 1128 Float_t tmp(0.), kMaxShortVal(32767.); // protect against data overflow due to wrong gain calibration
893e2ec6 1129 Float_t gain(1.); Float_t onlcf(1.); Short_t signal(0);
c66dc420 1130 // Store the amplitudes of the pads in the cluster for later analysis
1131 // and check whether one of these pads is masked in the database
1132 signals[3]=Max.signals[1];
1133 Int_t ipad(1), jpad(0);
3d0c7d6d 1134 // Look to the right
c66dc420 1135 while((jpad = Max.col-ipad)){
1136 if(!(signal = fDigits->GetData(Max.row, jpad, Max.time))) break; // empty digit !
1137 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(jpad, Max.row);
893e2ec6 1138 onlcf = fCalOnlGainROC ? fCalOnlGainROC->GetGainCorrectionFactor(Max.row,jpad) : 1;
1139 tmp = (signal - fBaseline) / (onlcf * gain) + 0.5f;
f05239f1 1140 signal = (Short_t)TMath::Min(tmp, kMaxShortVal);
c66dc420 1141 if(signal<fSigThresh) break; // signal under threshold
3d0c7d6d 1142 nPadCount++;
c66dc420 1143 if(ipad<=3) signals[3 - ipad] = signal;
1144 ipad++;
3d0c7d6d 1145 }
c66dc420 1146 ipad=1;
3d0c7d6d 1147 // Look to the left
c66dc420 1148 while((jpad = Max.col+ipad)<fColMax){
1149 if(!(signal = fDigits->GetData(Max.row, jpad, Max.time))) break; // empty digit !
1150 gain = fCalGainFactorDetValue * fCalGainFactorROC->GetValue(jpad, Max.row);
893e2ec6 1151 onlcf = fCalOnlGainROC ? fCalOnlGainROC->GetGainCorrectionFactor(Max.row,jpad) : 1;
1152 tmp = (signal - fBaseline) / (onlcf * gain) + 0.5f;
f05239f1 1153 signal = (Short_t)TMath::Min(tmp, kMaxShortVal);
c66dc420 1154 if(signal<fSigThresh) break; // signal under threshold
3d0c7d6d 1155 nPadCount++;
c66dc420 1156 if(ipad<=3) signals[3 + ipad] = signal;
1157 ipad++;
3d0c7d6d 1158 }
1159
c66dc420 1160 AliDebug(4, Form("Signals[%3d %3d %3d %3d %3d %3d %3d] Npads[%d]."
1161 , signals[0], signals[1], signals[2], signals[3], signals[4], signals[5], signals[6], nPadCount));
3d0c7d6d 1162}
1163
1164//_____________________________________________________________________________
e7295a3a 1165void AliTRDclusterizer::AddClusterToArray(AliTRDcluster* cluster)
3d0c7d6d 1166{
1167 //
1168 // Add a cluster to the array
1169 //
1170
1171 Int_t n = RecPoints()->GetEntriesFast();
1172 if(n!=fNoOfClusters)AliError(Form("fNoOfClusters != RecPoints()->GetEntriesFast %i != %i \n", fNoOfClusters, n));
1173 new((*RecPoints())[n]) AliTRDcluster(*cluster);
1174}
1175
3fe61b77 1176//_____________________________________________________________________________
6cd9a21f 1177Bool_t AliTRDclusterizer::AddLabels()
3551db50 1178{
1179 //
3fe61b77 1180 // Add the track indices to the found clusters
3551db50 1181 //
1182
3fe61b77 1183 const Int_t kNclus = 3;
1184 const Int_t kNdict = AliTRDdigitsManager::kNDict;
1185 const Int_t kNtrack = kNdict * kNclus;
1186
1187 Int_t iClusterROC = 0;
1188
1189 Int_t row = 0;
1190 Int_t col = 0;
1191 Int_t time = 0;
1192 Int_t iPad = 0;
1193
1194 // Temporary array to collect the track indices
6cd9a21f 1195 Int_t *idxTracks = new Int_t[kNtrack*fClusterROC];
3fe61b77 1196
1197 // Loop through the dictionary arrays one-by-one
1198 // to keep memory consumption low
07897df4 1199 AliTRDarrayDictionary *tracksIn(NULL); //mod
3fe61b77 1200 for (Int_t iDict = 0; iDict < kNdict; iDict++) {
1201
1202 // tracksIn should be expanded beforehand!
6cd9a21f 1203 tracksIn = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(fDet,iDict);
3fe61b77 1204
1205 // Loop though the clusters found in this ROC
6cd9a21f 1206 for (iClusterROC = 0; iClusterROC < fClusterROC; iClusterROC++) {
317b5644 1207
3fe61b77 1208 AliTRDcluster *cluster = (AliTRDcluster *)
b65e5048 1209 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
3fe61b77 1210 row = cluster->GetLabel(0);
1211 col = cluster->GetLabel(1);
1212 time = cluster->GetLabel(2);
1213
1214 for (iPad = 0; iPad < kNclus; iPad++) {
b65e5048 1215 Int_t iPadCol = col - 1 + iPad;
1216 Int_t index = tracksIn->GetData(row,iPadCol,time); //Modification of -1 in Track
1217 idxTracks[3*iPad+iDict + iClusterROC*kNtrack] = index;
3fe61b77 1218 }
1219
1220 }
1221
1222 }
1223
1224 // Copy the track indices into the cluster
1225 // Loop though the clusters found in this ROC
6cd9a21f 1226 for (iClusterROC = 0; iClusterROC < fClusterROC; iClusterROC++) {
317b5644 1227
3fe61b77 1228 AliTRDcluster *cluster = (AliTRDcluster *)
1229 RecPoints()->UncheckedAt(firstClusterROC+iClusterROC);
1230 cluster->SetLabel(-9999,0);
1231 cluster->SetLabel(-9999,1);
1232 cluster->SetLabel(-9999,2);
1233
1234 cluster->AddTrackIndex(&idxTracks[iClusterROC*kNtrack]);
1235
1236 }
1237
1238 delete [] idxTracks;
1239
1240 return kTRUE;
1241
1242}
1243
3fe61b77 1244//_____________________________________________________________________________
e7295a3a 1245Float_t AliTRDclusterizer::Unfold(Double_t eps, Int_t layer, const Double_t *const padSignal) const
3fe61b77 1246{
1247 //
1248 // Method to unfold neighbouring maxima.
1249 // The charge ratio on the overlapping pad is calculated
1250 // until there is no more change within the range given by eps.
1251 // The resulting ratio is then returned to the calling method.
1252 //
1253
1254 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
6d50f529 1255 if (!calibration) {
3fe61b77 1256 AliError("No AliTRDcalibDB instance available\n");
1257 return kFALSE;
6d50f529 1258 }
3fe61b77 1259
1260 Int_t irc = 0;
1261 Int_t itStep = 0; // Count iteration steps
1262
1263 Double_t ratio = 0.5; // Start value for ratio
1264 Double_t prevRatio = 0.0; // Store previous ratio
1265
1266 Double_t newLeftSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store left cluster signal
1267 Double_t newRightSignal[3] = { 0.0, 0.0, 0.0 }; // Array to store right cluster signal
1268 Double_t newSignal[3] = { 0.0, 0.0, 0.0 };
1269
1270 // Start the iteration
1271 while ((TMath::Abs(prevRatio - ratio) > eps) && (itStep < 10)) {
1272
1273 itStep++;
1274 prevRatio = ratio;
1275
1276 // Cluster position according to charge ratio
1277 Double_t maxLeft = (ratio*padSignal[2] - padSignal[0])
064d808d 1278 / (padSignal[0] + padSignal[1] + ratio * padSignal[2]);
3fe61b77 1279 Double_t maxRight = (padSignal[4] - (1-ratio)*padSignal[2])
1280 / ((1.0 - ratio)*padSignal[2] + padSignal[3] + padSignal[4]);
1281
1282 // Set cluster charge ratio
064d808d 1283 irc = calibration->PadResponse(1.0, maxLeft, layer, newSignal);
3fe61b77 1284 Double_t ampLeft = padSignal[1] / newSignal[1];
064d808d 1285 irc = calibration->PadResponse(1.0, maxRight, layer, newSignal);
3fe61b77 1286 Double_t ampRight = padSignal[3] / newSignal[1];
1287
1288 // Apply pad response to parameters
053767a4 1289 irc = calibration->PadResponse(ampLeft ,maxLeft ,layer,newLeftSignal );
1290 irc = calibration->PadResponse(ampRight,maxRight,layer,newRightSignal);
3fe61b77 1291
1292 // Calculate new overlapping ratio
1293 ratio = TMath::Min((Double_t) 1.0
1294 ,newLeftSignal[2] / (newLeftSignal[2] + newRightSignal[0]));
1295
b43a3e17 1296 }
88719a08 1297
3fe61b77 1298 return ratio;
1299
1300}
88719a08 1301
3fe61b77 1302//_____________________________________________________________________________
fc0882f3 1303void AliTRDclusterizer::TailCancelation(const AliTRDrecoParam* const recoParam)
3fe61b77 1304{
1305 //
fc0882f3 1306 // Applies the tail cancelation
3fe61b77 1307 //
1308
f05239f1 1309 Int_t nexp = recoParam->GetTCnexp();
1310 if(!nexp) return;
1311
3fe61b77 1312 Int_t iRow = 0;
1313 Int_t iCol = 0;
1314 Int_t iTime = 0;
1315
a2fbb6ec 1316 TTreeSRedirector *fDebugStream = fReconstructor->GetDebugStream(AliTRDrecoParam::kClusterizer);
fc0882f3 1317 Bool_t debugStreaming = recoParam->GetStreamLevel(AliTRDrecoParam::kClusterizer) > 7 && fReconstructor->IsDebugStreaming();
064d808d 1318 while(fIndexes->NextRCIndex(iRow, iCol))
3fe61b77 1319 {
664030bc 1320 // if corrupted then don't make the tail cancallation
1321 if (fCalPadStatusROC->GetStatus(iCol, iRow)) continue;
5a8db426 1322
cb5522da 1323 if(debugStreaming){
1ab4da8c 1324 for (iTime = 0; iTime < fTimeTotal; iTime++)
1325 (*fDebugStream) << "TailCancellation"
1326 << "col=" << iCol
1327 << "row=" << iRow
1328 << "\n";
cb5522da 1329 }
5a8db426 1330
664030bc 1331 // Apply the tail cancelation via the digital filter
9dcc64cc 1332 //DeConvExp(fDigits->GetDataAddress(iRow,iCol),fTimeTotal,nexp);
1333 ApplyTCTM(fDigits->GetDataAddress(iRow,iCol),fTimeTotal,nexp);
3fe61b77 1334 } // while irow icol
1b3a719f 1335
3fe61b77 1336 return;
1337
1338}
1339
9dcc64cc 1340
1341//_____________________________________________________________________________
1342void AliTRDclusterizer::ApplyTCTM(Short_t *const arr, const Int_t nTime, const Int_t nexp)
1343{
1344 //
1345 // Steer tail cancellation
1346 //
1347
1348
1349 switch(nexp) {
1350 case 1:
1351 case 2:
1352 DeConvExp(arr,nTime,nexp);
1353 break;
1354 case -1:
1355 ConvExp(arr,nTime);
1356 break;
1357 case -2:
1358 DeConvExp(arr,nTime,1);
1359 ConvExp(arr,nTime);
1360 break;
1361 default:
1362 break;
1363 }
1364}
1365
1366
1367//_____________________________________________________________________________
1368void AliTRDclusterizer::ConvExp(Short_t *const arr, const Int_t nTime)
1369{
1370 //
1371 // Tail maker
1372 //
1373
1374 // Initialization (coefficient = alpha, rates = lambda)
1375 Float_t slope = 1.0;
1376 Float_t coeff = 0.5;
1377 Float_t rate;
1378
1379 Double_t par[4];
1380 fReconstructor->GetRecoParam()->GetTCParams(par);
1381 slope = par[1];
1382 coeff = par[3];
1383
1384 Double_t dt = 0.1;
1385
1386 rate = TMath::Exp(-dt/(slope));
1387
1388 Float_t reminder = .0;
1389 Float_t correction = 0.0;
1390 Float_t result = 0.0;
1391
1392 for (int i = nTime-1; i >= 0; i--) {
1393
1394 result = arr[i] + correction - fBaseline; // No rescaling
1395 arr[i] = (Short_t)(result + fBaseline + 0.5f);
1396
1397 correction = 0.0;
1398
1399 correction += reminder = rate * (reminder + coeff * result);
1400 }
1401}
1402
1403
3fe61b77 1404//_____________________________________________________________________________
1ab4da8c 1405void AliTRDclusterizer::DeConvExp(Short_t *const arr, const Int_t nTime, const Int_t nexp)
3fe61b77 1406{
1407 //
1408 // Tail cancellation by deconvolution for PASA v4 TRF
1409 //
1410
664030bc 1411 Float_t rates[2];
1412 Float_t coefficients[2];
3fe61b77 1413
1414 // Initialization (coefficient = alpha, rates = lambda)
664030bc 1415 Float_t r1 = 1.0;
1416 Float_t r2 = 1.0;
1417 Float_t c1 = 0.5;
1418 Float_t c2 = 0.5;
3fe61b77 1419
1420 if (nexp == 1) { // 1 Exponentials
1421 r1 = 1.156;
1422 r2 = 0.130;
1423 c1 = 0.066;
1424 c2 = 0.000;
1425 }
1426 if (nexp == 2) { // 2 Exponentials
181c7f7e 1427 Double_t par[4];
a2fbb6ec 1428 fReconstructor->GetRecoParam()->GetTCParams(par);
181c7f7e 1429 r1 = par[0];//1.156;
1430 r2 = par[1];//0.130;
1431 c1 = par[2];//0.114;
1432 c2 = par[3];//0.624;
3fe61b77 1433 }
1434
1435 coefficients[0] = c1;
1436 coefficients[1] = c2;
1437
fc0882f3 1438 Double_t dt = 0.1;
3fe61b77 1439
1440 rates[0] = TMath::Exp(-dt/(r1));
634a1625 1441 rates[1] = (nexp == 1) ? .0 : TMath::Exp(-dt/(r2));
3fe61b77 1442
634a1625 1443 Float_t reminder[2] = { .0, .0 };
664030bc 1444 Float_t correction = 0.0;
1445 Float_t result = 0.0;
3fe61b77 1446
634a1625 1447 for (int i = 0; i < nTime; i++) {
3fe61b77 1448
1ab4da8c 1449 result = arr[i] - correction - fBaseline; // No rescaling
1450 arr[i] = (Short_t)(result + fBaseline + 0.5f);
3fe61b77 1451
3fe61b77 1452 correction = 0.0;
634a1625 1453 for (int k = 0; k < 2; k++) {
1454 correction += reminder[k] = rates[k] * (reminder[k] + coefficients[k] * result);
3fe61b77 1455 }
6d50f529 1456 }
6d50f529 1457}
1458
1459//_____________________________________________________________________________
66f6bfd9 1460TClonesArray *AliTRDclusterizer::RecPoints()
6d50f529 1461{
1462 //
1463 // Returns the list of rec points
1464 //
1465
d2eba04b 1466 fRecPoints = AliTRDReconstructor::GetClusters();
1467 if (!fRecPoints) AliError("Missing cluster array");
6d50f529 1468 return fRecPoints;
3551db50 1469}
fc546d21 1470
a5b99acd 1471//_____________________________________________________________________________
cb8b99ee 1472TClonesArray *AliTRDclusterizer::TrackletsArray(const TString &trkltype)
a5b99acd 1473{
1474 //
a1c095f1 1475 // Returns the array of on-line tracklets
a5b99acd 1476 //
d2eba04b 1477 fTracklets = AliTRDReconstructor::GetTracklets(trkltype.Data());
1478 if (!fTracklets) AliError("Missing online tracklets array");
a5b99acd 1479 return fTracklets;
a5b99acd 1480}
1481
a1c095f1 1482//_____________________________________________________________________________
1483TClonesArray* AliTRDclusterizer::TracksArray()
1484{
1485 // return array of GTU tracks (create TClonesArray if necessary)
1486
d2eba04b 1487 fTracks = AliTRDReconstructor::GetTracks();
1488 if (!fTracks) AliError("Missing online tracks array");
a1c095f1 1489 return fTracks;
1490}