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