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