]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDdigitizer.cxx
Adding analysis task
[u/mrichter/AliRoot.git] / TRD / AliTRDdigitizer.cxx
CommitLineData
f7336fa3 1/**************************************************************************
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 **************************************************************************/
15
88cb7938 16/* $Id$ */
f7336fa3 17
625f5260 18////////////////////////////////////////////////////////////////////////////
19// //
20// Creates and handles digits from TRD hits //
21// //
22// Authors: C. Blume (blume@ikf.uni-frankfurt.de) //
23// C. Lippmann //
24// B. Vulpescu //
25// //
26// The following effects are included: //
27// - Diffusion //
28// - ExB effects //
29// - Gas gain including fluctuations //
30// - Pad-response (simple Gaussian approximation) //
31// - Time-response //
32// - Electronics noise //
33// - Electronics gain //
34// - Digitization //
b65e5048 35// - Zero suppression //
625f5260 36// //
37////////////////////////////////////////////////////////////////////////////
6798b56e 38
f7a1cc68 39#include <TGeoManager.h>
abaf1f1d 40#include <TList.h>
f7a1cc68 41#include <TMath.h>
f7a1cc68 42#include <TRandom.h>
f7a1cc68 43#include <TTree.h>
26d3c914 44
793ff80c 45#include "AliRun.h"
3e2e3ece 46#include "AliMC.h"
88cb7938 47#include "AliRunLoader.h"
48#include "AliLoader.h"
49#include "AliConfig.h"
f21fc003 50#include "AliDigitizationInput.h"
88cb7938 51#include "AliRunLoader.h"
52#include "AliLoader.h"
ad2cc20b 53#include "AliLog.h"
621310dd 54
f7336fa3 55#include "AliTRD.h"
793ff80c 56#include "AliTRDhit.h"
f7336fa3 57#include "AliTRDdigitizer.h"
b65e5048 58#include "AliTRDarrayDictionary.h"
59#include "AliTRDarrayADC.h"
60#include "AliTRDarraySignal.h"
da581aea 61#include "AliTRDdigitsManager.h"
793ff80c 62#include "AliTRDgeometry.h"
a5cadd36 63#include "AliTRDpadPlane.h"
3551db50 64#include "AliTRDcalibDB.h"
65#include "AliTRDSimParam.h"
66#include "AliTRDCommonParam.h"
ecf39416 67#include "AliTRDfeeParam.h"
b65e5048 68#include "AliTRDmcmSim.h"
966f6939 69#include "AliTRDdigitsParam.h"
70
4329977a 71#include "Cal/AliTRDCalROC.h"
72#include "Cal/AliTRDCalDet.h"
ea3eaa08 73#include "Cal/AliTRDCalOnlineGainTableROC.h"
4329977a 74
f7336fa3 75ClassImp(AliTRDdigitizer)
76
77//_____________________________________________________________________________
85cbec76 78AliTRDdigitizer::AliTRDdigitizer()
4d18a639 79 :AliDigitizer()
80 ,fRunLoader(0)
81 ,fDigitsManager(0)
82 ,fSDigitsManager(0)
83 ,fSDigitsManagerList(0)
84 ,fTRD(0)
85 ,fGeo(0)
50002f37 86 ,fMcmSim(new AliTRDmcmSim)
4d18a639 87 ,fEvent(0)
88 ,fMasks(0)
89 ,fCompress(kTRUE)
90 ,fSDigits(kFALSE)
4d18a639 91 ,fMergeSignalOnly(kFALSE)
f7336fa3 92{
93 //
94 // AliTRDdigitizer default constructor
95 //
3551db50 96
f7336fa3 97}
98
99//_____________________________________________________________________________
4d18a639 100AliTRDdigitizer::AliTRDdigitizer(const Text_t *name, const Text_t *title)
101 :AliDigitizer(name,title)
102 ,fRunLoader(0)
103 ,fDigitsManager(0)
104 ,fSDigitsManager(0)
105 ,fSDigitsManagerList(0)
106 ,fTRD(0)
107 ,fGeo(0)
50002f37 108 ,fMcmSim(new AliTRDmcmSim)
4d18a639 109 ,fEvent(0)
110 ,fMasks(0)
111 ,fCompress(kTRUE)
112 ,fSDigits(kFALSE)
4d18a639 113 ,fMergeSignalOnly(kFALSE)
f7336fa3 114{
115 //
85cbec76 116 // AliTRDdigitizer constructor
117 //
118
85cbec76 119}
120
121//_____________________________________________________________________________
f21fc003 122AliTRDdigitizer::AliTRDdigitizer(AliDigitizationInput* digInput
4d18a639 123 , const Text_t *name, const Text_t *title)
f21fc003 124 :AliDigitizer(digInput,name,title)
4d18a639 125 ,fRunLoader(0)
126 ,fDigitsManager(0)
127 ,fSDigitsManager(0)
128 ,fSDigitsManagerList(0)
129 ,fTRD(0)
130 ,fGeo(0)
50002f37 131 ,fMcmSim(new AliTRDmcmSim)
4d18a639 132 ,fEvent(0)
133 ,fMasks(0)
134 ,fCompress(kTRUE)
135 ,fSDigits(kFALSE)
4d18a639 136 ,fMergeSignalOnly(kFALSE)
85cbec76 137{
138 //
139 // AliTRDdigitizer constructor
f7336fa3 140 //
141
bfc40adc 142}
143
144//_____________________________________________________________________________
f21fc003 145AliTRDdigitizer::AliTRDdigitizer(AliDigitizationInput* digInput)
146 :AliDigitizer(digInput,"AliTRDdigitizer","TRD digitizer")
4d18a639 147 ,fRunLoader(0)
148 ,fDigitsManager(0)
149 ,fSDigitsManager(0)
150 ,fSDigitsManagerList(0)
151 ,fTRD(0)
152 ,fGeo(0)
50002f37 153 ,fMcmSim(new AliTRDmcmSim)
4d18a639 154 ,fEvent(0)
155 ,fMasks(0)
156 ,fCompress(kTRUE)
157 ,fSDigits(kFALSE)
4d18a639 158 ,fMergeSignalOnly(kFALSE)
bfc40adc 159{
160 //
161 // AliTRDdigitizer constructor
162 //
163
f7336fa3 164}
165
8230f242 166//_____________________________________________________________________________
4d18a639 167AliTRDdigitizer::AliTRDdigitizer(const AliTRDdigitizer &d)
168 :AliDigitizer(d)
169 ,fRunLoader(0)
170 ,fDigitsManager(0)
171 ,fSDigitsManager(0)
172 ,fSDigitsManagerList(0)
173 ,fTRD(0)
174 ,fGeo(0)
50002f37 175 ,fMcmSim(new AliTRDmcmSim)
4d18a639 176 ,fEvent(0)
177 ,fMasks(0)
178 ,fCompress(d.fCompress)
179 ,fSDigits(d.fSDigits)
4d18a639 180 ,fMergeSignalOnly(d.fMergeSignalOnly)
8230f242 181{
182 //
183 // AliTRDdigitizer copy constructor
184 //
185
8230f242 186}
187
f7336fa3 188//_____________________________________________________________________________
189AliTRDdigitizer::~AliTRDdigitizer()
190{
8230f242 191 //
192 // AliTRDdigitizer destructor
193 //
f7336fa3 194
04e58504 195 delete fDigitsManager;
196 fDigitsManager = 0;
197
198 // s-digitsmanager will be deleted via list
199 fSDigitsManager = 0;
9deca2df 200 if (fSDigitsManagerList) {
201 fSDigitsManagerList->Delete();
202 delete fSDigitsManagerList;
203 }
04e58504 204 fSDigitsManagerList = 0;
205
206 delete [] fMasks;
207 fMasks = 0;
208
209 delete fMcmSim;
210 fMcmSim = 0;
211
212 delete fGeo;
213 fGeo = 0;
f162af62 214
f7336fa3 215}
216
8230f242 217//_____________________________________________________________________________
dd9a6ee3 218AliTRDdigitizer &AliTRDdigitizer::operator=(const AliTRDdigitizer &d)
219{
220 //
221 // Assignment operator
222 //
223
625f5260 224 if (this != &d) {
225 ((AliTRDdigitizer &) d).Copy(*this);
226 }
4d18a639 227
dd9a6ee3 228 return *this;
229
230}
231
232//_____________________________________________________________________________
e0d47c25 233void AliTRDdigitizer::Copy(TObject &d) const
8230f242 234{
235 //
236 // Copy function
237 //
238
85a5290f 239 ((AliTRDdigitizer &) d).fRunLoader = 0;
4487dad0 240 ((AliTRDdigitizer &) d).fDigitsManager = 0;
85a5290f 241 ((AliTRDdigitizer &) d).fSDigitsManager = 0;
242 ((AliTRDdigitizer &) d).fSDigitsManagerList = 0;
4487dad0 243 ((AliTRDdigitizer &) d).fTRD = 0;
244 ((AliTRDdigitizer &) d).fGeo = 0;
85a5290f 245 ((AliTRDdigitizer &) d).fEvent = 0;
246 ((AliTRDdigitizer &) d).fMasks = 0;
abaf1f1d 247 ((AliTRDdigitizer &) d).fCompress = fCompress;
abaf1f1d 248 ((AliTRDdigitizer &) d).fSDigits = fSDigits;
4487dad0 249 ((AliTRDdigitizer &) d).fMergeSignalOnly = fMergeSignalOnly;
3becff3c 250
e23fbb27 251}
252
e23fbb27 253//_____________________________________________________________________________
f21fc003 254void AliTRDdigitizer::Digitize(const Option_t* option)
e23fbb27 255{
256 //
257 // Executes the merging
258 //
259
260 Int_t iInput;
261
262 AliTRDdigitsManager *sdigitsManager;
263
264 TString optionString = option;
265 if (optionString.Contains("deb")) {
9afbd7de 266 AliLog::SetClassDebugLevel("AliTRDdigitizer",1);
7925de54 267 AliInfo("Called with debug option");
e23fbb27 268 }
269
cec4059b 270 // The AliRoot file is already connected by the manager
625f5260 271 AliRunLoader *inrl = 0x0;
88cb7938 272
9afbd7de 273 if (gAlice) {
7925de54 274 AliDebug(1,"AliRun object found on file.");
9afbd7de 275 }
4487dad0 276 else {
f21fc003 277 inrl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(0));
88cb7938 278 inrl->LoadgAlice();
279 gAlice = inrl->GetAliRun();
9afbd7de 280 if (!gAlice) {
13242232 281 AliError("Could not find AliRun object.");
9afbd7de 282 return;
283 }
4487dad0 284 }
cec4059b 285
f21fc003 286 Int_t nInput = fDigInput->GetNinputs();
4d18a639 287 fMasks = new Int_t[nInput];
e23fbb27 288 for (iInput = 0; iInput < nInput; iInput++) {
f21fc003 289 fMasks[iInput] = fDigInput->GetMask(iInput);
e23fbb27 290 }
e23fbb27 291
9afbd7de 292 //
e23fbb27 293 // Initialization
9afbd7de 294 //
e23fbb27 295
f21fc003 296 AliRunLoader *orl = AliRunLoader::GetRunLoader(fDigInput->GetOutputFolderName());
95867fd1 297
67c67368 298 if (InitDetector()) {
9afbd7de 299
95867fd1 300 AliLoader *ogime = orl->GetLoader("TRDLoader");
67c67368 301
95867fd1 302 TTree *tree = 0;
9afbd7de 303 if (fSDigits) {
304 // If we produce SDigits
305 tree = ogime->TreeS();
306 if (!tree) {
307 ogime->MakeTree("S");
67c67368 308 tree = ogime->TreeS();
67c67368 309 }
9afbd7de 310 }
311 else {
312 // If we produce Digits
313 tree = ogime->TreeD();
314 if (!tree) {
315 ogime->MakeTree("D");
316 tree = ogime->TreeD();
67c67368 317 }
9afbd7de 318 }
319
67c67368 320 MakeBranch(tree);
9afbd7de 321
67c67368 322 }
323
e23fbb27 324 for (iInput = 0; iInput < nInput; iInput++) {
325
7925de54 326 AliDebug(1,Form("Add input stream %d",iInput));
e23fbb27 327
9afbd7de 328 // Check if the input tree exists
f21fc003 329 inrl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(iInput));
4d18a639 330 AliLoader *gime = inrl->GetLoader("TRDLoader");
88cb7938 331
4d18a639 332 TTree *treees = gime->TreeS();
9afbd7de 333 if (treees == 0x0) {
334 if (gime->LoadSDigits()) {
335 AliError(Form("Error Occured while loading S. Digits for input %d.",iInput));
336 return;
337 }
4d18a639 338 treees = gime->TreeS();
9afbd7de 339 }
88cb7938 340
341 if (treees == 0x0) {
7925de54 342 AliError(Form("Input stream %d does not exist",iInput));
c57e2264 343 return;
344 }
345
e23fbb27 346 // Read the s-digits via digits manager
347 sdigitsManager = new AliTRDdigitsManager();
e23fbb27 348 sdigitsManager->SetSDigits(kTRUE);
88cb7938 349
f21fc003 350 AliRunLoader *rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(iInput));
4d18a639 351 AliLoader *gimme = rl->GetLoader("TRDLoader");
b65e5048 352 if (!gimme->TreeS())
353 {
354 gimme->LoadSDigits();
355 }
e23fbb27 356
b65e5048 357 sdigitsManager->ReadDigits(gimme->TreeS());
358
e23fbb27 359 // Add the s-digits to the input list
360 AddSDigitsManager(sdigitsManager);
361
362 }
363
364 // Convert the s-digits to normal digits
7925de54 365 AliDebug(1,"Do the conversion");
e23fbb27 366 SDigits2Digits();
367
368 // Store the digits
7925de54 369 AliDebug(1,"Write the digits");
e23fbb27 370 fDigitsManager->WriteDigits();
88cb7938 371
9afbd7de 372 // Write parameters
67c67368 373 orl->CdGAFile();
67c67368 374
26d3c914 375 // Clean up
b1113c6b 376 DeleteSDigitsManager();
377
26d3c914 378 AliDebug(1,"Done");
379
e23fbb27 380}
381
f7336fa3 382//_____________________________________________________________________________
e23fbb27 383Bool_t AliTRDdigitizer::Open(const Char_t *file, Int_t nEvent)
f7336fa3 384{
385 //
386 // Opens a ROOT-file with TRD-hits and reads in the hit-tree
387 //
f7336fa3 388 // Connect the AliRoot file containing Geometry, Kine, and Hits
3becff3c 389 //
f540341d 390
e191bb57 391 TString evfoldname = AliConfig::GetDefaultEventFolderName();
9afbd7de 392
f540341d 393 fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
9afbd7de 394 if (!fRunLoader) {
395 fRunLoader = AliRunLoader::Open(file,evfoldname,"UPDATE");
396 }
9afbd7de 397 if (!fRunLoader) {
95867fd1 398 AliError(Form("Can not open session for file %s.",file));
399 return kFALSE;
400 }
401
402 if (!fRunLoader->GetAliRun()) {
403 fRunLoader->LoadgAlice();
404 }
405 gAlice = fRunLoader->GetAliRun();
406
407 if (gAlice) {
7925de54 408 AliDebug(1,"AliRun object found on file.");
95867fd1 409 }
410 else {
7925de54 411 AliError("Could not find AliRun object.");
95867fd1 412 return kFALSE;
413 }
414
415 fEvent = nEvent;
416
417 AliLoader *loader = fRunLoader->GetLoader("TRDLoader");
418 if (!loader) {
419 AliError("Can not get TRD loader from Run Loader");
420 return kFALSE;
421 }
422
423 if (InitDetector()) {
424 TTree *tree = 0;
425 if (fSDigits) {
426 // If we produce SDigits
427 tree = loader->TreeS();
428 if (!tree) {
429 loader->MakeTree("S");
430 tree = loader->TreeS();
431 }
432 }
433 else {
434 // If we produce Digits
435 tree = loader->TreeD();
436 if (!tree) {
437 loader->MakeTree("D");
438 tree = loader->TreeD();
439 }
440 }
441 return MakeBranch(tree);
442 }
443 else {
444 return kFALSE;
445 }
446
447}
448
449//_____________________________________________________________________________
621310dd 450Bool_t AliTRDdigitizer::Open(AliRunLoader * const runLoader, Int_t nEvent)
95867fd1 451{
452 //
453 // Opens a ROOT-file with TRD-hits and reads in the hit-tree
454 //
455 // Connect the AliRoot file containing Geometry, Kine, and Hits
456 //
457
458 fRunLoader = runLoader;
459 if (!fRunLoader) {
460 AliError("RunLoader does not exist");
461 return kFALSE;
4d18a639 462 }
88cb7938 463
9afbd7de 464 if (!fRunLoader->GetAliRun()) {
465 fRunLoader->LoadgAlice();
466 }
88cb7938 467 gAlice = fRunLoader->GetAliRun();
468
da581aea 469 if (gAlice) {
7925de54 470 AliDebug(1,"AliRun object found on file.");
da581aea 471 }
472 else {
7925de54 473 AliError("Could not find AliRun object.");
da581aea 474 return kFALSE;
475 }
f7336fa3 476
477 fEvent = nEvent;
478
4d18a639 479 AliLoader *loader = fRunLoader->GetLoader("TRDLoader");
9afbd7de 480 if (!loader) {
481 AliError("Can not get TRD loader from Run Loader");
482 return kFALSE;
483 }
88cb7938 484
abaf1f1d 485 if (InitDetector()) {
4d18a639 486 TTree *tree = 0;
9afbd7de 487 if (fSDigits) {
488 // If we produce SDigits
489 tree = loader->TreeS();
490 if (!tree) {
491 loader->MakeTree("S");
492 tree = loader->TreeS();
4d18a639 493 }
9afbd7de 494 }
495 else {
496 // If we produce Digits
95867fd1 497 tree = loader->TreeD();
9afbd7de 498 if (!tree) {
499 loader->MakeTree("D");
500 tree = loader->TreeD();
4d18a639 501 }
9afbd7de 502 }
88cb7938 503 return MakeBranch(tree);
abaf1f1d 504 }
505 else {
506 return kFALSE;
507 }
793ff80c 508
509}
510
511//_____________________________________________________________________________
512Bool_t AliTRDdigitizer::InitDetector()
513{
514 //
515 // Sets the pointer to the TRD detector and the geometry
516 //
517
dd9a6ee3 518 // Get the pointer to the detector class and check for version 1
4487dad0 519 fTRD = (AliTRD *) gAlice->GetDetector("TRD");
cec4059b 520 if (!fTRD) {
7925de54 521 AliFatal("No TRD module found");
cec4059b 522 exit(1);
523 }
dd9a6ee3 524 if (fTRD->IsVersion() != 1) {
7925de54 525 AliFatal("TRD must be version 1 (slow simulator)");
dd9a6ee3 526 exit(1);
527 }
528
529 // Get the geometry
f162af62 530 fGeo = new AliTRDgeometry();
dd9a6ee3 531
abaf1f1d 532 // Create a digits manager
625f5260 533 if (fDigitsManager) {
534 delete fDigitsManager;
535 }
abaf1f1d 536 fDigitsManager = new AliTRDdigitsManager();
537 fDigitsManager->SetSDigits(fSDigits);
538 fDigitsManager->CreateArrays();
539 fDigitsManager->SetEvent(fEvent);
abaf1f1d 540
541 // The list for the input s-digits manager to be merged
47b5729a 542 if (fSDigitsManagerList) {
543 fSDigitsManagerList->Delete();
3becff3c 544 }
545 else {
47b5729a 546 fSDigitsManagerList = new TList();
547 }
abaf1f1d 548
4487dad0 549 return kTRUE;
f7336fa3 550
551}
876a928e 552
6244debe 553//_____________________________________________________________________________
95867fd1 554Bool_t AliTRDdigitizer::MakeBranch(TTree *tree) const
6244debe 555{
abaf1f1d 556 //
557 // Create the branches for the digits array
6244debe 558 //
559
88cb7938 560 return fDigitsManager->MakeBranch(tree);
6244debe 561
562}
563
625f5260 564//_____________________________________________________________________________
565void AliTRDdigitizer::AddSDigitsManager(AliTRDdigitsManager *man)
566{
567 //
568 // Add a digits manager for s-digits to the input list.
569 //
570
571 fSDigitsManagerList->Add(man);
572
573}
574
575//_____________________________________________________________________________
576void AliTRDdigitizer::DeleteSDigitsManager()
577{
578 //
579 // Removes digits manager from the input list.
580 //
581
582 fSDigitsManagerList->Delete();
583
584}
585
f7336fa3 586//_____________________________________________________________________________
587Bool_t AliTRDdigitizer::MakeDigits()
588{
589 //
872a7aba 590 // Creates digits.
f7336fa3 591 //
592
625f5260 593 AliDebug(1,"Start creating digits");
594
595 if (!fGeo) {
596 AliError("No geometry defined");
597 return kFALSE;
598 }
f7336fa3 599
625f5260 600 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
601 if (!calibration) {
602 AliFatal("Could not get calibration object");
603 return kFALSE;
604 }
605
606 const Int_t kNdet = AliTRDgeometry::Ndet();
607
608 Float_t **hits = new Float_t*[kNdet];
609 Int_t *nhit = new Int_t[kNdet];
12c9b1c3 610 memset(nhit,0,kNdet*sizeof(Int_t));
625f5260 611
b65e5048 612 AliTRDarraySignal *signals = 0x0;
5896bc23 613
876a928e 614 // Check the number of time bins from simParam against OCDB,
615 // if OCDB value is not supposed to be used.
616 // As default, the value from OCDB is taken
617 if (AliTRDSimParam::Instance()->GetNTBoverwriteOCDB()) {
618 if (calibration->GetNumberOfTimeBinsDCS() != AliTRDSimParam::Instance()->GetNTimeBins()) {
619 AliWarning(Form("Number of time bins is different to OCDB value [SIM=%d, OCDB=%d]"
620 ,AliTRDSimParam::Instance()->GetNTimeBins()
621 ,calibration->GetNumberOfTimeBinsDCS()));
622 }
623 // Save the values for the raw data headers
624 fDigitsManager->GetDigitsParam()->SetNTimeBinsAll(AliTRDSimParam::Instance()->GetNTimeBins());
625 }
626 else {
6d25aca0 627 // Get the OCDB values
628 Int_t NTB=calibration->GetNumberOfTimeBinsDCS();
629 if (NTB < 0) { // Currently -1 gets returned for "undefined" and "mixed",
630 // one might go back to -1 undefined and -2 mixed?
631 AliError("No useful DCS information available for this run! Using standard values.");
632 // We fall back to the standard OCDB object,
633 // cache the current run number..
634 Long64_t run = calibration->GetRun();
635 calibration->SetRun(0);
636 NTB=calibration->GetNumberOfTimeBinsDCS();
637 // ..to set it again
638 calibration->SetRun(run);
639 // If there's no standard OCDB object, we can still fail
640 if(NTB < 0){
641 AliFatal("No standard object found in the OCDB!");
642 }
fbe8ffe3 643 }
6d25aca0 644 // Save the values for the raw data headers
645 fDigitsManager->GetDigitsParam()->SetNTimeBinsAll(NTB);
5896bc23 646 }
876a928e 647
648 // Save the values for the raw data headers
649 fDigitsManager->GetDigitsParam()->SetADCbaselineAll(AliTRDSimParam::Instance()->GetADCbaseline());
625f5260 650
651 // Sort all hits according to detector number
652 if (!SortHits(hits,nhit)) {
653 AliError("Sorting hits failed");
024c0422 654 delete [] hits;
655 delete [] nhit;
625f5260 656 return kFALSE;
657 }
658
659 // Loop through all detectors
660 for (Int_t det = 0; det < kNdet; det++) {
661
662 // Detectors that are switched off, not installed, etc.
2f597d7f 663 if ((!calibration->IsChamberNoData(det)) &&
625f5260 664 ( fGeo->ChamberInGeometry(det)) &&
665 (nhit[det] > 0)) {
666
b65e5048 667 signals = new AliTRDarraySignal();
3d652c1f 668
625f5260 669 // Convert the hits of the current detector to detector signals
670 if (!ConvertHits(det,hits[det],nhit[det],signals)) {
b65e5048 671 AliError(Form("Conversion of hits failed for detector=%d",det));
024c0422 672 delete [] hits;
673 delete [] nhit;
674 delete signals;
675 signals = 0x0;
625f5260 676 return kFALSE;
677 }
ea3eaa08 678
625f5260 679 // Convert the detector signals to digits or s-digits
680 if (!ConvertSignals(det,signals)) {
b65e5048 681 AliError(Form("Conversion of signals failed for detector=%d",det));
024c0422 682 delete [] hits;
683 delete [] nhit;
684 delete signals;
685 signals = 0x0;
b65e5048 686 return kFALSE;
625f5260 687 }
688
689 // Delete the signals array
690 delete signals;
691 signals = 0x0;
692
693 } // if: detector status
694
27cea06a 695 delete [] hits[det];
696
625f5260 697 } // for: detector
698
ff8935b1 699 if (!fSDigits) {
ea3eaa08 700 if (AliDataLoader *trklLoader
701 = AliRunLoader::Instance()->GetLoader("TRDLoader")->GetDataLoader("tracklets")) {
ff8935b1 702 if (trklLoader->Tree())
703 trklLoader->WriteData("OVERWRITE");
704 }
705 }
ce4786b9 706
625f5260 707 delete [] hits;
708 delete [] nhit;
709
710 return kTRUE;
711
712}
713
714//_____________________________________________________________________________
715Bool_t AliTRDdigitizer::SortHits(Float_t **hits, Int_t *nhit)
716{
717 //
718 // Read all the hits and sorts them according to detector number
719 // in the output array <hits>.
720 //
721
722 AliDebug(1,"Start sorting hits");
723
724 const Int_t kNdet = AliTRDgeometry::Ndet();
725 // Size of the hit vector
726 const Int_t kNhit = 6;
727
728 Float_t *xyz = 0;
729 Int_t nhitTrk = 0;
730
731 Int_t *lhit = new Int_t[kNdet];
12c9b1c3 732 memset(lhit,0,kNdet*sizeof(Int_t));
625f5260 733
734 for (Int_t det = 0; det < kNdet; det++) {
12c9b1c3 735 hits[det] = 0x0;
625f5260 736 }
737
738 AliLoader *gimme = fRunLoader->GetLoader("TRDLoader");
739 if (!gimme->TreeH()) {
740 gimme->LoadHits();
741 }
742 TTree *hitTree = gimme->TreeH();
743 if (hitTree == 0x0) {
744 AliError("Can not get TreeH");
af63084f 745 delete [] lhit;
625f5260 746 return kFALSE;
747 }
748 fTRD->SetTreeAddress();
749
750 // Get the number of entries in the hit tree
751 // (Number of primary particles creating a hit somewhere)
752 Int_t nTrk = (Int_t) hitTree->GetEntries();
753 AliDebug(1,Form("Found %d tracks",nTrk));
754
755 // Loop through all the tracks in the tree
756 for (Int_t iTrk = 0; iTrk < nTrk; iTrk++) {
757
3e2e3ece 758 gAlice->GetMCApp()->ResetHits();
625f5260 759 hitTree->GetEvent(iTrk);
760
761 if (!fTRD->Hits()) {
762 AliError(Form("No hits array for track = %d",iTrk));
763 continue;
764 }
765
766 // Number of hits for this track
767 nhitTrk = fTRD->Hits()->GetEntriesFast();
768
769 Int_t hitCnt = 0;
770 // Loop through the TRD hits
771 AliTRDhit *hit = (AliTRDhit *) fTRD->FirstHit(-1);
772 while (hit) {
773
774 hitCnt++;
775
776 // Don't analyze test hits
777 if (((Int_t) hit->GetCharge()) != 0) {
778
779 Int_t trk = hit->Track();
780 Int_t det = hit->GetDetector();
781 Int_t q = hit->GetCharge();
782 Float_t x = hit->X();
783 Float_t y = hit->Y();
784 Float_t z = hit->Z();
785 Float_t time = hit->GetTime();
786
787 if (nhit[det] == lhit[det]) {
788 // Inititialization of new detector
789 xyz = new Float_t[kNhit*(nhitTrk+lhit[det])];
790 if (hits[det]) {
791 memcpy(xyz,hits[det],sizeof(Float_t)*kNhit*lhit[det]);
792 delete [] hits[det];
793 }
794 lhit[det] += nhitTrk;
795 hits[det] = xyz;
796 }
797 else {
798 xyz = hits[det];
799 }
800 xyz[nhit[det]*kNhit+0] = x;
801 xyz[nhit[det]*kNhit+1] = y;
802 xyz[nhit[det]*kNhit+2] = z;
803 xyz[nhit[det]*kNhit+3] = q;
804 xyz[nhit[det]*kNhit+4] = trk;
805 xyz[nhit[det]*kNhit+5] = time;
806 nhit[det]++;
807
808 } // if: charge != 0
809
810 hit = (AliTRDhit *) fTRD->NextHit();
811
812 } // for: hits of one track
813
814 } // for: tracks
815
816 delete [] lhit;
817
818 return kTRUE;
819
820}
f7336fa3 821
625f5260 822//_____________________________________________________________________________
621310dd 823Bool_t AliTRDdigitizer::ConvertHits(Int_t det
824 , const Float_t * const hits
825 , Int_t nhit
b65e5048 826 , AliTRDarraySignal *signals)
625f5260 827{
828 //
829 // Converts the detectorwise sorted hits to detector signals
830 //
831
832 AliDebug(1,Form("Start converting hits for detector=%d (nhits=%d)",det,nhit));
f7336fa3 833
793ff80c 834 // Number of pads included in the pad response
a5cadd36 835 const Int_t kNpad = 3;
793ff80c 836 // Number of track dictionary arrays
625f5260 837 const Int_t kNdict = AliTRDdigitsManager::kNDict;
838 // Size of the hit vector
839 const Int_t kNhit = 6;
793ff80c 840
4329977a 841 // Width of the amplification region
842 const Float_t kAmWidth = AliTRDgeometry::AmThick();
3becff3c 843 // Width of the drift region
ccb4315c 844 const Float_t kDrWidth = AliTRDgeometry::DrThick();
4329977a 845 // Drift + amplification region
846 const Float_t kDrMin = - 0.5 * kAmWidth;
847 const Float_t kDrMax = kDrWidth + 0.5 * kAmWidth;
3551db50 848
625f5260 849 Int_t iPad = 0;
850 Int_t dict = 0;
851 Int_t timeBinTRFend = 1;
872a7aba 852
a5cadd36 853 Double_t pos[3];
4329977a 854 Double_t loc[3];
a5cadd36 855 Double_t padSignal[kNpad];
856 Double_t signalOld[kNpad];
872a7aba 857
b65e5048 858 AliTRDarrayDictionary *dictionary[kNdict];
4329977a 859
9afbd7de 860 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
9afbd7de 861 AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
625f5260 862 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
863
3becff3c 864 if (!commonParam) {
4329977a 865 AliFatal("Could not get common parameterss");
3551db50 866 return kFALSE;
867 }
625f5260 868 if (!simParam) {
869 AliFatal("Could not get simulation parameters");
870 return kFALSE;
871 }
3becff3c 872 if (!calibration) {
4329977a 873 AliFatal("Could not get calibration object");
3551db50 874 return kFALSE;
875 }
876
625f5260 877 // Get the detector wise calibration objects
878 AliTRDCalROC *calVdriftROC = 0;
879 Float_t calVdriftDetValue = 0.0;
880 const AliTRDCalDet *calVdriftDet = calibration->GetVdriftDet();
881 AliTRDCalROC *calT0ROC = 0;
882 Float_t calT0DetValue = 0.0;
883 const AliTRDCalDet *calT0Det = calibration->GetT0Det();
9b1d8507 884 Double_t calExBDetValue = 0.0;
885 const AliTRDCalDet *calExBDet = calibration->GetExBDet();
4329977a 886
4329977a 887 if (simParam->TRFOn()) {
888 timeBinTRFend = ((Int_t) (simParam->GetTRFhi()
889 * commonParam->GetSamplingFrequency())) - 1;
4329977a 890 }
891
876a928e 892 Int_t nTimeTotal = fDigitsManager->GetDigitsParam()->GetNTimeBins(det);
b43a3e17 893 Float_t samplingRate = commonParam->GetSamplingFrequency();
4329977a 894 Float_t elAttachProp = simParam->GetElAttachProp() / 100.0;
a328fff9 895
625f5260 896 AliTRDpadPlane *padPlane = fGeo->GetPadPlane(det);
b65e5048 897 Int_t layer = fGeo->GetLayer(det); //update
625f5260 898 Float_t row0 = padPlane->GetRow0ROC();
899 Int_t nRowMax = padPlane->GetNrows();
900 Int_t nColMax = padPlane->GetNcols();
901
902 // Create a new array for the signals
903 signals->Allocate(nRowMax,nColMax,nTimeTotal);
904
905 // Create a new array for the dictionary
906 for (dict = 0; dict < kNdict; dict++) {
b65e5048 907 dictionary[dict] = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(det,dict);
625f5260 908 dictionary[dict]->Allocate(nRowMax,nColMax,nTimeTotal);
909 }
910
911 // Loop through the hits in this detector
912 for (Int_t hit = 0; hit < nhit; hit++) {
913
914 pos[0] = hits[hit*kNhit+0];
915 pos[1] = hits[hit*kNhit+1];
916 pos[2] = hits[hit*kNhit+2];
917 Float_t q = hits[hit*kNhit+3];
918 Float_t hittime = hits[hit*kNhit+5];
919 Int_t track = ((Int_t) hits[hit*kNhit+4]);
920
921 Int_t inDrift = 1;
922
923 // Find the current volume with the geo manager
924 gGeoManager->SetCurrentPoint(pos);
925 gGeoManager->FindNode();
926 if (strstr(gGeoManager->GetPath(),"/UK")) {
927 inDrift = 0;
928 }
793ff80c 929
625f5260 930 // Get the calibration objects
931 calVdriftROC = calibration->GetVdriftROC(det);
932 calVdriftDetValue = calVdriftDet->GetValue(det);
933 calT0ROC = calibration->GetT0ROC(det);
934 calT0DetValue = calT0Det->GetValue(det);
9b1d8507 935 calExBDetValue = calExBDet->GetValue(det);
625f5260 936
937 // Go to the local coordinate system:
938 // loc[0] - col direction in amplification or driftvolume
939 // loc[1] - row direction in amplification or driftvolume
940 // loc[2] - time direction in amplification or driftvolume
941 gGeoManager->MasterToLocal(pos,loc);
942 if (inDrift) {
943 // Relative to middle of amplification region
944 loc[2] = loc[2] - kDrWidth/2.0 - kAmWidth/2.0;
945 }
793ff80c 946
625f5260 947 // The driftlength [cm] (w/o diffusion yet !).
948 // It is negative if the hit is between pad plane and anode wires.
949 Double_t driftlength = -1.0 * loc[2];
e23fbb27 950
625f5260 951 // Stupid patch to take care of TR photons that are absorbed
952 // outside the chamber volume. A real fix would actually need
953 // a more clever implementation of the TR hit generation
954 if (q < 0.0) {
955 if ((loc[1] < padPlane->GetRowEndROC()) ||
956 (loc[1] > padPlane->GetRow0ROC())) {
f881dc35 957 continue;
958 }
625f5260 959 if ((driftlength < kDrMin) ||
960 (driftlength > kDrMax)) {
961 continue;
4329977a 962 }
625f5260 963 }
f881dc35 964
625f5260 965 // Get row and col of unsmeared electron to retrieve drift velocity
966 // The pad row (z-direction)
967 Int_t rowE = padPlane->GetPadRowNumberROC(loc[1]);
968 if (rowE < 0) {
969 continue;
970 }
971 Double_t rowOffset = padPlane->GetPadRowOffsetROC(rowE,loc[1]);
972 // The pad column (rphi-direction)
973 Double_t offsetTilt = padPlane->GetTiltOffset(rowOffset);
974 Int_t colE = padPlane->GetPadColNumber(loc[0]+offsetTilt);
975 if (colE < 0) {
976 continue;
977 }
0a17cc30 978 Double_t colOffset = 0.0;
f881dc35 979
625f5260 980 // Normalized drift length
981 Float_t driftvelocity = calVdriftDetValue * calVdriftROC->GetValue(colE,rowE);
982 Double_t absdriftlength = TMath::Abs(driftlength);
983 if (commonParam->ExBOn()) {
9b1d8507 984 absdriftlength /= TMath::Sqrt(1.0 / (1.0 + calExBDetValue*calExBDetValue));
625f5260 985 }
986
987 // Loop over all electrons of this hit
988 // TR photons produce hits with negative charge
989 Int_t nEl = ((Int_t) TMath::Abs(q));
990 for (Int_t iEl = 0; iEl < nEl; iEl++) {
991
992 // Now the real local coordinate system of the ROC
993 // column direction: locC
994 // row direction: locR
995 // time direction: locT
996 // locR and locC are identical to the coordinates of the corresponding
997 // volumina of the drift or amplification region.
998 // locT is defined relative to the wire plane (i.e. middle of amplification
26d3c914 999 // region), meaning locT = 0, and is negative for hits coming from the
625f5260 1000 // drift region.
1001 Double_t locC = loc[0];
1002 Double_t locR = loc[1];
1003 Double_t locT = loc[2];
1004
1005 // Electron attachment
1006 if (simParam->ElAttachOn()) {
1007 if (gRandom->Rndm() < (absdriftlength * elAttachProp)) {
1008 continue;
f881dc35 1009 }
625f5260 1010 }
1011
1012 // Apply the diffusion smearing
1013 if (simParam->DiffusionOn()) {
9b1d8507 1014 if (!(Diffusion(driftvelocity,absdriftlength,calExBDetValue,locR,locC,locT))) {
625f5260 1015 continue;
f881dc35 1016 }
f881dc35 1017 }
793ff80c 1018
625f5260 1019 // Apply E x B effects (depends on drift direction)
9b1d8507 1020 if (commonParam->ExBOn()) {
1021 locC = locC + calExBDetValue * driftlength;
729161c5 1022 }
1023
625f5260 1024 // The electron position after diffusion and ExB in pad coordinates.
4329977a 1025 // The pad row (z-direction)
625f5260 1026 rowE = padPlane->GetPadRowNumberROC(locR);
1027 if (rowE < 0) continue;
1028 rowOffset = padPlane->GetPadRowOffsetROC(rowE,locR);
4329977a 1029
1030 // The pad column (rphi-direction)
625f5260 1031 offsetTilt = padPlane->GetTiltOffset(rowOffset);
1032 colE = padPlane->GetPadColNumber(locC+offsetTilt);
1033 if (colE < 0) continue;
1034 colOffset = padPlane->GetPadColOffset(colE,locC+offsetTilt);
3d652c1f 1035
625f5260 1036 // Also re-retrieve drift velocity because col and row may have changed
1037 driftvelocity = calVdriftDetValue * calVdriftROC->GetValue(colE,rowE);
1038 Float_t t0 = calT0DetValue + calT0ROC->GetValue(colE,rowE);
1039
1040 // Convert the position to drift time [mus], using either constant drift velocity or
1041 // time structure of drift cells (non-isochronity, GARFIELD calculation).
1042 // Also add absolute time of hits to take pile-up events into account properly
1043 Double_t drifttime;
1044 if (simParam->TimeStructOn()) {
1045 // Get z-position with respect to anode wire
58897a75 1046 Double_t zz = row0 - locR + padPlane->GetAnodeWireOffset();
625f5260 1047 zz -= ((Int_t)(2 * zz)) / 2.0;
1048 if (zz > 0.25) {
1049 zz = 0.5 - zz;
1050 }
1051 // Use drift time map (GARFIELD)
a076fc2f 1052 drifttime = commonParam->TimeStruct(driftvelocity,0.5*kAmWidth-1.0*locT,zz)
625f5260 1053 + hittime;
1054 }
1055 else {
1056 // Use constant drift velocity
26d3c914 1057 drifttime = TMath::Abs(locT) / driftvelocity
625f5260 1058 + hittime;
4329977a 1059 }
625f5260 1060
1061 // Apply the gas gain including fluctuations
1062 Double_t ggRndm = 0.0;
1063 do {
1064 ggRndm = gRandom->Rndm();
1065 } while (ggRndm <= 0);
eb52b657 1066 Double_t signal = -(simParam->GetGasGain()) * TMath::Log(ggRndm);
625f5260 1067
1068 // Apply the pad response
1069 if (simParam->PRFOn()) {
1070 // The distance of the electron to the center of the pad
1071 // in units of pad width
1072 Double_t dist = (colOffset - 0.5*padPlane->GetColSize(colE))
1073 / padPlane->GetColSize(colE);
1074 // This is a fixed parametrization, i.e. not dependent on
1075 // calibration values !
053767a4 1076 if (!(calibration->PadResponse(signal,dist,layer,padSignal))) continue;
625f5260 1077 }
1078 else {
1079 padSignal[0] = 0.0;
1080 padSignal[1] = signal;
1081 padSignal[2] = 0.0;
4329977a 1082 }
f881dc35 1083
625f5260 1084 // The time bin (always positive), with t0 distortion
1085 Double_t timeBinIdeal = drifttime * samplingRate + t0;
1086 // Protection
1087 if (TMath::Abs(timeBinIdeal) > 2*nTimeTotal) {
1088 timeBinIdeal = 2 * nTimeTotal;
1089 }
1090 Int_t timeBinTruncated = ((Int_t) timeBinIdeal);
1091 // The distance of the position to the middle of the timebin
1092 Double_t timeOffset = ((Float_t) timeBinTruncated
1093 + 0.5 - timeBinIdeal) / samplingRate;
3551db50 1094
625f5260 1095 // Sample the time response inside the drift region
1096 // + additional time bins before and after.
1097 // The sampling is done always in the middle of the time bin
1098 for (Int_t iTimeBin = TMath::Max(timeBinTruncated,0)
1099 ;iTimeBin < TMath::Min(timeBinTruncated+timeBinTRFend,nTimeTotal)
1100 ;iTimeBin++) {
1101
1102 // Apply the time response
1103 Double_t timeResponse = 1.0;
1104 Double_t crossTalk = 0.0;
1105 Double_t time = (iTimeBin - timeBinTruncated) / samplingRate + timeOffset;
58897a75 1106
625f5260 1107 if (simParam->TRFOn()) {
1108 timeResponse = simParam->TimeResponse(time);
f881dc35 1109 }
625f5260 1110 if (simParam->CTOn()) {
1111 crossTalk = simParam->CrossTalk(time);
f881dc35 1112 }
e23fbb27 1113
625f5260 1114 signalOld[0] = 0.0;
1115 signalOld[1] = 0.0;
1116 signalOld[2] = 0.0;
e23fbb27 1117
625f5260 1118 for (iPad = 0; iPad < kNpad; iPad++) {
f7336fa3 1119
625f5260 1120 Int_t colPos = colE + iPad - 1;
1121 if (colPos < 0) continue;
1122 if (colPos >= nColMax) break;
e23fbb27 1123
625f5260 1124 // Add the signals
b65e5048 1125 signalOld[iPad] = signals->GetData(rowE,colPos,iTimeBin);
e23fbb27 1126
625f5260 1127 if (colPos != colE) {
1128 // Cross talk added to non-central pads
1129 signalOld[iPad] += padSignal[iPad]
1130 * (timeResponse + crossTalk);
1131 }
1132 else {
1133 // W/o cross talk at central pad
1134 signalOld[iPad] += padSignal[iPad]
1135 * timeResponse;
1136 }
f881dc35 1137
b65e5048 1138 signals->SetData(rowE,colPos,iTimeBin,signalOld[iPad]);
625f5260 1139
1140 // Store the track index in the dictionary
1141 // Note: We store index+1 in order to allow the array to be compressed
b65e5048 1142 // Note2: Taking out the +1 in track
625f5260 1143 if (signalOld[iPad] > 0.0) {
1144 for (dict = 0; dict < kNdict; dict++) {
b65e5048 1145 Int_t oldTrack = dictionary[dict]->GetData(rowE,colPos,iTimeBin);
1146 if (oldTrack == track) break;
1147 if (oldTrack == -1 ) {
1148 dictionary[dict]->SetData(rowE,colPos,iTimeBin,track);
1149 break;
1150 }
f881dc35 1151 }
625f5260 1152 }
872a7aba 1153
625f5260 1154 } // Loop: pads
f7336fa3 1155
625f5260 1156 } // Loop: time bins
f7336fa3 1157
625f5260 1158 } // Loop: electrons of a single hit
f7336fa3 1159
625f5260 1160 } // Loop: hits
f7336fa3 1161
625f5260 1162 AliDebug(2,Form("Finished analyzing %d hits",nhit));
e23fbb27 1163
625f5260 1164 return kTRUE;
e23fbb27 1165
625f5260 1166}
793ff80c 1167
625f5260 1168//_____________________________________________________________________________
b65e5048 1169Bool_t AliTRDdigitizer::ConvertSignals(Int_t det, AliTRDarraySignal *signals)
625f5260 1170{
4329977a 1171 //
625f5260 1172 // Convert signals to digits
4329977a 1173 //
1174
625f5260 1175 AliDebug(1,Form("Start converting the signals for detector %d",det));
1176
1177 if (fSDigits) {
1178 // Convert the signal array to s-digits
1179 if (!Signal2SDigits(det,signals)) {
1180 return kFALSE;
793ff80c 1181 }
625f5260 1182 }
1183 else {
1184 // Convert the signal array to digits
1185 if (!Signal2ADC(det,signals)) {
1186 return kFALSE;
793ff80c 1187 }
d295185b 1188 // Run digital processing for digits
1189 RunDigitalProcessing(det);
625f5260 1190 }
f7336fa3 1191
625f5260 1192 // Compress the arrays
3d652c1f 1193 CompressOutputArrays(det);
6244debe 1194
625f5260 1195 return kTRUE;
6244debe 1196
625f5260 1197}
4329977a 1198
625f5260 1199//_____________________________________________________________________________
b65e5048 1200Bool_t AliTRDdigitizer::Signal2ADC(Int_t det, AliTRDarraySignal *signals)
625f5260 1201{
1202 //
1203 // Converts the sampled electron signals to ADC values for a given chamber
1204 //
6244debe 1205
625f5260 1206 AliDebug(1,Form("Start converting signals to ADC values for detector=%d",det));
e23fbb27 1207
625f5260 1208 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
1209 if (!calibration) {
1210 AliFatal("Could not get calibration object");
1211 return kFALSE;
1212 }
793ff80c 1213
625f5260 1214 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
1215 if (!simParam) {
1216 AliFatal("Could not get simulation parameters");
1217 return kFALSE;
1218 }
f7336fa3 1219
625f5260 1220 // Converts number of electrons to fC
1221 const Double_t kEl2fC = 1.602e-19 * 1.0e15;
0c24ba98 1222
625f5260 1223 // Coupling factor
1224 Double_t coupling = simParam->GetPadCoupling()
1225 * simParam->GetTimeCoupling();
1226 // Electronics conversion factor
1227 Double_t convert = kEl2fC
1228 * simParam->GetChipGain();
1229 // ADC conversion factor
1230 Double_t adcConvert = simParam->GetADCoutRange()
1231 / simParam->GetADCinRange();
1232 // The electronics baseline in mV
1233 Double_t baseline = simParam->GetADCbaseline()
1234 / adcConvert;
1235 // The electronics baseline in electrons
1236 Double_t baselineEl = baseline
1237 / convert;
1238
1239 Int_t row = 0;
1240 Int_t col = 0;
1241 Int_t time = 0;
1242
1243 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1244 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
876a928e 1245 Int_t nTimeTotal = fDigitsManager->GetDigitsParam()->GetNTimeBins(det);
1246 if (fSDigitsManager->GetDigitsParam()->GetNTimeBins(det)) {
1247 nTimeTotal = fSDigitsManager->GetDigitsParam()->GetNTimeBins(det);
1248 }
1249 else {
1250 AliFatal("Could not get number of time bins");
1251 return kFALSE;
1252 }
abaf1f1d 1253
ea3eaa08 1254 // The gain factor calibration objects
893e2ec6 1255 const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
1256 AliTRDCalROC *calGainFactorROC = 0x0;
1257 Float_t calGainFactorDetValue = 0.0;
f7336fa3 1258
893e2ec6 1259 AliTRDarrayADC *digits = 0x0;
e23fbb27 1260
625f5260 1261 if (!signals) {
1262 AliError(Form("Signals array for detector %d does not exist\n",det));
1263 return kFALSE;
1264 }
1265 if (signals->HasData()) {
1266 // Expand the container if neccessary
b65e5048 1267 signals->Expand();
625f5260 1268 }
1269 else {
1270 // Create missing containers
1271 signals->Allocate(nRowMax,nColMax,nTimeTotal);
f7336fa3 1272 }
1273
625f5260 1274 // Get the container for the digits of this detector
1275 if (fDigitsManager->HasSDigits()) {
1276 AliError("Digits manager has s-digits");
1277 return kFALSE;
1278 }
b65e5048 1279
1280 digits = (AliTRDarrayADC *) fDigitsManager->GetDigits(det);
625f5260 1281 // Allocate memory space for the digits buffer
1282 if (!digits->HasData()) {
1283 digits->Allocate(nRowMax,nColMax,nTimeTotal);
0c24ba98 1284 }
1285
625f5260 1286 // Get the calibration objects
1287 calGainFactorROC = calibration->GetGainFactorROC(det);
1288 calGainFactorDetValue = calGainFactorDet->GetValue(det);
abaf1f1d 1289
625f5260 1290 // Create the digits for this chamber
1291 for (row = 0; row < nRowMax; row++ ) {
1292 for (col = 0; col < nColMax; col++ ) {
abaf1f1d 1293
3d652c1f 1294 // halfchamber masking
1295 Int_t iMcm = (Int_t)(col/18); // current group of 18 col pads
1296 Int_t halfchamberside = (iMcm>3 ? 1 : 0); // 0=Aside, 1=Bside
1297 // Halfchambers that are switched off, masked by calibration
1298 if (calibration->IsHalfChamberNoData(det, halfchamberside))
1299 continue;
1300
625f5260 1301 // Check whether pad is masked
1302 // Bridged pads are not considered yet!!!
ea3eaa08 1303 if (calibration->IsPadMasked(det,col,row) ||
1304 calibration->IsPadNotConnected(det,col,row)) {
625f5260 1305 continue;
1306 }
abaf1f1d 1307
625f5260 1308 // The gain factors
fc358d0f 1309 Float_t padgain = calGainFactorDetValue
1310 * calGainFactorROC->GetValue(col,row);
625f5260 1311 if (padgain <= 0) {
1312 AliError(Form("Not a valid gain %f, %d %d %d",padgain,det,col,row));
1313 }
abaf1f1d 1314
625f5260 1315 for (time = 0; time < nTimeTotal; time++) {
1316
1317 // Get the signal amplitude
b65e5048 1318 Float_t signalAmp = signals->GetData(row,col,time);
625f5260 1319 // Pad and time coupling
1320 signalAmp *= coupling;
1321 // Gain factors
1322 signalAmp *= padgain;
1323
1324 // Add the noise, starting from minus ADC baseline in electrons
1325 signalAmp = TMath::Max((Double_t) gRandom->Gaus(signalAmp,simParam->GetNoise())
1326 ,-baselineEl);
1327
1328 // Convert to mV
1329 signalAmp *= convert;
1330 // Add ADC baseline in mV
1331 signalAmp += baseline;
1332
1333 // Convert to ADC counts. Set the overflow-bit fADCoutRange if the
1334 // signal is larger than fADCinRange
1335 Short_t adc = 0;
1336 if (signalAmp >= simParam->GetADCinRange()) {
1337 adc = ((Short_t) simParam->GetADCoutRange());
1338 }
1339 else {
1340 adc = TMath::Nint(signalAmp * adcConvert);
1341 }
abaf1f1d 1342
b65e5048 1343 // Saving all digits
1344 digits->SetData(row,col,time,adc);
abaf1f1d 1345
625f5260 1346 } // for: time
b65e5048 1347
625f5260 1348 } // for: col
1349 } // for: row
b1113c6b 1350
625f5260 1351 return kTRUE;
b1113c6b 1352
1353}
1354
abaf1f1d 1355//_____________________________________________________________________________
b65e5048 1356Bool_t AliTRDdigitizer::Signal2SDigits(Int_t det, AliTRDarraySignal *signals)
abaf1f1d 1357{
1358 //
625f5260 1359 // Converts the sampled electron signals to s-digits
abaf1f1d 1360 //
1361
625f5260 1362 AliDebug(1,Form("Start converting signals to s-digits for detector=%d",det));
abaf1f1d 1363
4329977a 1364 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
9afbd7de 1365 if (!calibration) {
4329977a 1366 AliFatal("Could not get calibration object");
3551db50 1367 return kFALSE;
1368 }
6bf5f0ce 1369
625f5260 1370 Int_t row = 0;
1371 Int_t col = 0;
1372 Int_t time = 0;
9afbd7de 1373
625f5260 1374 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1375 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
876a928e 1376 Int_t nTimeTotal = fDigitsManager->GetDigitsParam()->GetNTimeBins(det);
e23fbb27 1377
625f5260 1378 // Get the container for the digits of this detector
1379 if (!fDigitsManager->HasSDigits()) {
1380 AliError("Digits manager has no s-digits");
1381 return kFALSE;
1382 }
b65e5048 1383
1384 AliTRDarraySignal *digits = (AliTRDarraySignal *) fDigitsManager->GetSDigits(det);
625f5260 1385 // Allocate memory space for the digits buffer
1386 if (!digits->HasData()) {
1387 digits->Allocate(nRowMax,nColMax,nTimeTotal);
1388 }
e23fbb27 1389
625f5260 1390 // Create the sdigits for this chamber
1391 for (row = 0; row < nRowMax; row++ ) {
1392 for (col = 0; col < nColMax; col++ ) {
3d652c1f 1393
1394 // halfchamber masking
1395 Int_t iMcm = (Int_t)(col/18); // current group of 18 col pads
1396 Int_t halfchamberside = (iMcm>3 ? 1 : 0); // 0=Aside, 1=Bside
1397 // Halfchambers that are switched off, masked by calibration
1398 if (calibration->IsHalfChamberNoData(det, halfchamberside))
1399 continue;
1400
1401 for (time = 0; time < nTimeTotal; time++) {
b65e5048 1402 digits->SetData(row,col,time,signals->GetData(row,col,time));
625f5260 1403 } // for: time
1404 } // for: col
1405 } // for: row
3d652c1f 1406
625f5260 1407 return kTRUE;
abaf1f1d 1408
625f5260 1409}
abaf1f1d 1410
e7539003 1411//_____________________________________________________________________________
621310dd 1412Bool_t AliTRDdigitizer::Digits2SDigits(AliTRDdigitsManager * const manDig
1413 , AliTRDdigitsManager * const manSDig)
e7539003 1414{
1415 //
1416 // Converts digits into s-digits. Needed for embedding into real data.
1417 //
1418
1419 AliDebug(1,"Start converting digits to s-digits");
1420
6b4a4228 1421 if (!fGeo) {
1422 fGeo = new AliTRDgeometry();
1423 }
1424
e7539003 1425 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
1426 if (!calibration) {
1427 AliFatal("Could not get calibration object");
1428 return kFALSE;
1429 }
1430
1431 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
1432 if (!simParam) {
1433 AliFatal("Could not get simulation parameters");
1434 return kFALSE;
1435 }
1436
1437 // Converts number of electrons to fC
1438 const Double_t kEl2fC = 1.602e-19 * 1.0e15;
1439
1440 // Coupling factor
1441 Double_t coupling = simParam->GetPadCoupling()
1442 * simParam->GetTimeCoupling();
1443 // Electronics conversion factor
1444 Double_t convert = kEl2fC
1445 * simParam->GetChipGain();
1446 // ADC conversion factor
1447 Double_t adcConvert = simParam->GetADCoutRange()
1448 / simParam->GetADCinRange();
1449 // The electronics baseline in mV
1450 Double_t baseline = simParam->GetADCbaseline()
1451 / adcConvert;
1452 // The electronics baseline in electrons
6b4a4228 1453 //Double_t baselineEl = baseline
1454 // / convert;
e7539003 1455
1456 // The gainfactor calibration objects
fc358d0f 1457 // Not used since these digits are supposed to be from real raw data
e7539003 1458 //const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
1459 //AliTRDCalROC *calGainFactorROC = 0;
1460 //Float_t calGainFactorDetValue = 0.0;
1461
1462 Int_t row = 0;
1463 Int_t col = 0;
1464 Int_t time = 0;
1465
1466 for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
1467
1468 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1469 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
a0446ff1 1470 Int_t nTimeTotal = manDig->GetDigitsParam()->GetNTimeBins(det);
e7539003 1471
1472 // Get the calibration objects
1473 //calGainFactorROC = calibration->GetGainFactorROC(det);
1474 //calGainFactorDetValue = calGainFactorDet->GetValue(det);
1475
1476 // Get the digits
1477 AliTRDarrayADC *digits = (AliTRDarrayADC *) manDig->GetDigits(det);
1478
1479 if (!manSDig->HasSDigits()) {
1480 AliError("SDigits manager has no s-digits");
1481 return kFALSE;
1482 }
1483 // Get the s-digits
1484 AliTRDarraySignal *sdigits = (AliTRDarraySignal *) manSDig->GetSDigits(det);
1485 AliTRDarrayDictionary *tracks0 = (AliTRDarrayDictionary *) manSDig->GetDictionary(det,0);
1486 AliTRDarrayDictionary *tracks1 = (AliTRDarrayDictionary *) manSDig->GetDictionary(det,1);
1487 AliTRDarrayDictionary *tracks2 = (AliTRDarrayDictionary *) manSDig->GetDictionary(det,2);
1488 // Allocate memory space for the digits buffer
1489 sdigits->Allocate(nRowMax,nColMax,nTimeTotal);
1490 tracks0->Allocate(nRowMax,nColMax,nTimeTotal);
1491 tracks1->Allocate(nRowMax,nColMax,nTimeTotal);
1492 tracks2->Allocate(nRowMax,nColMax,nTimeTotal);
1493
5896bc23 1494 // Keep the digits param
a0446ff1 1495 manSDig->GetDigitsParam()->SetNTimeBinsAll(manDig->GetDigitsParam()->GetNTimeBins(0));
1496 manSDig->GetDigitsParam()->SetADCbaselineAll(manDig->GetDigitsParam()->GetADCbaseline(0));
5896bc23 1497
45d77489 1498 if (digits->HasData()) {
1499
1500 digits->Expand();
1501
1502 // Create the sdigits for this chamber
1503 for (row = 0; row < nRowMax; row++ ) {
1504 for (col = 0; col < nColMax; col++ ) {
1505
1506 // The gain factors
1507 //Float_t padgain = calGainFactorDetValue
1508 // * calGainFactorROC->GetValue(col,row);
1509
1510 for (time = 0; time < nTimeTotal; time++) {
1511
1512 Short_t adcVal = digits->GetData(row,col,time);
1513 Double_t signal = (Double_t) adcVal;
1514 // ADC -> signal in mV
1515 signal /= adcConvert;
1516 // Subtract baseline in mV
1517 signal -= baseline;
1518 // Signal in mV -> signal in #electrons
1519 signal /= convert;
1520 // Gain factor
1521 //signal /= padgain; // Not needed for real data
1522 // Pad and time coupling
1523 signal /= coupling;
1524
1525 sdigits->SetData(row,col,time,signal);
1526 tracks0->SetData(row,col,time,0);
1527 tracks1->SetData(row,col,time,0);
1528 tracks2->SetData(row,col,time,0);
1529
1530 } // for: time
1531
1532 } // for: col
1533 } // for: row
e7539003 1534
45d77489 1535 } // if: has data
1536
e7539003 1537 sdigits->Compress(0);
1538 tracks0->Compress();
1539 tracks1->Compress();
1540 tracks2->Compress();
1541
45d77489 1542 // No compress just remove
1543 manDig->RemoveDigits(det);
1544 manDig->RemoveDictionaries(det);
1545
e7539003 1546 } // for: det
1547
1548 return kTRUE;
1549
1550}
1551
625f5260 1552//_____________________________________________________________________________
1553Bool_t AliTRDdigitizer::SDigits2Digits()
1554{
1555 //
1556 // Merges the input s-digits and converts them to normal digits
1557 //
e23fbb27 1558
625f5260 1559 if (!MergeSDigits()) {
1560 return kFALSE;
1561 }
f7336fa3 1562
625f5260 1563 return ConvertSDigits();
f7336fa3 1564
1565}
1566
16bf9884 1567//_____________________________________________________________________________
abaf1f1d 1568Bool_t AliTRDdigitizer::MergeSDigits()
16bf9884 1569{
1570 //
abaf1f1d 1571 // Merges the input s-digits:
1572 // - The amplitude of the different inputs are summed up.
1573 // - Of the track IDs from the input dictionaries only one is
1574 // kept for each input. This works for maximal 3 different merged inputs.
16bf9884 1575 //
1576
abaf1f1d 1577 // Number of track dictionary arrays
1578 const Int_t kNDict = AliTRDdigitsManager::kNDict;
1579
4d18a639 1580 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
9afbd7de 1581 if (!simParam) {
4329977a 1582 AliFatal("Could not get simulation parameters");
3551db50 1583 return kFALSE;
1584 }
1585
4d18a639 1586 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
9afbd7de 1587 if (!calibration) {
4329977a 1588 AliFatal("Could not get calibration object");
3551db50 1589 return kFALSE;
1590 }
1591
abaf1f1d 1592 Int_t iDict = 0;
e23fbb27 1593 Int_t jDict = 0;
abaf1f1d 1594
b65e5048 1595 AliTRDarraySignal *digitsA;
1596 AliTRDarraySignal *digitsB;
1597 AliTRDarrayDictionary *dictionaryA[kNDict];
1598 AliTRDarrayDictionary *dictionaryB[kNDict];
abaf1f1d 1599
b65e5048 1600 AliTRDdigitsManager *mergeSDigitsManager = 0x0;
abaf1f1d 1601 // Get the first s-digits
1602 fSDigitsManager = (AliTRDdigitsManager *) fSDigitsManagerList->First();
9afbd7de 1603 if (!fSDigitsManager) {
7925de54 1604 AliError("No SDigits manager");
9afbd7de 1605 return kFALSE;
1606 }
abaf1f1d 1607
1608 // Loop through the other sets of s-digits
b65e5048 1609 mergeSDigitsManager = (AliTRDdigitsManager *) fSDigitsManagerList->After(fSDigitsManager);
abaf1f1d 1610
9afbd7de 1611 if (mergeSDigitsManager) {
7925de54 1612 AliDebug(1,Form("Merge %d input files.",fSDigitsManagerList->GetSize()));
9afbd7de 1613 }
1614 else {
7925de54 1615 AliDebug(1,"Only one input file.");
abaf1f1d 1616 }
3551db50 1617
abaf1f1d 1618 Int_t iMerge = 0;
b65e5048 1619
abaf1f1d 1620 while (mergeSDigitsManager) {
1621
1622 iMerge++;
5896bc23 1623
abaf1f1d 1624 // Loop through the detectors
1625 for (Int_t iDet = 0; iDet < AliTRDgeometry::Ndet(); iDet++) {
1626
a0446ff1 1627 Int_t nTimeTotal = fSDigitsManager->GetDigitsParam()->GetNTimeBins(iDet);
1628 if (mergeSDigitsManager->GetDigitsParam()->GetNTimeBins(iDet) != nTimeTotal) {
1629 AliError(Form("Mismatch in the number of time bins [%d,%d] in detector %d"
1630 ,nTimeTotal
1631 ,mergeSDigitsManager->GetDigitsParam()->GetNTimeBins(iDet)
1632 ,iDet));
1633 return kFALSE;
1634 }
1635
625f5260 1636 Int_t nRowMax = fGeo->GetPadPlane(iDet)->GetNrows();
1637 Int_t nColMax = fGeo->GetPadPlane(iDet)->GetNcols();
b65e5048 1638
abaf1f1d 1639 // Loop through the pixels of one detector and add the signals
b65e5048 1640 digitsA = (AliTRDarraySignal *) fSDigitsManager->GetSDigits(iDet);
1641 digitsB = (AliTRDarraySignal *) mergeSDigitsManager->GetSDigits(iDet);
1642 digitsA->Expand();
1643 if (!digitsA->HasData()) continue;
1644 digitsB->Expand();
1645 if (!digitsB->HasData()) continue;
1646
abaf1f1d 1647 for (iDict = 0; iDict < kNDict; iDict++) {
b65e5048 1648 dictionaryA[iDict] = (AliTRDarrayDictionary *) fSDigitsManager->GetDictionary(iDet,iDict);
1649 dictionaryB[iDict] = (AliTRDarrayDictionary *) mergeSDigitsManager->GetDictionary(iDet,iDict);
1650 dictionaryA[iDict]->Expand();
abaf1f1d 1651 dictionaryB[iDict]->Expand();
1652 }
1653
4487dad0 1654 // Merge only detectors that contain a signal
1655 Bool_t doMerge = kTRUE;
1656 if (fMergeSignalOnly) {
b65e5048 1657 if (digitsA->GetOverThreshold(0) == 0) {
1658 doMerge = kFALSE;
4487dad0 1659 }
abaf1f1d 1660 }
b65e5048 1661
4487dad0 1662 if (doMerge) {
b65e5048 1663
1664 AliDebug(1,Form("Merge detector %d of input no.%d",iDet,iMerge+1));
1665
1666 for (Int_t iRow = 0; iRow < nRowMax; iRow++ ) {
1667 for (Int_t iCol = 0; iCol < nColMax; iCol++ ) {
1668 for (Int_t iTime = 0; iTime < nTimeTotal; iTime++) {
1669
4487dad0 1670 // Add the amplitudes of the summable digits
b65e5048 1671 Float_t ampA = digitsA->GetData(iRow,iCol,iTime);
1672 Float_t ampB = digitsB->GetData(iRow,iCol,iTime);
1673 ampA += ampB;
1674 digitsA->SetData(iRow,iCol,iTime,ampA);
1675
1676 // Add the mask to the track id if defined.
1677 for (iDict = 0; iDict < kNDict; iDict++) {
1678 Int_t trackB = dictionaryB[iDict]->GetData(iRow,iCol,iTime);
1679 if ((fMasks) && (trackB > 0)) {
1680 for (jDict = 0; jDict < kNDict; jDict++) {
1681 Int_t trackA = dictionaryA[iDict]->GetData(iRow,iCol,iTime);
1682 if (trackA == 0) {
1683 trackA = trackB + fMasks[iMerge];
1684 dictionaryA[iDict]->SetData(iRow,iCol,iTime,trackA);
625f5260 1685 } // if: track A == 0
b65e5048 1686 } // for: jDict
1687 } // if: fMasks and trackB > 0
625f5260 1688 } // for: iDict
abaf1f1d 1689
625f5260 1690 } // for: iTime
1691 } // for: iCol
1692 } // for: iRow
4487dad0 1693
625f5260 1694 } // if: doMerge
1695
1696 mergeSDigitsManager->RemoveDigits(iDet);
1697 mergeSDigitsManager->RemoveDictionaries(iDet);
b65e5048 1698
abaf1f1d 1699 if (fCompress) {
b65e5048 1700 digitsA->Compress(0);
1701 for (iDict = 0; iDict < kNDict; iDict++) {
1702 dictionaryA[iDict]->Compress();
abaf1f1d 1703 }
1704 }
b65e5048 1705
625f5260 1706 } // for: detectors
b65e5048 1707
abaf1f1d 1708 // The next set of s-digits
b65e5048 1709 mergeSDigitsManager = (AliTRDdigitsManager *) fSDigitsManagerList->After(mergeSDigitsManager);
1710
625f5260 1711 } // while: mergeDigitsManagers
b65e5048 1712
625f5260 1713 return kTRUE;
1714
1715}
1716
1717//_____________________________________________________________________________
1718Bool_t AliTRDdigitizer::ConvertSDigits()
1719{
1720 //
1721 // Converts s-digits to normal digits
1722 //
1723
b65e5048 1724 AliTRDarraySignal *digitsIn = 0x0;
625f5260 1725
1726 if (!fSDigitsManager->HasSDigits()) {
1727 AliError("No s-digits in digits manager");
1728 return kFALSE;
abaf1f1d 1729 }
1730
625f5260 1731 // Loop through the detectors
1732 for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
1733
1734 // Get the merged s-digits (signals)
b65e5048 1735 digitsIn = (AliTRDarraySignal *) fSDigitsManager->GetSDigits(det);
625f5260 1736 if (!digitsIn->HasData()) {
1737 AliDebug(2,Form("No digits for det=%d",det));
1738 continue;
1739 }
b0a41e80 1740
625f5260 1741 // Convert the merged sdigits to digits
1742 if (!Signal2ADC(det,digitsIn)) {
1743 continue;
1744 }
1745
1746 // Copy the dictionary information to the output array
1747 if (!CopyDictionary(det)) {
1748 continue;
1749 }
1750
1751 // Delete
1752 fSDigitsManager->RemoveDigits(det);
1753 fSDigitsManager->RemoveDictionaries(det);
1754
d295185b 1755 // Run digital processing
1756 RunDigitalProcessing(det);
1757
625f5260 1758 // Compress the arrays
1759 CompressOutputArrays(det);
1760
1761 } // for: detector numbers
1762
ff8935b1 1763 if (AliDataLoader *trklLoader = AliRunLoader::Instance()->GetLoader("TRDLoader")->GetDataLoader("tracklets")) {
1764 if (trklLoader->Tree())
1765 trklLoader->WriteData("OVERWRITE");
1766 }
1767
5896bc23 1768 // Save the values for the raw data headers
876a928e 1769 if (AliTRDSimParam::Instance()->GetNTBoverwriteOCDB()) {
1770 fDigitsManager->GetDigitsParam()->SetNTimeBinsAll(AliTRDSimParam::Instance()->GetNTimeBins());
1771 }
1772 else {
1773 fDigitsManager->GetDigitsParam()->SetNTimeBinsAll(AliTRDcalibDB::Instance()->GetNumberOfTimeBinsDCS());
1774 }
a0446ff1 1775 fDigitsManager->GetDigitsParam()->SetADCbaselineAll(AliTRDSimParam::Instance()->GetADCbaseline());
b0a41e80 1776
16bf9884 1777 return kTRUE;
1778
1779}
1780
abaf1f1d 1781//_____________________________________________________________________________
625f5260 1782Bool_t AliTRDdigitizer::CopyDictionary(Int_t det)
abaf1f1d 1783{
1784 //
625f5260 1785 // Copies the dictionary information from the s-digits arrays
1786 // to the output arrays
abaf1f1d 1787 //
1788
625f5260 1789 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
1790 if (!calibration) {
1791 AliFatal("Could not get calibration object");
4d18a639 1792 return kFALSE;
1793 }
abaf1f1d 1794
625f5260 1795 AliDebug(1,Form("Start copying dictionaries for detector=%d",det));
1796
1797 const Int_t kNDict = AliTRDdigitsManager::kNDict;
b65e5048 1798 AliTRDarrayDictionary *dictionaryIn[kNDict];
1799 AliTRDarrayDictionary *dictionaryOut[kNDict];
625f5260 1800
1801 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1802 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
876a928e 1803 Int_t nTimeTotal = fSDigitsManager->GetDigitsParam()->GetNTimeBins(det);
625f5260 1804
1805 Int_t row = 0;
1806 Int_t col = 0;
1807 Int_t time = 0;
1808 Int_t dict = 0;
1809
1810 for (dict = 0; dict < kNDict; dict++) {
1811
b65e5048 1812 dictionaryIn[dict] = (AliTRDarrayDictionary *) fSDigitsManager->GetDictionary(det,dict);
625f5260 1813 dictionaryIn[dict]->Expand();
b65e5048 1814 dictionaryOut[dict] = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(det,dict);
625f5260 1815 dictionaryOut[dict]->Allocate(nRowMax,nColMax,nTimeTotal);
1816
1817 for (row = 0; row < nRowMax; row++) {
1818 for (col = 0; col < nColMax; col++) {
1819 for (time = 0; time < nTimeTotal; time++) {
b65e5048 1820 Int_t track = dictionaryIn[dict]->GetData(row,col,time);
1821 dictionaryOut[dict]->SetData(row,col,time,track);
625f5260 1822 } // for: time
1823 } // for: col
1824 } // for: row
b65e5048 1825
625f5260 1826 } // for: dictionaries
b65e5048 1827
625f5260 1828 return kTRUE;
1829
1830}
1831
1832//_____________________________________________________________________________
1833void AliTRDdigitizer::CompressOutputArrays(Int_t det)
1834{
1835 //
1836 // Compress the output arrays
1837 //
1838
1839 const Int_t kNDict = AliTRDdigitsManager::kNDict;
b65e5048 1840 AliTRDarrayDictionary *dictionary = 0x0;
625f5260 1841
1842 if (fCompress) {
1843
b65e5048 1844 if (!fSDigits) {
1845 AliTRDarrayADC *digits = 0x0;
1846 digits = (AliTRDarrayADC *) fDigitsManager->GetDigits(det);
1847 digits->Compress();
1848 }
1849
1850 if (fSDigits) {
1851 AliTRDarraySignal *digits = 0x0;
1852 digits = (AliTRDarraySignal *) fDigitsManager->GetSDigits(det);
1853 digits->Compress(0);
1854 }
1855
625f5260 1856 for (Int_t dict = 0; dict < kNDict; dict++) {
b65e5048 1857 dictionary = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(det,dict);
1858 dictionary->Compress();
625f5260 1859 }
1860
1861 }
abaf1f1d 1862
1863}
1864
f7336fa3 1865//_____________________________________________________________________________
0a29d0f1 1866Bool_t AliTRDdigitizer::WriteDigits() const
f7336fa3 1867{
1868 //
1869 // Writes out the TRD-digits and the dictionaries
1870 //
1871
4d18a639 1872 // Write parameters
bdbb05bb 1873 fRunLoader->CdGAFile();
bdbb05bb 1874
da581aea 1875 // Store the digits and the dictionary in the tree
abaf1f1d 1876 return fDigitsManager->WriteDigits();
f7336fa3 1877
1878}
793ff80c 1879
8e64dd77 1880//_____________________________________________________________________________
88cb7938 1881void AliTRDdigitizer::InitOutput(Int_t iEvent)
8e64dd77 1882{
1883 //
1884 // Initializes the output branches
1885 //
1886
1887 fEvent = iEvent;
88cb7938 1888
9afbd7de 1889 if (!fRunLoader) {
1890 AliError("Run Loader is NULL");
1891 return;
1892 }
1893
4329977a 1894 AliLoader *loader = fRunLoader->GetLoader("TRDLoader");
9afbd7de 1895 if (!loader) {
1896 AliError("Can not get TRD loader from Run Loader");
1897 return;
1898 }
88cb7938 1899
4d18a639 1900 TTree *tree = 0;
88cb7938 1901
9afbd7de 1902 if (fSDigits) {
1903 // If we produce SDigits
88cb7938 1904 tree = loader->TreeS();
9afbd7de 1905 if (!tree) {
88cb7938 1906 loader->MakeTree("S");
1907 tree = loader->TreeS();
9afbd7de 1908 }
1909 }
1910 else {
1911 // If we produce Digits
1912 tree = loader->TreeD();
1913 if (!tree) {
1914 loader->MakeTree("D");
1915 tree = loader->TreeD();
1916 }
1917 }
88cb7938 1918 fDigitsManager->SetEvent(iEvent);
1919 fDigitsManager->MakeBranch(tree);
8e64dd77 1920
1921}
3551db50 1922
3551db50 1923//_____________________________________________________________________________
a076fc2f 1924Int_t AliTRDdigitizer::Diffusion(Float_t vdrift, Double_t absdriftlength
9b1d8507 1925 , Double_t exbvalue
a076fc2f 1926 , Double_t &lRow, Double_t &lCol, Double_t &lTime)
3551db50 1927{
1928 //
a076fc2f 1929 // Applies the diffusion smearing to the position of a single electron.
1930 // Depends on absolute drift length.
3551db50 1931 //
1932
a076fc2f 1933 Float_t diffL = 0.0;
1934 Float_t diffT = 0.0;
4d18a639 1935
a076fc2f 1936 if (AliTRDCommonParam::Instance()->GetDiffCoeff(diffL,diffT,vdrift)) {
3551db50 1937
a076fc2f 1938 Float_t driftSqrt = TMath::Sqrt(absdriftlength);
1939 Float_t sigmaT = driftSqrt * diffT;
1940 Float_t sigmaL = driftSqrt * diffL;
1941 lRow = gRandom->Gaus(lRow ,sigmaT);
9b1d8507 1942 if (AliTRDCommonParam::Instance()->ExBOn()) {
1943 lCol = gRandom->Gaus(lCol ,sigmaT * 1.0 / (1.0 + exbvalue*exbvalue));
1944 lTime = gRandom->Gaus(lTime,sigmaL * 1.0 / (1.0 + exbvalue*exbvalue));
1945 }
1946 else {
1947 lCol = gRandom->Gaus(lCol ,sigmaT);
1948 lTime = gRandom->Gaus(lTime,sigmaL);
1949 }
4d18a639 1950
a076fc2f 1951 return 1;
7754cd1f 1952
3551db50 1953 }
a076fc2f 1954 else {
3551db50 1955
a076fc2f 1956 return 0;
1b95a37b 1957
3551db50 1958 }
9afbd7de 1959
3551db50 1960}
3551db50 1961
b65e5048 1962//_____________________________________________________________________________
d295185b 1963void AliTRDdigitizer::RunDigitalProcessing(Int_t det)
b65e5048 1964{
1965 //
b0a41e80 1966 // Run the digital processing in the TRAP
b65e5048 1967 //
1968
b0a41e80 1969 AliTRDfeeParam *feeParam = AliTRDfeeParam::Instance();
b65e5048 1970
d295185b 1971 AliTRDarrayADC *digits = fDigitsManager->GetDigits(det);
1972 if (!digits)
1973 return;
1974
b65e5048 1975 //Call the methods in the mcm class using the temporary array as input
fd5349a9 1976 // process the data in the same order as in hardware
1977 for (Int_t side = 0; side <= 1; side++) {
1978 for(Int_t rob = side; rob < digits->GetNrow() / 2; rob += 2) {
1979 for(Int_t mcm = 0; mcm < 16; mcm++) {
3d652c1f 1980 fMcmSim->Init(det, rob, mcm);
fd5349a9 1981 fMcmSim->SetDataByPad(digits, fDigitsManager);
1982 fMcmSim->Filter();
1983 if (feeParam->GetTracklet()) {
1984 fMcmSim->Tracklet();
1985 fMcmSim->StoreTracklets();
1986 }
1987 fMcmSim->ZSMapping();
1988 fMcmSim->WriteData(digits);
c8b1590d 1989 }
b65e5048 1990 }
b0a41e80 1991 }
b65e5048 1992}
980493fb 1993