Rawstream classes and digitsManager of AliTRD now changed to use new AliTRDSignalInde...
[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
f7336fa3 39#include <TMath.h>
40#include <TVector.h>
41#include <TRandom.h>
94de3818 42#include <TROOT.h>
43#include <TTree.h>
793ff80c 44#include <TFile.h>
45#include <TF1.h>
abaf1f1d 46#include <TList.h>
85cbec76 47#include <TTask.h>
3becff3c 48#include <TGeoManager.h>
793ff80c 49#include "AliRun.h"
3e2e3ece 50#include "AliMC.h"
88cb7938 51#include "AliRunLoader.h"
52#include "AliLoader.h"
53#include "AliConfig.h"
db30bf0f 54#include "AliMagF.h"
85cbec76 55#include "AliRunDigitizer.h"
88cb7938 56#include "AliRunLoader.h"
57#include "AliLoader.h"
ad2cc20b 58#include "AliLog.h"
f7336fa3 59#include "AliTRD.h"
793ff80c 60#include "AliTRDhit.h"
f7336fa3 61#include "AliTRDdigitizer.h"
b65e5048 62
63#include "AliTRDarrayDictionary.h"
64#include "AliTRDarrayADC.h"
65#include "AliTRDarraySignal.h"
da581aea 66#include "AliTRDdigitsManager.h"
793ff80c 67#include "AliTRDgeometry.h"
a5cadd36 68#include "AliTRDpadPlane.h"
3551db50 69#include "AliTRDcalibDB.h"
70#include "AliTRDSimParam.h"
71#include "AliTRDCommonParam.h"
ecf39416 72#include "AliTRDfeeParam.h"
b65e5048 73#include "AliTRDmcmSim.h"
4329977a 74#include "Cal/AliTRDCalROC.h"
75#include "Cal/AliTRDCalDet.h"
76
f7336fa3 77ClassImp(AliTRDdigitizer)
78
79//_____________________________________________________________________________
85cbec76 80AliTRDdigitizer::AliTRDdigitizer()
4d18a639 81 :AliDigitizer()
82 ,fRunLoader(0)
83 ,fDigitsManager(0)
84 ,fSDigitsManager(0)
85 ,fSDigitsManagerList(0)
86 ,fTRD(0)
87 ,fGeo(0)
88 ,fEvent(0)
89 ,fMasks(0)
90 ,fCompress(kTRUE)
91 ,fSDigits(kFALSE)
4d18a639 92 ,fMergeSignalOnly(kFALSE)
93 ,fDiffLastVdrift(0)
94 ,fDiffusionT(0.0)
95 ,fDiffusionL(0.0)
96 ,fOmegaTau(0.0)
97 ,fLorentzFactor(0.0)
98 ,fTimeLastVdrift(0)
99 ,fTimeStruct1(0)
100 ,fTimeStruct2(0)
101 ,fVDlo(0)
102 ,fVDhi(0)
f7336fa3 103{
104 //
105 // AliTRDdigitizer default constructor
106 //
3551db50 107
108 Init();
3becff3c 109
f7336fa3 110}
111
112//_____________________________________________________________________________
4d18a639 113AliTRDdigitizer::AliTRDdigitizer(const Text_t *name, const Text_t *title)
114 :AliDigitizer(name,title)
115 ,fRunLoader(0)
116 ,fDigitsManager(0)
117 ,fSDigitsManager(0)
118 ,fSDigitsManagerList(0)
119 ,fTRD(0)
120 ,fGeo(0)
121 ,fEvent(0)
122 ,fMasks(0)
123 ,fCompress(kTRUE)
124 ,fSDigits(kFALSE)
4d18a639 125 ,fMergeSignalOnly(kFALSE)
126 ,fDiffLastVdrift(0)
127 ,fDiffusionT(0.0)
128 ,fDiffusionL(0.0)
129 ,fOmegaTau(0.0)
130 ,fLorentzFactor(0.0)
131 ,fTimeLastVdrift(0)
132 ,fTimeStruct1(0)
133 ,fTimeStruct2(0)
134 ,fVDlo(0)
135 ,fVDhi(0)
f7336fa3 136{
137 //
85cbec76 138 // AliTRDdigitizer constructor
139 //
140
3551db50 141 Init();
3becff3c 142
85cbec76 143}
144
145//_____________________________________________________________________________
146AliTRDdigitizer::AliTRDdigitizer(AliRunDigitizer *manager
4d18a639 147 , const Text_t *name, const Text_t *title)
148 :AliDigitizer(manager,name,title)
149 ,fRunLoader(0)
150 ,fDigitsManager(0)
151 ,fSDigitsManager(0)
152 ,fSDigitsManagerList(0)
153 ,fTRD(0)
154 ,fGeo(0)
155 ,fEvent(0)
156 ,fMasks(0)
157 ,fCompress(kTRUE)
158 ,fSDigits(kFALSE)
4d18a639 159 ,fMergeSignalOnly(kFALSE)
160 ,fDiffLastVdrift(0)
161 ,fDiffusionT(0.0)
162 ,fDiffusionL(0.0)
163 ,fOmegaTau(0.0)
164 ,fLorentzFactor(0.0)
165 ,fTimeLastVdrift(0)
166 ,fTimeStruct1(0)
167 ,fTimeStruct2(0)
168 ,fVDlo(0)
169 ,fVDhi(0)
85cbec76 170{
171 //
172 // AliTRDdigitizer constructor
f7336fa3 173 //
174
3551db50 175 Init();
3becff3c 176
bfc40adc 177}
178
179//_____________________________________________________________________________
180AliTRDdigitizer::AliTRDdigitizer(AliRunDigitizer *manager)
4d18a639 181 :AliDigitizer(manager,"AliTRDdigitizer","TRD digitizer")
182 ,fRunLoader(0)
183 ,fDigitsManager(0)
184 ,fSDigitsManager(0)
185 ,fSDigitsManagerList(0)
186 ,fTRD(0)
187 ,fGeo(0)
188 ,fEvent(0)
189 ,fMasks(0)
190 ,fCompress(kTRUE)
191 ,fSDigits(kFALSE)
4d18a639 192 ,fMergeSignalOnly(kFALSE)
193 ,fDiffLastVdrift(0)
194 ,fDiffusionT(0.0)
195 ,fDiffusionL(0.0)
196 ,fOmegaTau(0.0)
197 ,fLorentzFactor(0.0)
198 ,fTimeLastVdrift(0)
199 ,fTimeStruct1(0)
200 ,fTimeStruct2(0)
201 ,fVDlo(0)
202 ,fVDhi(0)
bfc40adc 203{
204 //
205 // AliTRDdigitizer constructor
206 //
207
3551db50 208 Init();
3becff3c 209
3551db50 210}
88cb7938 211
3551db50 212//_____________________________________________________________________________
213Bool_t AliTRDdigitizer::Init()
214{
3becff3c 215 //
216 // Initialize the digitizer with default values
217 //
218
85a5290f 219 fRunLoader = 0;
4487dad0 220 fDigitsManager = 0;
4487dad0 221 fSDigitsManager = 0;
85a5290f 222 fSDigitsManagerList = 0;
4487dad0 223 fTRD = 0;
224 fGeo = 0;
3becff3c 225
b65e5048 226
abaf1f1d 227 fEvent = 0;
85a5290f 228 fMasks = 0;
abaf1f1d 229 fCompress = kTRUE;
abaf1f1d 230 fSDigits = kFALSE;
4487dad0 231 fMergeSignalOnly = kFALSE;
3551db50 232
4d18a639 233 fTimeLastVdrift = -1;
234 fTimeStruct1 = 0;
235 fTimeStruct2 = 0;
236 fVDlo = 0;
237 fVDhi = 0;
3551db50 238
4d18a639 239 fDiffLastVdrift = -1;
240 fDiffusionT = 0.0;
241 fDiffusionL = 0.0;
242 fLorentzFactor = 0.0;
793ff80c 243
3551db50 244 return AliDigitizer::Init();
3becff3c 245
f7336fa3 246}
247
248//_____________________________________________________________________________
4d18a639 249AliTRDdigitizer::AliTRDdigitizer(const AliTRDdigitizer &d)
250 :AliDigitizer(d)
251 ,fRunLoader(0)
252 ,fDigitsManager(0)
253 ,fSDigitsManager(0)
254 ,fSDigitsManagerList(0)
255 ,fTRD(0)
256 ,fGeo(0)
257 ,fEvent(0)
258 ,fMasks(0)
259 ,fCompress(d.fCompress)
260 ,fSDigits(d.fSDigits)
4d18a639 261 ,fMergeSignalOnly(d.fMergeSignalOnly)
262 ,fDiffLastVdrift(-1)
263 ,fDiffusionT(0.0)
264 ,fDiffusionL(0.0)
265 ,fOmegaTau(0.0)
266 ,fLorentzFactor(0.0)
267 ,fTimeLastVdrift(-1)
268 ,fTimeStruct1(0)
269 ,fTimeStruct2(0)
270 ,fVDlo(0)
271 ,fVDhi(0)
8230f242 272{
273 //
274 // AliTRDdigitizer copy constructor
275 //
276
4d18a639 277 // Do not copy timestructs, just invalidate lastvdrift.
278 // Next time they are requested, they get recalculated
279 if (((AliTRDdigitizer &) d).fTimeStruct1) {
b65e5048 280 delete [] ((AliTRDdigitizer &) d).fTimeStruct1;
4d18a639 281 ((AliTRDdigitizer &) d).fTimeStruct1 = 0;
282 }
283 if (((AliTRDdigitizer &) d).fTimeStruct2) {
284 delete [] ((AliTRDdigitizer &) d).fTimeStruct2;
285 ((AliTRDdigitizer &) d).fTimeStruct2 = 0;
286 }
8230f242 287
288}
289
290//_____________________________________________________________________________
f7336fa3 291AliTRDdigitizer::~AliTRDdigitizer()
292{
8230f242 293 //
294 // AliTRDdigitizer destructor
295 //
f7336fa3 296
abaf1f1d 297 if (fDigitsManager) {
298 delete fDigitsManager;
4d18a639 299 fDigitsManager = 0;
f7336fa3 300 }
301
b65e5048 302 if (fDigitsManager) { //typo? fSDigitsManager?
4d18a639 303 delete fSDigitsManager;
304 fSDigitsManager = 0;
305 }
f7336fa3 306
abaf1f1d 307 if (fSDigitsManagerList) {
47b5729a 308 fSDigitsManagerList->Delete();
abaf1f1d 309 delete fSDigitsManagerList;
4487dad0 310 fSDigitsManagerList = 0;
e23fbb27 311 }
312
313 if (fMasks) {
314 delete [] fMasks;
4329977a 315 fMasks = 0;
e23fbb27 316 }
317
4d18a639 318 if (fTimeStruct1) {
319 delete [] fTimeStruct1;
320 fTimeStruct1 = 0;
3551db50 321 }
322
4d18a639 323 if (fTimeStruct2) {
324 delete [] fTimeStruct2;
325 fTimeStruct2 = 0;
3551db50 326 }
3becff3c 327
f162af62 328 if (fGeo) {
329 delete fGeo;
330 fGeo = 0;
331 }
332
f7336fa3 333}
334
335//_____________________________________________________________________________
dd9a6ee3 336AliTRDdigitizer &AliTRDdigitizer::operator=(const AliTRDdigitizer &d)
337{
338 //
339 // Assignment operator
340 //
341
625f5260 342 if (this != &d) {
343 ((AliTRDdigitizer &) d).Copy(*this);
344 }
4d18a639 345
dd9a6ee3 346 return *this;
347
348}
349
350//_____________________________________________________________________________
e0d47c25 351void AliTRDdigitizer::Copy(TObject &d) const
8230f242 352{
353 //
354 // Copy function
355 //
356
85a5290f 357 ((AliTRDdigitizer &) d).fRunLoader = 0;
4487dad0 358 ((AliTRDdigitizer &) d).fDigitsManager = 0;
85a5290f 359 ((AliTRDdigitizer &) d).fSDigitsManager = 0;
360 ((AliTRDdigitizer &) d).fSDigitsManagerList = 0;
4487dad0 361 ((AliTRDdigitizer &) d).fTRD = 0;
362 ((AliTRDdigitizer &) d).fGeo = 0;
85a5290f 363 ((AliTRDdigitizer &) d).fEvent = 0;
364 ((AliTRDdigitizer &) d).fMasks = 0;
abaf1f1d 365 ((AliTRDdigitizer &) d).fCompress = fCompress;
abaf1f1d 366 ((AliTRDdigitizer &) d).fSDigits = fSDigits;
4487dad0 367 ((AliTRDdigitizer &) d).fMergeSignalOnly = fMergeSignalOnly;
0c24ba98 368
3551db50 369 AliTRDdigitizer& target = (AliTRDdigitizer &) d;
370
3becff3c 371 // Do not copy timestructs, just invalidate lastvdrift.
372 // Next time they are requested, they get recalculated
4d18a639 373 if (target.fTimeStruct1) {
95867fd1 374 delete [] target.fTimeStruct1;
4d18a639 375 target.fTimeStruct1 = 0;
3551db50 376 }
4d18a639 377 if (target.fTimeStruct2) {
95867fd1 378 delete [] target.fTimeStruct2;
4d18a639 379 target.fTimeStruct2 = 0;
3becff3c 380 }
4d18a639 381 target.fTimeLastVdrift = -1;
3becff3c 382
e23fbb27 383}
384
385//_____________________________________________________________________________
4d18a639 386void AliTRDdigitizer::Exec(Option_t *option)
e23fbb27 387{
388 //
389 // Executes the merging
390 //
391
392 Int_t iInput;
393
394 AliTRDdigitsManager *sdigitsManager;
395
396 TString optionString = option;
397 if (optionString.Contains("deb")) {
9afbd7de 398 AliLog::SetClassDebugLevel("AliTRDdigitizer",1);
7925de54 399 AliInfo("Called with debug option");
e23fbb27 400 }
401
cec4059b 402 // The AliRoot file is already connected by the manager
625f5260 403 AliRunLoader *inrl = 0x0;
88cb7938 404
9afbd7de 405 if (gAlice) {
7925de54 406 AliDebug(1,"AliRun object found on file.");
9afbd7de 407 }
4487dad0 408 else {
88cb7938 409 inrl = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
410 inrl->LoadgAlice();
411 gAlice = inrl->GetAliRun();
9afbd7de 412 if (!gAlice) {
7925de54 413 AliError("Could not find AliRun object.")
9afbd7de 414 return;
415 }
4487dad0 416 }
cec4059b 417
e23fbb27 418 Int_t nInput = fManager->GetNinputs();
4d18a639 419 fMasks = new Int_t[nInput];
e23fbb27 420 for (iInput = 0; iInput < nInput; iInput++) {
421 fMasks[iInput] = fManager->GetMask(iInput);
422 }
e23fbb27 423
9afbd7de 424 //
e23fbb27 425 // Initialization
9afbd7de 426 //
e23fbb27 427
95867fd1 428 AliRunLoader *orl = AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
429
67c67368 430 if (InitDetector()) {
9afbd7de 431
95867fd1 432 AliLoader *ogime = orl->GetLoader("TRDLoader");
67c67368 433
95867fd1 434 TTree *tree = 0;
9afbd7de 435 if (fSDigits) {
436 // If we produce SDigits
437 tree = ogime->TreeS();
438 if (!tree) {
439 ogime->MakeTree("S");
67c67368 440 tree = ogime->TreeS();
67c67368 441 }
9afbd7de 442 }
443 else {
444 // If we produce Digits
445 tree = ogime->TreeD();
446 if (!tree) {
447 ogime->MakeTree("D");
448 tree = ogime->TreeD();
67c67368 449 }
9afbd7de 450 }
451
67c67368 452 MakeBranch(tree);
9afbd7de 453
67c67368 454 }
455
e23fbb27 456 for (iInput = 0; iInput < nInput; iInput++) {
457
7925de54 458 AliDebug(1,Form("Add input stream %d",iInput));
e23fbb27 459
9afbd7de 460 // Check if the input tree exists
88cb7938 461 inrl = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(iInput));
4d18a639 462 AliLoader *gime = inrl->GetLoader("TRDLoader");
88cb7938 463
4d18a639 464 TTree *treees = gime->TreeS();
9afbd7de 465 if (treees == 0x0) {
466 if (gime->LoadSDigits()) {
467 AliError(Form("Error Occured while loading S. Digits for input %d.",iInput));
468 return;
469 }
4d18a639 470 treees = gime->TreeS();
9afbd7de 471 }
88cb7938 472
473 if (treees == 0x0) {
7925de54 474 AliError(Form("Input stream %d does not exist",iInput));
c57e2264 475 return;
476 }
477
e23fbb27 478 // Read the s-digits via digits manager
479 sdigitsManager = new AliTRDdigitsManager();
e23fbb27 480 sdigitsManager->SetSDigits(kTRUE);
88cb7938 481
4d18a639 482 AliRunLoader *rl = AliRunLoader::GetRunLoader(fManager->GetInputFolderName(iInput));
483 AliLoader *gimme = rl->GetLoader("TRDLoader");
b65e5048 484 if (!gimme->TreeS())
485 {
486 gimme->LoadSDigits();
487 }
e23fbb27 488
b65e5048 489 sdigitsManager->ReadDigits(gimme->TreeS());
490
e23fbb27 491 // Add the s-digits to the input list
492 AddSDigitsManager(sdigitsManager);
493
494 }
495
496 // Convert the s-digits to normal digits
7925de54 497 AliDebug(1,"Do the conversion");
e23fbb27 498 SDigits2Digits();
499
500 // Store the digits
7925de54 501 AliDebug(1,"Write the digits");
e23fbb27 502 fDigitsManager->WriteDigits();
88cb7938 503
9afbd7de 504 // Write parameters
67c67368 505 orl->CdGAFile();
67c67368 506
7925de54 507 AliDebug(1,"Done");
e23fbb27 508
b1113c6b 509 DeleteSDigitsManager();
510
e23fbb27 511}
512
513//_____________________________________________________________________________
e23fbb27 514Bool_t AliTRDdigitizer::Open(const Char_t *file, Int_t nEvent)
f7336fa3 515{
516 //
517 // Opens a ROOT-file with TRD-hits and reads in the hit-tree
518 //
f7336fa3 519 // Connect the AliRoot file containing Geometry, Kine, and Hits
3becff3c 520 //
f540341d 521
e191bb57 522 TString evfoldname = AliConfig::GetDefaultEventFolderName();
9afbd7de 523
f540341d 524 fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
9afbd7de 525 if (!fRunLoader) {
526 fRunLoader = AliRunLoader::Open(file,evfoldname,"UPDATE");
527 }
9afbd7de 528 if (!fRunLoader) {
95867fd1 529 AliError(Form("Can not open session for file %s.",file));
530 return kFALSE;
531 }
532
533 if (!fRunLoader->GetAliRun()) {
534 fRunLoader->LoadgAlice();
535 }
536 gAlice = fRunLoader->GetAliRun();
537
538 if (gAlice) {
7925de54 539 AliDebug(1,"AliRun object found on file.");
95867fd1 540 }
541 else {
7925de54 542 AliError("Could not find AliRun object.");
95867fd1 543 return kFALSE;
544 }
545
546 fEvent = nEvent;
547
548 AliLoader *loader = fRunLoader->GetLoader("TRDLoader");
549 if (!loader) {
550 AliError("Can not get TRD loader from Run Loader");
551 return kFALSE;
552 }
553
554 if (InitDetector()) {
555 TTree *tree = 0;
556 if (fSDigits) {
557 // If we produce SDigits
558 tree = loader->TreeS();
559 if (!tree) {
560 loader->MakeTree("S");
561 tree = loader->TreeS();
562 }
563 }
564 else {
565 // If we produce Digits
566 tree = loader->TreeD();
567 if (!tree) {
568 loader->MakeTree("D");
569 tree = loader->TreeD();
570 }
571 }
572 return MakeBranch(tree);
573 }
574 else {
575 return kFALSE;
576 }
577
578}
579
580//_____________________________________________________________________________
581Bool_t AliTRDdigitizer::Open(AliRunLoader *runLoader, Int_t nEvent)
582{
583 //
584 // Opens a ROOT-file with TRD-hits and reads in the hit-tree
585 //
586 // Connect the AliRoot file containing Geometry, Kine, and Hits
587 //
588
589 fRunLoader = runLoader;
590 if (!fRunLoader) {
591 AliError("RunLoader does not exist");
592 return kFALSE;
4d18a639 593 }
88cb7938 594
9afbd7de 595 if (!fRunLoader->GetAliRun()) {
596 fRunLoader->LoadgAlice();
597 }
88cb7938 598 gAlice = fRunLoader->GetAliRun();
599
da581aea 600 if (gAlice) {
7925de54 601 AliDebug(1,"AliRun object found on file.");
da581aea 602 }
603 else {
7925de54 604 AliError("Could not find AliRun object.");
da581aea 605 return kFALSE;
606 }
f7336fa3 607
608 fEvent = nEvent;
609
4d18a639 610 AliLoader *loader = fRunLoader->GetLoader("TRDLoader");
9afbd7de 611 if (!loader) {
612 AliError("Can not get TRD loader from Run Loader");
613 return kFALSE;
614 }
88cb7938 615
abaf1f1d 616 if (InitDetector()) {
4d18a639 617 TTree *tree = 0;
9afbd7de 618 if (fSDigits) {
619 // If we produce SDigits
620 tree = loader->TreeS();
621 if (!tree) {
622 loader->MakeTree("S");
623 tree = loader->TreeS();
4d18a639 624 }
9afbd7de 625 }
626 else {
627 // If we produce Digits
95867fd1 628 tree = loader->TreeD();
9afbd7de 629 if (!tree) {
630 loader->MakeTree("D");
631 tree = loader->TreeD();
4d18a639 632 }
9afbd7de 633 }
88cb7938 634 return MakeBranch(tree);
abaf1f1d 635 }
636 else {
637 return kFALSE;
638 }
793ff80c 639
640}
641
642//_____________________________________________________________________________
643Bool_t AliTRDdigitizer::InitDetector()
644{
645 //
646 // Sets the pointer to the TRD detector and the geometry
647 //
648
dd9a6ee3 649 // Get the pointer to the detector class and check for version 1
4487dad0 650 fTRD = (AliTRD *) gAlice->GetDetector("TRD");
cec4059b 651 if (!fTRD) {
7925de54 652 AliFatal("No TRD module found");
cec4059b 653 exit(1);
654 }
dd9a6ee3 655 if (fTRD->IsVersion() != 1) {
7925de54 656 AliFatal("TRD must be version 1 (slow simulator)");
dd9a6ee3 657 exit(1);
658 }
659
660 // Get the geometry
f162af62 661 fGeo = new AliTRDgeometry();
dd9a6ee3 662
abaf1f1d 663 // Create a digits manager
625f5260 664 if (fDigitsManager) {
665 delete fDigitsManager;
666 }
abaf1f1d 667 fDigitsManager = new AliTRDdigitsManager();
668 fDigitsManager->SetSDigits(fSDigits);
669 fDigitsManager->CreateArrays();
670 fDigitsManager->SetEvent(fEvent);
abaf1f1d 671
672 // The list for the input s-digits manager to be merged
47b5729a 673 if (fSDigitsManagerList) {
674 fSDigitsManagerList->Delete();
3becff3c 675 }
676 else {
47b5729a 677 fSDigitsManagerList = new TList();
678 }
abaf1f1d 679
4487dad0 680 return kTRUE;
f7336fa3 681
682}
f7336fa3 683//_____________________________________________________________________________
95867fd1 684Bool_t AliTRDdigitizer::MakeBranch(TTree *tree) const
6244debe 685{
abaf1f1d 686 //
687 // Create the branches for the digits array
6244debe 688 //
689
88cb7938 690 return fDigitsManager->MakeBranch(tree);
6244debe 691
692}
693
694//_____________________________________________________________________________
625f5260 695void AliTRDdigitizer::AddSDigitsManager(AliTRDdigitsManager *man)
696{
697 //
698 // Add a digits manager for s-digits to the input list.
699 //
700
701 fSDigitsManagerList->Add(man);
702
703}
704
705//_____________________________________________________________________________
706void AliTRDdigitizer::DeleteSDigitsManager()
707{
708 //
709 // Removes digits manager from the input list.
710 //
711
712 fSDigitsManagerList->Delete();
713
714}
715
716//_____________________________________________________________________________
f7336fa3 717Bool_t AliTRDdigitizer::MakeDigits()
718{
719 //
872a7aba 720 // Creates digits.
f7336fa3 721 //
722
625f5260 723 AliDebug(1,"Start creating digits");
724
725 if (!fGeo) {
726 AliError("No geometry defined");
727 return kFALSE;
728 }
f7336fa3 729
625f5260 730 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
731 if (!calibration) {
732 AliFatal("Could not get calibration object");
733 return kFALSE;
734 }
735
736 const Int_t kNdet = AliTRDgeometry::Ndet();
737
738 Float_t **hits = new Float_t*[kNdet];
739 Int_t *nhit = new Int_t[kNdet];
740
b65e5048 741 AliTRDarraySignal *signals = 0x0;
625f5260 742
743 // Sort all hits according to detector number
744 if (!SortHits(hits,nhit)) {
745 AliError("Sorting hits failed");
746 return kFALSE;
747 }
748
749 // Loop through all detectors
750 for (Int_t det = 0; det < kNdet; det++) {
751
752 // Detectors that are switched off, not installed, etc.
753 if (( calibration->IsChamberInstalled(det)) &&
b65e5048 754 (!calibration->IsChamberMasked(det)) &&
625f5260 755 ( fGeo->ChamberInGeometry(det)) &&
756 (nhit[det] > 0)) {
757
b65e5048 758 signals = new AliTRDarraySignal();
759
625f5260 760 // Convert the hits of the current detector to detector signals
761 if (!ConvertHits(det,hits[det],nhit[det],signals)) {
b65e5048 762 AliError(Form("Conversion of hits failed for detector=%d",det));
625f5260 763 return kFALSE;
764 }
765 // Convert the detector signals to digits or s-digits
766 if (!ConvertSignals(det,signals)) {
b65e5048 767 AliError(Form("Conversion of signals failed for detector=%d",det));
768 return kFALSE;
625f5260 769 }
770
771 // Delete the signals array
772 delete signals;
773 signals = 0x0;
774
775 } // if: detector status
776
27cea06a 777 delete [] hits[det];
778
625f5260 779 } // for: detector
780
781 delete [] hits;
782 delete [] nhit;
783
784 return kTRUE;
785
786}
787
788//_____________________________________________________________________________
789Bool_t AliTRDdigitizer::SortHits(Float_t **hits, Int_t *nhit)
790{
791 //
792 // Read all the hits and sorts them according to detector number
793 // in the output array <hits>.
794 //
795
796 AliDebug(1,"Start sorting hits");
797
798 const Int_t kNdet = AliTRDgeometry::Ndet();
799 // Size of the hit vector
800 const Int_t kNhit = 6;
801
802 Float_t *xyz = 0;
803 Int_t nhitTrk = 0;
804
805 Int_t *lhit = new Int_t[kNdet];
806
807 for (Int_t det = 0; det < kNdet; det++) {
808 lhit[det] = 0;
809 nhit[det] = 0;
810 hits[det] = 0;
811 }
812
813 AliLoader *gimme = fRunLoader->GetLoader("TRDLoader");
814 if (!gimme->TreeH()) {
815 gimme->LoadHits();
816 }
817 TTree *hitTree = gimme->TreeH();
818 if (hitTree == 0x0) {
819 AliError("Can not get TreeH");
820 return kFALSE;
821 }
822 fTRD->SetTreeAddress();
823
824 // Get the number of entries in the hit tree
825 // (Number of primary particles creating a hit somewhere)
826 Int_t nTrk = (Int_t) hitTree->GetEntries();
827 AliDebug(1,Form("Found %d tracks",nTrk));
828
829 // Loop through all the tracks in the tree
830 for (Int_t iTrk = 0; iTrk < nTrk; iTrk++) {
831
3e2e3ece 832 gAlice->GetMCApp()->ResetHits();
625f5260 833 hitTree->GetEvent(iTrk);
834
835 if (!fTRD->Hits()) {
836 AliError(Form("No hits array for track = %d",iTrk));
837 continue;
838 }
839
840 // Number of hits for this track
841 nhitTrk = fTRD->Hits()->GetEntriesFast();
842
843 Int_t hitCnt = 0;
844 // Loop through the TRD hits
845 AliTRDhit *hit = (AliTRDhit *) fTRD->FirstHit(-1);
846 while (hit) {
847
848 hitCnt++;
849
850 // Don't analyze test hits
851 if (((Int_t) hit->GetCharge()) != 0) {
852
853 Int_t trk = hit->Track();
854 Int_t det = hit->GetDetector();
855 Int_t q = hit->GetCharge();
856 Float_t x = hit->X();
857 Float_t y = hit->Y();
858 Float_t z = hit->Z();
859 Float_t time = hit->GetTime();
860
861 if (nhit[det] == lhit[det]) {
862 // Inititialization of new detector
863 xyz = new Float_t[kNhit*(nhitTrk+lhit[det])];
864 if (hits[det]) {
865 memcpy(xyz,hits[det],sizeof(Float_t)*kNhit*lhit[det]);
866 delete [] hits[det];
867 }
868 lhit[det] += nhitTrk;
869 hits[det] = xyz;
870 }
871 else {
872 xyz = hits[det];
873 }
874 xyz[nhit[det]*kNhit+0] = x;
875 xyz[nhit[det]*kNhit+1] = y;
876 xyz[nhit[det]*kNhit+2] = z;
877 xyz[nhit[det]*kNhit+3] = q;
878 xyz[nhit[det]*kNhit+4] = trk;
879 xyz[nhit[det]*kNhit+5] = time;
880 nhit[det]++;
881
882 } // if: charge != 0
883
884 hit = (AliTRDhit *) fTRD->NextHit();
885
886 } // for: hits of one track
887
888 } // for: tracks
889
890 delete [] lhit;
891
892 return kTRUE;
893
894}
f7336fa3 895
625f5260 896//_____________________________________________________________________________
897Bool_t AliTRDdigitizer::ConvertHits(Int_t det, Float_t *hits, Int_t nhit
b65e5048 898 , AliTRDarraySignal *signals)
625f5260 899{
900 //
901 // Converts the detectorwise sorted hits to detector signals
902 //
903
904 AliDebug(1,Form("Start converting hits for detector=%d (nhits=%d)",det,nhit));
f7336fa3 905
793ff80c 906 // Number of pads included in the pad response
a5cadd36 907 const Int_t kNpad = 3;
793ff80c 908 // Number of track dictionary arrays
625f5260 909 const Int_t kNdict = AliTRDdigitsManager::kNDict;
910 // Size of the hit vector
911 const Int_t kNhit = 6;
793ff80c 912
4329977a 913 // Width of the amplification region
914 const Float_t kAmWidth = AliTRDgeometry::AmThick();
3becff3c 915 // Width of the drift region
ccb4315c 916 const Float_t kDrWidth = AliTRDgeometry::DrThick();
4329977a 917 // Drift + amplification region
918 const Float_t kDrMin = - 0.5 * kAmWidth;
919 const Float_t kDrMax = kDrWidth + 0.5 * kAmWidth;
3551db50 920
625f5260 921 Int_t iPad = 0;
922 Int_t dict = 0;
923 Int_t timeBinTRFend = 1;
872a7aba 924
a5cadd36 925 Double_t pos[3];
4329977a 926 Double_t loc[3];
a5cadd36 927 Double_t padSignal[kNpad];
928 Double_t signalOld[kNpad];
872a7aba 929
b65e5048 930 AliTRDarrayDictionary *dictionary[kNdict];
4329977a 931
9afbd7de 932 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
9afbd7de 933 AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
625f5260 934 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
935
3becff3c 936 if (!commonParam) {
4329977a 937 AliFatal("Could not get common parameterss");
3551db50 938 return kFALSE;
939 }
625f5260 940 if (!simParam) {
941 AliFatal("Could not get simulation parameters");
942 return kFALSE;
943 }
3becff3c 944 if (!calibration) {
4329977a 945 AliFatal("Could not get calibration object");
3551db50 946 return kFALSE;
947 }
948
625f5260 949 // Get the detector wise calibration objects
950 AliTRDCalROC *calVdriftROC = 0;
951 Float_t calVdriftDetValue = 0.0;
952 const AliTRDCalDet *calVdriftDet = calibration->GetVdriftDet();
953 AliTRDCalROC *calT0ROC = 0;
954 Float_t calT0DetValue = 0.0;
955 const AliTRDCalDet *calT0Det = calibration->GetT0Det();
4329977a 956
4329977a 957 if (simParam->TRFOn()) {
958 timeBinTRFend = ((Int_t) (simParam->GetTRFhi()
959 * commonParam->GetSamplingFrequency())) - 1;
4329977a 960 }
961
3becff3c 962 Int_t nTimeTotal = calibration->GetNumberOfTimeBins();
b43a3e17 963 Float_t samplingRate = commonParam->GetSamplingFrequency();
4329977a 964 Float_t elAttachProp = simParam->GetElAttachProp() / 100.0;
a328fff9 965
625f5260 966 AliTRDpadPlane *padPlane = fGeo->GetPadPlane(det);
b65e5048 967 Int_t layer = fGeo->GetLayer(det); //update
625f5260 968 Float_t row0 = padPlane->GetRow0ROC();
969 Int_t nRowMax = padPlane->GetNrows();
970 Int_t nColMax = padPlane->GetNcols();
971
972 // Create a new array for the signals
973 signals->Allocate(nRowMax,nColMax,nTimeTotal);
974
975 // Create a new array for the dictionary
976 for (dict = 0; dict < kNdict; dict++) {
b65e5048 977 dictionary[dict] = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(det,dict);
625f5260 978 dictionary[dict]->Allocate(nRowMax,nColMax,nTimeTotal);
979 }
980
981 // Loop through the hits in this detector
982 for (Int_t hit = 0; hit < nhit; hit++) {
983
984 pos[0] = hits[hit*kNhit+0];
985 pos[1] = hits[hit*kNhit+1];
986 pos[2] = hits[hit*kNhit+2];
987 Float_t q = hits[hit*kNhit+3];
988 Float_t hittime = hits[hit*kNhit+5];
989 Int_t track = ((Int_t) hits[hit*kNhit+4]);
990
991 Int_t inDrift = 1;
992
993 // Find the current volume with the geo manager
994 gGeoManager->SetCurrentPoint(pos);
995 gGeoManager->FindNode();
996 if (strstr(gGeoManager->GetPath(),"/UK")) {
997 inDrift = 0;
998 }
793ff80c 999
625f5260 1000 // Get the calibration objects
1001 calVdriftROC = calibration->GetVdriftROC(det);
1002 calVdriftDetValue = calVdriftDet->GetValue(det);
1003 calT0ROC = calibration->GetT0ROC(det);
1004 calT0DetValue = calT0Det->GetValue(det);
1005
1006 // Go to the local coordinate system:
1007 // loc[0] - col direction in amplification or driftvolume
1008 // loc[1] - row direction in amplification or driftvolume
1009 // loc[2] - time direction in amplification or driftvolume
1010 gGeoManager->MasterToLocal(pos,loc);
1011 if (inDrift) {
1012 // Relative to middle of amplification region
1013 loc[2] = loc[2] - kDrWidth/2.0 - kAmWidth/2.0;
1014 }
793ff80c 1015
625f5260 1016 // The driftlength [cm] (w/o diffusion yet !).
1017 // It is negative if the hit is between pad plane and anode wires.
1018 Double_t driftlength = -1.0 * loc[2];
e23fbb27 1019
625f5260 1020 // Stupid patch to take care of TR photons that are absorbed
1021 // outside the chamber volume. A real fix would actually need
1022 // a more clever implementation of the TR hit generation
1023 if (q < 0.0) {
1024 if ((loc[1] < padPlane->GetRowEndROC()) ||
1025 (loc[1] > padPlane->GetRow0ROC())) {
f881dc35 1026 continue;
1027 }
625f5260 1028 if ((driftlength < kDrMin) ||
1029 (driftlength > kDrMax)) {
1030 continue;
4329977a 1031 }
625f5260 1032 }
f881dc35 1033
625f5260 1034 // Get row and col of unsmeared electron to retrieve drift velocity
1035 // The pad row (z-direction)
1036 Int_t rowE = padPlane->GetPadRowNumberROC(loc[1]);
1037 if (rowE < 0) {
1038 continue;
1039 }
1040 Double_t rowOffset = padPlane->GetPadRowOffsetROC(rowE,loc[1]);
1041 // The pad column (rphi-direction)
1042 Double_t offsetTilt = padPlane->GetTiltOffset(rowOffset);
1043 Int_t colE = padPlane->GetPadColNumber(loc[0]+offsetTilt);
1044 if (colE < 0) {
1045 continue;
1046 }
0a17cc30 1047 Double_t colOffset = 0.0;
f881dc35 1048
625f5260 1049 // Normalized drift length
1050 Float_t driftvelocity = calVdriftDetValue * calVdriftROC->GetValue(colE,rowE);
1051 Double_t absdriftlength = TMath::Abs(driftlength);
1052 if (commonParam->ExBOn()) {
1053 absdriftlength /= TMath::Sqrt(GetLorentzFactor(driftvelocity));
1054 }
1055
1056 // Loop over all electrons of this hit
1057 // TR photons produce hits with negative charge
1058 Int_t nEl = ((Int_t) TMath::Abs(q));
1059 for (Int_t iEl = 0; iEl < nEl; iEl++) {
1060
1061 // Now the real local coordinate system of the ROC
1062 // column direction: locC
1063 // row direction: locR
1064 // time direction: locT
1065 // locR and locC are identical to the coordinates of the corresponding
1066 // volumina of the drift or amplification region.
1067 // locT is defined relative to the wire plane (i.e. middle of amplification
1068 // region), meaming locT = 0, and is negative for hits coming from the
1069 // drift region.
1070 Double_t locC = loc[0];
1071 Double_t locR = loc[1];
1072 Double_t locT = loc[2];
1073
1074 // Electron attachment
1075 if (simParam->ElAttachOn()) {
1076 if (gRandom->Rndm() < (absdriftlength * elAttachProp)) {
1077 continue;
f881dc35 1078 }
625f5260 1079 }
1080
1081 // Apply the diffusion smearing
1082 if (simParam->DiffusionOn()) {
1083 if (!(Diffusion(driftvelocity,absdriftlength,locR,locC,locT))) {
1084 continue;
f881dc35 1085 }
f881dc35 1086 }
793ff80c 1087
625f5260 1088 // Apply E x B effects (depends on drift direction)
1089 if (commonParam->ExBOn()) {
1090 if (!(ExB(driftvelocity,driftlength,locC))) {
4329977a 1091 continue;
1092 }
729161c5 1093 }
1094
625f5260 1095 // The electron position after diffusion and ExB in pad coordinates.
4329977a 1096 // The pad row (z-direction)
625f5260 1097 rowE = padPlane->GetPadRowNumberROC(locR);
1098 if (rowE < 0) continue;
1099 rowOffset = padPlane->GetPadRowOffsetROC(rowE,locR);
4329977a 1100
1101 // The pad column (rphi-direction)
625f5260 1102 offsetTilt = padPlane->GetTiltOffset(rowOffset);
1103 colE = padPlane->GetPadColNumber(locC+offsetTilt);
1104 if (colE < 0) continue;
1105 colOffset = padPlane->GetPadColOffset(colE,locC+offsetTilt);
b65e5048 1106
625f5260 1107 // Also re-retrieve drift velocity because col and row may have changed
1108 driftvelocity = calVdriftDetValue * calVdriftROC->GetValue(colE,rowE);
1109 Float_t t0 = calT0DetValue + calT0ROC->GetValue(colE,rowE);
1110
1111 // Convert the position to drift time [mus], using either constant drift velocity or
1112 // time structure of drift cells (non-isochronity, GARFIELD calculation).
1113 // Also add absolute time of hits to take pile-up events into account properly
1114 Double_t drifttime;
1115 if (simParam->TimeStructOn()) {
1116 // Get z-position with respect to anode wire
1117 Double_t zz = row0 - locR + simParam->GetAnodeWireOffset();
1118 zz -= ((Int_t)(2 * zz)) / 2.0;
1119 if (zz > 0.25) {
1120 zz = 0.5 - zz;
1121 }
1122 // Use drift time map (GARFIELD)
1123 drifttime = TimeStruct(driftvelocity,0.5*kAmWidth-1.0*locT,zz)
1124 + hittime;
1125 }
1126 else {
1127 // Use constant drift velocity
1128 drifttime = -1.0 * locT / driftvelocity
1129 + hittime;
4329977a 1130 }
625f5260 1131
1132 // Apply the gas gain including fluctuations
1133 Double_t ggRndm = 0.0;
1134 do {
1135 ggRndm = gRandom->Rndm();
1136 } while (ggRndm <= 0);
eb52b657 1137 Double_t signal = -(simParam->GetGasGain()) * TMath::Log(ggRndm);
625f5260 1138
1139 // Apply the pad response
1140 if (simParam->PRFOn()) {
1141 // The distance of the electron to the center of the pad
1142 // in units of pad width
1143 Double_t dist = (colOffset - 0.5*padPlane->GetColSize(colE))
1144 / padPlane->GetColSize(colE);
1145 // This is a fixed parametrization, i.e. not dependent on
1146 // calibration values !
053767a4 1147 if (!(calibration->PadResponse(signal,dist,layer,padSignal))) continue;
625f5260 1148 }
1149 else {
1150 padSignal[0] = 0.0;
1151 padSignal[1] = signal;
1152 padSignal[2] = 0.0;
4329977a 1153 }
f881dc35 1154
625f5260 1155 // The time bin (always positive), with t0 distortion
1156 Double_t timeBinIdeal = drifttime * samplingRate + t0;
1157 // Protection
1158 if (TMath::Abs(timeBinIdeal) > 2*nTimeTotal) {
1159 timeBinIdeal = 2 * nTimeTotal;
1160 }
1161 Int_t timeBinTruncated = ((Int_t) timeBinIdeal);
1162 // The distance of the position to the middle of the timebin
1163 Double_t timeOffset = ((Float_t) timeBinTruncated
1164 + 0.5 - timeBinIdeal) / samplingRate;
3551db50 1165
625f5260 1166 // Sample the time response inside the drift region
1167 // + additional time bins before and after.
1168 // The sampling is done always in the middle of the time bin
1169 for (Int_t iTimeBin = TMath::Max(timeBinTruncated,0)
1170 ;iTimeBin < TMath::Min(timeBinTruncated+timeBinTRFend,nTimeTotal)
1171 ;iTimeBin++) {
1172
1173 // Apply the time response
1174 Double_t timeResponse = 1.0;
1175 Double_t crossTalk = 0.0;
1176 Double_t time = (iTimeBin - timeBinTruncated) / samplingRate + timeOffset;
1177 if (simParam->TRFOn()) {
1178 timeResponse = simParam->TimeResponse(time);
f881dc35 1179 }
625f5260 1180 if (simParam->CTOn()) {
1181 crossTalk = simParam->CrossTalk(time);
f881dc35 1182 }
e23fbb27 1183
625f5260 1184 signalOld[0] = 0.0;
1185 signalOld[1] = 0.0;
1186 signalOld[2] = 0.0;
e23fbb27 1187
625f5260 1188 for (iPad = 0; iPad < kNpad; iPad++) {
f7336fa3 1189
625f5260 1190 Int_t colPos = colE + iPad - 1;
1191 if (colPos < 0) continue;
1192 if (colPos >= nColMax) break;
e23fbb27 1193
625f5260 1194 // Add the signals
b65e5048 1195 signalOld[iPad] = signals->GetData(rowE,colPos,iTimeBin);
e23fbb27 1196
625f5260 1197 if (colPos != colE) {
1198 // Cross talk added to non-central pads
1199 signalOld[iPad] += padSignal[iPad]
1200 * (timeResponse + crossTalk);
1201 }
1202 else {
1203 // W/o cross talk at central pad
1204 signalOld[iPad] += padSignal[iPad]
1205 * timeResponse;
1206 }
f881dc35 1207
b65e5048 1208 signals->SetData(rowE,colPos,iTimeBin,signalOld[iPad]);
625f5260 1209
1210 // Store the track index in the dictionary
1211 // Note: We store index+1 in order to allow the array to be compressed
b65e5048 1212 // Note2: Taking out the +1 in track
625f5260 1213 if (signalOld[iPad] > 0.0) {
1214 for (dict = 0; dict < kNdict; dict++) {
b65e5048 1215 Int_t oldTrack = dictionary[dict]->GetData(rowE,colPos,iTimeBin);
1216 if (oldTrack == track) break;
1217 if (oldTrack == -1 ) {
1218 dictionary[dict]->SetData(rowE,colPos,iTimeBin,track);
1219 break;
1220 }
f881dc35 1221 }
625f5260 1222 }
872a7aba 1223
625f5260 1224 } // Loop: pads
f7336fa3 1225
625f5260 1226 } // Loop: time bins
f7336fa3 1227
625f5260 1228 } // Loop: electrons of a single hit
f7336fa3 1229
625f5260 1230 } // Loop: hits
f7336fa3 1231
625f5260 1232 AliDebug(2,Form("Finished analyzing %d hits",nhit));
e23fbb27 1233
625f5260 1234 return kTRUE;
e23fbb27 1235
625f5260 1236}
793ff80c 1237
625f5260 1238//_____________________________________________________________________________
b65e5048 1239Bool_t AliTRDdigitizer::ConvertSignals(Int_t det, AliTRDarraySignal *signals)
625f5260 1240{
4329977a 1241 //
625f5260 1242 // Convert signals to digits
4329977a 1243 //
1244
625f5260 1245 AliDebug(1,Form("Start converting the signals for detector %d",det));
1246
1247 if (fSDigits) {
1248 // Convert the signal array to s-digits
1249 if (!Signal2SDigits(det,signals)) {
1250 return kFALSE;
793ff80c 1251 }
625f5260 1252 }
1253 else {
1254 // Convert the signal array to digits
1255 if (!Signal2ADC(det,signals)) {
1256 return kFALSE;
793ff80c 1257 }
625f5260 1258 }
f7336fa3 1259
625f5260 1260 // Compress the arrays
b65e5048 1261 CompressOutputArrays(det);
6244debe 1262
625f5260 1263 return kTRUE;
6244debe 1264
625f5260 1265}
4329977a 1266
625f5260 1267//_____________________________________________________________________________
b65e5048 1268Bool_t AliTRDdigitizer::Signal2ADC(Int_t det, AliTRDarraySignal *signals)
625f5260 1269{
1270 //
1271 // Converts the sampled electron signals to ADC values for a given chamber
1272 //
6244debe 1273
625f5260 1274 AliDebug(1,Form("Start converting signals to ADC values for detector=%d",det));
e23fbb27 1275
625f5260 1276 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
1277 if (!calibration) {
1278 AliFatal("Could not get calibration object");
1279 return kFALSE;
1280 }
793ff80c 1281
625f5260 1282 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
1283 if (!simParam) {
1284 AliFatal("Could not get simulation parameters");
1285 return kFALSE;
1286 }
f7336fa3 1287
625f5260 1288 // Converts number of electrons to fC
1289 const Double_t kEl2fC = 1.602e-19 * 1.0e15;
0c24ba98 1290
625f5260 1291 // Coupling factor
1292 Double_t coupling = simParam->GetPadCoupling()
1293 * simParam->GetTimeCoupling();
1294 // Electronics conversion factor
1295 Double_t convert = kEl2fC
1296 * simParam->GetChipGain();
1297 // ADC conversion factor
1298 Double_t adcConvert = simParam->GetADCoutRange()
1299 / simParam->GetADCinRange();
1300 // The electronics baseline in mV
1301 Double_t baseline = simParam->GetADCbaseline()
1302 / adcConvert;
1303 // The electronics baseline in electrons
1304 Double_t baselineEl = baseline
1305 / convert;
1306
1307 Int_t row = 0;
1308 Int_t col = 0;
1309 Int_t time = 0;
1310
1311 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1312 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
1313 Int_t nTimeTotal = calibration->GetNumberOfTimeBins();
abaf1f1d 1314
625f5260 1315 // The gainfactor calibration objects
1316 const AliTRDCalDet *calGainFactorDet = calibration->GetGainFactorDet();
1317 AliTRDCalROC *calGainFactorROC = 0;
1318 Float_t calGainFactorDetValue = 0.0;
f7336fa3 1319
b65e5048 1320 AliTRDarrayADC *digits = 0x0;
e23fbb27 1321
625f5260 1322 if (!signals) {
1323 AliError(Form("Signals array for detector %d does not exist\n",det));
1324 return kFALSE;
1325 }
1326 if (signals->HasData()) {
1327 // Expand the container if neccessary
b65e5048 1328 signals->Expand();
625f5260 1329 }
1330 else {
1331 // Create missing containers
1332 signals->Allocate(nRowMax,nColMax,nTimeTotal);
f7336fa3 1333 }
1334
625f5260 1335 // Get the container for the digits of this detector
1336 if (fDigitsManager->HasSDigits()) {
1337 AliError("Digits manager has s-digits");
1338 return kFALSE;
1339 }
b65e5048 1340
1341 digits = (AliTRDarrayADC *) fDigitsManager->GetDigits(det);
625f5260 1342 // Allocate memory space for the digits buffer
1343 if (!digits->HasData()) {
1344 digits->Allocate(nRowMax,nColMax,nTimeTotal);
0c24ba98 1345 }
1346
625f5260 1347 // Get the calibration objects
1348 calGainFactorROC = calibration->GetGainFactorROC(det);
1349 calGainFactorDetValue = calGainFactorDet->GetValue(det);
abaf1f1d 1350
625f5260 1351 // Create the digits for this chamber
1352 for (row = 0; row < nRowMax; row++ ) {
1353 for (col = 0; col < nColMax; col++ ) {
abaf1f1d 1354
625f5260 1355 // Check whether pad is masked
1356 // Bridged pads are not considered yet!!!
1357 if (calibration->IsPadMasked(det,col,row)) {
1358 continue;
1359 }
abaf1f1d 1360
625f5260 1361 // The gain factors
1362 Float_t padgain = calGainFactorDetValue
1363 * calGainFactorROC->GetValue(col,row);
1364 if (padgain <= 0) {
1365 AliError(Form("Not a valid gain %f, %d %d %d",padgain,det,col,row));
1366 }
abaf1f1d 1367
625f5260 1368 for (time = 0; time < nTimeTotal; time++) {
1369
1370 // Get the signal amplitude
b65e5048 1371 Float_t signalAmp = signals->GetData(row,col,time);
625f5260 1372 // Pad and time coupling
1373 signalAmp *= coupling;
1374 // Gain factors
1375 signalAmp *= padgain;
1376
1377 // Add the noise, starting from minus ADC baseline in electrons
1378 signalAmp = TMath::Max((Double_t) gRandom->Gaus(signalAmp,simParam->GetNoise())
1379 ,-baselineEl);
1380
1381 // Convert to mV
1382 signalAmp *= convert;
1383 // Add ADC baseline in mV
1384 signalAmp += baseline;
1385
1386 // Convert to ADC counts. Set the overflow-bit fADCoutRange if the
1387 // signal is larger than fADCinRange
1388 Short_t adc = 0;
1389 if (signalAmp >= simParam->GetADCinRange()) {
1390 adc = ((Short_t) simParam->GetADCoutRange());
1391 }
1392 else {
1393 adc = TMath::Nint(signalAmp * adcConvert);
1394 }
abaf1f1d 1395
b65e5048 1396 // Saving all digits
1397 digits->SetData(row,col,time,adc);
abaf1f1d 1398
625f5260 1399 } // for: time
b65e5048 1400
625f5260 1401 } // for: col
1402 } // for: row
b1113c6b 1403
b65e5048 1404 // Do the Zero Suppression
1405 ZS(digits);
1406
625f5260 1407 return kTRUE;
b1113c6b 1408
1409}
1410
1411//_____________________________________________________________________________
b65e5048 1412Bool_t AliTRDdigitizer::Signal2SDigits(Int_t det, AliTRDarraySignal *signals)
abaf1f1d 1413{
1414 //
625f5260 1415 // Converts the sampled electron signals to s-digits
abaf1f1d 1416 //
1417
625f5260 1418 AliDebug(1,Form("Start converting signals to s-digits for detector=%d",det));
abaf1f1d 1419
4329977a 1420 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
9afbd7de 1421 if (!calibration) {
4329977a 1422 AliFatal("Could not get calibration object");
3551db50 1423 return kFALSE;
1424 }
6bf5f0ce 1425
625f5260 1426 Int_t row = 0;
1427 Int_t col = 0;
1428 Int_t time = 0;
9afbd7de 1429
625f5260 1430 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1431 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
1432 Int_t nTimeTotal = calibration->GetNumberOfTimeBins();
e23fbb27 1433
625f5260 1434 // Get the container for the digits of this detector
b65e5048 1435
625f5260 1436 if (!fDigitsManager->HasSDigits()) {
1437 AliError("Digits manager has no s-digits");
1438 return kFALSE;
1439 }
b65e5048 1440
1441 AliTRDarraySignal *digits = (AliTRDarraySignal *) fDigitsManager->GetSDigits(det);
625f5260 1442 // Allocate memory space for the digits buffer
1443 if (!digits->HasData()) {
1444 digits->Allocate(nRowMax,nColMax,nTimeTotal);
1445 }
e23fbb27 1446
625f5260 1447 // Create the sdigits for this chamber
1448 for (row = 0; row < nRowMax; row++ ) {
1449 for (col = 0; col < nColMax; col++ ) {
1450 for (time = 0; time < nTimeTotal; time++) {
b65e5048 1451 digits->SetData(row,col,time,signals->GetData(row,col,time));
625f5260 1452 } // for: time
1453 } // for: col
1454 } // for: row
b65e5048 1455
625f5260 1456 return kTRUE;
abaf1f1d 1457
625f5260 1458}
abaf1f1d 1459
625f5260 1460//_____________________________________________________________________________
1461Bool_t AliTRDdigitizer::SDigits2Digits()
1462{
1463 //
1464 // Merges the input s-digits and converts them to normal digits
1465 //
e23fbb27 1466
625f5260 1467 if (!MergeSDigits()) {
1468 return kFALSE;
1469 }
f7336fa3 1470
625f5260 1471 return ConvertSDigits();
f7336fa3 1472
1473}
1474
1475//_____________________________________________________________________________
abaf1f1d 1476Bool_t AliTRDdigitizer::MergeSDigits()
16bf9884 1477{
1478 //
abaf1f1d 1479 // Merges the input s-digits:
1480 // - The amplitude of the different inputs are summed up.
1481 // - Of the track IDs from the input dictionaries only one is
1482 // kept for each input. This works for maximal 3 different merged inputs.
16bf9884 1483 //
1484
abaf1f1d 1485 // Number of track dictionary arrays
1486 const Int_t kNDict = AliTRDdigitsManager::kNDict;
1487
4d18a639 1488 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
9afbd7de 1489 if (!simParam) {
4329977a 1490 AliFatal("Could not get simulation parameters");
3551db50 1491 return kFALSE;
1492 }
1493
4d18a639 1494 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
9afbd7de 1495 if (!calibration) {
4329977a 1496 AliFatal("Could not get calibration object");
3551db50 1497 return kFALSE;
1498 }
1499
abaf1f1d 1500 Int_t iDict = 0;
e23fbb27 1501 Int_t jDict = 0;
abaf1f1d 1502
b65e5048 1503 AliTRDarraySignal *digitsA;
1504 AliTRDarraySignal *digitsB;
1505 AliTRDarrayDictionary *dictionaryA[kNDict];
1506 AliTRDarrayDictionary *dictionaryB[kNDict];
abaf1f1d 1507
b65e5048 1508 AliTRDdigitsManager *mergeSDigitsManager = 0x0;
abaf1f1d 1509 // Get the first s-digits
1510 fSDigitsManager = (AliTRDdigitsManager *) fSDigitsManagerList->First();
9afbd7de 1511 if (!fSDigitsManager) {
7925de54 1512 AliError("No SDigits manager");
9afbd7de 1513 return kFALSE;
1514 }
abaf1f1d 1515
1516 // Loop through the other sets of s-digits
b65e5048 1517 mergeSDigitsManager = (AliTRDdigitsManager *) fSDigitsManagerList->After(fSDigitsManager);
abaf1f1d 1518
9afbd7de 1519 if (mergeSDigitsManager) {
7925de54 1520 AliDebug(1,Form("Merge %d input files.",fSDigitsManagerList->GetSize()));
9afbd7de 1521 }
1522 else {
7925de54 1523 AliDebug(1,"Only one input file.");
abaf1f1d 1524 }
3551db50 1525
b65e5048 1526 Int_t nTimeTotal = calibration->GetNumberOfTimeBins();
abaf1f1d 1527 Int_t iMerge = 0;
b65e5048 1528
abaf1f1d 1529 while (mergeSDigitsManager) {
1530
1531 iMerge++;
b65e5048 1532
abaf1f1d 1533 // Loop through the detectors
1534 for (Int_t iDet = 0; iDet < AliTRDgeometry::Ndet(); iDet++) {
1535
625f5260 1536 Int_t nRowMax = fGeo->GetPadPlane(iDet)->GetNrows();
1537 Int_t nColMax = fGeo->GetPadPlane(iDet)->GetNcols();
b65e5048 1538
abaf1f1d 1539 // Loop through the pixels of one detector and add the signals
b65e5048 1540 digitsA = (AliTRDarraySignal *) fSDigitsManager->GetSDigits(iDet);
1541 digitsB = (AliTRDarraySignal *) mergeSDigitsManager->GetSDigits(iDet);
1542 digitsA->Expand();
1543 if (!digitsA->HasData()) continue;
1544 digitsB->Expand();
1545 if (!digitsB->HasData()) continue;
1546
abaf1f1d 1547 for (iDict = 0; iDict < kNDict; iDict++) {
b65e5048 1548 dictionaryA[iDict] = (AliTRDarrayDictionary *) fSDigitsManager->GetDictionary(iDet,iDict);
1549 dictionaryB[iDict] = (AliTRDarrayDictionary *) mergeSDigitsManager->GetDictionary(iDet,iDict);
1550 dictionaryA[iDict]->Expand();
abaf1f1d 1551 dictionaryB[iDict]->Expand();
1552 }
1553
4487dad0 1554 // Merge only detectors that contain a signal
1555 Bool_t doMerge = kTRUE;
1556 if (fMergeSignalOnly) {
b65e5048 1557 if (digitsA->GetOverThreshold(0) == 0) {
1558 doMerge = kFALSE;
4487dad0 1559 }
abaf1f1d 1560 }
b65e5048 1561
4487dad0 1562 if (doMerge) {
b65e5048 1563
1564 AliDebug(1,Form("Merge detector %d of input no.%d",iDet,iMerge+1));
1565
1566 for (Int_t iRow = 0; iRow < nRowMax; iRow++ ) {
1567 for (Int_t iCol = 0; iCol < nColMax; iCol++ ) {
1568 for (Int_t iTime = 0; iTime < nTimeTotal; iTime++) {
1569
4487dad0 1570 // Add the amplitudes of the summable digits
b65e5048 1571 Float_t ampA = digitsA->GetData(iRow,iCol,iTime);
1572 Float_t ampB = digitsB->GetData(iRow,iCol,iTime);
1573 ampA += ampB;
1574 digitsA->SetData(iRow,iCol,iTime,ampA);
1575
1576 // Add the mask to the track id if defined.
1577 for (iDict = 0; iDict < kNDict; iDict++) {
1578 Int_t trackB = dictionaryB[iDict]->GetData(iRow,iCol,iTime);
1579 if ((fMasks) && (trackB > 0)) {
1580 for (jDict = 0; jDict < kNDict; jDict++) {
1581 Int_t trackA = dictionaryA[iDict]->GetData(iRow,iCol,iTime);
1582 if (trackA == 0) {
1583 trackA = trackB + fMasks[iMerge];
1584 dictionaryA[iDict]->SetData(iRow,iCol,iTime,trackA);
625f5260 1585 } // if: track A == 0
b65e5048 1586 } // for: jDict
1587 } // if: fMasks and trackB > 0
625f5260 1588 } // for: iDict
abaf1f1d 1589
625f5260 1590 } // for: iTime
1591 } // for: iCol
1592 } // for: iRow
4487dad0 1593
625f5260 1594 } // if: doMerge
1595
1596 mergeSDigitsManager->RemoveDigits(iDet);
1597 mergeSDigitsManager->RemoveDictionaries(iDet);
b65e5048 1598
abaf1f1d 1599 if (fCompress) {
b65e5048 1600 digitsA->Compress(0);
1601 for (iDict = 0; iDict < kNDict; iDict++) {
1602 dictionaryA[iDict]->Compress();
abaf1f1d 1603 }
1604 }
b65e5048 1605
625f5260 1606 } // for: detectors
b65e5048 1607
abaf1f1d 1608 // The next set of s-digits
b65e5048 1609 mergeSDigitsManager = (AliTRDdigitsManager *) fSDigitsManagerList->After(mergeSDigitsManager);
1610
625f5260 1611 } // while: mergeDigitsManagers
b65e5048 1612
625f5260 1613 return kTRUE;
1614
1615}
1616
1617//_____________________________________________________________________________
1618Bool_t AliTRDdigitizer::ConvertSDigits()
1619{
1620 //
1621 // Converts s-digits to normal digits
1622 //
1623
b65e5048 1624 AliTRDarraySignal *digitsIn = 0x0;
625f5260 1625
1626 if (!fSDigitsManager->HasSDigits()) {
1627 AliError("No s-digits in digits manager");
1628 return kFALSE;
abaf1f1d 1629 }
1630
625f5260 1631 // Loop through the detectors
1632 for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) {
1633
1634 // Get the merged s-digits (signals)
b65e5048 1635 digitsIn = (AliTRDarraySignal *) fSDigitsManager->GetSDigits(det);
625f5260 1636 if (!digitsIn->HasData()) {
1637 AliDebug(2,Form("No digits for det=%d",det));
1638 continue;
1639 }
1640
1641 // Convert the merged sdigits to digits
1642 if (!Signal2ADC(det,digitsIn)) {
1643 continue;
1644 }
1645
1646 // Copy the dictionary information to the output array
1647 if (!CopyDictionary(det)) {
1648 continue;
1649 }
1650
1651 // Delete
1652 fSDigitsManager->RemoveDigits(det);
1653 fSDigitsManager->RemoveDictionaries(det);
1654
1655 // Compress the arrays
1656 CompressOutputArrays(det);
1657
1658 } // for: detector numbers
1659
16bf9884 1660 return kTRUE;
1661
1662}
1663
1664//_____________________________________________________________________________
625f5260 1665Bool_t AliTRDdigitizer::CopyDictionary(Int_t det)
abaf1f1d 1666{
1667 //
625f5260 1668 // Copies the dictionary information from the s-digits arrays
1669 // to the output arrays
abaf1f1d 1670 //
1671
625f5260 1672 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
1673 if (!calibration) {
1674 AliFatal("Could not get calibration object");
4d18a639 1675 return kFALSE;
1676 }
abaf1f1d 1677
625f5260 1678 AliDebug(1,Form("Start copying dictionaries for detector=%d",det));
1679
1680 const Int_t kNDict = AliTRDdigitsManager::kNDict;
b65e5048 1681 AliTRDarrayDictionary *dictionaryIn[kNDict];
1682 AliTRDarrayDictionary *dictionaryOut[kNDict];
625f5260 1683
1684 Int_t nRowMax = fGeo->GetPadPlane(det)->GetNrows();
1685 Int_t nColMax = fGeo->GetPadPlane(det)->GetNcols();
1686 Int_t nTimeTotal = calibration->GetNumberOfTimeBins();
1687
1688 Int_t row = 0;
1689 Int_t col = 0;
1690 Int_t time = 0;
1691 Int_t dict = 0;
1692
1693 for (dict = 0; dict < kNDict; dict++) {
1694
b65e5048 1695 dictionaryIn[dict] = (AliTRDarrayDictionary *) fSDigitsManager->GetDictionary(det,dict);
625f5260 1696 dictionaryIn[dict]->Expand();
b65e5048 1697 dictionaryOut[dict] = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(det,dict);
625f5260 1698 dictionaryOut[dict]->Allocate(nRowMax,nColMax,nTimeTotal);
1699
1700 for (row = 0; row < nRowMax; row++) {
1701 for (col = 0; col < nColMax; col++) {
1702 for (time = 0; time < nTimeTotal; time++) {
b65e5048 1703 Int_t track = dictionaryIn[dict]->GetData(row,col,time);
1704 dictionaryOut[dict]->SetData(row,col,time,track);
625f5260 1705 } // for: time
1706 } // for: col
1707 } // for: row
b65e5048 1708
625f5260 1709 } // for: dictionaries
b65e5048 1710
625f5260 1711 return kTRUE;
1712
1713}
1714
1715//_____________________________________________________________________________
1716void AliTRDdigitizer::CompressOutputArrays(Int_t det)
1717{
1718 //
1719 // Compress the output arrays
1720 //
1721
1722 const Int_t kNDict = AliTRDdigitsManager::kNDict;
b65e5048 1723 AliTRDarrayDictionary *dictionary = 0x0;
625f5260 1724
1725 if (fCompress) {
1726
b65e5048 1727 if (!fSDigits) {
1728 AliTRDarrayADC *digits = 0x0;
1729 digits = (AliTRDarrayADC *) fDigitsManager->GetDigits(det);
1730 digits->Compress();
1731 }
1732
1733 if (fSDigits) {
1734 AliTRDarraySignal *digits = 0x0;
1735 digits = (AliTRDarraySignal *) fDigitsManager->GetSDigits(det);
1736 digits->Compress(0);
1737 }
1738
625f5260 1739 for (Int_t dict = 0; dict < kNDict; dict++) {
b65e5048 1740 dictionary = (AliTRDarrayDictionary *) fDigitsManager->GetDictionary(det,dict);
1741 dictionary->Compress();
625f5260 1742 }
1743
1744 }
abaf1f1d 1745
1746}
1747
1748//_____________________________________________________________________________
0a29d0f1 1749Bool_t AliTRDdigitizer::WriteDigits() const
f7336fa3 1750{
1751 //
1752 // Writes out the TRD-digits and the dictionaries
1753 //
1754
4d18a639 1755 // Write parameters
bdbb05bb 1756 fRunLoader->CdGAFile();
bdbb05bb 1757
da581aea 1758 // Store the digits and the dictionary in the tree
abaf1f1d 1759 return fDigitsManager->WriteDigits();
f7336fa3 1760
1761}
793ff80c 1762
1763//_____________________________________________________________________________
88cb7938 1764void AliTRDdigitizer::InitOutput(Int_t iEvent)
8e64dd77 1765{
1766 //
1767 // Initializes the output branches
1768 //
1769
1770 fEvent = iEvent;
88cb7938 1771
9afbd7de 1772 if (!fRunLoader) {
1773 AliError("Run Loader is NULL");
1774 return;
1775 }
1776
4329977a 1777 AliLoader *loader = fRunLoader->GetLoader("TRDLoader");
9afbd7de 1778 if (!loader) {
1779 AliError("Can not get TRD loader from Run Loader");
1780 return;
1781 }
88cb7938 1782
4d18a639 1783 TTree *tree = 0;
88cb7938 1784
9afbd7de 1785 if (fSDigits) {
1786 // If we produce SDigits
88cb7938 1787 tree = loader->TreeS();
9afbd7de 1788 if (!tree) {
88cb7938 1789 loader->MakeTree("S");
1790 tree = loader->TreeS();
9afbd7de 1791 }
1792 }
1793 else {
1794 // If we produce Digits
1795 tree = loader->TreeD();
1796 if (!tree) {
1797 loader->MakeTree("D");
1798 tree = loader->TreeD();
1799 }
1800 }
88cb7938 1801 fDigitsManager->SetEvent(iEvent);
1802 fDigitsManager->MakeBranch(tree);
8e64dd77 1803
1804}
3551db50 1805
1806//_____________________________________________________________________________
1807Double_t AliTRDdigitizer::TimeStruct(Float_t vdrift, Double_t dist, Double_t z)
1808{
1809 //
1810 // Applies the time structure of the drift cells (by C.Lippmann).
1811 // The drift time of electrons to the anode wires depends on the
1812 // distance to the wire (z) and on the position in the drift region.
1813 //
1814 // input :
1815 // dist = radial distance from (cathode) pad plane [cm]
1816 // z = distance from anode wire (parallel to cathode planes) [cm]
1817 //
1818 // output :
1819 // tdrift = the drift time of an electron at the given position
1820 //
1821 // We interpolate between the drift time values at the two drift
1822 // velocities fVDlo and fVDhi, being smaller and larger than
1823 // fDriftVelocity. We use the two stored drift time maps fTimeStruct1
1824 // and fTimeStruct2, calculated for the two mentioned drift velocities.
1825 //
1826
1827 SampleTimeStruct(vdrift);
1828
4d18a639 1829 // Indices:
1830 Int_t r1 = (Int_t)(10 * dist);
9afbd7de 1831 if (r1 < 0) r1 = 0;
1832 if (r1 > 37) r1 = 37;
1833 Int_t r2 = r1 + 1;
1834 if (r2 < 0) r2 = 0;
1835 if (r2 > 37) r2 = 37;
1836 const Int_t kz1 = ((Int_t)(100 * z / 2.5));
1837 const Int_t kz2 = kz1 + 1;
1838
4d18a639 1839 if ((r1 < 0) ||
1840 (r1 > 37) ||
1841 (kz1 < 0) ||
1842 (kz1 > 10)) {
7925de54 1843 AliWarning(Form("Indices out of range: dist=%.2f, z=%.2f, r1=%d, kz1=%d"
9afbd7de 1844 ,dist,z,r1,kz1));
3551db50 1845 }
1846
4d18a639 1847 const Float_t ky111 = fTimeStruct1[r1+38*kz1];
9afbd7de 1848 const Float_t ky221 = ((r2 <= 37) && (kz2 <= 10))
4d18a639 1849 ? fTimeStruct1[r2+38*kz2]
1850 : fTimeStruct1[37+38*10];
9afbd7de 1851 const Float_t ky121 = (kz2 <= 10)
4d18a639 1852 ? fTimeStruct1[r1+38*kz2]
1853 : fTimeStruct1[r1+38*10];
9afbd7de 1854 const Float_t ky211 = (r2 <= 37)
4d18a639 1855 ? fTimeStruct1[r2+38*kz1]
1856 : fTimeStruct1[37+38*kz1];
3551db50 1857
1858 // 2D Interpolation, lower drift time map
1859 const Float_t ky11 = (ky211-ky111)*10*dist + ky111 - (ky211-ky111)*r1;
1860 const Float_t ky21 = (ky221-ky121)*10*dist + ky121 - (ky221-ky121)*r1;
1861
4d18a639 1862 const Float_t ky112 = fTimeStruct2[r1+38*kz1];
9afbd7de 1863 const Float_t ky222 = ((r2 <= 37) && (kz2 <= 10))
4d18a639 1864 ? fTimeStruct2[r2+38*kz2]
1865 : fTimeStruct2[37+38*10];
9afbd7de 1866 const Float_t ky122 = (kz2 <= 10)
4d18a639 1867 ? fTimeStruct2[r1+38*kz2]
1868 : fTimeStruct2[r1+38*10];
9afbd7de 1869 const Float_t ky212 = (r2 <= 37)
4d18a639 1870 ? fTimeStruct2[r2+38*kz1]
1871 : fTimeStruct2[37+38*kz1];
3551db50 1872
1873 // 2D Interpolation, larger drift time map
1874 const Float_t ky12 = (ky212-ky112)*10*dist + ky112 - (ky212-ky112)*r1;
1875 const Float_t ky22 = (ky222-ky122)*10*dist + ky122 - (ky222-ky122)*r1;
1876
4d18a639 1877 // Dist now is the drift distance to the anode wires (negative if electrons are
3551db50 1878 // between anode wire plane and cathode pad plane)
9afbd7de 1879 dist -= AliTRDgeometry::AmThick() / 2.0;
3551db50 1880
1881 // Get the drift times for the drift velocities fVDlo and fVDhi
9afbd7de 1882 const Float_t ktdrift1 = ((TMath::Abs(dist) > 0.005) || (z > 0.005))
1883 ? (ky21 - ky11) * 100 * z / 2.5 + ky11 - (ky21 - ky11) * kz1
1884 : 0.0;
1885 const Float_t ktdrift2 = ((TMath::Abs(dist) > 0.005) || (z > 0.005))
1886 ? (ky22 - ky12) * 100 * z / 2.5 + ky12 - (ky22 - ky12) * kz1
1887 : 0.0;
3551db50 1888
1889 // 1D Interpolation between the values at fVDlo and fVDhi
4d18a639 1890 Float_t a = (ktdrift2 - ktdrift1)
1891 / (fVDhi - fVDlo);
1892 Float_t b = ktdrift2 - a * fVDhi;
3551db50 1893
3551db50 1894 return a * vdrift + b;
1895
1896}
1897
1898//_____________________________________________________________________________
1899void AliTRDdigitizer::SampleTimeStruct(Float_t vdrift)
1900{
1901 //
1902 // Samples the timing structure of a drift cell
1903 // Drift Time data calculated with Garfield (by C.Lippmann)
1904 //
1905
4329977a 1906 // Nothing to do
4d18a639 1907 if (vdrift == fTimeLastVdrift) {
3551db50 1908 return;
9afbd7de 1909 }
4d18a639 1910 fTimeLastVdrift = vdrift;
3551db50 1911
9afbd7de 1912 // Drift time maps are saved for some drift velocity values (in drift region):
3551db50 1913 Float_t fVDsmp[8];
1914 fVDsmp[0] = 1.032;
1915 fVDsmp[1] = 1.158;
1916 fVDsmp[2] = 1.299;
1917 fVDsmp[3] = 1.450;
1918 fVDsmp[4] = 1.610;
1919 fVDsmp[5] = 1.783;
1920 fVDsmp[6] = 1.959;
1921 fVDsmp[7] = 2.134;
1922
9afbd7de 1923 if (vdrift < fVDsmp[0]) {
7925de54 1924 AliWarning(Form("Drift Velocity too small (%.3f<%.3f)",vdrift,fVDsmp[0]));
3551db50 1925 vdrift = fVDsmp[0];
9afbd7de 1926 }
1927 else if (vdrift > fVDsmp[7]) {
7925de54 1928 AliWarning(Form("Drift Velocity too large (%.3f>%.3f)",vdrift,fVDsmp[6]));
3551db50 1929 vdrift = fVDsmp[7];
1930 }
1931
1932 const Int_t ktimebin = 38;
9afbd7de 1933 const Int_t kZbin = 11;
3551db50 1934
1935 // Garfield simulation at UD = -1500V; vd = 1.032cm/microsec, <driftfield> = 525V/cm
1936 Float_t time1500[ktimebin][kZbin] =
1937 {{0.09170, 0.09205, 0.09306, 0.09475, 0.09716, 0.10035,
1938 0.10445, 0.10993, 0.11838, 0.13986, 0.37858},
1939 {0.06588, 0.06626, 0.06739, 0.06926, 0.07186, 0.07524,
1940 0.07951, 0.08515, 0.09381, 0.11601, 0.35673},
1941 {0.03946, 0.04003, 0.04171, 0.04435, 0.04780, 0.05193,
1942 0.05680, 0.06306, 0.07290, 0.09873, 0.34748},
1943 {0.01151, 0.01283, 0.01718, 0.02282, 0.02880, 0.03479,
1944 0.04098, 0.04910, 0.06413, 0.10567, 0.36897},
1945 {0.01116, 0.01290, 0.01721, 0.02299, 0.02863, 0.03447,
1946 0.04074, 0.04984, 0.06839, 0.11625, 0.37277},
1947 {0.03919, 0.03974, 0.04131, 0.04380, 0.04703, 0.05102,
1948 0.05602, 0.06309, 0.07651, 0.10938, 0.36838},
1949 {0.06493, 0.06560, 0.06640, 0.06802, 0.07051, 0.07392,
1950 0.07853, 0.08510, 0.09690, 0.12621, 0.38058},
1951 {0.09174, 0.09186, 0.09225, 0.09303, 0.09477, 0.00000,
1952 0.11205, 0.11952, 0.13461, 0.16984, 0.43017},
1953 {0.14356, 0.14494, 0.14959, 0.16002, 0.18328, 0.27981,
1954 0.22785, 0.21240, 0.21948, 0.25965, 0.52392},
1955 {0.23120, 0.23366, 0.24046, 0.25422, 0.28071, 0.36914,
1956 0.32999, 0.31208, 0.31772, 0.35804, 0.62249},
1957 {0.32686, 0.32916, 0.33646, 0.35053, 0.37710, 0.46292,
1958 0.42773, 0.40948, 0.41497, 0.45527, 0.71955},
1959 {0.42353, 0.42583, 0.43317, 0.44727, 0.47380, 0.55884,
1960 0.52479, 0.50650, 0.51194, 0.55225, 0.81658},
1961 {0.52038, 0.52271, 0.53000, 0.54415, 0.57064, 0.65545,
1962 0.62172, 0.60341, 0.60885, 0.64915, 0.91339},
1963 {0.61724, 0.61953, 0.62694, 0.64098, 0.66756, 0.75226,
1964 0.71862, 0.70030, 0.70575, 0.74604, 1.01035},
1965 {0.71460, 0.71678, 0.72376, 0.73786, 0.76447, 0.84913,
1966 0.81551, 0.79720, 0.80264, 0.84292, 1.10723},
1967 {0.81101, 0.81334, 0.82066, 0.83475, 0.86127, 0.94599,
1968 0.91240, 0.89408, 0.89952, 0.93981, 1.20409},
1969 {0.90788, 0.91023, 0.91752, 0.93163, 0.95815, 1.04293,
1970 1.00929, 0.99096, 0.99640, 1.03669, 1.30106},
1971 {1.00477, 1.00707, 1.01449, 1.02852, 1.05504, 1.13976,
1972 1.10617, 1.08784, 1.09329, 1.13358, 1.39796},
1973 {1.10166, 1.10397, 1.11130, 1.12541, 1.15257, 1.23672,
1974 1.20307, 1.18472, 1.19018, 1.23046, 1.49486},
1975 {1.19854, 1.20084, 1.20818, 1.22235, 1.24885, 1.33355,
1976 1.29992, 1.28156, 1.28707, 1.32735, 1.59177},
1977 {1.29544, 1.29780, 1.30507, 1.31917, 1.34575, 1.43073,
1978 1.39681, 1.37851, 1.38396, 1.42377, 1.68854},
1979 {1.39236, 1.39462, 1.40205, 1.41607, 1.44259, 1.52745,
1980 1.49368, 1.47541, 1.48083, 1.52112, 1.78546},
1981 {1.49314, 1.49149, 1.49885, 1.51297, 1.53949, 1.62420,
1982 1.59016, 1.57231, 1.57772, 1.61800, 1.88048},
1983 {1.58610, 1.58839, 1.59572, 1.60983, 1.63635, 1.72109,
1984 1.68651, 1.66921, 1.67463, 1.71489, 1.97918},
1985 {1.68400, 1.68529, 1.69261, 1.70671, 1.73331, 1.81830,
1986 1.78341, 1.76605, 1.77150, 1.81179, 2.07608},
1987 {1.77991, 1.78215, 1.78952, 1.80385, 1.83014, 1.91486,
1988 1.88128, 1.86215, 1.86837, 1.90865, 2.17304},
1989 {1.87674, 1.87904, 1.88647, 1.90052, 1.92712, 2.01173,
1990 1.97812, 1.95905, 1.96527, 2.00710, 2.26979},
1991 {1.97369, 1.97594, 1.98326, 1.99869, 2.02442, 2.10865,
1992 2.07501, 2.05666, 2.06214, 2.10243, 2.36669},
1993 {2.07052, 2.07281, 2.08016, 2.09425, 2.12132, 2.20555,
1994 2.17182, 2.15341, 2.15904, 2.19933, 2.46363},
1995 {2.16742, 2.16971, 2.17707, 2.19114, 2.21766, 2.30240,
1996 2.26877, 2.25015, 2.25573, 2.29586, 2.56060},
1997 {2.26423, 2.26659, 2.27396, 2.28803, 2.31456, 2.40828,
1998 2.36567, 2.34705, 2.35282, 2.39765, 2.65744},
1999 {2.36153, 2.36349, 2.37330, 2.38501, 2.41159, 2.49940,
2000 2.46257, 2.44420, 2.44843, 2.48987, 2.75431},
2001 {2.46558, 2.46035, 2.46822, 2.48181, 2.50849, 2.59630,
2002 2.55947, 2.54112, 2.54513, 2.58677, 2.85094},
2003 {2.56248, 2.55723, 2.56486, 2.57871, 2.60520, 2.68998,
2004 2.65626, 2.63790, 2.64316, 2.68360, 2.94813},
2005 {2.65178, 2.65441, 2.66153, 2.67556, 2.70210, 2.78687,
2006 2.75319, 2.73463, 2.74032, 2.78060, 3.04503},
2007 {2.74868, 2.75131, 2.75870, 2.77245, 2.79385, 2.88700,
2008 2.85009, 2.83177, 2.83723, 2.87750, 3.14193},
2009 {2.84574, 2.84789, 2.85560, 2.86935, 2.89075, 2.98060,
2010 2.94576, 2.92868, 2.93356, 2.97436, 3.23868},
2011 {2.94239, 2.94469, 2.95221, 2.96625, 2.99345, 3.07747,
2012 3.04266, 3.02545, 3.03051, 3.07118, 3.33555}};
2013
2014 // Garfield simulation at UD = -1600V; vd = 1.158cm/microsec, <driftfield> = 558V/cm
2015 Float_t time1600[ktimebin][kZbin] =
2016 {{0.09169, 0.09203, 0.09305, 0.09473, 0.09714, 0.10032,
2017 0.10441, 0.10990, 0.11835, 0.13986, 0.37845},
2018 {0.06589, 0.06626, 0.06738, 0.06924, 0.07184, 0.07521,
2019 0.07947, 0.08512, 0.09379, 0.11603, 0.35648},
2020 {0.03947, 0.04003, 0.04171, 0.04434, 0.04778, 0.05190,
2021 0.05678, 0.06304, 0.07292, 0.09876, 0.34759},
2022 {0.01111, 0.01281, 0.01718, 0.02281, 0.02879, 0.03477,
2023 0.04097, 0.04910, 0.06415, 0.10573, 0.36896},
2024 {0.01120, 0.01311, 0.01721, 0.02279, 0.02862, 0.03446,
2025 0.04074, 0.04981, 0.06825, 0.11595, 0.37255},
2026 {0.03919, 0.03980, 0.04132, 0.04380, 0.04704, 0.05102,
2027 0.05602, 0.06302, 0.07633, 0.10896, 0.36743},
2028 {0.06531, 0.06528, 0.06631, 0.06805, 0.07053, 0.07392,
2029 0.07853, 0.08505, 0.09669, 0.12578, 0.37967},
2030 {0.09157, 0.09171, 0.09216, 0.09301, 0.09475, 0.00000,
2031 0.11152, 0.11879, 0.13352, 0.16802, 0.42750},
2032 {0.13977, 0.14095, 0.14509, 0.15433, 0.17534, 0.26406,
2033 0.21660, 0.20345, 0.21113, 0.25067, 0.51434},
2034 {0.21816, 0.22041, 0.22631, 0.23850, 0.26208, 0.34340,
2035 0.30755, 0.29237, 0.29878, 0.33863, 0.60258},
2036 {0.30344, 0.30547, 0.31241, 0.32444, 0.34809, 0.42696,
2037 0.39464, 0.37919, 0.38546, 0.42530, 0.68926},
2038 {0.38969, 0.39164, 0.39810, 0.41059, 0.43441, 0.51246,
2039 0.48112, 0.46562, 0.47191, 0.51172, 0.77558},
2040 {0.47592, 0.47799, 0.48442, 0.49689, 0.52061, 0.59855,
2041 0.56752, 0.55201, 0.55826, 0.59808, 0.86202},
2042 {0.56226, 0.56428, 0.57074, 0.58324, 0.60696, 0.68483,
2043 0.65388, 0.63837, 0.64461, 0.68445, 0.94830},
2044 {0.64881, 0.65063, 0.65709, 0.66958, 0.69331, 0.77117,
2045 0.74023, 0.72472, 0.73098, 0.77079, 1.03486},
2046 {0.73506, 0.73698, 0.74344, 0.75596, 0.77964, 0.85751,
2047 0.82658, 0.81107, 0.81731, 0.85712, 1.12106},
2048 {0.82132, 0.82333, 0.82979, 0.84228, 0.86608, 0.94386,
2049 0.91293, 0.89742, 0.90367, 0.94335, 1.20737},
2050 {0.90767, 0.90968, 0.91614, 0.92863, 0.95236, 1.03021,
2051 0.99928, 0.98377, 0.99001, 1.02984, 1.29371},
2052 {0.99410, 0.99602, 1.00257, 1.01498, 1.03869, 1.11720,
2053 1.08563, 1.07011, 1.07637, 1.11621, 1.37873},
2054 {1.08036, 1.08240, 1.08884, 1.10138, 1.12504, 1.20301,
2055 1.17198, 1.15647, 1.16272, 1.20255, 1.46651},
2056 {1.16670, 1.16872, 1.17525, 1.18783, 1.21139, 1.28934,
2057 1.25833, 1.24281, 1.24909, 1.28889, 1.55275},
2058 {1.25307, 1.25510, 1.26153, 1.27404, 1.29773, 1.37584,
2059 1.34469, 1.32916, 1.33536, 1.37524, 1.63915},
2060 {1.33942, 1.34146, 1.34788, 1.36040, 1.38410, 1.46438,
2061 1.43105, 1.41537, 1.42176, 1.46158, 1.72538},
2062 {1.42579, 1.42782, 1.43458, 1.44674, 1.47043, 1.55085,
2063 1.51675, 1.50168, 1.50810, 1.54793, 1.81174},
2064 {1.51207, 1.51454, 1.52060, 1.53307, 1.55684, 1.63478,
2065 1.60336, 1.58820, 1.59446, 1.63414, 1.89814},
2066 {1.59856, 1.60047, 1.60693, 1.61942, 1.64317, 1.72257,
2067 1.69008, 1.67454, 1.68080, 1.72063, 1.98433},
2068 {1.68481, 1.68682, 1.69330, 1.70584, 1.72949, 1.80752,
2069 1.77643, 1.76089, 1.76716, 1.80692, 2.07069},
2070 {1.77117, 1.77319, 1.77969, 1.79260, 1.81583, 1.89376,
2071 1.86226, 1.84720, 1.85355, 1.89256, 2.15343},
2072 {1.85748, 1.85967, 1.86605, 1.87848, 1.90222, 1.98010,
2073 1.94913, 1.93271, 1.93981, 1.97968, 2.24355},
2074 {1.94386, 1.94587, 1.95233, 1.96484, 1.98854, 2.06646,
2075 2.03542, 2.01755, 2.02617, 2.06604, 2.32993},
2076 {2.03022, 2.03230, 2.03868, 2.05134, 2.07488, 2.15367,
2077 2.12178, 2.10391, 2.11252, 2.15432, 2.41623},
2078 {2.11656, 2.11857, 2.12505, 2.13772, 2.16147, 2.23919,
2079 2.20817, 2.19265, 2.20744, 2.23872, 2.49996},
2080 {2.20291, 2.20611, 2.21137, 2.22387, 2.24758, 2.32563,
2081 2.29450, 2.27901, 2.28525, 2.32507, 2.58897},
2082 {2.28922, 2.29172, 2.29774, 2.31345, 2.33400, 2.41287,
2083 2.38086, 2.36535, 2.37160, 2.40869, 2.67113},
2084 {2.37572, 2.37764, 2.38410, 2.39803, 2.42046, 2.49817,
2085 2.46721, 2.45171, 2.45794, 2.49505, 2.76061},
2086 {2.46190, 2.46396, 2.47043, 2.48340, 2.50665, 2.58453,
2087 2.55357, 2.53728, 2.54430, 2.58407, 2.84816},
2088 {2.54833, 2.55032, 2.55679, 2.56976, 2.59312, 2.67103,
2089 2.63993, 2.62364, 2.63062, 2.67040, 2.93444},
2090 {2.63456, 2.63660, 2.64304, 2.65555, 2.67938, 2.75739,
2091 2.72629, 2.71064, 2.71688, 2.75671, 3.01886}};
2092
2093 // Garfield simulation at UD = -1700V; vd = 1.299cm/microsec, <driftfield> = 590V/cm
2094 Float_t time1700[ktimebin][kZbin] =
2095 {{0.09167, 0.09201, 0.09302, 0.09471, 0.09712, 0.10029,
2096 0.10438, 0.10986, 0.11832, 0.13986, 0.37824},
2097 {0.06591, 0.06626, 0.06736, 0.06923, 0.07183, 0.07519,
2098 0.07944, 0.08511, 0.09378, 0.11603, 0.35625},
2099 {0.03946, 0.04003, 0.04170, 0.04433, 0.04777, 0.05189,
2100 0.05676, 0.06301, 0.07291, 0.09880, 0.34724},
2101 {0.01110, 0.01281, 0.01718, 0.02280, 0.02879, 0.03476,
2102 0.04096, 0.04910, 0.06417, 0.10582, 0.36861},
2103 {0.01115, 0.01294, 0.01721, 0.02276, 0.02862, 0.03447,
2104 0.04074, 0.04980, 0.06812, 0.11565, 0.37231},
2105 {0.03920, 0.03974, 0.04133, 0.04381, 0.04706, 0.05105,
2106 0.05603, 0.06299, 0.07618, 0.10860, 0.36646},
2107 {0.06498, 0.06529, 0.06634, 0.06808, 0.07055, 0.07395,
2108 0.07852, 0.08500, 0.09650, 0.12532, 0.37850},
2109 {0.09143, 0.09159, 0.09207, 0.09297, 0.09473, 0.00000,
2110 0.11102, 0.11809, 0.13245, 0.16627, 0.42496},
2111 {0.13646, 0.13750, 0.14112, 0.14926, 0.16806, 0.24960,
2112 0.20627, 0.19536, 0.20366, 0.24256, 0.50557},
2113 {0.20678, 0.20848, 0.21384, 0.22450, 0.24552, 0.32018,
2114 0.28740, 0.27477, 0.28196, 0.32128, 0.58475},
2115 {0.28287, 0.28461, 0.29020, 0.30108, 0.32224, 0.39467,
2116 0.36500, 0.35217, 0.35926, 0.39860, 0.66194},
2117 {0.35972, 0.36145, 0.36713, 0.37797, 0.39912, 0.47091,
2118 0.44212, 0.42925, 0.43632, 0.47563, 0.73892},
2119 {0.43667, 0.43841, 0.44413, 0.45494, 0.47607, 0.54780,
2120 0.51912, 0.50627, 0.51334, 0.55254, 0.81595},
2121 {0.51365, 0.51540, 0.52101, 0.53193, 0.55305, 0.62463,
2122 0.59617, 0.58328, 0.59035, 0.62965, 0.89303},
2123 {0.59064, 0.59240, 0.59801, 0.60893, 0.63009, 0.70169,
2124 0.67317, 0.66028, 0.66735, 0.70666, 0.96995},
2125 {0.66765, 0.66939, 0.67501, 0.68592, 0.70724, 0.77863,
2126 0.75016, 0.73728, 0.74435, 0.78366, 1.04696},
2127 {0.74464, 0.74636, 0.75200, 0.76293, 0.78405, 0.85561,
2128 0.82716, 0.81427, 0.82133, 0.86064, 1.12396},
2129 {0.82165, 0.82340, 0.82902, 0.83991, 0.86104, 0.93266,
2130 0.90414, 0.89128, 0.89834, 0.93763, 1.20100},
2131 {0.89863, 0.90042, 0.90659, 0.91705, 0.93805, 1.00960,
2132 0.98115, 0.96825, 0.97533, 1.01462, 1.27801},
2133 {0.97563, 0.97740, 0.98310, 0.99391, 1.01504, 1.08659,
2134 1.05814, 1.04526, 1.05233, 1.09163, 1.35503},
2135 {1.05276, 1.05451, 1.06002, 1.07090, 1.09099, 1.16357,
2136 1.13516, 1.12225, 1.12933, 1.16863, 1.43195},
2137 {1.12977, 1.13138, 1.13700, 1.14792, 1.16797, 1.24061,
2138 1.21212, 1.19926, 1.20626, 1.24554, 1.50900},
2139 {1.20664, 1.20839, 1.21400, 1.22490, 1.24606, 1.31772,
2140 1.28914, 1.27382, 1.28329, 1.32262, 1.58550},
2141 {1.28367, 1.28541, 1.29099, 1.30189, 1.32312, 1.39460,
2142 1.36612, 1.34924, 1.36030, 1.39961, 1.66310},
2143 {1.36064, 1.36249, 1.36799, 1.37896, 1.40004, 1.48030,
2144 1.44314, 1.43032, 1.43731, 1.47659, 1.73442},
2145 {1.43762, 1.43937, 1.44497, 1.45618, 1.47704, 1.54932,
2146 1.52012, 1.50725, 1.51430, 1.55357, 1.81708},
2147 {1.51462, 1.51937, 1.52203, 1.53316, 1.55403, 1.62572,
2148 1.59713, 1.58424, 1.59128, 1.63061, 1.89406},
2149 {1.59162, 1.59338, 1.59947, 1.60989, 1.63103, 1.70270,
2150 1.67411, 1.66124, 1.66799, 1.70759, 1.97103},
2151 {1.66874, 1.67037, 1.67597, 1.68687, 1.70814, 1.77969,
2152 1.75112, 1.73806, 1.74530, 1.78457, 2.04794},
2153 {1.74693, 1.74749, 1.75297, 1.76476, 1.78500, 1.85667,
2154 1.82811, 1.81504, 1.82101, 1.86161, 2.12492},
2155 {1.82260, 1.82437, 1.82995, 1.84174, 1.86202, 1.93372,
2156 1.90509, 1.89202, 1.89930, 1.93859, 2.20189},
2157 {1.89964, 1.90135, 1.90693, 1.91789, 1.93952, 2.01080,
2158 1.98207, 1.96921, 1.97628, 2.01384, 2.27887},
2159 {1.97662, 1.97917, 1.98611, 1.99487, 2.01601, 2.08778,
2160 2.05846, 2.04623, 2.05330, 2.09244, 2.35585},
2161 {2.05359, 2.05615, 2.06309, 2.07187, 2.09867, 2.16459,
2162 2.13610, 2.12322, 2.13029, 2.16942, 2.43199},
2163 {2.13063, 2.13233, 2.13795, 2.14886, 2.17008, 2.24199,
2164 2.21310, 2.20020, 2.20727, 2.24659, 2.50983},
2165 {2.20761, 2.20931, 2.21955, 2.22624, 2.24708, 2.32147,
2166 2.29009, 2.27725, 2.28276, 2.32359, 2.58680},
2167 {2.28459, 2.29108, 2.29202, 2.30286, 2.32007, 2.39559,
2168 2.36683, 2.35422, 2.36119, 2.40058, 2.66081},
2169 {2.36153, 2.36806, 2.36889, 2.37985, 2.40092, 2.47828,
2170 2.44381, 2.43099, 2.43819, 2.47750, 2.73779}};
2171
2172 // Garfield simulation at UD = -1800V; vd = 1.450cm/microsec, <driftfield> = 623V/cm
2173 Float_t time1800[ktimebin][kZbin] =
2174 {{0.09166, 0.09199, 0.09300, 0.09470, 0.09709, 0.10026,
2175 0.10434, 0.10983, 0.11831, 0.13987, 0.37802},
2176 {0.06585, 0.06623, 0.06735, 0.06921, 0.07180, 0.07520,
2177 0.07941, 0.08507, 0.09376, 0.11604, 0.35624},
2178 {0.03945, 0.04004, 0.04169, 0.04432, 0.04776, 0.05187,
2179 0.05674, 0.06300, 0.07290, 0.09884, 0.34704},
2180 {0.01108, 0.01287, 0.01717, 0.02280, 0.02880, 0.03476,
2181 0.04095, 0.04909, 0.06419, 0.10589, 0.36843},
2182 {0.01115, 0.01287, 0.01720, 0.02276, 0.02862, 0.03448,
2183 0.04073, 0.04973, 0.06799, 0.11535, 0.37224},
2184 {0.03918, 0.03975, 0.04134, 0.04382, 0.04707, 0.05105,
2185 0.05603, 0.06296, 0.07605, 0.10822, 0.36560},
2186 {0.06498, 0.06532, 0.06635, 0.06809, 0.07058, 0.07395,
2187 0.07855, 0.08495, 0.09632, 0.12488, 0.37730},
2188 {0.09130, 0.09160, 0.09199, 0.09300, 0.09472, 0.00000,
2189 0.11059, 0.11747, 0.13146, 0.16462, 0.42233},
2190 {0.13364, 0.13449, 0.13767, 0.14481, 0.16147, 0.23635,
2191 0.19706, 0.18812, 0.19704, 0.23520, 0.49749},
2192 {0.19698, 0.19844, 0.20311, 0.21236, 0.23082, 0.29920,
2193 0.26936, 0.25927, 0.26732, 0.30601, 0.56871},
2194 {0.26518, 0.26670, 0.27160, 0.28099, 0.29955, 0.36597,
2195 0.33885, 0.32858, 0.33653, 0.37524, 0.63801},
2196 {0.33441, 0.33553, 0.34040, 0.34987, 0.36841, 0.43428,
2197 0.40797, 0.39763, 0.40556, 0.44425, 0.70698},
2198 {0.40296, 0.40447, 0.40934, 0.41881, 0.43737, 0.50306,
2199 0.47695, 0.46662, 0.47455, 0.51329, 0.77600},
2200 {0.47296, 0.47344, 0.47830, 0.48779, 0.50632, 0.57200,
2201 0.54593, 0.53559, 0.54351, 0.58222, 0.84489},
2202 {0.54089, 0.54264, 0.54727, 0.55673, 0.57529, 0.64094,
2203 0.61490, 0.60457, 0.61249, 0.65118, 0.91394},
2204 {0.60987, 0.61138, 0.61624, 0.62573, 0.64428, 0.70989,
2205 0.68397, 0.67354, 0.68147, 0.72015, 0.98291},
2206 {0.67883, 0.68035, 0.68521, 0.69469, 0.71324, 0.77896,
2207 0.75287, 0.74251, 0.75043, 0.78912, 1.04458},
2208 {0.74780, 0.74932, 0.75421, 0.76367, 0.78221, 0.84785,
2209 0.82185, 0.81148, 0.81941, 0.85811, 1.12085},
2210 {0.81690, 0.81830, 0.82316, 0.83263, 0.85120, 0.91683,
2211 0.89077, 0.88045, 0.88837, 0.92707, 1.18976},
2212 {0.88574, 0.88726, 0.89228, 0.90198, 0.92017, 0.98578,
2213 0.95974, 0.94947, 0.95734, 0.99604, 1.25873},
2214 {0.95493, 0.95624, 0.96110, 0.97058, 0.98913, 1.05481,
2215 1.02873, 1.01839, 1.02631, 1.06503, 1.32772},
2216 {1.02392, 1.02524, 1.03008, 1.03955, 1.05810, 1.12378,
2217 1.09757, 1.08605, 1.09530, 1.13399, 1.39669},
2218 {1.09270, 1.09418, 1.09911, 1.10854, 1.12714, 1.19281,
2219 1.16502, 1.15633, 1.16427, 1.20271, 1.46574},
2220 {1.16168, 1.16323, 1.16801, 1.17772, 1.19604, 1.26190,
2221 1.23399, 1.22531, 1.23323, 1.27194, 1.53475},
2222 {1.23061, 1.23214, 1.23698, 1.24669, 1.26503, 1.33073,
2223 1.30461, 1.29428, 1.30220, 1.34091, 1.60372},
2224 {1.29960, 1.30110, 1.30596, 1.31544, 1.33398, 1.39962,
2225 1.37228, 1.36323, 1.37121, 1.40988, 1.67273},
2226 {1.36851, 1.37007, 1.37512, 1.38441, 1.40297, 1.46865,
2227 1.44256, 1.43222, 1.44017, 1.47878, 1.74155},
2228 {1.43752, 1.43904, 1.44773, 1.45338, 1.47220, 1.53759,
2229 1.51136, 1.50119, 1.50914, 1.54775, 1.81050},
2230 {1.50646, 1.50802, 1.51288, 1.52237, 1.54097, 1.60697,
2231 1.58049, 1.57018, 1.57811, 1.61678, 1.87947},
2232 {1.57545, 1.57720, 1.58185, 1.59134, 1.60996, 1.67787,
2233 1.64929, 1.63914, 1.64707, 1.68570, 1.94851},
2234 {1.64442, 1.64617, 1.65081, 1.66035, 1.67893, 1.74684,
2235 1.71826, 1.70745, 1.71604, 1.75310, 2.01748},
2236 {1.71337, 1.71513, 1.71978, 1.72932, 1.74645, 1.81346,
2237 1.78739, 1.77642, 1.78501, 1.82151, 2.08644},
2238 {1.78238, 1.78410, 1.78876, 1.79824, 1.81678, 1.88332,
2239 1.85639, 1.84262, 1.85397, 1.89270, 2.15533},
2240 {1.85135, 1.85306, 1.85778, 1.86728, 1.88580, 1.95615,
2241 1.92536, 1.91171, 1.92283, 1.96165, 2.22428},
2242 {1.92774, 1.92184, 1.92672, 1.93618, 1.95477, 2.02048,
2243 1.99427, 1.98068, 1.99192, 2.03062, 2.29338},
2244 {1.98929, 1.99081, 1.99567, 2.00515, 2.02373, 2.08987,
2245 2.06332, 2.05249, 2.05939, 2.09928, 2.36227},
2246 {2.05829, 2.05978, 2.06464, 2.07414, 2.09272, 2.15850,
2247 2.12928, 2.12194, 2.12987, 2.16825, 2.43083},
2248 {2.12726, 2.12869, 2.13360, 2.14425, 2.16160, 2.22872,
2249 2.20118, 2.19078, 2.19876, 2.23416, 2.50007}};
2250
2251 // Garfield simulation at UD = -1900V; vd = 1.610cm/microsec, <driftfield> = 655V/cm
2252 Float_t time1900[ktimebin][kZbin] =
2253 {{0.09166, 0.09198, 0.09298, 0.09467, 0.09707, 0.10023,
2254 0.10431, 0.10980, 0.11828, 0.13988, 0.37789},
2255 {0.06584, 0.06622, 0.06735, 0.06920, 0.07179, 0.07514,
2256 0.07938, 0.08505, 0.09374, 0.11606, 0.35599},
2257 {0.03945, 0.04002, 0.04169, 0.04432, 0.04775, 0.05185,
2258 0.05672, 0.06298, 0.07290, 0.09888, 0.34695},
2259 {0.01109, 0.01281, 0.01717, 0.02279, 0.02878, 0.03476,
2260 0.04094, 0.04909, 0.06421, 0.10597, 0.36823},
2261 {0.01115, 0.01287, 0.01720, 0.02294, 0.02862, 0.03448,
2262 0.04074, 0.04973, 0.06783, 0.11506, 0.37206},
2263 {0.03940, 0.03975, 0.04135, 0.04386, 0.04708, 0.05106,
2264 0.05604, 0.06293, 0.07592, 0.10787, 0.36484},
2265 {0.06500, 0.06534, 0.06638, 0.06811, 0.07060, 0.07413,
2266 0.07852, 0.08491, 0.09614, 0.12446, 0.37626},
2267 {0.09119, 0.09140, 0.09194, 0.09293, 0.09471, 0.00000,
2268 0.11013, 0.11685, 0.13050, 0.16302, 0.41991},
2269 {0.13111, 0.13190, 0.13466, 0.14091, 0.15554, 0.22409,
2270 0.18846, 0.18167, 0.19113, 0.22854, 0.48995},
2271 {0.18849, 0.18975, 0.19380, 0.20185, 0.21797, 0.28050,
2272 0.25368, 0.24575, 0.25446, 0.29249, 0.55442},
2273 {0.24995, 0.25125, 0.25563, 0.26366, 0.27986, 0.34065,
2274 0.31605, 0.30815, 0.31680, 0.35482, 0.61697},
2275 {0.31187, 0.31324, 0.31745, 0.32580, 0.34205, 0.40217,
2276 0.37825, 0.37031, 0.37897, 0.41696, 0.67890},
2277 {0.37401, 0.37531, 0.37955, 0.38777, 0.40395, 0.46408,
2278 0.44037, 0.43242, 0.44108, 0.47906, 0.74122},
2279 {0.43610, 0.43741, 0.44161, 0.44986, 0.46604, 0.52614,
2280 0.50248, 0.49452, 0.50316, 0.54116, 0.80326},
2281 {0.49820, 0.49988, 0.50372, 0.51196, 0.52814, 0.58822,
2282 0.56459, 0.55661, 0.56527, 0.60326, 0.86526},
2283 {0.56032, 0.56161, 0.56582, 0.57408, 0.59024, 0.65032,
2284 0.62670, 0.61872, 0.62737, 0.66537, 0.92749},
2285 {0.62240, 0.62371, 0.62792, 0.63624, 0.65236, 0.71241,
2286 0.68881, 0.68081, 0.68947, 0.72750, 0.98941},
2287 {0.68449, 0.68581, 0.69002, 0.69828, 0.71444, 0.77452,
2288 0.75089, 0.74295, 0.75157, 0.78957, 1.05157},
2289 {0.74660, 0.74790, 0.75212, 0.76036, 0.77654, 0.83748,
2290 0.81299, 0.80501, 0.81193, 0.85168, 1.11375},
2291 {0.80870, 0.81017, 0.81423, 0.82246, 0.83867, 0.89908,
2292 0.87509, 0.86660, 0.87577, 0.91376, 1.17586},
2293 {0.87080, 0.87233, 0.87632, 0.88458, 0.90074, 0.96083,
2294 0.93718, 0.92922, 0.93787, 0.97588, 1.23794},
2295 {0.93291, 0.93422, 0.93844, 0.94667, 0.96293, 1.02295,
2296 0.99929, 0.99127, 0.99997, 1.03797, 1.29995},
2297 {0.99500, 0.99645, 1.00308, 1.00877, 1.02497, 1.08504,
2298 1.06140, 1.05343, 1.06203, 1.10006, 1.36216},
2299 {1.05712, 1.05926, 1.06262, 1.07092, 1.08706, 1.14754,
2300 1.12350, 1.11550, 1.12417, 1.16218, 1.42427},
2301 {1.11921, 1.12059, 1.12473, 1.13297, 1.14916, 1.21140,
2302 1.18560, 1.17284, 1.18625, 1.22414, 1.48629},
2303 {1.18140, 1.18262, 1.18690, 1.19508, 1.21125, 1.27139,
2304 1.24164, 1.23495, 1.24838, 1.28634, 1.54852},
2305 {1.24340, 1.24473, 1.24901, 1.25732, 1.27336, 1.33358,
2306 1.30793, 1.30179, 1.31047, 1.34848, 1.61066},
2307 {1.30551, 1.30684, 1.31104, 1.32056, 1.33553, 1.39609,
2308 1.37004, 1.36392, 1.37045, 1.41057, 1.67259},
2309 {1.36755, 1.36892, 1.37315, 1.39148, 1.39755, 1.45820,
2310 1.43215, 1.42602, 1.43467, 1.47268, 1.73477},
2311 {1.42966, 1.43101, 1.43549, 1.45359, 1.45976, 1.52031,
2312 1.49601, 1.48811, 1.49677, 1.53477, 1.79691},
2313 {1.49180, 1.49321, 1.49760, 1.51570, 1.52175, 1.58185,
2314 1.55771, 1.55023, 1.55888, 1.59672, 1.85501},
2315 {1.55391, 1.55527, 1.55943, 1.57782, 1.58391, 1.64395,
2316 1.62008, 1.61233, 1.62085, 1.65883, 1.92091},
2317 {1.61599, 1.61732, 1.62154, 1.63993, 1.64612, 1.70608,
2318 1.68237, 1.67108, 1.68301, 1.72110, 1.97931},
2319 {1.67808, 1.67948, 1.68364, 1.70204, 1.70823, 1.76858,
2320 1.74404, 1.73539, 1.74512, 1.78321, 2.04522},
2321 {1.74019, 1.74152, 1.74573, 1.76415, 1.77015, 1.83040,
2322 1.80615, 1.79366, 1.80723, 1.84509, 2.10742},
2323 {1.80235, 1.80362, 1.80783, 1.82626, 1.83227, 1.89246,
2324 1.86795, 1.85405, 1.86938, 1.90720, 2.16953},
2325 {1.86442, 1.86572, 1.86994, 1.88837, 1.89438, 1.95445,
2326 1.93006, 1.92283, 1.93148, 1.96931, 2.23147},
2327 {1.92700, 1.92783, 1.93197, 1.95049, 1.95649, 2.01668,
2328 1.99217, 1.98486, 1.99352, 2.03143, 2.29358}};
2329
2330 // Garfield simulation at UD = -2000V; vd = 1.783cm/microsec, <driftfield> = 688V/cm
2331 Float_t time2000[ktimebin][kZbin] =
2332 {{0.09176, 0.09196, 0.09296, 0.09465, 0.09704, 0.10020,
2333 0.10427, 0.10977, 0.11825, 0.13988, 0.37774},
2334 {0.06583, 0.06620, 0.06735, 0.06918, 0.07177, 0.07513,
2335 0.07936, 0.08503, 0.09372, 0.11606, 0.35586},
2336 {0.03944, 0.04001, 0.04170, 0.04431, 0.04774, 0.05184,
2337 0.05670, 0.06296, 0.07291, 0.09893, 0.34680},
2338 {0.01108, 0.01281, 0.01719, 0.02279, 0.02879, 0.03474,
2339 0.04093, 0.04908, 0.06422, 0.10605, 0.36800},
2340 {0.01114, 0.01287, 0.01720, 0.02276, 0.02863, 0.03449,
2341 0.04073, 0.04970, 0.06774, 0.11478, 0.37179},
2342 {0.03925, 0.03977, 0.04135, 0.04386, 0.04711, 0.05108,
2343 0.05604, 0.06290, 0.07580, 0.10748, 0.36386},
2344 {0.06501, 0.06536, 0.06640, 0.06814, 0.07062, 0.07398,
2345 0.07852, 0.08487, 0.09598, 0.12405, 0.37519},
2346 {0.09109, 0.09127, 0.09188, 0.09292, 0.09472, 0.00000,
2347 0.10964, 0.11630, 0.12960, 0.16150, 0.41765},
2348 {0.12898, 0.12968, 0.13209, 0.13749, 0.15034, 0.21286,
2349 0.18088, 0.17590, 0.18591, 0.22254, 0.48315},
2350 {0.18122, 0.18227, 0.18574, 0.19263, 0.20674, 0.26376,
2351 0.23960, 0.23375, 0.24316, 0.28047, 0.54179},
2352 {0.23674, 0.23784, 0.24142, 0.24847, 0.26264, 0.31810,
2353 0.29602, 0.29008, 0.29944, 0.33675, 0.59795},
2354 {0.29279, 0.29382, 0.29742, 0.30448, 0.31865, 0.37364,
2355 0.35215, 0.34629, 0.35555, 0.39286, 0.65411},
2356 {0.34875, 0.34987, 0.35346, 0.36054, 0.37472, 0.42956,
2357 0.40825, 0.40229, 0.41167, 0.44894, 0.71033},
2358 {0.40484, 0.40594, 0.40954, 0.41660, 0.43077, 0.48560,
2359 0.46433, 0.45840, 0.46772, 0.50500, 0.76632},
2360 {0.46090, 0.46201, 0.46560, 0.47267, 0.48684, 0.54167,
2361 0.52041, 0.51449, 0.52382, 0.56108, 0.82227},
2362 {0.51698, 0.51809, 0.52173, 0.52874, 0.54291, 0.59776,
2363 0.57646, 0.57052, 0.57986, 0.61717, 0.87836},
2364 {0.57306, 0.57418, 0.57782, 0.58513, 0.59899, 0.65380,
2365 0.63255, 0.62661, 0.63594, 0.67325, 0.93460},
2366 {0.62912, 0.63024, 0.63383, 0.64103, 0.65506, 0.70988,
2367 0.68484, 0.68267, 0.69202, 0.72878, 0.99046},
2368 {0.68521, 0.68633, 0.68990, 0.69699, 0.71115, 0.76595,
2369 0.74468, 0.73872, 0.74814, 0.78538, 1.04674},
2370 {0.74127, 0.74239, 0.74605, 0.75303, 0.77022, 0.82204,
2371 0.80078, 0.79484, 0.80416, 0.84147, 1.10261},
2372 {0.79736, 0.79846, 0.80206, 0.80947, 0.82330, 0.87813,
2373 0.85688, 0.85087, 0.86023, 0.89752, 1.15874},
2374 {0.85342, 0.85454, 0.85815, 0.86519, 0.87936, 0.93417,
2375 0.91293, 0.90428, 0.91631, 0.95360, 1.20760},
2376 {0.90949, 0.91061, 0.91423, 0.92128, 0.93544, 0.99026,
2377 0.96807, 0.96305, 0.97239, 1.00967, 1.27078},
2378 {0.96556, 0.96669, 0.97111, 0.97734, 0.99151, 1.04664,
2379 1.02508, 1.01879, 1.02846, 1.06167, 1.32695},
2380 {1.02167, 1.02279, 1.02656, 1.03341, 1.04759, 1.10242,
2381 1.08115, 1.07003, 1.08453, 1.12184, 1.38304},
2382 {1.07776, 1.07883, 1.08242, 1.08950, 1.10384, 1.16422,
2383 1.13725, 1.13133, 1.14061, 1.17793, 1.43910},
2384 {1.13379, 1.13492, 1.13864, 1.14567, 1.15973, 1.21455,
2385 1.19323, 1.18734, 1.19668, 1.23401, 1.49528},
2386 {1.18988, 1.19098, 1.19457, 1.20164, 1.21582, 1.27064,
2387 1.24937, 1.24044, 1.25275, 1.29004, 1.55137},
2388 {1.24592, 1.24706, 1.25087, 1.25773, 1.27188, 1.32670,
2389 1.30544, 1.29953, 1.30883, 1.34613, 1.60743},
2390 {1.30202, 1.30313, 1.30673, 1.31381, 1.32797, 1.38278,
2391 1.36151, 1.35167, 1.36490, 1.40221, 1.66306},
2392 {1.35809, 1.35921, 1.36282, 1.36986, 1.38403, 1.43888,
2393 1.41760, 1.41174, 1.42083, 1.45830, 1.71915},
2394 {1.41419, 1.41528, 1.41890, 1.42595, 1.44011, 1.49496,
2395 1.47368, 1.46769, 1.47706, 1.51436, 1.77523},
2396 {1.47131, 1.47141, 1.47494, 1.48850, 1.49620, 1.55137,
2397 1.52977, 1.51820, 1.53315, 1.57042, 1.83158},
2398 {1.52635, 1.52750, 1.53103, 1.53814, 1.55228, 1.60736,
2399 1.58503, 1.57986, 1.58920, 1.62649, 1.88767},
2400 {1.58418, 1.58355, 1.58711, 1.59526, 1.60833, 1.66316,
2401 1.63345, 1.63261, 1.64556, 1.68204, 1.94359},
2402 {1.64027, 1.63958, 1.64489, 1.65024, 1.66443, 1.71925,
2403 1.69794, 1.69201, 1.70143, 1.73865, 1.99968},
2404 {1.69450, 1.69566, 1.69940, 1.70697, 1.71841, 1.77819,
2405 1.75396, 1.74814, 1.75743, 1.79083, 2.05427},
2406 {1.75054, 1.75221, 1.75527, 1.76306, 1.77662, 1.83428,
2407 1.81006, 1.81173, 1.81345, 1.85076, 2.10289}};
2408
2409 // Garfield simulation at UD = -2100V; vd = 1.959cm/microsec, <driftfield> = 720V/cm
2410 Float_t time2100[ktimebin][kZbin] =
2411 {{0.09160, 0.09194, 0.09294, 0.09462, 0.09701, 0.10017,
2412 0.10424, 0.10974, 0.11823, 0.13988, 0.37762},
2413 {0.06585, 0.06619, 0.06731, 0.06916, 0.07174, 0.07509,
2414 0.07933, 0.08500, 0.09370, 0.11609, 0.35565},
2415 {0.03960, 0.04001, 0.04171, 0.04430, 0.04774, 0.05182,
2416 0.05668, 0.06294, 0.07291, 0.09896, 0.34676},
2417 {0.01109, 0.01280, 0.01716, 0.02279, 0.02876, 0.03474,
2418 0.04096, 0.04908, 0.06424, 0.10612, 0.36790},
2419 {0.01114, 0.01285, 0.01719, 0.02287, 0.02863, 0.03449,
2420 0.04073, 0.04964, 0.06759, 0.11446, 0.37162},
2421 {0.03922, 0.03977, 0.04146, 0.04386, 0.04711, 0.05109,
2422 0.05605, 0.06287, 0.07575, 0.10713, 0.36298},
2423 {0.06504, 0.06538, 0.06641, 0.06818, 0.07064, 0.07426,
2424 0.07852, 0.08483, 0.09581, 0.12363, 0.37424},
2425 {0.09103, 0.09129, 0.09186, 0.09291, 0.09476, 0.00000,
2426 0.10923, 0.11578, 0.12873, 0.16005, 0.41525},
2427 {0.12723, 0.12777, 0.12988, 0.13458, 0.14579, 0.20264,
2428 0.17421, 0.17078, 0.18132, 0.21708, 0.47699},
2429 {0.17508, 0.17601, 0.17897, 0.18487, 0.19698, 0.24881,
2430 0.22737, 0.22337, 0.23348, 0.27000, 0.53032},
2431 {0.22571, 0.22663, 0.22969, 0.23570, 0.24787, 0.29826,
2432 0.27871, 0.27462, 0.28471, 0.32122, 0.58166},
2433 {0.27664, 0.27759, 0.28067, 0.28669, 0.29891, 0.34898,
2434 0.32982, 0.32570, 0.33576, 0.37229, 0.63268},
2435 {0.32766, 0.32862, 0.33170, 0.33778, 0.34988, 0.39973,
2436 0.38088, 0.37675, 0.38680, 0.42333, 0.68159},
2437 {0.37872, 0.37966, 0.38275, 0.38875, 0.40093, 0.45073,
2438 0.43192, 0.42780, 0.43786, 0.47438, 0.73480},
2439 {0.42974, 0.43070, 0.43378, 0.43982, 0.45196, 0.50177,
2440 0.48297, 0.47884, 0.48889, 0.52544, 0.78581},
2441 {0.48081, 0.48175, 0.48482, 0.49084, 0.50302, 0.55290,
2442 0.53398, 0.52988, 0.53994, 0.57647, 0.83687},
2443 {0.53645, 0.53295, 0.53586, 0.54188, 0.55408, 0.60398,
2444 0.58504, 0.58092, 0.59100, 0.62768, 0.88773},
2445 {0.58345, 0.58409, 0.58690, 0.59292, 0.60510, 0.65562,
2446 0.63609, 0.63197, 0.64203, 0.67856, 0.93907},
2447 {0.63397, 0.63490, 0.63795, 0.64403, 0.65613, 0.70612,
2448 0.68714, 0.68301, 0.69294, 0.72955, 0.99000},
2449 {0.68496, 0.68592, 0.68899, 0.69504, 0.70733, 0.75708,
2450 0.73818, 0.73405, 0.74412, 0.78064, 1.04100},
2451 {0.73600, 0.73696, 0.74003, 0.74624, 0.75828, 0.80805,
2452 0.78904, 0.78512, 0.79517, 0.83152, 1.09205},
2453 {0.78709, 0.78801, 0.79108, 0.79709, 0.80931, 0.85906,
2454 0.84027, 0.83614, 0.84621, 0.88269, 1.14058},
2455 {0.83808, 0.83905, 0.84215, 0.84816, 0.86031, 0.91011,
2456 0.89139, 0.88718, 0.89725, 0.93377, 1.19413},
2457 {0.88916, 0.89010, 0.89320, 0.89920, 0.91136, 0.96117,
2458 0.94235, 0.93822, 0.94828, 0.98480, 1.24538},
2459 {0.94036, 0.94113, 0.94422, 0.95023, 0.96241, 1.01220,
2460 0.99310, 0.98927, 0.99933, 1.03585, 1.29629},
2461 {0.99139, 0.99220, 0.99525, 1.00127, 1.01344, 1.06324,
2462 1.04451, 1.04033, 1.04836, 1.08690, 1.34727},
2463 {1.04261, 1.04325, 1.04628, 1.05232, 1.06448, 1.12090,
2464 1.09546, 1.09136, 1.10142, 1.13795, 1.39831},
2465 {1.09331, 1.09429, 1.09742, 1.10336, 1.11557, 1.16547,
2466 1.14658, 1.13642, 1.15247, 1.18898, 1.44936},
2467 {1.14436, 1.14539, 1.14847, 1.15443, 1.16662, 1.21794,
2468 1.19763, 1.19329, 1.20349, 1.23956, 1.50043},
2469 {1.19533, 1.19651, 1.19943, 1.20548, 1.21666, 1.26753,
2470 1.24862, 1.24434, 1.25455, 1.29106, 1.55142},
2471 {1.24638, 1.24756, 1.25046, 1.25648, 1.26764, 1.31858,
2472 1.29967, 1.29538, 1.30499, 1.34211, 1.60250},
2473 {1.29747, 1.29847, 1.30175, 1.30753, 1.31869, 1.36969,
2474 1.35069, 1.34656, 1.35663, 1.39316, 1.64644},
2475 {1.35537, 1.34952, 1.35255, 1.35869, 1.36973, 1.41387,
2476 1.40173, 1.39761, 1.40768, 1.44396, 1.70238},
2477 {1.39956, 1.40056, 1.40380, 1.40961, 1.42178, 1.46492,
2478 1.45278, 1.45423, 1.45872, 1.49522, 1.75557},
2479 {1.45080, 1.45159, 1.45463, 1.46109, 1.47287, 1.52263,
2480 1.50382, 1.50050, 1.50977, 1.54502, 1.80670},
2481 {1.50165, 1.50264, 1.50570, 1.51214, 1.52233, 1.57370,
2482 1.55484, 1.55155, 1.56080, 1.59731, 1.85778},
2483 {1.55269, 1.55364, 1.55675, 1.56274, 1.57491, 1.62598,
2484 1.60590, 1.60259, 1.61185, 1.64836, 1.90883},
2485 {1.60368, 1.60469, 1.60779, 1.61373, 1.62596, 1.67738,
2486 1.65651, 1.65249, 1.66290, 1.69936, 1.95959}};
2487
2488 // Garfield simulation at UD = -2200V; vd = 2.134cm/microsec, <driftfield> = 753V/cm
2489 Float_t time2200[ktimebin][kZbin] =
2490 {{0.09162, 0.09194, 0.09292, 0.09460, 0.09702, 0.10014,
2491 0.10421, 0.10971, 0.11820, 0.13990, 0.37745},
2492 {0.06581, 0.06618, 0.06730, 0.06915, 0.07173, 0.07507,
2493 0.07931, 0.08497, 0.09368, 0.11609, 0.35560},
2494 {0.03947, 0.04001, 0.04167, 0.04429, 0.04772, 0.05183,
2495 0.05667, 0.06293, 0.07292, 0.09900, 0.34673},
2496 {0.01111, 0.01280, 0.01716, 0.02279, 0.02876, 0.03473,
2497 0.04091, 0.04907, 0.06426, 0.10620, 0.36766},
2498 {0.01113, 0.01285, 0.01719, 0.02276, 0.02863, 0.03452,
2499 0.04076, 0.04960, 0.06745, 0.11419, 0.37139},
2500 {0.03923, 0.03978, 0.04137, 0.04387, 0.04713, 0.05110,
2501 0.05605, 0.06284, 0.07551, 0.10677, 0.36210},
2502 {0.06505, 0.06540, 0.06644, 0.06820, 0.07069, 0.07401,
2503 0.07852, 0.08479, 0.09565, 0.12325, 0.37313},
2504 {0.09107, 0.09127, 0.09181, 0.09291, 0.09474, 0.00000,
2505 0.10883, 0.11528, 0.12789, 0.15865, 0.41313},
2506 {0.12559, 0.12622, 0.12800, 0.13206, 0.14166, 0.19331,
2507 0.16832, 0.16632, 0.17724, 0.21218, 0.47098},
2508 {0.16992, 0.17070, 0.17325, 0.17831, 0.18871, 0.23557,
2509 0.21690, 0.21451, 0.22514, 0.26082, 0.52034},
2510 {0.21640, 0.21722, 0.21987, 0.22500, 0.23540, 0.28097,
2511 0.26399, 0.26154, 0.27214, 0.30784, 0.56734},
2512 {0.26318, 0.26400, 0.26679, 0.27181, 0.28220, 0.32739,
2513 0.31090, 0.30842, 0.31902, 0.35474, 0.61415},
2514 {0.31001, 0.31085, 0.31348, 0.31866, 0.32903, 0.37412,
2515 0.35777, 0.35546, 0.36588, 0.40159, 0.66103},
2516 {0.35687, 0.35769, 0.36033, 0.36556, 0.37588, 0.42094,
2517 0.40523, 0.40214, 0.41273, 0.44841, 0.70785},
2518 {0.40372, 0.40457, 0.40723, 0.41234, 0.42273, 0.46778,
2519 0.45148, 0.44903, 0.45961, 0.49526, 0.75486},
2520 {0.45062, 0.45139, 0.45404, 0.45966, 0.46958, 0.51470,
2521 0.49833, 0.49584, 0.50644, 0.54211, 0.80160},
2522 {0.49742, 0.49825, 0.50088, 0.50605, 0.51644, 0.56148,
2523 0.54518, 0.54270, 0.55330, 0.58897, 0.84854},
2524 {0.54427, 0.54510, 0.54774, 0.55290, 0.56329, 0.60846,
2525 0.59203, 0.58955, 0.60014, 0.63578, 0.89528},
2526 {0.59119, 0.59199, 0.59471, 0.59975, 0.61014, 0.65533,
2527 0.63889, 0.63636, 0.64699, 0.68269, 0.94197},
2528 {0.63866, 0.63880, 0.64145, 0.64664, 0.65701, 0.70639,
2529 0.68574, 0.68325, 0.69385, 0.72949, 0.98900},
2530 {0.68483, 0.68566, 0.68831, 0.69347, 0.70386, 0.74890,
2531 0.73260, 0.73010, 0.74069, 0.77638, 1.03320},
2532 {0.73168, 0.73255, 0.73515, 0.74031, 0.75072, 0.79576,
2533 0.77117, 0.77501, 0.78755, 0.82318, 1.08006},
2534 {0.77854, 0.78310, 0.78200, 0.79525, 0.79756, 0.84281,
2535 0.81803, 0.82393, 0.83441, 0.87008, 1.12692},
2536 {0.82541, 0.82642, 0.82916, 0.83528, 0.84442, 0.89086,
2537 0.87315, 0.87079, 0.88125, 0.91694, 1.17648},
2538 {0.87226, 0.87308, 0.87602, 0.88086, 0.89128, 0.93772,
2539 0.92001, 0.91751, 0.92811, 0.95587, 1.22328},
2540 {0.91921, 0.91994, 0.92256, 0.92772, 0.94713, 0.98566,
2541 0.96690, 0.96436, 0.97495, 1.01064, 1.26882},
2542 {0.96790, 0.96679, 0.96941, 0.97463, 0.99399, 1.03001,
2543 1.01376, 1.01112, 1.02181, 1.05749, 1.31568},
2544 {1.01278, 1.01390, 1.01674, 1.02147, 1.03182, 1.07820,
2545 1.06056, 1.05798, 1.06867, 1.10433, 1.36390},
2546 {1.05964, 1.06076, 1.06331, 1.06833, 1.07870, 1.13297,
2547 1.10742, 1.10520, 1.11543, 1.15120, 1.41069},
2548 {1.10664, 1.10762, 1.10997, 1.11519, 1.12556, 1.17531,
2549 1.15427, 1.14620, 1.16229, 1.19805, 1.45758},
2550 {1.15352, 1.15421, 1.15683, 1.16218, 1.17242, 1.21910,
2551 1.20035, 1.19863, 1.20579, 1.24473, 1.50412},
2552 {1.20019, 1.20115, 1.20369, 1.20892, 1.21928, 1.26913,
2553 1.24721, 1.24549, 1.25605, 1.29159, 1.54920},
2554 {1.24707, 1.24846, 1.25052, 1.25602, 1.26608, 1.31558,
2555 1.29448, 1.29232, 1.30293, 1.33675, 1.59798},
2556 {1.29391, 1.29475, 1.29738, 1.30255, 1.31294, 1.36244,
2557 1.34167, 1.33918, 1.34979, 1.38229, 1.64496},
2558 {1.34078, 1.34304, 1.34424, 1.35565, 1.35980, 1.40930,
2559 1.38853, 1.38229, 1.39664, 1.42863, 1.69162},
2560 {1.38762, 1.38847, 1.39110, 1.39627, 1.40666, 1.45183,
2561 1.43539, 1.43289, 1.44348, 1.47549, 1.73876},
2562 {1.43524, 1.43533, 1.43796, 1.44310, 1.45371, 1.49305,
2563 1.48224, 1.47941, 1.49034, 1.52601, 1.78552},
2564 {1.48122, 1.48219, 1.48482, 1.48991, 1.50030, 1.53991,
2565 1.52898, 1.52653, 1.53653, 1.57282, 1.82386}};
2566
4d18a639 2567 if (fTimeStruct1) {
2568 delete [] fTimeStruct1;
2569 }
2570 fTimeStruct1 = new Float_t[ktimebin*kZbin];
2571
2572 if (fTimeStruct2) {
2573 delete [] fTimeStruct2;
2574 }
2575 fTimeStruct2 = new Float_t[ktimebin*kZbin];
2576
2577 for (Int_t ctrt = 0; ctrt < ktimebin; ctrt++) {
2578 for (Int_t ctrz = 0; ctrz < kZbin; ctrz++) {
2579 if (vdrift > fVDsmp[6]) {
2580 fTimeStruct1[ctrt+ctrz*ktimebin] = time2100[ctrt][ctrz];
2581 fTimeStruct2[ctrt+ctrz*ktimebin] = time2200[ctrt][ctrz];
2582 fVDlo = fVDsmp[6];
2583 fVDhi = fVDsmp[7];
2584 }
2585 else if (vdrift > fVDsmp[5]) {
2586 fTimeStruct1[ctrt+ctrz*ktimebin] = time2000[ctrt][ctrz];
2587 fTimeStruct2[ctrt+ctrz*ktimebin] = time2100[ctrt][ctrz];
2588 fVDlo = fVDsmp[5];
2589 fVDhi = fVDsmp[6];
2590 }
2591 else if (vdrift > fVDsmp[4]) {
2592 fTimeStruct1[ctrt+ctrz*ktimebin] = time1900[ctrt][ctrz];
2593 fTimeStruct2[ctrt+ctrz*ktimebin] = time2000[ctrt][ctrz];
2594 fVDlo = fVDsmp[4];
2595 fVDhi = fVDsmp[5];
2596 }
2597 else if (vdrift > fVDsmp[3]) {
2598 fTimeStruct1[ctrt+ctrz*ktimebin] = time1800[ctrt][ctrz];
2599 fTimeStruct2[ctrt+ctrz*ktimebin] = time1900[ctrt][ctrz];
2600 fVDlo = fVDsmp[3];
2601 fVDhi = fVDsmp[4];
2602 }
2603 else if (vdrift > fVDsmp[2]) {
2604 fTimeStruct1[ctrt+ctrz*ktimebin] = time1700[ctrt][ctrz];
2605 fTimeStruct2[ctrt+ctrz*ktimebin] = time1800[ctrt][ctrz];
2606 fVDlo = fVDsmp[2];
2607 fVDhi = fVDsmp[3];
2608 }
2609 else if (vdrift > fVDsmp[1]) {
2610 fTimeStruct1[ctrt+ctrz*ktimebin] = time1600[ctrt][ctrz];
2611 fTimeStruct2[ctrt+ctrz*ktimebin] = time1700[ctrt][ctrz];
2612 fVDlo = fVDsmp[1];
2613 fVDhi = fVDsmp[2];
2614 }
2615 else if (vdrift > (fVDsmp[0] - 1.0e-5)) {
2616 fTimeStruct1[ctrt+ctrz*ktimebin] = time1500[ctrt][ctrz];
2617 fTimeStruct2[ctrt+ctrz*ktimebin] = time1600[ctrt][ctrz];
2618 fVDlo = fVDsmp[0];
2619 fVDhi = fVDsmp[1];
3551db50 2620 }
2621 }
2622 }
4d18a639 2623
3551db50 2624}
2625
2626//_____________________________________________________________________________
2627void AliTRDdigitizer::RecalcDiffusion(Float_t vdrift)
2628{
4d18a639 2629 //
2630 // Recalculates the diffusion parameters
2631 //
2632
2633 if (vdrift == fDiffLastVdrift) {
3551db50 2634 return;
4d18a639 2635 }
7754cd1f 2636
4d18a639 2637 AliTRDSimParam *simParam = AliTRDSimParam::Instance();
9afbd7de 2638 if (!simParam) {
4329977a 2639 AliFatal("Could not get simulation parameters");
3551db50 2640 return;
2641 }
2642
4d18a639 2643 AliTRDCommonParam *commonParam = AliTRDCommonParam::Instance();
9afbd7de 2644 if (!commonParam) {
4329977a 2645 AliFatal("Could not get common parameters");
3551db50 2646 return;
2647 }
2648
4d18a639 2649 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
9afbd7de 2650 if (!calibration) {
4329977a 2651 AliFatal("Could not get calibration object");
3551db50 2652 return;
2653 }
1b95a37b 2654
4d18a639 2655 fDiffLastVdrift = vdrift;
0a17cc30 2656
2657 if (simParam->IsXenon()) {
b65e5048 2658
0a17cc30 2659 //
2660 // Vd and B-field dependent diffusion and Lorentz angle
2661 //
b65e5048 2662
0a17cc30 2663 // The magnetic field strength
2664 Double_t x[3] = { 0.0, 0.0, 0.0 };
2665 Double_t b[3];
2666 gAlice->Field(x,b); // b[] is in kilo Gauss
2667 Float_t field = b[2] * 0.1; // Tesla
b65e5048 2668
2669
2670
0a17cc30 2671 // DiffusionL
2672 const Int_t kNbL = 5;
2673 Float_t p0L[kNbL] = { 0.007440, 0.007493, 0.007513, 0.007672, 0.007831 };
2674 Float_t p1L[kNbL] = { 0.019252, 0.018912, 0.018636, 0.018012, 0.017343 };
2675 Float_t p2L[kNbL] = { -0.005042, -0.004926, -0.004867, -0.004650, -0.004424 };
2676 Float_t p3L[kNbL] = { 0.000195, 0.000189, 0.000195, 0.000182, 0.000169 };
b65e5048 2677
0a17cc30 2678 Int_t ibL = ((Int_t) (10 * (field - 0.15)));
2679 ibL = TMath::Max( 0,ibL);
2680 ibL = TMath::Min(kNbL,ibL);
b65e5048 2681
0a17cc30 2682 fDiffusionL = p0L[ibL]
b65e5048 2683 + p1L[ibL] * vdrift
2684 + p2L[ibL] * vdrift*vdrift
2685 + p3L[ibL] * vdrift*vdrift*vdrift;
2686
0a17cc30 2687 // DiffusionT
2688 const Int_t kNbT = 5;
2689 Float_t p0T[kNbT] = { 0.009550, 0.009599, 0.009674, 0.009757, 0.009850 };
2690 Float_t p1T[kNbT] = { 0.006667, 0.006539, 0.006359, 0.006153, 0.005925 };
2691 Float_t p2T[kNbT] = { -0.000853, -0.000798, -0.000721, -0.000635, -0.000541 };
2692 Float_t p3T[kNbT] = { 0.000131, 0.000122, 0.000111, 0.000098, 0.000085 };
b65e5048 2693
0a17cc30 2694 Int_t ibT= ((Int_t) (10 * (field - 0.15)));
2695 ibT = TMath::Max( 0,ibT);
2696 ibT = TMath::Min(kNbT,ibT);
b65e5048 2697
0a17cc30 2698 fDiffusionT = p0T[ibT]
2699 + p1T[ibT] * vdrift
2700 + p2T[ibT] * vdrift*vdrift
2701 + p3T[ibT] * vdrift*vdrift*vdrift;
b65e5048 2702
0a17cc30 2703 // OmegaTau
2704 fOmegaTau = calibration->GetOmegaTau(vdrift,field);
0a17cc30 2705 if (commonParam->ExBOn()) {
2706 fLorentzFactor = 1.0 / (1.0 + fOmegaTau*fOmegaTau);
2707 }
2708 else {
2709 fLorentzFactor = 1.0;
2710 }
b65e5048 2711
0a17cc30 2712 }
b65e5048 2713
0a17cc30 2714 else if (simParam->IsArgon()) {
3551db50 2715
0a17cc30 2716 // Diffusion constants and Lorentz angle only for B = 0.5T
2717 fDiffusionL = 0.0182;
2718 fDiffusionT = 0.0159;
2719 fOmegaTau = 0.0219769;
2720 if (commonParam->ExBOn()) {
2721 fLorentzFactor = 1.0 / (1.0 + fOmegaTau*fOmegaTau);
2722 }
2723 else {
2724 fLorentzFactor = 1.0;
2725 }
1b95a37b 2726
3551db50 2727 }
9afbd7de 2728
3551db50 2729}
2730
2731//_____________________________________________________________________________
2732Float_t AliTRDdigitizer::GetDiffusionL(Float_t vdrift)
2733{
2734 //
2735 // Returns the longitudinal diffusion coefficient for a given drift
2736 // velocity <vd> and a B-field <b> for Xe/CO2 (15%).
2737 // The values are according to a GARFIELD simulation.
2738 //
2739
2740 RecalcDiffusion(vdrift);
4d18a639 2741
2742 return fDiffusionL;
9afbd7de 2743
3551db50 2744}
2745
2746//_____________________________________________________________________________
2747Float_t AliTRDdigitizer::GetDiffusionT(Float_t vdrift)
2748{
2749 //
2750 // Returns the transverse diffusion coefficient for a given drift
2751 // velocity <vd> and a B-field <b> for Xe/CO2 (15%).
2752 // The values are according to a GARFIELD simulation.
2753 //
2754
2755 RecalcDiffusion(vdrift);
4d18a639 2756
2757 return fDiffusionT;
9afbd7de 2758
3551db50 2759}
2760
2761//_____________________________________________________________________________
4329977a 2762Int_t AliTRDdigitizer::Diffusion(Float_t vdrift, Double_t absdriftlength
2763 , Double_t &lRow, Double_t &lCol, Double_t &lTime)
3551db50 2764{
2765 //
4329977a 2766 // Applies the diffusion smearing to the position of a single electron.
2767 // Depends on absolute drift length.
3551db50 2768 //
2769
2770 RecalcDiffusion(vdrift);
2771
4329977a 2772 Float_t driftSqrt = TMath::Sqrt(absdriftlength);
4d18a639 2773 Float_t sigmaT = driftSqrt * fDiffusionT;
2774 Float_t sigmaL = driftSqrt * fDiffusionL;
4329977a 2775 lRow = gRandom->Gaus(lRow ,sigmaT);
2776 lCol = gRandom->Gaus(lCol ,sigmaT * GetLorentzFactor(vdrift));
2777 lTime = gRandom->Gaus(lTime,sigmaL * GetLorentzFactor(vdrift));
3551db50 2778
2779 return 1;
9afbd7de 2780
3551db50 2781}
2782
2783//_____________________________________________________________________________
2784Float_t AliTRDdigitizer::GetLorentzFactor(Float_t vd)
2785{
9afbd7de 2786 //
2787 // Returns the recalculated Lorentz factor
2788 //
2789
3551db50 2790 RecalcDiffusion(vd);
4d18a639 2791
2792 return fLorentzFactor;
9afbd7de 2793
3551db50 2794}
2795
2796//_____________________________________________________________________________
4329977a 2797Int_t AliTRDdigitizer::ExB(Float_t vdrift, Double_t driftlength, Double_t &lCol)
3551db50 2798{
2799 //
4329977a 2800 // Applies E x B effects to the position of a single electron.
2801 // Depends on signed drift length.
3551db50 2802 //
2803
2804 RecalcDiffusion(vdrift);
4329977a 2805
2806 lCol = lCol + fOmegaTau * driftlength;
3551db50 2807
2808 return 1;
9afbd7de 2809
3551db50 2810}
b65e5048 2811
2812//_____________________________________________________________________________
2813void AliTRDdigitizer::ZS(AliTRDarrayADC *digits)
2814{
2815 //
2816 // Apply the ZS
2817 //
2818
2819 // Create the temporary digits container
2820 AliTRDarrayADC *tempDigits;
2821 tempDigits = new AliTRDarrayADC();
2822 Int_t dim4 = digits->GetNrow();
2823 Int_t dim5 = digits->GetNcol()+2;
2824 Int_t dim6 = digits->GetNtime();
2825 Int_t lim = dim5-1;
2826
2827 tempDigits->Allocate(dim4,dim5,dim6);
2828
2829 for(Int_t row=0;row<dim4;row++)
2830 {
2831 for(Int_t col=0;col<dim5;col++)
2832 {
2833 for(Int_t time=0;time<dim6;time++)
2834 {
2835 if(col==0||col==lim)
2836 {
2837 tempDigits->SetData(row,col,time,0);
2838 }
2839 else
2840 {
2841 tempDigits->SetData(row,col,time,digits->GetData(row,col-1,time));
2842 }
2843 }
2844 }
2845 }
2846
2847 //Create and initialize the mcm object
2848 AliTRDmcmSim* mcmfast;
2849 mcmfast = new AliTRDmcmSim();
2850 mcmfast->StartfastZS(dim5,dim6);
2851
2852 //Call the methods in the mcm class using the temporary array as input
2853 for(Int_t row=0;row<dim4;row++)
2854 {
2855 for(Int_t col=0;col<dim5;col++)
2856 {
2857 for(Int_t time=0;time<dim6;time++)
2858 {
2859 mcmfast->SetData(col,time,tempDigits->GetData(row,col,time));
2860 }
2861 }
2862 mcmfast->Filter();
2863 mcmfast->ZSMapping();
2864 mcmfast->FlagDigitsArray(tempDigits,row);
2865 mcmfast->StartfastZS(dim5,dim6);
2866 }
2867
2868 //Modify the digits array to indicate suppressed values
2869 for(Int_t irow=0; irow<dim4;irow++)
2870 {
2871 for(Int_t icol=1; icol<lim;icol++)
2872 {
2873 for(Int_t itime=0; itime<dim6;itime++)
2874 {
2875 if(tempDigits->GetData(irow,icol,itime)==-1) // If supressed in temporary array
2876 {
2877 digits->SetData(irow,icol-1,itime,-1); // Supressed values indicated by -1 in the digits array
2878 }
2879 }
2880 }
2881 }
2882
2883 // Delete objects
2884 delete mcmfast;
2885 delete tempDigits;
2886
2887}