]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDdigitizer.cxx
ID gen=3 for all ch
[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
7298445f 628 Int_t nTB = calibration->GetNumberOfTimeBinsDCS();
629 if (nTB < 0) { // Currently -1 gets returned for "undefined" and "mixed",
6d25aca0 630 // one might go back to -1 undefined and -2 mixed?
631 AliError("No useful DCS information available for this run! Using standard values.");
7298445f 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 // }
643 nTB = AliTRDSimParam::Instance()->GetNTimeBins();
fbe8ffe3 644 }
6d25aca0 645 // Save the values for the raw data headers
7298445f 646 fDigitsManager->GetDigitsParam()->SetNTimeBinsAll(nTB);
5896bc23 647 }
876a928e 648
649 // Save the values for the raw data headers
650 fDigitsManager->GetDigitsParam()->SetADCbaselineAll(AliTRDSimParam::Instance()->GetADCbaseline());
625f5260 651
652 // Sort all hits according to detector number
653 if (!SortHits(hits,nhit)) {
654 AliError("Sorting hits failed");
024c0422 655 delete [] hits;
656 delete [] nhit;
625f5260 657 return kFALSE;
658 }
659
660 // Loop through all detectors
661 for (Int_t det = 0; det < kNdet; det++) {
662
663 // Detectors that are switched off, not installed, etc.
2f597d7f 664 if ((!calibration->IsChamberNoData(det)) &&
625f5260 665 ( fGeo->ChamberInGeometry(det)) &&
666 (nhit[det] > 0)) {
667
b65e5048 668 signals = new AliTRDarraySignal();
3d652c1f 669
625f5260 670 // Convert the hits of the current detector to detector signals
671 if (!ConvertHits(det,hits[det],nhit[det],signals)) {
b65e5048 672 AliError(Form("Conversion of hits failed for detector=%d",det));
024c0422 673 delete [] hits;
674 delete [] nhit;
675 delete signals;
676 signals = 0x0;
625f5260 677 return kFALSE;
678 }
ea3eaa08 679
625f5260 680 // Convert the detector signals to digits or s-digits
681 if (!ConvertSignals(det,signals)) {
b65e5048 682 AliError(Form("Conversion of signals failed for detector=%d",det));
024c0422 683 delete [] hits;
684 delete [] nhit;
685 delete signals;
686 signals = 0x0;
b65e5048 687 return kFALSE;
625f5260 688 }
689
690 // Delete the signals array
691 delete signals;
692 signals = 0x0;
693
694 } // if: detector status
695
27cea06a 696 delete [] hits[det];
697
625f5260 698 } // for: detector
699
ff8935b1 700 if (!fSDigits) {
ea3eaa08 701 if (AliDataLoader *trklLoader
702 = AliRunLoader::Instance()->GetLoader("TRDLoader")->GetDataLoader("tracklets")) {
ff8935b1 703 if (trklLoader->Tree())
704 trklLoader->WriteData("OVERWRITE");
705 }
706 }
ce4786b9 707
625f5260 708 delete [] hits;
709 delete [] nhit;
710
711 return kTRUE;
712
713}
714
715//_____________________________________________________________________________
716Bool_t AliTRDdigitizer::SortHits(Float_t **hits, Int_t *nhit)
717{
718 //
719 // Read all the hits and sorts them according to detector number
720 // in the output array <hits>.
721 //
722
723 AliDebug(1,"Start sorting hits");
724
725 const Int_t kNdet = AliTRDgeometry::Ndet();
726 // Size of the hit vector
727 const Int_t kNhit = 6;
728
729 Float_t *xyz = 0;
730 Int_t nhitTrk = 0;
731
732 Int_t *lhit = new Int_t[kNdet];
12c9b1c3 733 memset(lhit,0,kNdet*sizeof(Int_t));
625f5260 734
735 for (Int_t det = 0; det < kNdet; det++) {
12c9b1c3 736 hits[det] = 0x0;
625f5260 737 }
738
739 AliLoader *gimme = fRunLoader->GetLoader("TRDLoader");
740 if (!gimme->TreeH()) {
741 gimme->LoadHits();
742 }
743 TTree *hitTree = gimme->TreeH();
744 if (hitTree == 0x0) {
745 AliError("Can not get TreeH");
af63084f 746 delete [] lhit;
625f5260 747 return kFALSE;
748 }
749 fTRD->SetTreeAddress();
750
751 // Get the number of entries in the hit tree
752 // (Number of primary particles creating a hit somewhere)
753 Int_t nTrk = (Int_t) hitTree->GetEntries();
754 AliDebug(1,Form("Found %d tracks",nTrk));
755
756 // Loop through all the tracks in the tree
757 for (Int_t iTrk = 0; iTrk < nTrk; iTrk++) {
758
3e2e3ece 759 gAlice->GetMCApp()->ResetHits();
625f5260 760 hitTree->GetEvent(iTrk);
761
762 if (!fTRD->Hits()) {
763 AliError(Form("No hits array for track = %d",iTrk));
764 continue;
765 }
766
767 // Number of hits for this track
768 nhitTrk = fTRD->Hits()->GetEntriesFast();
769
770 Int_t hitCnt = 0;
771 // Loop through the TRD hits
772 AliTRDhit *hit = (AliTRDhit *) fTRD->FirstHit(-1);
773 while (hit) {
774
775 hitCnt++;
776
777 // Don't analyze test hits
778 if (((Int_t) hit->GetCharge()) != 0) {
779
780 Int_t trk = hit->Track();
781 Int_t det = hit->GetDetector();
782 Int_t q = hit->GetCharge();
783 Float_t x = hit->X();
784 Float_t y = hit->Y();
785 Float_t z = hit->Z();
786 Float_t time = hit->GetTime();
787
788 if (nhit[det] == lhit[det]) {
789 // Inititialization of new detector
790 xyz = new Float_t[kNhit*(nhitTrk+lhit[det])];
791 if (hits[det]) {
792 memcpy(xyz,hits[det],sizeof(Float_t)*kNhit*lhit[det]);
793 delete [] hits[det];
794 }
795 lhit[det] += nhitTrk;
796 hits[det] = xyz;
797 }
798 else {
799 xyz = hits[det];
800 }
801 xyz[nhit[det]*kNhit+0] = x;
802 xyz[nhit[det]*kNhit+1] = y;
803 xyz[nhit[det]*kNhit+2] = z;
804 xyz[nhit[det]*kNhit+3] = q;
805 xyz[nhit[det]*kNhit+4] = trk;
806 xyz[nhit[det]*kNhit+5] = time;
807 nhit[det]++;
808
809 } // if: charge != 0
810
811 hit = (AliTRDhit *) fTRD->NextHit();
812
813 } // for: hits of one track
814
815 } // for: tracks
816
817 delete [] lhit;
818
819 return kTRUE;
820
821}
f7336fa3 822
625f5260 823//_____________________________________________________________________________
621310dd 824Bool_t AliTRDdigitizer::ConvertHits(Int_t det
825 , const Float_t * const hits
826 , Int_t nhit
b65e5048 827 , AliTRDarraySignal *signals)
625f5260 828{
829 //
830 // Converts the detectorwise sorted hits to detector signals
831 //
832
833 AliDebug(1,Form("Start converting hits for detector=%d (nhits=%d)",det,nhit));
f7336fa3 834
793ff80c 835 // Number of pads included in the pad response
a5cadd36 836 const Int_t kNpad = 3;
793ff80c 837 // Number of track dictionary arrays
625f5260 838 const Int_t kNdict = AliTRDdigitsManager::kNDict;
839 // Size of the hit vector
840 const Int_t kNhit = 6;
793ff80c 841
4329977a 842 // Width of the amplification region
843 const Float_t kAmWidth = AliTRDgeometry::AmThick();
3becff3c 844 // Width of the drift region
ccb4315c 845 const Float_t kDrWidth = AliTRDgeometry::DrThick();
4329977a 846 // Drift + amplification region
847 const Float_t kDrMin = - 0.5 * kAmWidth;
848 const Float_t kDrMax = kDrWidth + 0.5 * kAmWidth;
3551db50 849
625f5260 850 Int_t iPad = 0;
851 Int_t dict = 0;
852 Int_t timeBinTRFend = 1;
872a7aba 853
a5cadd36 854 Double_t pos[3];
4329977a 855 Double_t loc[3];
a5cadd36 856 Double_t padSignal[kNpad];
857 Double_t signalOld[kNpad];
872a7aba 858
b65e5048 859 AliTRDarrayDictionary *dictionary[kNdict];
4329977a 860
9afbd7de 861 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
9afbd7de 862 AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
625f5260 863 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
864
3becff3c 865 if (!commonParam) {
4329977a 866 AliFatal("Could not get common parameterss");
3551db50 867 return kFALSE;
868 }
625f5260 869 if (!simParam) {
870 AliFatal("Could not get simulation parameters");
871 return kFALSE;
872 }
3becff3c 873 if (!calibration) {
4329977a 874 AliFatal("Could not get calibration object");
3551db50 875 return kFALSE;
876 }
877
625f5260 878 // Get the detector wise calibration objects
879 AliTRDCalROC *calVdriftROC = 0;
880 Float_t calVdriftDetValue = 0.0;
881 const AliTRDCalDet *calVdriftDet = calibration->GetVdriftDet();
882 AliTRDCalROC *calT0ROC = 0;
883 Float_t calT0DetValue = 0.0;
884 const AliTRDCalDet *calT0Det = calibration->GetT0Det();
9b1d8507 885 Double_t calExBDetValue = 0.0;
886 const AliTRDCalDet *calExBDet = calibration->GetExBDet();
4329977a 887
4329977a 888 if (simParam->TRFOn()) {
889 timeBinTRFend = ((Int_t) (simParam->GetTRFhi()
890 * commonParam->GetSamplingFrequency())) - 1;
4329977a 891 }
892
876a928e 893 Int_t nTimeTotal = fDigitsManager->GetDigitsParam()->GetNTimeBins(det);
b43a3e17 894 Float_t samplingRate = commonParam->GetSamplingFrequency();
4329977a 895 Float_t elAttachProp = simParam->GetElAttachProp() / 100.0;
a328fff9 896
625f5260 897 AliTRDpadPlane *padPlane = fGeo->GetPadPlane(det);
b65e5048 898 Int_t layer = fGeo->GetLayer(det); //update
625f5260 899 Float_t row0 = padPlane->GetRow0ROC();
900 Int_t nRowMax = padPlane->GetNrows();
901 Int_t nColMax = padPlane->GetNcols();
902
903 // Create a new array for the signals
904 signals->Allocate(nRowMax,nColMax,nTimeTotal);
905
906 // Create a new array for the dictionary
907 for (dict = 0; dict < kNdict; dict++) {
b65e5048 908 dictionary[dict] = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(det,dict);
625f5260 909 dictionary[dict]->Allocate(nRowMax,nColMax,nTimeTotal);
910 }
911
912 // Loop through the hits in this detector
913 for (Int_t hit = 0; hit < nhit; hit++) {
914
915 pos[0] = hits[hit*kNhit+0];
916 pos[1] = hits[hit*kNhit+1];
917 pos[2] = hits[hit*kNhit+2];
918 Float_t q = hits[hit*kNhit+3];
919 Float_t hittime = hits[hit*kNhit+5];
920 Int_t track = ((Int_t) hits[hit*kNhit+4]);
921
922 Int_t inDrift = 1;
923
924 // Find the current volume with the geo manager
925 gGeoManager->SetCurrentPoint(pos);
926 gGeoManager->FindNode();
927 if (strstr(gGeoManager->GetPath(),"/UK")) {
928 inDrift = 0;
929 }
793ff80c 930
625f5260 931 // Get the calibration objects
932 calVdriftROC = calibration->GetVdriftROC(det);
933 calVdriftDetValue = calVdriftDet->GetValue(det);
934 calT0ROC = calibration->GetT0ROC(det);
935 calT0DetValue = calT0Det->GetValue(det);
9b1d8507 936 calExBDetValue = calExBDet->GetValue(det);
625f5260 937
938 // Go to the local coordinate system:
939 // loc[0] - col direction in amplification or driftvolume
940 // loc[1] - row direction in amplification or driftvolume
941 // loc[2] - time direction in amplification or driftvolume
942 gGeoManager->MasterToLocal(pos,loc);
943 if (inDrift) {
944 // Relative to middle of amplification region
945 loc[2] = loc[2] - kDrWidth/2.0 - kAmWidth/2.0;
946 }
793ff80c 947
625f5260 948 // The driftlength [cm] (w/o diffusion yet !).
949 // It is negative if the hit is between pad plane and anode wires.
950 Double_t driftlength = -1.0 * loc[2];
e23fbb27 951
625f5260 952 // Stupid patch to take care of TR photons that are absorbed
953 // outside the chamber volume. A real fix would actually need
954 // a more clever implementation of the TR hit generation
955 if (q < 0.0) {
956 if ((loc[1] < padPlane->GetRowEndROC()) ||
957 (loc[1] > padPlane->GetRow0ROC())) {
f881dc35 958 continue;
959 }
625f5260 960 if ((driftlength < kDrMin) ||
961 (driftlength > kDrMax)) {
962 continue;
4329977a 963 }
625f5260 964 }
f881dc35 965
625f5260 966 // Get row and col of unsmeared electron to retrieve drift velocity
967 // The pad row (z-direction)
968 Int_t rowE = padPlane->GetPadRowNumberROC(loc[1]);
969 if (rowE < 0) {
970 continue;
971 }
972 Double_t rowOffset = padPlane->GetPadRowOffsetROC(rowE,loc[1]);
973 // The pad column (rphi-direction)
974 Double_t offsetTilt = padPlane->GetTiltOffset(rowOffset);
975 Int_t colE = padPlane->GetPadColNumber(loc[0]+offsetTilt);
976 if (colE < 0) {
977 continue;
978 }
0a17cc30 979 Double_t colOffset = 0.0;
f881dc35 980
625f5260 981 // Normalized drift length
982 Float_t driftvelocity = calVdriftDetValue * calVdriftROC->GetValue(colE,rowE);
983 Double_t absdriftlength = TMath::Abs(driftlength);
984 if (commonParam->ExBOn()) {
9b1d8507 985 absdriftlength /= TMath::Sqrt(1.0 / (1.0 + calExBDetValue*calExBDetValue));
625f5260 986 }
987
988 // Loop over all electrons of this hit
989 // TR photons produce hits with negative charge
990 Int_t nEl = ((Int_t) TMath::Abs(q));
991 for (Int_t iEl = 0; iEl < nEl; iEl++) {
992
993 // Now the real local coordinate system of the ROC
994 // column direction: locC
995 // row direction: locR
996 // time direction: locT
997 // locR and locC are identical to the coordinates of the corresponding
998 // volumina of the drift or amplification region.
999 // locT is defined relative to the wire plane (i.e. middle of amplification
26d3c914 1000 // region), meaning locT = 0, and is negative for hits coming from the
625f5260 1001 // drift region.
1002 Double_t locC = loc[0];
1003 Double_t locR = loc[1];
1004 Double_t locT = loc[2];
1005
1006 // Electron attachment
1007 if (simParam->ElAttachOn()) {
1008 if (gRandom->Rndm() < (absdriftlength * elAttachProp)) {
1009 continue;
f881dc35 1010 }
625f5260 1011 }
1012
1013 // Apply the diffusion smearing
1014 if (simParam->DiffusionOn()) {
9b1d8507 1015 if (!(Diffusion(driftvelocity,absdriftlength,calExBDetValue,locR,locC,locT))) {
625f5260 1016 continue;
f881dc35 1017 }
f881dc35 1018 }
793ff80c 1019
625f5260 1020 // Apply E x B effects (depends on drift direction)
9b1d8507 1021 if (commonParam->ExBOn()) {
1022 locC = locC + calExBDetValue * driftlength;
729161c5 1023 }
1024
625f5260 1025 // The electron position after diffusion and ExB in pad coordinates.
4329977a 1026 // The pad row (z-direction)
625f5260 1027 rowE = padPlane->GetPadRowNumberROC(locR);
1028 if (rowE < 0) continue;
1029 rowOffset = padPlane->GetPadRowOffsetROC(rowE,locR);
4329977a 1030
1031 // The pad column (rphi-direction)
625f5260 1032 offsetTilt = padPlane->GetTiltOffset(rowOffset);
1033 colE = padPlane->GetPadColNumber(locC+offsetTilt);
1034 if (colE < 0) continue;
1035 colOffset = padPlane->GetPadColOffset(colE,locC+offsetTilt);
3d652c1f 1036
625f5260 1037 // Also re-retrieve drift velocity because col and row may have changed
1038 driftvelocity = calVdriftDetValue * calVdriftROC->GetValue(colE,rowE);
1039 Float_t t0 = calT0DetValue + calT0ROC->GetValue(colE,rowE);
1040
1041 // Convert the position to drift time [mus], using either constant drift velocity or
1042 // time structure of drift cells (non-isochronity, GARFIELD calculation).
1043 // Also add absolute time of hits to take pile-up events into account properly
1044 Double_t drifttime;
1045 if (simParam->TimeStructOn()) {
1046 // Get z-position with respect to anode wire
58897a75 1047 Double_t zz = row0 - locR + padPlane->GetAnodeWireOffset();
625f5260 1048 zz -= ((Int_t)(2 * zz)) / 2.0;
1049 if (zz > 0.25) {
1050 zz = 0.5 - zz;
1051 }
1052 // Use drift time map (GARFIELD)
a076fc2f 1053 drifttime = commonParam->TimeStruct(driftvelocity,0.5*kAmWidth-1.0*locT,zz)
625f5260 1054 + hittime;
1055 }
1056 else {
1057 // Use constant drift velocity
26d3c914 1058 drifttime = TMath::Abs(locT) / driftvelocity
625f5260 1059 + hittime;
4329977a 1060 }
625f5260 1061
1062 // Apply the gas gain including fluctuations
1063 Double_t ggRndm = 0.0;
1064 do {
1065 ggRndm = gRandom->Rndm();
1066 } while (ggRndm <= 0);
eb52b657 1067 Double_t signal = -(simParam->GetGasGain()) * TMath::Log(ggRndm);
625f5260 1068
1069 // Apply the pad response
1070 if (simParam->PRFOn()) {
1071 // The distance of the electron to the center of the pad
1072 // in units of pad width
1073 Double_t dist = (colOffset - 0.5*padPlane->GetColSize(colE))
1074 / padPlane->GetColSize(colE);
1075 // This is a fixed parametrization, i.e. not dependent on
1076 // calibration values !
053767a4 1077 if (!(calibration->PadResponse(signal,dist,layer,padSignal))) continue;
625f5260 1078 }
1079 else {
1080 padSignal[0] = 0.0;
1081 padSignal[1] = signal;
1082 padSignal[2] = 0.0;
4329977a 1083 }
f881dc35 1084
625f5260 1085 // The time bin (always positive), with t0 distortion
1086 Double_t timeBinIdeal = drifttime * samplingRate + t0;
1087 // Protection
1088 if (TMath::Abs(timeBinIdeal) > 2*nTimeTotal) {
1089 timeBinIdeal = 2 * nTimeTotal;
1090 }
1091 Int_t timeBinTruncated = ((Int_t) timeBinIdeal);
1092 // The distance of the position to the middle of the timebin
1093 Double_t timeOffset = ((Float_t) timeBinTruncated
1094 + 0.5 - timeBinIdeal) / samplingRate;
3551db50 1095
625f5260 1096 // Sample the time response inside the drift region
1097 // + additional time bins before and after.
1098 // The sampling is done always in the middle of the time bin
1099 for (Int_t iTimeBin = TMath::Max(timeBinTruncated,0)
1100 ;iTimeBin < TMath::Min(timeBinTruncated+timeBinTRFend,nTimeTotal)
1101 ;iTimeBin++) {
1102
1103 // Apply the time response
1104 Double_t timeResponse = 1.0;
1105 Double_t crossTalk = 0.0;
1106 Double_t time = (iTimeBin - timeBinTruncated) / samplingRate + timeOffset;
58897a75 1107
625f5260 1108 if (simParam->TRFOn()) {
1109 timeResponse = simParam->TimeResponse(time);
f881dc35 1110 }
625f5260 1111 if (simParam->CTOn()) {
1112 crossTalk = simParam->CrossTalk(time);
f881dc35 1113 }
e23fbb27 1114
625f5260 1115 signalOld[0] = 0.0;
1116 signalOld[1] = 0.0;
1117 signalOld[2] = 0.0;
e23fbb27 1118
625f5260 1119 for (iPad = 0; iPad < kNpad; iPad++) {
f7336fa3 1120
625f5260 1121 Int_t colPos = colE + iPad - 1;
1122 if (colPos < 0) continue;
1123 if (colPos >= nColMax) break;
e23fbb27 1124
625f5260 1125 // Add the signals
b65e5048 1126 signalOld[iPad] = signals->GetData(rowE,colPos,iTimeBin);
e23fbb27 1127
625f5260 1128 if (colPos != colE) {
1129 // Cross talk added to non-central pads
1130 signalOld[iPad] += padSignal[iPad]
1131 * (timeResponse + crossTalk);
1132 }
1133 else {
1134 // W/o cross talk at central pad
1135 signalOld[iPad] += padSignal[iPad]
1136 * timeResponse;
1137 }
f881dc35 1138
b65e5048 1139 signals->SetData(rowE,colPos,iTimeBin,signalOld[iPad]);
625f5260 1140
1141 // Store the track index in the dictionary
1142 // Note: We store index+1 in order to allow the array to be compressed
b65e5048 1143 // Note2: Taking out the +1 in track
625f5260 1144 if (signalOld[iPad] > 0.0) {
1145 for (dict = 0; dict < kNdict; dict++) {
b65e5048 1146 Int_t oldTrack = dictionary[dict]->GetData(rowE,colPos,iTimeBin);
1147 if (oldTrack == track) break;
1148 if (oldTrack == -1 ) {
1149 dictionary[dict]->SetData(rowE,colPos,iTimeBin,track);
1150 break;
1151 }
f881dc35 1152 }
625f5260 1153 }
872a7aba 1154
625f5260 1155 } // Loop: pads
f7336fa3 1156
625f5260 1157 } // Loop: time bins
f7336fa3 1158
625f5260 1159 } // Loop: electrons of a single hit
f7336fa3 1160
625f5260 1161 } // Loop: hits
f7336fa3 1162
625f5260 1163 AliDebug(2,Form("Finished analyzing %d hits",nhit));
e23fbb27 1164
625f5260 1165 return kTRUE;
e23fbb27 1166
625f5260 1167}
793ff80c 1168
625f5260 1169//_____________________________________________________________________________
b65e5048 1170Bool_t AliTRDdigitizer::ConvertSignals(Int_t det, AliTRDarraySignal *signals)
625f5260 1171{
4329977a 1172 //
625f5260 1173 // Convert signals to digits
4329977a 1174 //
1175
625f5260 1176 AliDebug(1,Form("Start converting the signals for detector %d",det));
1177
1178 if (fSDigits) {
1179 // Convert the signal array to s-digits
1180 if (!Signal2SDigits(det,signals)) {
1181 return kFALSE;
793ff80c 1182 }
625f5260 1183 }
1184 else {
1185 // Convert the signal array to digits
1186 if (!Signal2ADC(det,signals)) {
1187 return kFALSE;
793ff80c 1188 }
d295185b 1189 // Run digital processing for digits
1190 RunDigitalProcessing(det);
625f5260 1191 }
f7336fa3 1192
625f5260 1193 // Compress the arrays
3d652c1f 1194 CompressOutputArrays(det);
6244debe 1195
625f5260 1196 return kTRUE;
6244debe 1197
625f5260 1198}
4329977a 1199
625f5260 1200//_____________________________________________________________________________
b65e5048 1201Bool_t AliTRDdigitizer::Signal2ADC(Int_t det, AliTRDarraySignal *signals)
625f5260 1202{
1203 //
1204 // Converts the sampled electron signals to ADC values for a given chamber
1205 //
6244debe 1206
625f5260 1207 AliDebug(1,Form("Start converting signals to ADC values for detector=%d",det));
e23fbb27 1208
625f5260 1209 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
1210 if (!calibration) {
1211 AliFatal("Could not get calibration object");
1212 return kFALSE;
1213 }
793ff80c 1214
625f5260 1215 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
1216 if (!simParam) {
1217 AliFatal("Could not get simulation parameters");
1218 return kFALSE;
1219 }
f7336fa3 1220
625f5260 1221 // Converts number of electrons to fC
1222 const Double_t kEl2fC = 1.602e-19 * 1.0e15;
0c24ba98 1223
625f5260 1224 // Coupling factor
1225 Double_t coupling = simParam->GetPadCoupling()
1226 * simParam->GetTimeCoupling();
1227 // Electronics conversion factor
1228 Double_t convert = kEl2fC
1229 * simParam->GetChipGain();
1230 // ADC conversion factor
1231 Double_t adcConvert = simParam->GetADCoutRange()
1232 / simParam->GetADCinRange();
1233 // The electronics baseline in mV
1234 Double_t baseline = simParam->GetADCbaseline()
1235 / adcConvert;
1236 // The electronics baseline in electrons
1237 Double_t baselineEl = baseline
1238 / convert;
1239
1240 Int_t row = 0;
1241 Int_t col = 0;
1242 Int_t time = 0;
1243
1244 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1245 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
876a928e 1246 Int_t nTimeTotal = fDigitsManager->GetDigitsParam()->GetNTimeBins(det);
1247 if (fSDigitsManager->GetDigitsParam()->GetNTimeBins(det)) {
1248 nTimeTotal = fSDigitsManager->GetDigitsParam()->GetNTimeBins(det);
1249 }
1250 else {
1251 AliFatal("Could not get number of time bins");
1252 return kFALSE;
1253 }
abaf1f1d 1254
ea3eaa08 1255 // The gain factor calibration objects
893e2ec6 1256 const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
1257 AliTRDCalROC *calGainFactorROC = 0x0;
1258 Float_t calGainFactorDetValue = 0.0;
f7336fa3 1259
893e2ec6 1260 AliTRDarrayADC *digits = 0x0;
e23fbb27 1261
625f5260 1262 if (!signals) {
1263 AliError(Form("Signals array for detector %d does not exist\n",det));
1264 return kFALSE;
1265 }
1266 if (signals->HasData()) {
1267 // Expand the container if neccessary
b65e5048 1268 signals->Expand();
625f5260 1269 }
1270 else {
1271 // Create missing containers
1272 signals->Allocate(nRowMax,nColMax,nTimeTotal);
f7336fa3 1273 }
1274
625f5260 1275 // Get the container for the digits of this detector
1276 if (fDigitsManager->HasSDigits()) {
1277 AliError("Digits manager has s-digits");
1278 return kFALSE;
1279 }
b65e5048 1280
1281 digits = (AliTRDarrayADC *) fDigitsManager->GetDigits(det);
625f5260 1282 // Allocate memory space for the digits buffer
1283 if (!digits->HasData()) {
1284 digits->Allocate(nRowMax,nColMax,nTimeTotal);
0c24ba98 1285 }
1286
625f5260 1287 // Get the calibration objects
1288 calGainFactorROC = calibration->GetGainFactorROC(det);
1289 calGainFactorDetValue = calGainFactorDet->GetValue(det);
abaf1f1d 1290
625f5260 1291 // Create the digits for this chamber
1292 for (row = 0; row < nRowMax; row++ ) {
1293 for (col = 0; col < nColMax; col++ ) {
abaf1f1d 1294
3d652c1f 1295 // halfchamber masking
1296 Int_t iMcm = (Int_t)(col/18); // current group of 18 col pads
1297 Int_t halfchamberside = (iMcm>3 ? 1 : 0); // 0=Aside, 1=Bside
1298 // Halfchambers that are switched off, masked by calibration
1299 if (calibration->IsHalfChamberNoData(det, halfchamberside))
1300 continue;
1301
625f5260 1302 // Check whether pad is masked
1303 // Bridged pads are not considered yet!!!
ea3eaa08 1304 if (calibration->IsPadMasked(det,col,row) ||
1305 calibration->IsPadNotConnected(det,col,row)) {
625f5260 1306 continue;
1307 }
abaf1f1d 1308
625f5260 1309 // The gain factors
fc358d0f 1310 Float_t padgain = calGainFactorDetValue
1311 * calGainFactorROC->GetValue(col,row);
625f5260 1312 if (padgain <= 0) {
1313 AliError(Form("Not a valid gain %f, %d %d %d",padgain,det,col,row));
1314 }
abaf1f1d 1315
625f5260 1316 for (time = 0; time < nTimeTotal; time++) {
1317
1318 // Get the signal amplitude
b65e5048 1319 Float_t signalAmp = signals->GetData(row,col,time);
625f5260 1320 // Pad and time coupling
1321 signalAmp *= coupling;
1322 // Gain factors
1323 signalAmp *= padgain;
1324
1325 // Add the noise, starting from minus ADC baseline in electrons
1326 signalAmp = TMath::Max((Double_t) gRandom->Gaus(signalAmp,simParam->GetNoise())
1327 ,-baselineEl);
1328
1329 // Convert to mV
1330 signalAmp *= convert;
1331 // Add ADC baseline in mV
1332 signalAmp += baseline;
1333
1334 // Convert to ADC counts. Set the overflow-bit fADCoutRange if the
1335 // signal is larger than fADCinRange
1336 Short_t adc = 0;
1337 if (signalAmp >= simParam->GetADCinRange()) {
1338 adc = ((Short_t) simParam->GetADCoutRange());
1339 }
1340 else {
1341 adc = TMath::Nint(signalAmp * adcConvert);
1342 }
abaf1f1d 1343
b65e5048 1344 // Saving all digits
1345 digits->SetData(row,col,time,adc);
abaf1f1d 1346
625f5260 1347 } // for: time
b65e5048 1348
625f5260 1349 } // for: col
1350 } // for: row
b1113c6b 1351
625f5260 1352 return kTRUE;
b1113c6b 1353
1354}
1355
abaf1f1d 1356//_____________________________________________________________________________
b65e5048 1357Bool_t AliTRDdigitizer::Signal2SDigits(Int_t det, AliTRDarraySignal *signals)
abaf1f1d 1358{
1359 //
625f5260 1360 // Converts the sampled electron signals to s-digits
abaf1f1d 1361 //
1362
625f5260 1363 AliDebug(1,Form("Start converting signals to s-digits for detector=%d",det));
abaf1f1d 1364
4329977a 1365 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
9afbd7de 1366 if (!calibration) {
4329977a 1367 AliFatal("Could not get calibration object");
3551db50 1368 return kFALSE;
1369 }
6bf5f0ce 1370
625f5260 1371 Int_t row = 0;
1372 Int_t col = 0;
1373 Int_t time = 0;
9afbd7de 1374
625f5260 1375 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1376 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
876a928e 1377 Int_t nTimeTotal = fDigitsManager->GetDigitsParam()->GetNTimeBins(det);
e23fbb27 1378
625f5260 1379 // Get the container for the digits of this detector
1380 if (!fDigitsManager->HasSDigits()) {
1381 AliError("Digits manager has no s-digits");
1382 return kFALSE;
1383 }
b65e5048 1384
1385 AliTRDarraySignal *digits = (AliTRDarraySignal *) fDigitsManager->GetSDigits(det);
625f5260 1386 // Allocate memory space for the digits buffer
1387 if (!digits->HasData()) {
1388 digits->Allocate(nRowMax,nColMax,nTimeTotal);
1389 }
e23fbb27 1390
625f5260 1391 // Create the sdigits for this chamber
1392 for (row = 0; row < nRowMax; row++ ) {
1393 for (col = 0; col < nColMax; col++ ) {
3d652c1f 1394
1395 // halfchamber masking
1396 Int_t iMcm = (Int_t)(col/18); // current group of 18 col pads
1397 Int_t halfchamberside = (iMcm>3 ? 1 : 0); // 0=Aside, 1=Bside
1398 // Halfchambers that are switched off, masked by calibration
1399 if (calibration->IsHalfChamberNoData(det, halfchamberside))
1400 continue;
1401
1402 for (time = 0; time < nTimeTotal; time++) {
b65e5048 1403 digits->SetData(row,col,time,signals->GetData(row,col,time));
625f5260 1404 } // for: time
1405 } // for: col
1406 } // for: row
3d652c1f 1407
625f5260 1408 return kTRUE;
abaf1f1d 1409
625f5260 1410}
abaf1f1d 1411
e7539003 1412//_____________________________________________________________________________
621310dd 1413Bool_t AliTRDdigitizer::Digits2SDigits(AliTRDdigitsManager * const manDig
1414 , AliTRDdigitsManager * const manSDig)
e7539003 1415{
1416 //
1417 // Converts digits into s-digits. Needed for embedding into real data.
1418 //
1419
1420 AliDebug(1,"Start converting digits to s-digits");
1421
6b4a4228 1422 if (!fGeo) {
1423 fGeo = new AliTRDgeometry();
1424 }
1425
e7539003 1426 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
1427 if (!calibration) {
1428 AliFatal("Could not get calibration object");
1429 return kFALSE;
1430 }
1431
1432 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
1433 if (!simParam) {
1434 AliFatal("Could not get simulation parameters");
1435 return kFALSE;
1436 }
1437
1438 // Converts number of electrons to fC
1439 const Double_t kEl2fC = 1.602e-19 * 1.0e15;
1440
1441 // Coupling factor
1442 Double_t coupling = simParam->GetPadCoupling()
1443 * simParam->GetTimeCoupling();
1444 // Electronics conversion factor
1445 Double_t convert = kEl2fC
1446 * simParam->GetChipGain();
1447 // ADC conversion factor
1448 Double_t adcConvert = simParam->GetADCoutRange()
1449 / simParam->GetADCinRange();
1450 // The electronics baseline in mV
1451 Double_t baseline = simParam->GetADCbaseline()
1452 / adcConvert;
1453 // The electronics baseline in electrons
6b4a4228 1454 //Double_t baselineEl = baseline
1455 // / convert;
e7539003 1456
1457 // The gainfactor calibration objects
fc358d0f 1458 // Not used since these digits are supposed to be from real raw data
e7539003 1459 //const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
1460 //AliTRDCalROC *calGainFactorROC = 0;
1461 //Float_t calGainFactorDetValue = 0.0;
1462
1463 Int_t row = 0;
1464 Int_t col = 0;
1465 Int_t time = 0;
1466
1467 for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
1468
1469 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1470 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
a0446ff1 1471 Int_t nTimeTotal = manDig->GetDigitsParam()->GetNTimeBins(det);
e7539003 1472
1473 // Get the calibration objects
1474 //calGainFactorROC = calibration->GetGainFactorROC(det);
1475 //calGainFactorDetValue = calGainFactorDet->GetValue(det);
1476
1477 // Get the digits
1478 AliTRDarrayADC *digits = (AliTRDarrayADC *) manDig->GetDigits(det);
1479
1480 if (!manSDig->HasSDigits()) {
1481 AliError("SDigits manager has no s-digits");
1482 return kFALSE;
1483 }
1484 // Get the s-digits
1485 AliTRDarraySignal *sdigits = (AliTRDarraySignal *) manSDig->GetSDigits(det);
1486 AliTRDarrayDictionary *tracks0 = (AliTRDarrayDictionary *) manSDig->GetDictionary(det,0);
1487 AliTRDarrayDictionary *tracks1 = (AliTRDarrayDictionary *) manSDig->GetDictionary(det,1);
1488 AliTRDarrayDictionary *tracks2 = (AliTRDarrayDictionary *) manSDig->GetDictionary(det,2);
1489 // Allocate memory space for the digits buffer
1490 sdigits->Allocate(nRowMax,nColMax,nTimeTotal);
1491 tracks0->Allocate(nRowMax,nColMax,nTimeTotal);
1492 tracks1->Allocate(nRowMax,nColMax,nTimeTotal);
1493 tracks2->Allocate(nRowMax,nColMax,nTimeTotal);
1494
5896bc23 1495 // Keep the digits param
a0446ff1 1496 manSDig->GetDigitsParam()->SetNTimeBinsAll(manDig->GetDigitsParam()->GetNTimeBins(0));
1497 manSDig->GetDigitsParam()->SetADCbaselineAll(manDig->GetDigitsParam()->GetADCbaseline(0));
5896bc23 1498
45d77489 1499 if (digits->HasData()) {
1500
1501 digits->Expand();
1502
1503 // Create the sdigits for this chamber
1504 for (row = 0; row < nRowMax; row++ ) {
1505 for (col = 0; col < nColMax; col++ ) {
1506
1507 // The gain factors
1508 //Float_t padgain = calGainFactorDetValue
1509 // * calGainFactorROC->GetValue(col,row);
1510
1511 for (time = 0; time < nTimeTotal; time++) {
1512
1513 Short_t adcVal = digits->GetData(row,col,time);
1514 Double_t signal = (Double_t) adcVal;
1515 // ADC -> signal in mV
1516 signal /= adcConvert;
1517 // Subtract baseline in mV
1518 signal -= baseline;
1519 // Signal in mV -> signal in #electrons
1520 signal /= convert;
1521 // Gain factor
1522 //signal /= padgain; // Not needed for real data
1523 // Pad and time coupling
1524 signal /= coupling;
1525
1526 sdigits->SetData(row,col,time,signal);
1527 tracks0->SetData(row,col,time,0);
1528 tracks1->SetData(row,col,time,0);
1529 tracks2->SetData(row,col,time,0);
1530
1531 } // for: time
1532
1533 } // for: col
1534 } // for: row
e7539003 1535
45d77489 1536 } // if: has data
1537
e7539003 1538 sdigits->Compress(0);
1539 tracks0->Compress();
1540 tracks1->Compress();
1541 tracks2->Compress();
1542
45d77489 1543 // No compress just remove
1544 manDig->RemoveDigits(det);
1545 manDig->RemoveDictionaries(det);
1546
e7539003 1547 } // for: det
1548
1549 return kTRUE;
1550
1551}
1552
625f5260 1553//_____________________________________________________________________________
1554Bool_t AliTRDdigitizer::SDigits2Digits()
1555{
1556 //
1557 // Merges the input s-digits and converts them to normal digits
1558 //
e23fbb27 1559
625f5260 1560 if (!MergeSDigits()) {
1561 return kFALSE;
1562 }
f7336fa3 1563
625f5260 1564 return ConvertSDigits();
f7336fa3 1565
1566}
1567
16bf9884 1568//_____________________________________________________________________________
abaf1f1d 1569Bool_t AliTRDdigitizer::MergeSDigits()
16bf9884 1570{
1571 //
abaf1f1d 1572 // Merges the input s-digits:
1573 // - The amplitude of the different inputs are summed up.
1574 // - Of the track IDs from the input dictionaries only one is
1575 // kept for each input. This works for maximal 3 different merged inputs.
16bf9884 1576 //
1577
abaf1f1d 1578 // Number of track dictionary arrays
1579 const Int_t kNDict = AliTRDdigitsManager::kNDict;
1580
4d18a639 1581 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
9afbd7de 1582 if (!simParam) {
4329977a 1583 AliFatal("Could not get simulation parameters");
3551db50 1584 return kFALSE;
1585 }
1586
4d18a639 1587 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
9afbd7de 1588 if (!calibration) {
4329977a 1589 AliFatal("Could not get calibration object");
3551db50 1590 return kFALSE;
1591 }
1592
abaf1f1d 1593 Int_t iDict = 0;
e23fbb27 1594 Int_t jDict = 0;
abaf1f1d 1595
b65e5048 1596 AliTRDarraySignal *digitsA;
1597 AliTRDarraySignal *digitsB;
1598 AliTRDarrayDictionary *dictionaryA[kNDict];
1599 AliTRDarrayDictionary *dictionaryB[kNDict];
abaf1f1d 1600
b65e5048 1601 AliTRDdigitsManager *mergeSDigitsManager = 0x0;
abaf1f1d 1602 // Get the first s-digits
1603 fSDigitsManager = (AliTRDdigitsManager *) fSDigitsManagerList->First();
9afbd7de 1604 if (!fSDigitsManager) {
7925de54 1605 AliError("No SDigits manager");
9afbd7de 1606 return kFALSE;
1607 }
abaf1f1d 1608
1609 // Loop through the other sets of s-digits
b65e5048 1610 mergeSDigitsManager = (AliTRDdigitsManager *) fSDigitsManagerList->After(fSDigitsManager);
abaf1f1d 1611
9afbd7de 1612 if (mergeSDigitsManager) {
7925de54 1613 AliDebug(1,Form("Merge %d input files.",fSDigitsManagerList->GetSize()));
9afbd7de 1614 }
1615 else {
7925de54 1616 AliDebug(1,"Only one input file.");
abaf1f1d 1617 }
3551db50 1618
abaf1f1d 1619 Int_t iMerge = 0;
b65e5048 1620
abaf1f1d 1621 while (mergeSDigitsManager) {
1622
1623 iMerge++;
5896bc23 1624
abaf1f1d 1625 // Loop through the detectors
1626 for (Int_t iDet = 0; iDet < AliTRDgeometry::Ndet(); iDet++) {
1627
a0446ff1 1628 Int_t nTimeTotal = fSDigitsManager->GetDigitsParam()->GetNTimeBins(iDet);
1629 if (mergeSDigitsManager->GetDigitsParam()->GetNTimeBins(iDet) != nTimeTotal) {
1630 AliError(Form("Mismatch in the number of time bins [%d,%d] in detector %d"
1631 ,nTimeTotal
1632 ,mergeSDigitsManager->GetDigitsParam()->GetNTimeBins(iDet)
1633 ,iDet));
1634 return kFALSE;
1635 }
1636
625f5260 1637 Int_t nRowMax = fGeo->GetPadPlane(iDet)->GetNrows();
1638 Int_t nColMax = fGeo->GetPadPlane(iDet)->GetNcols();
b65e5048 1639
abaf1f1d 1640 // Loop through the pixels of one detector and add the signals
b65e5048 1641 digitsA = (AliTRDarraySignal *) fSDigitsManager->GetSDigits(iDet);
1642 digitsB = (AliTRDarraySignal *) mergeSDigitsManager->GetSDigits(iDet);
1643 digitsA->Expand();
1644 if (!digitsA->HasData()) continue;
1645 digitsB->Expand();
1646 if (!digitsB->HasData()) continue;
1647
abaf1f1d 1648 for (iDict = 0; iDict < kNDict; iDict++) {
b65e5048 1649 dictionaryA[iDict] = (AliTRDarrayDictionary *) fSDigitsManager->GetDictionary(iDet,iDict);
1650 dictionaryB[iDict] = (AliTRDarrayDictionary *) mergeSDigitsManager->GetDictionary(iDet,iDict);
1651 dictionaryA[iDict]->Expand();
abaf1f1d 1652 dictionaryB[iDict]->Expand();
1653 }
1654
4487dad0 1655 // Merge only detectors that contain a signal
1656 Bool_t doMerge = kTRUE;
1657 if (fMergeSignalOnly) {
b65e5048 1658 if (digitsA->GetOverThreshold(0) == 0) {
1659 doMerge = kFALSE;
4487dad0 1660 }
abaf1f1d 1661 }
b65e5048 1662
4487dad0 1663 if (doMerge) {
b65e5048 1664
1665 AliDebug(1,Form("Merge detector %d of input no.%d",iDet,iMerge+1));
1666
1667 for (Int_t iRow = 0; iRow < nRowMax; iRow++ ) {
1668 for (Int_t iCol = 0; iCol < nColMax; iCol++ ) {
1669 for (Int_t iTime = 0; iTime < nTimeTotal; iTime++) {
1670
4487dad0 1671 // Add the amplitudes of the summable digits
b65e5048 1672 Float_t ampA = digitsA->GetData(iRow,iCol,iTime);
1673 Float_t ampB = digitsB->GetData(iRow,iCol,iTime);
1674 ampA += ampB;
1675 digitsA->SetData(iRow,iCol,iTime,ampA);
1676
1677 // Add the mask to the track id if defined.
1678 for (iDict = 0; iDict < kNDict; iDict++) {
1679 Int_t trackB = dictionaryB[iDict]->GetData(iRow,iCol,iTime);
1680 if ((fMasks) && (trackB > 0)) {
1681 for (jDict = 0; jDict < kNDict; jDict++) {
1682 Int_t trackA = dictionaryA[iDict]->GetData(iRow,iCol,iTime);
1683 if (trackA == 0) {
1684 trackA = trackB + fMasks[iMerge];
1685 dictionaryA[iDict]->SetData(iRow,iCol,iTime,trackA);
625f5260 1686 } // if: track A == 0
b65e5048 1687 } // for: jDict
1688 } // if: fMasks and trackB > 0
625f5260 1689 } // for: iDict
abaf1f1d 1690
625f5260 1691 } // for: iTime
1692 } // for: iCol
1693 } // for: iRow
4487dad0 1694
625f5260 1695 } // if: doMerge
1696
1697 mergeSDigitsManager->RemoveDigits(iDet);
1698 mergeSDigitsManager->RemoveDictionaries(iDet);
b65e5048 1699
abaf1f1d 1700 if (fCompress) {
b65e5048 1701 digitsA->Compress(0);
1702 for (iDict = 0; iDict < kNDict; iDict++) {
1703 dictionaryA[iDict]->Compress();
abaf1f1d 1704 }
1705 }
b65e5048 1706
625f5260 1707 } // for: detectors
b65e5048 1708
abaf1f1d 1709 // The next set of s-digits
b65e5048 1710 mergeSDigitsManager = (AliTRDdigitsManager *) fSDigitsManagerList->After(mergeSDigitsManager);
1711
625f5260 1712 } // while: mergeDigitsManagers
b65e5048 1713
625f5260 1714 return kTRUE;
1715
1716}
1717
1718//_____________________________________________________________________________
1719Bool_t AliTRDdigitizer::ConvertSDigits()
1720{
1721 //
1722 // Converts s-digits to normal digits
1723 //
1724
b65e5048 1725 AliTRDarraySignal *digitsIn = 0x0;
625f5260 1726
1727 if (!fSDigitsManager->HasSDigits()) {
1728 AliError("No s-digits in digits manager");
1729 return kFALSE;
abaf1f1d 1730 }
1731
625f5260 1732 // Loop through the detectors
1733 for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
1734
1735 // Get the merged s-digits (signals)
b65e5048 1736 digitsIn = (AliTRDarraySignal *) fSDigitsManager->GetSDigits(det);
625f5260 1737 if (!digitsIn->HasData()) {
1738 AliDebug(2,Form("No digits for det=%d",det));
1739 continue;
1740 }
b0a41e80 1741
625f5260 1742 // Convert the merged sdigits to digits
1743 if (!Signal2ADC(det,digitsIn)) {
1744 continue;
1745 }
1746
1747 // Copy the dictionary information to the output array
1748 if (!CopyDictionary(det)) {
1749 continue;
1750 }
1751
1752 // Delete
1753 fSDigitsManager->RemoveDigits(det);
1754 fSDigitsManager->RemoveDictionaries(det);
1755
d295185b 1756 // Run digital processing
1757 RunDigitalProcessing(det);
1758
625f5260 1759 // Compress the arrays
1760 CompressOutputArrays(det);
1761
1762 } // for: detector numbers
1763
ff8935b1 1764 if (AliDataLoader *trklLoader = AliRunLoader::Instance()->GetLoader("TRDLoader")->GetDataLoader("tracklets")) {
1765 if (trklLoader->Tree())
1766 trklLoader->WriteData("OVERWRITE");
1767 }
1768
5896bc23 1769 // Save the values for the raw data headers
876a928e 1770 if (AliTRDSimParam::Instance()->GetNTBoverwriteOCDB()) {
1771 fDigitsManager->GetDigitsParam()->SetNTimeBinsAll(AliTRDSimParam::Instance()->GetNTimeBins());
1772 }
1773 else {
1774 fDigitsManager->GetDigitsParam()->SetNTimeBinsAll(AliTRDcalibDB::Instance()->GetNumberOfTimeBinsDCS());
1775 }
a0446ff1 1776 fDigitsManager->GetDigitsParam()->SetADCbaselineAll(AliTRDSimParam::Instance()->GetADCbaseline());
b0a41e80 1777
16bf9884 1778 return kTRUE;
1779
1780}
1781
abaf1f1d 1782//_____________________________________________________________________________
625f5260 1783Bool_t AliTRDdigitizer::CopyDictionary(Int_t det)
abaf1f1d 1784{
1785 //
625f5260 1786 // Copies the dictionary information from the s-digits arrays
1787 // to the output arrays
abaf1f1d 1788 //
1789
625f5260 1790 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
1791 if (!calibration) {
1792 AliFatal("Could not get calibration object");
4d18a639 1793 return kFALSE;
1794 }
abaf1f1d 1795
625f5260 1796 AliDebug(1,Form("Start copying dictionaries for detector=%d",det));
1797
1798 const Int_t kNDict = AliTRDdigitsManager::kNDict;
b65e5048 1799 AliTRDarrayDictionary *dictionaryIn[kNDict];
1800 AliTRDarrayDictionary *dictionaryOut[kNDict];
625f5260 1801
1802 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1803 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
876a928e 1804 Int_t nTimeTotal = fSDigitsManager->GetDigitsParam()->GetNTimeBins(det);
625f5260 1805
1806 Int_t row = 0;
1807 Int_t col = 0;
1808 Int_t time = 0;
1809 Int_t dict = 0;
1810
1811 for (dict = 0; dict < kNDict; dict++) {
1812
b65e5048 1813 dictionaryIn[dict] = (AliTRDarrayDictionary *) fSDigitsManager->GetDictionary(det,dict);
625f5260 1814 dictionaryIn[dict]->Expand();
b65e5048 1815 dictionaryOut[dict] = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(det,dict);
625f5260 1816 dictionaryOut[dict]->Allocate(nRowMax,nColMax,nTimeTotal);
1817
1818 for (row = 0; row < nRowMax; row++) {
1819 for (col = 0; col < nColMax; col++) {
1820 for (time = 0; time < nTimeTotal; time++) {
b65e5048 1821 Int_t track = dictionaryIn[dict]->GetData(row,col,time);
1822 dictionaryOut[dict]->SetData(row,col,time,track);
625f5260 1823 } // for: time
1824 } // for: col
1825 } // for: row
b65e5048 1826
625f5260 1827 } // for: dictionaries
b65e5048 1828
625f5260 1829 return kTRUE;
1830
1831}
1832
1833//_____________________________________________________________________________
1834void AliTRDdigitizer::CompressOutputArrays(Int_t det)
1835{
1836 //
1837 // Compress the output arrays
1838 //
1839
1840 const Int_t kNDict = AliTRDdigitsManager::kNDict;
b65e5048 1841 AliTRDarrayDictionary *dictionary = 0x0;
625f5260 1842
1843 if (fCompress) {
1844
b65e5048 1845 if (!fSDigits) {
1846 AliTRDarrayADC *digits = 0x0;
1847 digits = (AliTRDarrayADC *) fDigitsManager->GetDigits(det);
1848 digits->Compress();
1849 }
1850
1851 if (fSDigits) {
1852 AliTRDarraySignal *digits = 0x0;
1853 digits = (AliTRDarraySignal *) fDigitsManager->GetSDigits(det);
1854 digits->Compress(0);
1855 }
1856
625f5260 1857 for (Int_t dict = 0; dict < kNDict; dict++) {
b65e5048 1858 dictionary = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(det,dict);
1859 dictionary->Compress();
625f5260 1860 }
1861
1862 }
abaf1f1d 1863
1864}
1865
f7336fa3 1866//_____________________________________________________________________________
0a29d0f1 1867Bool_t AliTRDdigitizer::WriteDigits() const
f7336fa3 1868{
1869 //
1870 // Writes out the TRD-digits and the dictionaries
1871 //
1872
4d18a639 1873 // Write parameters
bdbb05bb 1874 fRunLoader->CdGAFile();
bdbb05bb 1875
da581aea 1876 // Store the digits and the dictionary in the tree
abaf1f1d 1877 return fDigitsManager->WriteDigits();
f7336fa3 1878
1879}
793ff80c 1880
8e64dd77 1881//_____________________________________________________________________________
88cb7938 1882void AliTRDdigitizer::InitOutput(Int_t iEvent)
8e64dd77 1883{
1884 //
1885 // Initializes the output branches
1886 //
1887
1888 fEvent = iEvent;
88cb7938 1889
9afbd7de 1890 if (!fRunLoader) {
1891 AliError("Run Loader is NULL");
1892 return;
1893 }
1894
4329977a 1895 AliLoader *loader = fRunLoader->GetLoader("TRDLoader");
9afbd7de 1896 if (!loader) {
1897 AliError("Can not get TRD loader from Run Loader");
1898 return;
1899 }
88cb7938 1900
4d18a639 1901 TTree *tree = 0;
88cb7938 1902
9afbd7de 1903 if (fSDigits) {
1904 // If we produce SDigits
88cb7938 1905 tree = loader->TreeS();
9afbd7de 1906 if (!tree) {
88cb7938 1907 loader->MakeTree("S");
1908 tree = loader->TreeS();
9afbd7de 1909 }
1910 }
1911 else {
1912 // If we produce Digits
1913 tree = loader->TreeD();
1914 if (!tree) {
1915 loader->MakeTree("D");
1916 tree = loader->TreeD();
1917 }
1918 }
88cb7938 1919 fDigitsManager->SetEvent(iEvent);
1920 fDigitsManager->MakeBranch(tree);
8e64dd77 1921
1922}
3551db50 1923
3551db50 1924//_____________________________________________________________________________
a076fc2f 1925Int_t AliTRDdigitizer::Diffusion(Float_t vdrift, Double_t absdriftlength
9b1d8507 1926 , Double_t exbvalue
a076fc2f 1927 , Double_t &lRow, Double_t &lCol, Double_t &lTime)
3551db50 1928{
1929 //
a076fc2f 1930 // Applies the diffusion smearing to the position of a single electron.
1931 // Depends on absolute drift length.
3551db50 1932 //
1933
a076fc2f 1934 Float_t diffL = 0.0;
1935 Float_t diffT = 0.0;
4d18a639 1936
a076fc2f 1937 if (AliTRDCommonParam::Instance()->GetDiffCoeff(diffL,diffT,vdrift)) {
3551db50 1938
a076fc2f 1939 Float_t driftSqrt = TMath::Sqrt(absdriftlength);
1940 Float_t sigmaT = driftSqrt * diffT;
1941 Float_t sigmaL = driftSqrt * diffL;
1942 lRow = gRandom->Gaus(lRow ,sigmaT);
9b1d8507 1943 if (AliTRDCommonParam::Instance()->ExBOn()) {
1944 lCol = gRandom->Gaus(lCol ,sigmaT * 1.0 / (1.0 + exbvalue*exbvalue));
1945 lTime = gRandom->Gaus(lTime,sigmaL * 1.0 / (1.0 + exbvalue*exbvalue));
1946 }
1947 else {
1948 lCol = gRandom->Gaus(lCol ,sigmaT);
1949 lTime = gRandom->Gaus(lTime,sigmaL);
1950 }
4d18a639 1951
a076fc2f 1952 return 1;
7754cd1f 1953
3551db50 1954 }
a076fc2f 1955 else {
3551db50 1956
a076fc2f 1957 return 0;
1b95a37b 1958
3551db50 1959 }
9afbd7de 1960
3551db50 1961}
3551db50 1962
b65e5048 1963//_____________________________________________________________________________
d295185b 1964void AliTRDdigitizer::RunDigitalProcessing(Int_t det)
b65e5048 1965{
1966 //
b0a41e80 1967 // Run the digital processing in the TRAP
b65e5048 1968 //
1969
b0a41e80 1970 AliTRDfeeParam *feeParam = AliTRDfeeParam::Instance();
b65e5048 1971
d295185b 1972 AliTRDarrayADC *digits = fDigitsManager->GetDigits(det);
1973 if (!digits)
1974 return;
1975
b65e5048 1976 //Call the methods in the mcm class using the temporary array as input
fd5349a9 1977 // process the data in the same order as in hardware
1978 for (Int_t side = 0; side <= 1; side++) {
1979 for(Int_t rob = side; rob < digits->GetNrow() / 2; rob += 2) {
1980 for(Int_t mcm = 0; mcm < 16; mcm++) {
3d652c1f 1981 fMcmSim->Init(det, rob, mcm);
fd5349a9 1982 fMcmSim->SetDataByPad(digits, fDigitsManager);
1983 fMcmSim->Filter();
1984 if (feeParam->GetTracklet()) {
1985 fMcmSim->Tracklet();
1986 fMcmSim->StoreTracklets();
1987 }
1988 fMcmSim->ZSMapping();
1989 fMcmSim->WriteData(digits);
c8b1590d 1990 }
b65e5048 1991 }
b0a41e80 1992 }
b65e5048 1993}
980493fb 1994