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