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