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