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