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