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