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