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