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