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