First implementation of EMCAL trigger QA from Nicola Arbor
[u/mrichter/AliRoot.git] / TOF / AliTOFSDigitizer.cxx
CommitLineData
517b7f8f 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$ */
17
0e46b9ae 18//__________________________________________________________//
19// //
20// This is a TTask that constructs SDigits out of Hits //
21// A Summable Digits is the "sum" of all hits in a pad //
22// Detector response has been simulated via the method //
23// SimulateDetectorResponse //
24// //
25// -- Authors: F. Pierella, A. De Caro //
26// Use case: see AliTOFhits2sdigits.C macro in the CVS //
27//__________________________________________________________//
28
e939a978 29#include <TBenchmark.h>
7ca4655f 30#include <TClonesArray.h>
e939a978 31#include <TF1.h>
32#include <TFile.h>
33#include <TParticle.h>
34#include <TTree.h>
35#include <TRandom.h>
a1e17193 36#include <TROOT.h>
88cb7938 37
88cb7938 38#include "AliLoader.h"
0e46b9ae 39#include "AliLog.h"
d3c7bfac 40#include "AliMC.h"
88cb7938 41#include "AliRunLoader.h"
0e46b9ae 42#include "AliRun.h"
d3c7bfac 43
3f296ed3 44#include "AliTOFcalib.h"
45#include "AliTOFRecoParam.h"
0f4a7374 46#include "AliTOFGeometry.h"
5919c40c 47#include "AliTOFHitMap.h"
016e1f91 48#include "AliTOFhitT0.h"
0e46b9ae 49#include "AliTOFhit.h"
50#include "AliTOFSDigitizer.h"
51#include "AliTOFSDigit.h"
52#include "AliTOF.h"
53
5c7c93fa 54extern TROOT *gROOT;
517b7f8f 55
56ClassImp(AliTOFSDigitizer)
57
58//____________________________________________________________________________
655e379f 59AliTOFSDigitizer::AliTOFSDigitizer():
60 TTask("TOFSDigitizer",""),
61 fEvent1(-1),
62 fEvent2(-1),
63 ftail(0x0),
64 fHeadersFile(""),
65 fRunLoader(0x0),
66 fTOFLoader(0x0),
655e379f 67 fSelectedSector(-1),
68 fSelectedPlate(-1),
3f296ed3 69 fTimeResolution(100.),
655e379f 70 fpadefficiency(0),
71 fEdgeEffect(-1),
72 fEdgeTails(-1),
73 fHparameter(0),
74 fH2parameter(0),
75 fKparameter(0),
76 fK2parameter(0),
77 fEffCenter(0),
78 fEffBoundary(0),
79 fEff2Boundary(0),
80 fEff3Boundary(0),
81 fAddTRes(0),
82 fResCenter(0),
83 fResBoundary(0),
84 fResSlope(0),
85 fTimeWalkCenter(0),
86 fTimeWalkBoundary(0),
87 fTimeWalkSlope(0),
88 fTimeDelayFlag(-1),
89 fPulseHeightSlope(0),
90 fTimeDelaySlope(0),
91 fMinimumCharge(0),
92 fChargeSmearing(0),
93 fLogChargeSmearing(0),
94 fTimeSmearing(0),
95 fAverageTimeFlag(-1),
96 fAdcBin(0),
97 fAdcMean(0),
3f296ed3 98 fAdcRms(0),
99 fCalib(new AliTOFcalib())
517b7f8f 100{
101 // ctor
3f296ed3 102
517b7f8f 103}
d61f73d9 104
7aeeaf38 105//------------------------------------------------------------------------
655e379f 106AliTOFSDigitizer::AliTOFSDigitizer(const AliTOFSDigitizer &source):
107 TTask(source),
108 fEvent1(-1),
109 fEvent2(-1),
110 ftail(0x0),
111 fHeadersFile(""),
112 fRunLoader(0x0),
113 fTOFLoader(0x0),
655e379f 114 fSelectedSector(-1),
115 fSelectedPlate(-1),
3f296ed3 116 fTimeResolution(100.),
655e379f 117 fpadefficiency(0),
118 fEdgeEffect(-1),
119 fEdgeTails(-1),
120 fHparameter(0),
121 fH2parameter(0),
122 fKparameter(0),
123 fK2parameter(0),
124 fEffCenter(0),
125 fEffBoundary(0),
126 fEff2Boundary(0),
127 fEff3Boundary(0),
128 fAddTRes(0),
129 fResCenter(0),
130 fResBoundary(0),
131 fResSlope(0),
132 fTimeWalkCenter(0),
133 fTimeWalkBoundary(0),
134 fTimeWalkSlope(0),
135 fTimeDelayFlag(-1),
136 fPulseHeightSlope(0),
137 fTimeDelaySlope(0),
138 fMinimumCharge(0),
139 fChargeSmearing(0),
140 fLogChargeSmearing(0),
141 fTimeSmearing(0),
142 fAverageTimeFlag(-1),
143 fAdcBin(0),
144 fAdcMean(0),
3f296ed3 145 fAdcRms(0),
146 fCalib(new AliTOFcalib())
7aeeaf38 147{
148 // copy constructor
96f01799 149 //this->fTOFGeometry=source.fTOFGeometry;
7aeeaf38 150
151}
152
153//____________________________________________________________________________
2f584d46 154AliTOFSDigitizer& AliTOFSDigitizer::operator=(const AliTOFSDigitizer &/*source*/)
7aeeaf38 155{
156 // ass. op.
7aeeaf38 157 return *this;
158
159}
160
517b7f8f 161//____________________________________________________________________________
655e379f 162AliTOFSDigitizer::AliTOFSDigitizer(const char* HeaderFile, Int_t evNumber1, Int_t nEvents):
163 TTask("TOFSDigitizer",""),
164 fEvent1(-1),
165 fEvent2(-1),
166 ftail(0x0),
167 fHeadersFile(HeaderFile), // input filename (with hits)
168 fRunLoader(0x0),
169 fTOFLoader(0x0),
655e379f 170 fSelectedSector(-1), // by default we sdigitize all sectors
171 fSelectedPlate(-1), // by default we sdigitize all plates in all sectors
3f296ed3 172 fTimeResolution(100.),
655e379f 173 fpadefficiency(0),
174 fEdgeEffect(-1),
175 fEdgeTails(-1),
176 fHparameter(0),
177 fH2parameter(0),
178 fKparameter(0),
179 fK2parameter(0),
180 fEffCenter(0),
181 fEffBoundary(0),
182 fEff2Boundary(0),
183 fEff3Boundary(0),
184 fAddTRes(0),
185 fResCenter(0),
186 fResBoundary(0),
187 fResSlope(0),
188 fTimeWalkCenter(0),
189 fTimeWalkBoundary(0),
190 fTimeWalkSlope(0),
191 fTimeDelayFlag(-1),
192 fPulseHeightSlope(0),
193 fTimeDelaySlope(0),
194 fMinimumCharge(0),
195 fChargeSmearing(0),
196 fLogChargeSmearing(0),
197 fTimeSmearing(0),
198 fAverageTimeFlag(-1),
199 fAdcBin(0),
200 fAdcMean(0),
3f296ed3 201 fAdcRms(0),
202 fCalib(new AliTOFcalib())
517b7f8f 203{
340693af 204 //ctor, reading from input file
d61f73d9 205
d61f73d9 206 TFile * file = (TFile*) gROOT->GetFile(fHeadersFile.Data());
207
208 //File was not opened yet open file and get alirun object
209 if (file == 0) {
210 file = TFile::Open(fHeadersFile.Data(),"update") ;
211 gAlice = (AliRun *) file->Get("gAlice") ;
ea7a588a 212 }
26e447bd 213
517b7f8f 214 // add Task to //root/Tasks folder
e191bb57 215 TString evfoldname = AliConfig::GetDefaultEventFolderName();
f540341d 216 fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
217 if (!fRunLoader)
218 fRunLoader = AliRunLoader::Open(HeaderFile);//open session and mount on default event folder
88cb7938 219 if (fRunLoader == 0x0)
d61f73d9 220 {
d076c8d5 221 AliFatal("Event is not loaded. Exiting");
d61f73d9 222 return;
223 }
26e447bd 224
96f01799 225 /*
d3c7bfac 226 fRunLoader->CdGAFile();
227 TDirectory *savedir=gDirectory;
228 TFile *in=(TFile*)gFile;
229
96f01799 230
231// when fTOFGeometry was needed
d3c7bfac 232 if (!in->IsOpen()) {
233 AliWarning("Geometry file is not open default TOF geometry will be used");
234 fTOFGeometry = new AliTOFGeometry();
235 }
236 else {
237 in->cd();
238 fTOFGeometry = (AliTOFGeometry*)in->Get("TOFgeometry");
239 }
96f01799 240
d3c7bfac 241 savedir->cd();
96f01799 242 */
f540341d 243 if (fRunLoader->TreeE() == 0x0) fRunLoader->LoadHeader();
d61f73d9 244
245 if (evNumber1>=0) fEvent1 = evNumber1;
246 else fEvent1=0;
247
248 if (nEvents==0) fEvent2 = (Int_t)(fRunLoader->GetNumberOfEvents());
249 else if (nEvents>0) fEvent2 = evNumber1+nEvents;
250 else fEvent2 = 1;
251
252 if (!(fEvent2>fEvent1)) {
d076c8d5 253 AliError(Form("fEvent2 = %d <= fEvent1 = %d", fEvent2, fEvent1));
d61f73d9 254 fEvent1 = 0;
255 fEvent2 = 1;
d076c8d5 256 AliError(Form("Correction: fEvent2 = %d <= fEvent1 = %d", fEvent2, fEvent1));
26e447bd 257 }
d61f73d9 258
26e447bd 259 // init parameters for sdigitization
260 InitParameters();
d61f73d9 261
262 fTOFLoader = fRunLoader->GetLoader("TOFLoader");
263 if (fTOFLoader == 0x0)
264 {
d076c8d5 265 AliFatal("Can not find TOF loader in event. Exiting.");
d61f73d9 266 return;
267 }
268 fTOFLoader->PostSDigitizer(this);
3f296ed3 269
517b7f8f 270}
271
272//____________________________________________________________________________
d61f73d9 273AliTOFSDigitizer::~AliTOFSDigitizer()
517b7f8f 274{
275 // dtor
797e311f 276 fTOFLoader->CleanSDigitizer();
d3c7bfac 277
3f296ed3 278 if (fCalib) delete fCalib;
279
f73548c4 280}
281
282//____________________________________________________________________________
283void AliTOFSDigitizer::InitParameters()
284{
285 // set parameters for detector simulation
d61f73d9 286
3f296ed3 287 fCalib->Init();
288
289 //fTimeResolution = 80.; //120.; OLD
290 AliTOFRecoParam *recoParams = (AliTOFRecoParam*)fCalib->ReadRecParFromCDB("TOF/Calib",fRunLoader->GetRunNumber());
291 fTimeResolution = recoParams->GetTimeResolution(); // now from OCDB
292 if (fTimeResolution==0.) {
293 AliWarning("In OCDB found 0ps for TOF time resolution. It is set to 100ps.");
294 fTimeResolution = 100.;
295 }
296 AliDebug(1,Form(" TOF time resolution read from OCDB = %f ps",fTimeResolution));
fa2ad948 297 fpadefficiency = 0.995 ;
3f296ed3 298 //fEdgeEffect = 2 ; // edge effects according to test beam results
299 fEdgeEffect = 1 ; // edge effects according to test beam results
300 // but with fixed time resolution, i.e. fTimeResolution
f73548c4 301 fEdgeTails = 0 ;
302 fHparameter = 0.4 ;
303 fH2parameter = 0.15;
fa2ad948 304 fKparameter = 0.9 ;
305 fK2parameter = 0.55;
f73548c4 306 fEffCenter = fpadefficiency;
fa2ad948 307 fEffBoundary = 0.833;
308 fEff2Boundary = 0.94;
309 fEff3Boundary = 0.1;
8d6daa31 310 fAddTRes = 68. ; // \sqrt{2x20^2 + 15^2 + 2x10^2 + 30^2 + 50^2} (p-p)
311 //fAddTRes = 48. ; // \sqrt{2x20^2 + 15^2 + 2x10^2 + 30^2 + 15^2} (Pb-Pb)
7e6dce66 312 // 30^2+20^2+40^2+50^2+50^2+50^2 = 10400 ps^2 (very old value)
313 fResCenter = 35. ; //50. ; // OLD
f73548c4 314 fResBoundary = 70. ;
7e6dce66 315 fResSlope = 37. ; //40. ; // OLD
f73548c4 316 fTimeWalkCenter = 0. ;
317 fTimeWalkBoundary=0. ;
318 fTimeWalkSlope = 0. ;
2608880a 319 fTimeDelayFlag = 0 ;
f73548c4 320 fPulseHeightSlope=2.0 ;
321 fTimeDelaySlope =0.060;
322 // was fMinimumCharge = TMath::Exp(fPulseHeightSlope*fKparameter/2.);
323 fMinimumCharge = TMath::Exp(-fPulseHeightSlope*fHparameter);
324 fChargeSmearing=0.0 ;
325 fLogChargeSmearing=0.13;
326 fTimeSmearing =0.022;
327 fAverageTimeFlag=0 ;
43f77f2d 328
d61f73d9 329 fAdcBin = 0.25; // 1 ADC bin = 0.25 pC (or 0.03 pC)
ea7a588a 330 fAdcMean = 50.; // ADC distribution mpv value for Landau (in bins)
331 // it corresponds to a mean value of ~100 bins
332 fAdcRms = 25.; // ADC distribution rms value (in bins)
333 // it corresponds to distribution rms ~50 bins
f73548c4 334}
335
336//__________________________________________________________________
7e8c2e88 337Double_t TimeWithTail(const Double_t * const x, const Double_t * const par)
f73548c4 338{
339 // sigma - par[0], alpha - par[1], part - par[2]
340 // at x<part*sigma - gauss
341 // at x>part*sigma - TMath::Exp(-x/alpha)
342 Float_t xx =x[0];
343 Double_t f;
344 if(xx<par[0]*par[2]) {
345 f = TMath::Exp(-xx*xx/(2*par[0]*par[0]));
346 } else {
347 f = TMath::Exp(-(xx-par[0]*par[2])/par[1]-0.5*par[2]*par[2]);
348 }
349 return f;
517b7f8f 350}
351
352//____________________________________________________________________________
d61f73d9 353void AliTOFSDigitizer::Exec(Option_t *verboseOption) {
340693af 354 //execute TOF sdigitization
d61f73d9 355 if (strstr(verboseOption,"tim") || strstr(verboseOption,"all"))
ea7a588a 356 gBenchmark->Start("TOFSDigitizer");
517b7f8f 357
ea7a588a 358 if (fEdgeTails) ftail = new TF1("tail",TimeWithTail,-2,2,3);
d61f73d9 359
ea7a588a 360 Int_t nselectedHits=0;
361 Int_t ntotalsdigits=0;
362 Int_t ntotalupdates=0;
363 Int_t nnoisesdigits=0;
364 Int_t nsignalsdigits=0;
365 Int_t nHitsFromPrim=0;
366 Int_t nHitsFromSec=0;
367 Int_t nlargeTofDiff=0;
f73548c4 368
da3d3acd 369 Bool_t thereIsNotASelection=(fSelectedSector==-1) && (fSelectedPlate==-1);
55991c8b 370
f540341d 371 if (fRunLoader->GetAliRun() == 0x0) fRunLoader->LoadgAlice();
d61f73d9 372 gAlice = fRunLoader->GetAliRun();
ea7a588a 373
d61f73d9 374 fRunLoader->LoadKinematics();
375
7e6dce66 376 AliTOF *tof = (AliTOF *) gAlice->GetDetector("TOF");
d61f73d9 377
7e6dce66 378 if (!tof) {
d076c8d5 379 AliError("TOF not found");
d61f73d9 380 return;
381 }
3f296ed3 382
d61f73d9 383 fTOFLoader->LoadHits("read");
384 fTOFLoader->LoadSDigits("recreate");
3495d79c 385
386 Int_t vol[5]={-1,-1,-1,-1,-1}; // location for a digit
387 Int_t digit[2]={0,0}; // TOF digit variables
d61f73d9 388
3495d79c 389 Int_t nselectedHitsinEv=0;
390 Int_t ntotalsdigitsinEv=0;
391 Int_t ntotalupdatesinEv=0;
392 Int_t nnoisesdigitsinEv=0;
393 Int_t nsignalsdigitsinEv=0;
394
d61f73d9 395 for (Int_t iEvent=fEvent1; iEvent<fEvent2; iEvent++) {
0e46b9ae 396 //AliInfo(Form("------------------- %s -------------", GetName()));
397 //AliInfo(Form("Sdigitizing event %i", iEvent));
517b7f8f 398
d61f73d9 399 fRunLoader->GetEvent(iEvent);
400
3495d79c 401 TTree *hitTree = fTOFLoader->TreeH();
7e6dce66 402 if (!hitTree) return;
517b7f8f 403
d61f73d9 404 if (fTOFLoader->TreeS () == 0) fTOFLoader->MakeTree ("S");
405
5919c40c 406 //Make branch for digits
7e6dce66 407 tof->MakeBranch("S");
517b7f8f 408
d61f73d9 409 // recreate TClonesArray fSDigits - for backward compatibility
7e6dce66 410 if (tof->SDigits() == 0) {
411 tof->CreateSDigitsArray();
d61f73d9 412 } else {
7e6dce66 413 tof->RecreateSDigitsArray();
d61f73d9 414 }
5919c40c 415
7e6dce66 416 tof->SetTreeAddress();
87e54ebb 417
7e6dce66 418 Int_t version=tof->IsVersion();
d61f73d9 419
3495d79c 420 nselectedHitsinEv=0;
421 ntotalsdigitsinEv=0;
422 ntotalupdatesinEv=0;
423 nnoisesdigitsinEv=0;
424 nsignalsdigitsinEv=0;
016e1f91 425
5919c40c 426 TParticle *particle;
016e1f91 427 //AliTOFhit *tofHit;
7e6dce66 428 TClonesArray *tofHitArray = tof->Hits();
5919c40c 429
f73548c4 430 // create hit map
3495d79c 431 //AliTOFHitMap *hitMap = new AliTOFHitMap(tof->SDigits(), fTOFGeometry);
96f01799 432 AliTOFHitMap *hitMap = new AliTOFHitMap(tof->SDigits());
5919c40c 433
7e6dce66 434 TBranch * tofHitsBranch = hitTree->GetBranch("TOF");
bfec09a6 435
7e6dce66 436 Int_t ntracks = static_cast<Int_t>(hitTree->GetEntries());
5919c40c 437 for (Int_t track = 0; track < ntracks; track++)
438 {
3e2e3ece 439 gAlice->GetMCApp()->ResetHits();
d7ccea72 440 tofHitsBranch->GetEvent(track);
0e46b9ae 441
442 AliMC *mcApplication = (AliMC*)gAlice->GetMCApp();
443
3495d79c 444 particle = (TParticle*)mcApplication->Particle(track);
7e6dce66 445 Int_t nhits = tofHitArray->GetEntriesFast();
f73548c4 446 // cleaning all hits of the same track in the same pad volume
447 // it is a rare event, however it happens
448
d61f73d9 449 Int_t previousTrack =-1;
450 Int_t previousSector=-1;
451 Int_t previousPlate =-1;
452 Int_t previousStrip =-1;
453 Int_t previousPadX =-1;
454 Int_t previousPadZ =-1;
5919c40c 455
d61f73d9 456 for (Int_t hit = 0; hit < nhits; hit++) {
3495d79c 457 for (Int_t aa=0; aa<5;aa++) vol[aa]=-1; // location for a digit
458 for (Int_t aa=0; aa<2;aa++) digit[aa]=0; // TOF digit variables
459 Int_t tracknum;
7e6dce66 460 Float_t dxPad;
461 Float_t dzPad;
016e1f91 462 Float_t geantTime;
463
464 // fp: really sorry for this, it is a temporary trick to have
465 // track length too
dfef1a15 466 if (version<6) { //(version!=6 && version!=7)
7e6dce66 467 AliTOFhit *tofHit = (AliTOFhit *) tofHitArray->UncheckedAt(hit);
016e1f91 468 tracknum = tofHit->GetTrack();
469 vol[0] = tofHit->GetSector();
470 vol[1] = tofHit->GetPlate();
471 vol[2] = tofHit->GetStrip();
472 vol[3] = tofHit->GetPadx();
473 vol[4] = tofHit->GetPadz();
7e6dce66 474 dxPad = tofHit->GetDx();
475 dzPad = tofHit->GetDz();
3f296ed3 476 geantTime = tofHit->GetTof(); // unit [s] // already corrected per event_time smearing
016e1f91 477 } else {
7e6dce66 478 AliTOFhitT0 *tofHit = (AliTOFhitT0 *) tofHitArray->UncheckedAt(hit);
016e1f91 479 tracknum = tofHit->GetTrack();
480 vol[0] = tofHit->GetSector();
481 vol[1] = tofHit->GetPlate();
55991c8b 482 vol[2] = tofHit->GetStrip();
483 vol[3] = tofHit->GetPadx();
484 vol[4] = tofHit->GetPadz();
7e6dce66 485 dxPad = tofHit->GetDx();
486 dzPad = tofHit->GetDz();
3f296ed3 487 geantTime = tofHit->GetTof(); // unit [s] // already corrected per event_time_smearing
016e1f91 488 }
d61f73d9 489
016e1f91 490 geantTime *= 1.e+09; // conversion from [s] to [ns]
4d1c7395 491 // TOF matching window (~200ns) control
492 if (geantTime>=AliTOFGeometry::MatchingWindow()*1E-3) {
493 AliDebug(2,Form("Time measurement (%f) greater than the matching window (%f)",
494 geantTime, AliTOFGeometry::MatchingWindow()*1E-3));
495 continue;
496 }
c630773f 497
016e1f91 498 // selection case for sdigitizing only hits in a given plate of a given sector
499 if(thereIsNotASelection || (vol[0]==fSelectedSector && vol[1]==fSelectedPlate)){
55991c8b 500
501 Bool_t dummy=((tracknum==previousTrack) && (vol[0]==previousSector) && (vol[1]==previousPlate) && (vol[2]==previousStrip));
502
503 Bool_t isCloneOfThePrevious=dummy && ((vol[3]==previousPadX) && (vol[4]==previousPadZ));
504
b213b8bd 505 Bool_t isNeighOfThePrevious=dummy && ((((vol[3]==previousPadX-1) || (vol[3]==previousPadX+1)) && (vol[4]==previousPadZ)) || ((vol[3]==previousPadX) && ((vol[4]==previousPadZ+1) || (vol[4]==previousPadZ-1))));
55991c8b 506
b213b8bd 507 if(!isCloneOfThePrevious && !isNeighOfThePrevious){
55991c8b 508 // update "previous" values
509 // in fact, we are yet in the future, so the present is past
510 previousTrack=tracknum;
511 previousSector=vol[0];
512 previousPlate=vol[1];
513 previousStrip=vol[2];
514 previousPadX=vol[3];
515 previousPadZ=vol[4];
516
517 nselectedHits++;
518 nselectedHitsinEv++;
d61f73d9 519 if (particle->GetFirstMother() < 0) nHitsFromPrim++; // counts hits due to primary particles
55991c8b 520
7e6dce66 521 Float_t xStrip=AliTOFGeometry::XPad()*(vol[3]+0.5-0.5*AliTOFGeometry::NpadX())+dxPad;
522 Float_t zStrip=AliTOFGeometry::ZPad()*(vol[4]+0.5-0.5*AliTOFGeometry::NpadZ())+dzPad;
016e1f91 523
55991c8b 524 Int_t nActivatedPads = 0, nFiredPads = 0;
525 Bool_t isFired[4] = {kFALSE, kFALSE, kFALSE, kFALSE};
526 Float_t tofAfterSimul[4] = {0., 0., 0., 0.};
527 Float_t qInduced[4] = {0.,0.,0.,0.};
528 Int_t nPlace[4] = {0, 0, 0, 0};
529 Float_t averageTime = 0.;
530 SimulateDetectorResponse(zStrip,xStrip,geantTime,nActivatedPads,nFiredPads,isFired,nPlace,qInduced,tofAfterSimul,averageTime);
531 if(nFiredPads) {
532 for(Int_t indexOfPad=0; indexOfPad<nActivatedPads; indexOfPad++) {
533 if(isFired[indexOfPad]){ // the pad has fired
2608880a 534
55991c8b 535 Float_t timediff=geantTime-tofAfterSimul[indexOfPad];
5ab3605a 536
c630773f 537 // TOF matching window (~200ns) control
538 if (tofAfterSimul[indexOfPad]>=AliTOFGeometry::MatchingWindow()*1E-3) {
4d1c7395 539 AliDebug(2,Form("Time measurement (%f) greater than the matching window (%f)",
c630773f 540 tofAfterSimul[indexOfPad], AliTOFGeometry::MatchingWindow()*1E-3));
541 continue;
542 }
543
544 if(timediff>=0.2) nlargeTofDiff++; // greater than 200ps
55991c8b 545
9fa04290 546 digit[0] = TMath::Nint((tofAfterSimul[indexOfPad]*1.e+03)/AliTOFGeometry::TdcBinWidth()); // TDC bin number (each bin -> 24.4 ps)
55991c8b 547
548 Float_t landauFactor = gRandom->Landau(fAdcMean, fAdcRms);
9fa04290 549 digit[1] = TMath::Nint(qInduced[indexOfPad] * landauFactor); // ADC bins (each bin -> 0.25 (or 0.03) pC)
d61f73d9 550
55991c8b 551 // recalculate the volume only for neighbouring pads
ea7a588a 552 if(indexOfPad){
0f4a7374 553 (nPlace[indexOfPad]<=AliTOFGeometry::NpadX()) ? vol[4] = 0 : vol[4] = 1;
554 (nPlace[indexOfPad]<=AliTOFGeometry::NpadX()) ? vol[3] = nPlace[indexOfPad] - 1 : vol[3] = nPlace[indexOfPad] - AliTOFGeometry::NpadX() - 1;
ea7a588a 555 }
d61f73d9 556 // check if two sdigit are on the same pad;
557 // in that case we sum the two or more sdigits
55991c8b 558 if (hitMap->TestHit(vol) != kEmpty) {
559 AliTOFSDigit *sdig = static_cast<AliTOFSDigit*>(hitMap->GetHit(vol));
560 Int_t tdctime = (Int_t) digit[0];
561 Int_t adccharge = (Int_t) digit[1];
43f77f2d 562 sdig->Update(AliTOFGeometry::TdcBinWidth(),tdctime,adccharge,tracknum);
55991c8b 563 ntotalupdatesinEv++;
564 ntotalupdates++;
565 } else {
566
7e6dce66 567 tof->AddSDigit(tracknum, vol, digit);
55991c8b 568
569 if(indexOfPad){
570 nnoisesdigits++;
571 nnoisesdigitsinEv++;
572 } else {
573 nsignalsdigits++;
574 nsignalsdigitsinEv++;
575 }
576 ntotalsdigitsinEv++;
577 ntotalsdigits++;
578 hitMap->SetHit(vol);
579 } // if (hitMap->TestHit(vol) != kEmpty)
580 } // if(isFired[indexOfPad])
581 } // end loop on nActivatedPads
582 } // if(nFiredPads) i.e. if some pads has fired
583 } // close if(!isCloneOfThePrevious)
584 } // close the selection on sector and plate
5919c40c 585 } // end loop on hits for the current track
586 } // end loop on ntracks
55991c8b 587
5919c40c 588 delete hitMap;
d61f73d9 589
590 fTOFLoader->TreeS()->Reset();
591 fTOFLoader->TreeS()->Fill();
592 fTOFLoader->WriteSDigits("OVERWRITE");
593
7e6dce66 594 if (tof->SDigits()) tof->ResetSDigits();
d61f73d9 595
4d1c7395 596 if (strstr(verboseOption,"all") || strstr(verboseOption,"partial")) {
597 AliDebug(2,"----------------------------------------");
598 AliDebug(2,Form("After sdigitizing %d hits in event %d", nselectedHitsinEv, iEvent));
ea7a588a 599 //" (" << nHitsFromPrim << " from primaries and " << nHitsFromSec << " from secondaries) TOF hits, "
fda219f1 600 AliDebug(1,Form("%d sdigits have been created", ntotalsdigitsinEv));
4d1c7395 601 AliDebug(2,Form("(%d due to signals and %d due to border effect)", nsignalsdigitsinEv, nnoisesdigitsinEv));
602 AliDebug(2,Form("%d total updates of the hit map have been performed in current event", ntotalupdatesinEv));
603 AliDebug(2,"----------------------------------------");
ea7a588a 604 }
605
606 } //event loop on events
607
d61f73d9 608 fTOFLoader->UnloadSDigits();
609 fTOFLoader->UnloadHits();
610 fRunLoader->UnloadKinematics();
e615b5b5 611 //fRunLoader->UnloadgAlice();
d61f73d9 612
ea7a588a 613 // free used memory
614 if (ftail){
615 delete ftail;
616 ftail = 0;
617 }
618
619 nHitsFromSec=nselectedHits-nHitsFromPrim;
4d1c7395 620 if (strstr(verboseOption,"all") || strstr(verboseOption,"partial")) {
621 AliDebug(2,"----------------------------------------");
622 AliDebug(2,Form("After sdigitizing %d hits in %d events ", nselectedHits, fEvent2-fEvent1));
623 //" (" << nHitsFromPrim << " from primaries and " << nHitsFromSec << " from secondaries) TOF hits, "
624 AliDebug(2,Form("%d sdigits have been created", ntotalsdigits));
625 AliDebug(2,Form("(%d due to signals and %d due to border effect)", nsignalsdigits, nnoisesdigits));
626 AliDebug(2,Form("%d total updates of the hit map have been performed", ntotalupdates));
627 AliDebug(2,Form("in %d cases the time of flight difference is greater than 200 ps", nlargeTofDiff));
628 AliDebug(2,"----------------------------------------");
ea7a588a 629 }
630
517b7f8f 631
ea7a588a 632 if(strstr(verboseOption,"tim") || strstr(verboseOption,"all")){
633 gBenchmark->Stop("TOFSDigitizer");
d076c8d5 634 AliInfo("AliTOFSDigitizer:");
635 AliInfo(Form(" took %f seconds in order to make sdigits "
636 "%f seconds per event", gBenchmark->GetCpuTime("TOFSDigitizer"), gBenchmark->GetCpuTime("TOFSDigitizer")/(fEvent2-fEvent1)));
637 AliInfo(" +++++++++++++++++++++++++++++++++++++++++++++++++++ ");
ea7a588a 638 }
517b7f8f 639
640}
ea7a588a 641
517b7f8f 642//__________________________________________________________________
5c016a7b 643void AliTOFSDigitizer::Print(Option_t* /*opt*/)const
517b7f8f 644{
0e46b9ae 645 AliInfo(Form(" ------------------- %s ------------- ", GetName()));
517b7f8f 646}
f73548c4 647
648//__________________________________________________________________
55991c8b 649void AliTOFSDigitizer::SelectSectorAndPlate(Int_t sector, Int_t plate)
650{
340693af 651 //Select sector and plate
0f4a7374 652 Bool_t isaWrongSelection=(sector < 0) || (sector >= AliTOFGeometry::NSectors()) || (plate < 0) || (plate >= AliTOFGeometry::NPlates());
55991c8b 653 if(isaWrongSelection){
d076c8d5 654 AliError("You have selected an invalid value for sector or plate ");
655 AliError(Form("The correct range for sector is [0,%d]", AliTOFGeometry::NSectors()-1));
656 AliError(Form("The correct range for plate is [0,%d]", AliTOFGeometry::NPlates()-1));
657 AliError("By default we continue sdigitizing all hits in all plates of all sectors");
55991c8b 658 } else {
659 fSelectedSector=sector;
660 fSelectedPlate =plate;
d076c8d5 661 AliInfo(Form("SDigitizing only hits in plate %d of the sector %d", fSelectedPlate, fSelectedSector));
55991c8b 662 }
663}
664
665//__________________________________________________________________
f73548c4 666void AliTOFSDigitizer::SimulateDetectorResponse(Float_t z0, Float_t x0, Float_t geantTime, Int_t& nActivatedPads, Int_t& nFiredPads, Bool_t* isFired, Int_t* nPlace, Float_t* qInduced, Float_t* tofTime, Float_t& averageTime)
667{
668 // Description:
669 // Input: z0, x0 - hit position in the strip system (0,0 - center of the strip), cm
670 // geantTime - time generated by Geant, ns
671 // Output: nActivatedPads - the number of pads activated by the hit (1 || 2 || 4)
672 // nFiredPads - the number of pads fired (really activated) by the hit (nFiredPads <= nActivatedPads)
673 // qInduced[iPad]- charge induced on pad, arb. units
674 // this array is initialized at zero by the caller
675 // tofAfterSimul[iPad] - time calculated with edge effect algorithm, ns
676 // this array is initialized at zero by the caller
677 // averageTime - time given by pad hited by the Geant track taking into account the times (weighted) given by the pads fired for edge effect also.
678 // The weight is given by the qInduced[iPad]/qCenterPad
679 // this variable is initialized at zero by the caller
680 // nPlace[iPad] - the number of the pad place, iPad = 0, 1, 2, 3
681 // this variable is initialized at zero by the caller
682 //
683 // Description of used variables:
684 // eff[iPad] - efficiency of the pad
685 // res[iPad] - resolution of the pad, ns
686 // timeWalk[iPad] - time walk of the pad, ns
687 // timeDelay[iPad] - time delay for neighbouring pad to hited pad, ns
688 // PadId[iPad] - Pad Identifier
689 // E | F --> PadId[iPad] = 5 | 6
690 // A | B --> PadId[iPad] = 1 | 2
691 // C | D --> PadId[iPad] = 3 | 4
692 // nTail[iPad] - the tail number, = 1 for tailA, = 2 for tailB
693 // qCenterPad - charge extimated for each pad, arb. units
694 // weightsSum - sum of weights extimated for each pad fired, arb. units
695
0f4a7374 696 const Float_t kSigmaForTail[2] = {AliTOFGeometry::SigmaForTail1(),AliTOFGeometry::SigmaForTail2()}; //for tail
f73548c4 697 Int_t iz = 0, ix = 0;
698 Float_t dX = 0., dZ = 0., x = 0., z = 0.;
699 Float_t h = fHparameter, h2 = fH2parameter, k = fKparameter, k2 = fK2parameter;
700 Float_t effX = 0., effZ = 0., resX = 0., resZ = 0., timeWalkX = 0., timeWalkZ = 0.;
701 Float_t logOfqInd = 0.;
702 Float_t weightsSum = 0.;
703 Int_t nTail[4] = {0,0,0,0};
704 Int_t padId[4] = {0,0,0,0};
705 Float_t eff[4] = {0.,0.,0.,0.};
706 Float_t res[4] = {0.,0.,0.,0.};
707 // Float_t qCenterPad = fMinimumCharge * fMinimumCharge;
708 Float_t qCenterPad = 1.;
709 Float_t timeWalk[4] = {0.,0.,0.,0.};
710 Float_t timeDelay[4] = {0.,0.,0.,0.};
711
712 nActivatedPads = 0;
713 nFiredPads = 0;
714
715 (z0 <= 0) ? iz = 0 : iz = 1;
0f4a7374 716 dZ = z0 + (0.5 * AliTOFGeometry::NpadZ() - iz - 0.5) * AliTOFGeometry::ZPad(); // hit position in the pad frame, (0,0) - center of the pad
717 z = 0.5 * AliTOFGeometry::ZPad() - TMath::Abs(dZ); // variable for eff., res. and timeWalk. functions
718 iz++; // z row: 1, ..., AliTOFGeometry::NpadZ = 2
719 ix = (Int_t)((x0 + 0.5 * AliTOFGeometry::NpadX() * AliTOFGeometry::XPad()) / AliTOFGeometry::XPad());
720 dX = x0 + (0.5 * AliTOFGeometry::NpadX() - ix - 0.5) * AliTOFGeometry::XPad(); // hit position in the pad frame, (0,0) - center of the pad
721 x = 0.5 * AliTOFGeometry::XPad() - TMath::Abs(dX); // variable for eff., res. and timeWalk. functions;
722 ix++; // x row: 1, ..., AliTOFGeometry::NpadX = 48
f73548c4 723
724 ////// Pad A:
725 nActivatedPads++;
0f4a7374 726 nPlace[nActivatedPads-1] = (iz - 1) * AliTOFGeometry::NpadX() + ix;
f73548c4 727 qInduced[nActivatedPads-1] = qCenterPad;
728 padId[nActivatedPads-1] = 1;
2608880a 729
730 switch (fEdgeEffect) {
731 case 0:
732 eff[nActivatedPads-1] = fEffCenter;
733 if (gRandom->Rndm() < eff[nActivatedPads-1]) {
734 nFiredPads = 1;
735 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + fResCenter * fResCenter); // ns
736 isFired[nActivatedPads-1] = kTRUE;
737 tofTime[nActivatedPads-1] = gRandom->Gaus(geantTime + fTimeWalkCenter, res[0]);
738 averageTime = tofTime[nActivatedPads-1];
739 }
740 break;
741
742 case 1:
743 if(z < h) {
744 if(z < h2) {
745 effZ = fEffBoundary + (fEff2Boundary - fEffBoundary) * z / h2;
746 } else {
747 effZ = fEff2Boundary + (fEffCenter - fEff2Boundary) * (z - h2) / (h - h2);
748 }
749 //resZ = fTimeResolution;
750 //timeWalkZ = 0.;
751 nTail[nActivatedPads-1] = 1;
752 } else {
753 effZ = fEffCenter;
754 //resZ = fTimeResolution;
755 //timeWalkZ = 0.;
756 }
757
758 if(x < h) {
759 if(x < h2) {
760 effX = fEffBoundary + (fEff2Boundary - fEffBoundary) * x / h2;
761 } else {
762 effX = fEff2Boundary + (fEffCenter - fEff2Boundary) * (x - h2) / (h - h2);
763 }
764 //resX = fTimeResolution;
765 //timeWalkX = 0.;
766 nTail[nActivatedPads-1] = 1;
767 } else {
768 effX = fEffCenter;
769 //resX = fTimeResolution;
770 //timeWalkX = 0.;
771 }
772
773 (effZ<effX) ? eff[nActivatedPads-1] = effZ : eff[nActivatedPads-1] = effX;
774 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
775 timeWalk[nActivatedPads-1] = 0.; // ns
776
777
778 ////// Pad B:
779 if(z < k2) {
780 effZ = fEffBoundary - (fEffBoundary - fEff3Boundary) * (z / k2);
781 } else {
782 effZ = fEff3Boundary * (k - z) / (k - k2);
783 }
784 //resZ = fTimeResolution;
785 //timeWalkZ = 0.;
786
787 if(z < k && z > 0) {
788 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
789 nActivatedPads++;
790 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX();
791 eff[nActivatedPads-1] = effZ;
792 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
793 timeWalk[nActivatedPads-1] = 0.; // ns
794 nTail[nActivatedPads-1] = 2;
795 if (fTimeDelayFlag) {
796 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
797 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
798 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
799 } else {
800 timeDelay[nActivatedPads-1] = 0.;
801 }
802 padId[nActivatedPads-1] = 2;
803 }
804 }
805
806
807 ////// Pad C, D, E, F:
808 if(x < k2) {
809 effX = fEffBoundary - (fEffBoundary - fEff3Boundary) * (x / k2);
810 } else {
811 effX = fEff3Boundary * (k - x) / (k - k2);
812 }
813 //resX = fTimeResolution;
814 //timeWalkX = 0.;
815
816 if(x < k && x > 0) {
817 // C:
818 if(ix > 1 && dX < 0) {
819 nActivatedPads++;
820 nPlace[nActivatedPads-1] = nPlace[0] - 1;
821 eff[nActivatedPads-1] = effX;
822 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
823 timeWalk[nActivatedPads-1] = 0.; // ns
824 nTail[nActivatedPads-1] = 2;
825 if (fTimeDelayFlag) {
826 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
827 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
828 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
829 } else {
830 timeDelay[nActivatedPads-1] = 0.;
831 }
832 padId[nActivatedPads-1] = 3;
833
834 // D:
835 if(z < k && z > 0) {
836 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
837 nActivatedPads++;
838 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() - 1;
839 eff[nActivatedPads-1] = effX * effZ;
840 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
841 timeWalk[nActivatedPads-1] = 0.; // ns
842
843 nTail[nActivatedPads-1] = 2;
844 if (fTimeDelayFlag) {
845 if (TMath::Abs(x) < TMath::Abs(z)) {
846 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
847 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
848 } else {
849 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
850 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
851 }
852 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
853 } else {
854 timeDelay[nActivatedPads-1] = 0.;
855 }
856 padId[nActivatedPads-1] = 4;
857 }
858 } // end D
859 } // end C
860
861 // E:
862 if(ix < AliTOFGeometry::NpadX() && dX > 0) {
863 nActivatedPads++;
864 nPlace[nActivatedPads-1] = nPlace[0] + 1;
865 eff[nActivatedPads-1] = effX;
866 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
867 timeWalk[nActivatedPads-1] = 0.; // ns
868 nTail[nActivatedPads-1] = 2;
869 if (fTimeDelayFlag) {
870 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
871 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
872 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
873 } else {
874 timeDelay[nActivatedPads-1] = 0.;
875 }
876 padId[nActivatedPads-1] = 5;
877
878
879 // F:
880 if(z < k && z > 0) {
881 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
882 nActivatedPads++;
883 nPlace[nActivatedPads - 1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() + 1;
884 eff[nActivatedPads - 1] = effX * effZ;
885 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
886 timeWalk[nActivatedPads-1] = 0.; // ns
887 nTail[nActivatedPads-1] = 2;
888 if (fTimeDelayFlag) {
889 if (TMath::Abs(x) < TMath::Abs(z)) {
890 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
891 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
892 } else {
893 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
894 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
895 }
896 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
897 } else {
898 timeDelay[nActivatedPads-1] = 0.;
899 }
900 padId[nActivatedPads-1] = 6;
901 }
902 } // end F
903 } // end E
904 } // end if(x < k)
905
906
907 for (Int_t iPad = 0; iPad < nActivatedPads; iPad++) {
908 if(gRandom->Rndm() < eff[iPad]) {
909 isFired[iPad] = kTRUE;
910 nFiredPads++;
911 if(fEdgeTails) {
912 if(nTail[iPad] == 0) {
913 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
914 } else {
915 ftail->SetParameters(res[iPad], 2. * res[iPad], kSigmaForTail[nTail[iPad]-1]);
916 Double_t timeAB = ftail->GetRandom();
917 tofTime[iPad] = geantTime + timeWalk[iPad] + timeDelay[iPad] + timeAB;
918 }
919 } else {
920 //AliDebug(1,Form(" ----------------- TOF time resolution = %f",res[iPad]));
921 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
922 }
923 if (fAverageTimeFlag) {
924 averageTime += tofTime[iPad] * qInduced[iPad];
925 weightsSum += qInduced[iPad];
926 } else {
927 averageTime += tofTime[iPad];
928 weightsSum += 1.;
929 }
930
931 AliDebug(1,Form(" Activated pad %d: geantTime=%f, tw=%fns, td=%fns, tofTime=%fns, sigma=%fps",iPad,geantTime,timeWalk[iPad],timeDelay[iPad],tofTime[iPad],1000.*res[iPad]));
932
933 }
934
935 }
936 if (weightsSum!=0) averageTime /= weightsSum;
937 break;
938
939
940 case 2:
941 if(z < h) {
942 if(z < h2) {
943 effZ = fEffBoundary + (fEff2Boundary - fEffBoundary) * z / h2;
944 } else {
945 effZ = fEff2Boundary + (fEffCenter - fEff2Boundary) * (z - h2) / (h - h2);
946 }
947 resZ = fResBoundary + (fResCenter - fResBoundary) * z / h;
948 timeWalkZ = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * z / h;
949 nTail[nActivatedPads-1] = 1;
950 } else {
951 effZ = fEffCenter;
952 resZ = fResCenter;
953 timeWalkZ = fTimeWalkCenter;
954 }
955
956 if(x < h) {
957 if(x < h2) {
958 effX = fEffBoundary + (fEff2Boundary - fEffBoundary) * x / h2;
959 } else {
960 effX = fEff2Boundary + (fEffCenter - fEff2Boundary) * (x - h2) / (h - h2);
961 }
962 resX = fResBoundary + (fResCenter - fResBoundary) * x / h;
963 timeWalkX = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * x / h;
964 nTail[nActivatedPads-1] = 1;
965 } else {
966 effX = fEffCenter;
967 resX = fResCenter;
968 timeWalkX = fTimeWalkCenter;
969 }
970
971 (effZ<effX) ? eff[nActivatedPads-1] = effZ : eff[nActivatedPads-1] = effX;
972 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
973 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
974
975
976 ////// Pad B:
977 if(z < k2) {
978 effZ = fEffBoundary - (fEffBoundary - fEff3Boundary) * (z / k2);
979 } else {
980 effZ = fEff3Boundary * (k - z) / (k - k2);
981 }
982 resZ = fResBoundary + fResSlope * z / k;
983 timeWalkZ = fTimeWalkBoundary + fTimeWalkSlope * z / k;
984
985 if(z < k && z > 0) {
986 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
987 nActivatedPads++;
988 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX();
989 eff[nActivatedPads-1] = effZ;
990 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
991 timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ; // ns
992 nTail[nActivatedPads-1] = 2;
993 if (fTimeDelayFlag) {
994 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
995 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
996 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
997 } else {
998 timeDelay[nActivatedPads-1] = 0.;
999 }
1000 padId[nActivatedPads-1] = 2;
1001 }
1002 }
1003
1004
1005 ////// Pad C, D, E, F:
1006 if(x < k2) {
1007 effX = fEffBoundary - (fEffBoundary - fEff3Boundary) * (x / k2);
1008 } else {
1009 effX = fEff3Boundary * (k - x) / (k - k2);
1010 }
1011 resX = fResBoundary + fResSlope*x/k;
1012 timeWalkX = fTimeWalkBoundary + fTimeWalkSlope*x/k;
1013
1014 if(x < k && x > 0) {
1015 // C:
1016 if(ix > 1 && dX < 0) {
1017 nActivatedPads++;
1018 nPlace[nActivatedPads-1] = nPlace[0] - 1;
1019 eff[nActivatedPads-1] = effX;
1020 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX); // ns
1021 timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1022 nTail[nActivatedPads-1] = 2;
1023 if (fTimeDelayFlag) {
1024 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1025 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1026 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1027 } else {
1028 timeDelay[nActivatedPads-1] = 0.;
1029 }
1030 padId[nActivatedPads-1] = 3;
1031
1032 // D:
1033 if(z < k && z > 0) {
1034 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
1035 nActivatedPads++;
1036 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() - 1;
1037 eff[nActivatedPads-1] = effX * effZ;
1038 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
1039 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1040
1041 nTail[nActivatedPads-1] = 2;
1042 if (fTimeDelayFlag) {
1043 if (TMath::Abs(x) < TMath::Abs(z)) {
1044 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
1045 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
1046 } else {
1047 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1048 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1049 }
1050 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1051 } else {
1052 timeDelay[nActivatedPads-1] = 0.;
1053 }
1054 padId[nActivatedPads-1] = 4;
1055 }
1056 } // end D
1057 } // end C
1058
1059 // E:
1060 if(ix < AliTOFGeometry::NpadX() && dX > 0) {
1061 nActivatedPads++;
1062 nPlace[nActivatedPads-1] = nPlace[0] + 1;
1063 eff[nActivatedPads-1] = effX;
1064 res[nActivatedPads-1] = 0.001 * (TMath::Sqrt(fAddTRes*fAddTRes + resX * resX)); // ns
1065 timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1066 nTail[nActivatedPads-1] = 2;
1067 if (fTimeDelayFlag) {
1068 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1069 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1070 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1071 } else {
1072 timeDelay[nActivatedPads-1] = 0.;
1073 }
1074 padId[nActivatedPads-1] = 5;
1075
1076
1077 // F:
1078 if(z < k && z > 0) {
1079 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
1080 nActivatedPads++;
1081 nPlace[nActivatedPads - 1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() + 1;
1082 eff[nActivatedPads - 1] = effX * effZ;
1083 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
1084 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001*timeWalkX; // ns
1085 nTail[nActivatedPads-1] = 2;
1086 if (fTimeDelayFlag) {
1087 if (TMath::Abs(x) < TMath::Abs(z)) {
1088 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
1089 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
1090 } else {
1091 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1092 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1093 }
1094 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1095 } else {
1096 timeDelay[nActivatedPads-1] = 0.;
1097 }
1098 padId[nActivatedPads-1] = 6;
1099 }
1100 } // end F
1101 } // end E
1102 } // end if(x < k)
1103
1104
1105 for (Int_t iPad = 0; iPad < nActivatedPads; iPad++) {
1106 if (res[iPad] < fTimeResolution) res[iPad] = fTimeResolution;
1107 if(gRandom->Rndm() < eff[iPad]) {
1108 isFired[iPad] = kTRUE;
1109 nFiredPads++;
1110 if(fEdgeTails) {
1111 if(nTail[iPad] == 0) {
1112 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
1113 } else {
1114 ftail->SetParameters(res[iPad], 2. * res[iPad], kSigmaForTail[nTail[iPad]-1]);
1115 Double_t timeAB = ftail->GetRandom();
1116 tofTime[iPad] = geantTime + timeWalk[iPad] + timeDelay[iPad] + timeAB;
1117 }
1118 } else {
1119 AliDebug(1,Form(" ----------------- TOF time resolution = %f",res[iPad]));
1120 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
1121 }
1122 if (fAverageTimeFlag) {
1123 averageTime += tofTime[iPad] * qInduced[iPad];
1124 weightsSum += qInduced[iPad];
1125 } else {
1126 averageTime += tofTime[iPad];
1127 weightsSum += 1.;
1128 }
1129 }
1130 }
1131 if (weightsSum!=0) averageTime /= weightsSum;
1132
1133 } // switch (fEdgeEffect)
1134
1135}
1136
1137//__________________________________________________________________
1138void AliTOFSDigitizer::SimulateDetectorResponseOLD(Float_t z0, Float_t x0, Float_t geantTime, Int_t& nActivatedPads, Int_t& nFiredPads, Bool_t* isFired, Int_t* nPlace, Float_t* qInduced, Float_t* tofTime, Float_t& averageTime)
1139{
1140 // Description:
1141 // Input: z0, x0 - hit position in the strip system (0,0 - center of the strip), cm
1142 // geantTime - time generated by Geant, ns
1143 // Output: nActivatedPads - the number of pads activated by the hit (1 || 2 || 4)
1144 // nFiredPads - the number of pads fired (really activated) by the hit (nFiredPads <= nActivatedPads)
1145 // qInduced[iPad]- charge induced on pad, arb. units
1146 // this array is initialized at zero by the caller
1147 // tofAfterSimul[iPad] - time calculated with edge effect algorithm, ns
1148 // this array is initialized at zero by the caller
1149 // averageTime - time given by pad hited by the Geant track taking into account the times (weighted) given by the pads fired for edge effect also.
1150 // The weight is given by the qInduced[iPad]/qCenterPad
1151 // this variable is initialized at zero by the caller
1152 // nPlace[iPad] - the number of the pad place, iPad = 0, 1, 2, 3
1153 // this variable is initialized at zero by the caller
1154 //
1155 // Description of used variables:
1156 // eff[iPad] - efficiency of the pad
1157 // res[iPad] - resolution of the pad, ns
1158 // timeWalk[iPad] - time walk of the pad, ns
1159 // timeDelay[iPad] - time delay for neighbouring pad to hited pad, ns
1160 // PadId[iPad] - Pad Identifier
1161 // E | F --> PadId[iPad] = 5 | 6
1162 // A | B --> PadId[iPad] = 1 | 2
1163 // C | D --> PadId[iPad] = 3 | 4
1164 // nTail[iPad] - the tail number, = 1 for tailA, = 2 for tailB
1165 // qCenterPad - charge extimated for each pad, arb. units
1166 // weightsSum - sum of weights extimated for each pad fired, arb. units
1167
1168 const Float_t kSigmaForTail[2] = {AliTOFGeometry::SigmaForTail1(),AliTOFGeometry::SigmaForTail2()}; //for tail
1169 Int_t iz = 0, ix = 0;
1170 Float_t dX = 0., dZ = 0., x = 0., z = 0.;
1171 Float_t h = fHparameter, h2 = fH2parameter, k = fKparameter, k2 = fK2parameter;
1172 Float_t effX = 0., effZ = 0., resX = 0., resZ = 0., timeWalkX = 0., timeWalkZ = 0.;
1173 Float_t logOfqInd = 0.;
1174 Float_t weightsSum = 0.;
1175 Int_t nTail[4] = {0,0,0,0};
1176 Int_t padId[4] = {0,0,0,0};
1177 Float_t eff[4] = {0.,0.,0.,0.};
1178 Float_t res[4] = {0.,0.,0.,0.};
1179 // Float_t qCenterPad = fMinimumCharge * fMinimumCharge;
1180 Float_t qCenterPad = 1.;
1181 Float_t timeWalk[4] = {0.,0.,0.,0.};
1182 Float_t timeDelay[4] = {0.,0.,0.,0.};
1183
1184 nActivatedPads = 0;
1185 nFiredPads = 0;
1186
1187 (z0 <= 0) ? iz = 0 : iz = 1;
1188 dZ = z0 + (0.5 * AliTOFGeometry::NpadZ() - iz - 0.5) * AliTOFGeometry::ZPad(); // hit position in the pad frame, (0,0) - center of the pad
1189 z = 0.5 * AliTOFGeometry::ZPad() - TMath::Abs(dZ); // variable for eff., res. and timeWalk. functions
1190 iz++; // z row: 1, ..., AliTOFGeometry::NpadZ = 2
1191 ix = (Int_t)((x0 + 0.5 * AliTOFGeometry::NpadX() * AliTOFGeometry::XPad()) / AliTOFGeometry::XPad());
1192 dX = x0 + (0.5 * AliTOFGeometry::NpadX() - ix - 0.5) * AliTOFGeometry::XPad(); // hit position in the pad frame, (0,0) - center of the pad
1193 x = 0.5 * AliTOFGeometry::XPad() - TMath::Abs(dX); // variable for eff., res. and timeWalk. functions;
1194 ix++; // x row: 1, ..., AliTOFGeometry::NpadX = 48
1195
1196 ////// Pad A:
1197 nActivatedPads++;
1198 nPlace[nActivatedPads-1] = (iz - 1) * AliTOFGeometry::NpadX() + ix;
1199 qInduced[nActivatedPads-1] = qCenterPad;
1200 padId[nActivatedPads-1] = 1;
f73548c4 1201
1202 if (fEdgeEffect == 0) {
1203 eff[nActivatedPads-1] = fEffCenter;
1204 if (gRandom->Rndm() < eff[nActivatedPads-1]) {
1205 nFiredPads = 1;
7e6dce66 1206 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + fResCenter * fResCenter); // ns
f73548c4 1207 isFired[nActivatedPads-1] = kTRUE;
1208 tofTime[nActivatedPads-1] = gRandom->Gaus(geantTime + fTimeWalkCenter, res[0]);
1209 averageTime = tofTime[nActivatedPads-1];
1210 }
3f296ed3 1211 } else { // if (fEdgeEffet!=0)
1212
f73548c4 1213 if(z < h) {
1214 if(z < h2) {
1215 effZ = fEffBoundary + (fEff2Boundary - fEffBoundary) * z / h2;
1216 } else {
1217 effZ = fEff2Boundary + (fEffCenter - fEff2Boundary) * (z - h2) / (h - h2);
1218 }
3f296ed3 1219 if (fEdgeEffect==1)
1220 resZ = fTimeResolution;
1221 else if (fEdgeEffect==2)
1222 resZ = fResBoundary + (fResCenter - fResBoundary) * z / h;
f73548c4 1223 timeWalkZ = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * z / h;
1224 nTail[nActivatedPads-1] = 1;
1225 } else {
1226 effZ = fEffCenter;
3f296ed3 1227 if (fEdgeEffect==1)
1228 resZ = fTimeResolution;
1229 else if (fEdgeEffect==2)
1230 resZ = fResCenter;
f73548c4 1231 timeWalkZ = fTimeWalkCenter;
1232 }
1233
1234 if(x < h) {
1235 if(x < h2) {
1236 effX = fEffBoundary + (fEff2Boundary - fEffBoundary) * x / h2;
1237 } else {
1238 effX = fEff2Boundary + (fEffCenter - fEff2Boundary) * (x - h2) / (h - h2);
1239 }
3f296ed3 1240 if (fEdgeEffect==1)
1241 resX = fTimeResolution;
1242 else if (fEdgeEffect==2)
1243 resX = fResBoundary + (fResCenter - fResBoundary) * x / h;
f73548c4 1244 timeWalkX = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * x / h;
1245 nTail[nActivatedPads-1] = 1;
1246 } else {
1247 effX = fEffCenter;
3f296ed3 1248 if (fEdgeEffect==1)
1249 resX = fTimeResolution;
1250 else if (fEdgeEffect==2)
1251 resX = fResCenter;
f73548c4 1252 timeWalkX = fTimeWalkCenter;
1253 }
1254
1255 (effZ<effX) ? eff[nActivatedPads-1] = effZ : eff[nActivatedPads-1] = effX;
2608880a 1256 if (fEdgeEffect==1)
1257 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * resX : res[nActivatedPads-1] = 0.001 * resZ; // ns
1258 else
1259 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
f73548c4 1260 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1261
1262
1263 ////// Pad B:
1264 if(z < k2) {
1265 effZ = fEffBoundary - (fEffBoundary - fEff3Boundary) * (z / k2);
1266 } else {
1267 effZ = fEff3Boundary * (k - z) / (k - k2);
1268 }
3f296ed3 1269 if (fEdgeEffect==1)
1270 resZ = fTimeResolution;
1271 else if (fEdgeEffect==2)
1272 resZ = fResBoundary + fResSlope * z / k;
f73548c4 1273 timeWalkZ = fTimeWalkBoundary + fTimeWalkSlope * z / k;
1274
1275 if(z < k && z > 0) {
1276 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
1277 nActivatedPads++;
0f4a7374 1278 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX();
f73548c4 1279 eff[nActivatedPads-1] = effZ;
2608880a 1280 if (fEdgeEffect==1)
1281 res[nActivatedPads-1] = 0.001 * resZ; // ns
1282 else
1283 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
f73548c4 1284 timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ; // ns
1285 nTail[nActivatedPads-1] = 2;
1286 if (fTimeDelayFlag) {
1287 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * z / 2.);
1288 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * z / 2.);
1289 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
1290 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
1291 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1292 } else {
1293 timeDelay[nActivatedPads-1] = 0.;
1294 }
1295 padId[nActivatedPads-1] = 2;
1296 }
1297 }
1298
1299
1300 ////// Pad C, D, E, F:
1301 if(x < k2) {
1302 effX = fEffBoundary - (fEffBoundary - fEff3Boundary) * (x / k2);
1303 } else {
1304 effX = fEff3Boundary * (k - x) / (k - k2);
1305 }
3f296ed3 1306 if (fEdgeEffect==1)
1307 resX = fTimeResolution;
1308 else if (fEdgeEffect==2)
1309 resX = fResBoundary + fResSlope*x/k;
f73548c4 1310 timeWalkX = fTimeWalkBoundary + fTimeWalkSlope*x/k;
1311
1312 if(x < k && x > 0) {
1313 // C:
1314 if(ix > 1 && dX < 0) {
1315 nActivatedPads++;
1316 nPlace[nActivatedPads-1] = nPlace[0] - 1;
1317 eff[nActivatedPads-1] = effX;
2608880a 1318 if (fEdgeEffect==1)
1319 res[nActivatedPads-1] = 0.001 * resX; // ns
1320 else if (fEdgeEffect==2)
1321 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX); // ns
f73548c4 1322 timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1323 nTail[nActivatedPads-1] = 2;
1324 if (fTimeDelayFlag) {
1325 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * x / 2.);
1326 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * x / 2.);
1327 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1328 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1329 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1330 } else {
1331 timeDelay[nActivatedPads-1] = 0.;
1332 }
1333 padId[nActivatedPads-1] = 3;
1334
1335 // D:
1336 if(z < k && z > 0) {
1337 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
1338 nActivatedPads++;
0f4a7374 1339 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() - 1;
f73548c4 1340 eff[nActivatedPads-1] = effX * effZ;
2608880a 1341 if (fEdgeEffect==1)
1342 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * resX : res[nActivatedPads-1] = 0.001 * resZ; // ns
1343 else if (fEdgeEffect==2)
1344 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
f73548c4 1345 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1346
1347 nTail[nActivatedPads-1] = 2;
1348 if (fTimeDelayFlag) {
1349 if (TMath::Abs(x) < TMath::Abs(z)) {
1350 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * z / 2.);
1351 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * z / 2.);
1352 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
1353 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
1354 } else {
1355 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * x / 2.);
1356 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * x / 2.);
1357 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1358 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1359 }
1360 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1361 } else {
1362 timeDelay[nActivatedPads-1] = 0.;
1363 }
1364 padId[nActivatedPads-1] = 4;
1365 }
1366 } // end D
1367 } // end C
1368
1369 // E:
0f4a7374 1370 if(ix < AliTOFGeometry::NpadX() && dX > 0) {
f73548c4 1371 nActivatedPads++;
1372 nPlace[nActivatedPads-1] = nPlace[0] + 1;
1373 eff[nActivatedPads-1] = effX;
2608880a 1374 if (fEdgeEffect==1)
1375 res[nActivatedPads-1] = 0.001 * resX; // ns
1376 else if (fEdgeEffect==2)
1377 res[nActivatedPads-1] = 0.001 * (TMath::Sqrt(fAddTRes*fAddTRes + resX * resX)); // ns
f73548c4 1378 timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1379 nTail[nActivatedPads-1] = 2;
1380 if (fTimeDelayFlag) {
1381 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * x / 2.);
1382 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * x / 2.);
1383 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1384 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1385 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1386 } else {
1387 timeDelay[nActivatedPads-1] = 0.;
1388 }
1389 padId[nActivatedPads-1] = 5;
1390
1391
1392 // F:
1393 if(z < k && z > 0) {
1394 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
1395 nActivatedPads++;
0f4a7374 1396 nPlace[nActivatedPads - 1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() + 1;
f73548c4 1397 eff[nActivatedPads - 1] = effX * effZ;
2608880a 1398 if (fEdgeEffect==1)
1399 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * resX : res[nActivatedPads-1] = 0.001 * resZ; // ns
1400 else if (fEdgeEffect==2)
1401 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
f73548c4 1402 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001*timeWalkX; // ns
1403 nTail[nActivatedPads-1] = 2;
1404 if (fTimeDelayFlag) {
1405 if (TMath::Abs(x) < TMath::Abs(z)) {
1406 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * z / 2.);
1407 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * z / 2.);
1408 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
1409 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
1410 } else {
1411 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * x / 2.);
1412 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * x / 2.);
1413 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1414 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1415 }
1416 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1417 } else {
1418 timeDelay[nActivatedPads-1] = 0.;
1419 }
1420 padId[nActivatedPads-1] = 6;
1421 }
1422 } // end F
1423 } // end E
1424 } // end if(x < k)
1425
1426
1427 for (Int_t iPad = 0; iPad < nActivatedPads; iPad++) {
3f296ed3 1428 if (fEdgeEffect==2 && res[iPad] < fTimeResolution) res[iPad] = fTimeResolution;
f73548c4 1429 if(gRandom->Rndm() < eff[iPad]) {
1430 isFired[iPad] = kTRUE;
1431 nFiredPads++;
1432 if(fEdgeTails) {
1433 if(nTail[iPad] == 0) {
1434 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
1435 } else {
1436 ftail->SetParameters(res[iPad], 2. * res[iPad], kSigmaForTail[nTail[iPad]-1]);
1437 Double_t timeAB = ftail->GetRandom();
1438 tofTime[iPad] = geantTime + timeWalk[iPad] + timeDelay[iPad] + timeAB;
1439 }
1440 } else {
3f296ed3 1441 AliDebug(1,Form(" ----------------- TOF time resolution = %f",res[iPad]));
f73548c4 1442 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
1443 }
1444 if (fAverageTimeFlag) {
1445 averageTime += tofTime[iPad] * qInduced[iPad];
1446 weightsSum += qInduced[iPad];
1447 } else {
1448 averageTime += tofTime[iPad];
1449 weightsSum += 1.;
1450 }
1451 }
1452 }
1453 if (weightsSum!=0) averageTime /= weightsSum;
1454 } // end else (fEdgeEffect != 0)
1455}
1456
1457//__________________________________________________________________
1458void AliTOFSDigitizer::PrintParameters()const
1459{
1460 //
1461 // Print parameters used for sdigitization
1462 //
0e46b9ae 1463 AliInfo(Form(" ------------------- %s -------------", GetName()));
1464 AliInfo(" Parameters used for TOF SDigitization ");
f73548c4 1465 // Printing the parameters
1466
0e46b9ae 1467 AliInfo(Form(" Number of events: %i ", (fEvent2-fEvent1)));
1468 AliInfo(Form(" from event %i to event %i", fEvent1, (fEvent2-1)));
3f296ed3 1469 AliInfo(Form(" Time Resolution (ps) %f Pad Efficiency: %f ", fTimeResolution, fpadefficiency));
0e46b9ae 1470 AliInfo(Form(" Edge Effect option: %d", fEdgeEffect));
1471
1472 AliInfo(" Boundary Effect Simulation Parameters ");
4682c56e 1473 AliInfo(Form(" Hparameter: %f H2parameter: %f Kparameter: %f K2parameter: %f", fHparameter, fH2parameter, fKparameter, fK2parameter));
1474 AliInfo(Form(" Efficiency in the central region of the pad: %f", fEffCenter));
1475 AliInfo(Form(" Efficiency at the boundary region of the pad: %f", fEffBoundary));
1476 AliInfo(Form(" Efficiency value at H2parameter %f", fEff2Boundary));
1477 AliInfo(Form(" Efficiency value at K2parameter %f", fEff3Boundary));
1478 AliInfo(Form(" Resolution (ps) in the central region of the pad: %f", fResCenter));
1479 AliInfo(Form(" Resolution (ps) at the boundary of the pad : %f", fResBoundary));
1480 AliInfo(Form(" Slope (ps/K) for neighbouring pad : %f", fResSlope));
1481 AliInfo(Form(" Time walk (ps) in the central region of the pad : %f", fTimeWalkCenter));
1482 AliInfo(Form(" Time walk (ps) at the boundary of the pad : %f", fTimeWalkBoundary));
1483 AliInfo(Form(" Slope (ps/K) for neighbouring pad : %f", fTimeWalkSlope));
0e46b9ae 1484 AliInfo(" Pulse Heigth Simulation Parameters ");
1485 AliInfo(Form(" Flag for delay due to the PulseHeightEffect : %d", fTimeDelayFlag));
4682c56e 1486 AliInfo(Form(" Pulse Height Slope : %f", fPulseHeightSlope));
1487 AliInfo(Form(" Time Delay Slope : %f", fTimeDelaySlope));
1488 AliInfo(Form(" Minimum charge amount which could be induced : %f", fMinimumCharge));
1489 AliInfo(Form(" Smearing in charge in (q1/q2) vs x plot : %f", fChargeSmearing));
1490 AliInfo(Form(" Smearing in log of charge ratio : %f", fLogChargeSmearing));
1491 AliInfo(Form(" Smearing in time in time vs log(q1/q2) plot : %f", fTimeSmearing));
0e46b9ae 1492 AliInfo(Form(" Flag for average time : %d", fAverageTimeFlag));
1493 AliInfo(Form(" Edge tails option : %d", fEdgeTails));
f73548c4 1494
1495}