]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFSDigitizer.cxx
TOFtrackerV2 cpu usage optimezed
[u/mrichter/AliRoot.git] / TOF / AliTOFSDigitizer.cxx
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
16 /* $Id$ */
17
18 //__________________________________________________________//
19 //                                                          //
20 //   This is a class 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
29 #include <TBenchmark.h>
30 #include <TClonesArray.h>
31 #include <TF1.h>
32 #include <TFile.h>
33 #include <TParticle.h>
34 #include <TTree.h>
35 #include <TRandom.h>
36 #include <TROOT.h>
37
38 #include "AliLoader.h"
39 #include "AliLog.h"
40 #include "AliMC.h"
41 #include "AliRunLoader.h"
42 #include "AliRun.h"
43
44 #include "AliTOFcalib.h"
45 #include "AliTOFRecoParam.h"
46 #include "AliTOFGeometry.h"
47 #include "AliTOFHitMap.h"
48 #include "AliTOFhitT0.h"
49 #include "AliTOFhit.h"
50 #include "AliTOFSDigitizer.h"
51 #include "AliTOFSDigit.h"
52 #include "AliTOF.h"
53
54 //extern TROOT *gROOT;
55
56 ClassImp(AliTOFSDigitizer)
57
58 //____________________________________________________________________________ 
59 AliTOFSDigitizer::AliTOFSDigitizer():
60   TNamed("TOFSDigitizer",""),
61   fEvent1(-1),
62   fEvent2(-1),
63   ftail(0x0),
64   fHeadersFile(""),
65   fRunLoader(0x0),
66   fTOFLoader(0x0),
67   fSelectedSector(-1), 
68   fSelectedPlate(-1),
69   fTimeResolution(100.),
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),
98   fAdcRms(0),
99   fCalib(new AliTOFcalib())
100 {
101   // ctor
102
103 }
104
105 //------------------------------------------------------------------------
106 AliTOFSDigitizer::AliTOFSDigitizer(const AliTOFSDigitizer &source):
107   TNamed(source),
108   fEvent1(-1),
109   fEvent2(-1),
110   ftail(0x0),
111   fHeadersFile(""),
112   fRunLoader(0x0),
113   fTOFLoader(0x0),
114   fSelectedSector(-1), 
115   fSelectedPlate(-1),
116   fTimeResolution(100.),
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),
145   fAdcRms(0),
146   fCalib(new AliTOFcalib())
147 {
148   // copy constructor
149   //this->fTOFGeometry=source.fTOFGeometry;
150
151 }
152
153 //____________________________________________________________________________ 
154 AliTOFSDigitizer& AliTOFSDigitizer::operator=(const AliTOFSDigitizer &/*source*/)
155 {
156   // ass. op.
157   return *this;
158
159 }
160
161 //____________________________________________________________________________ 
162 AliTOFSDigitizer::AliTOFSDigitizer(const char* HeaderFile, Int_t evNumber1, Int_t nEvents):
163   TNamed("TOFSDigitizer",""),
164   fEvent1(-1),
165   fEvent2(-1),
166   ftail(0x0),
167   fHeadersFile(HeaderFile), // input filename (with hits)
168   fRunLoader(0x0),
169   fTOFLoader(0x0),
170   fSelectedSector(-1), // by default we sdigitize all sectors
171   fSelectedPlate(-1),  // by default we sdigitize all plates in all sectors
172   fTimeResolution(100.),
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),
201   fAdcRms(0),
202   fCalib(new AliTOFcalib())
203 {
204   //ctor, reading from input file 
205   
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") ;
212   }
213   
214   // add Task to //root/Tasks folder
215   TString evfoldname = AliConfig::GetDefaultEventFolderName();
216   fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
217   if (!fRunLoader)
218     fRunLoader = AliRunLoader::Open(HeaderFile);//open session and mount on default event folder
219   if (fRunLoader == 0x0)
220     {
221       AliFatal("Event is not loaded. Exiting");
222       return;
223     }
224
225   /*
226   fRunLoader->CdGAFile();
227   TDirectory *savedir=gDirectory;
228   TFile *in=(TFile*)gFile;
229
230    
231 // when fTOFGeometry was needed
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   }
240   
241   savedir->cd();
242   */
243   if (fRunLoader->TreeE() == 0x0) fRunLoader->LoadHeader();
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)) {
253     AliError(Form("fEvent2 = %d <= fEvent1 = %d", fEvent2, fEvent1));
254     fEvent1 = 0;
255     fEvent2 = 1;
256     AliError(Form("Correction: fEvent2 = %d <= fEvent1 = %d", fEvent2, fEvent1));
257   }
258   
259   // init parameters for sdigitization
260   InitParameters();
261   
262   fTOFLoader = fRunLoader->GetLoader("TOFLoader");
263   if (fTOFLoader == 0x0)
264     {
265       AliFatal("Can not find TOF loader in event. Exiting.");
266       return;
267     }
268 }
269
270 //____________________________________________________________________________ 
271 AliTOFSDigitizer::~AliTOFSDigitizer()
272 {
273   // dtor
274   if (fCalib) delete fCalib;
275
276 }
277
278 //____________________________________________________________________________ 
279 void AliTOFSDigitizer::InitParameters()
280 {
281   // set parameters for detector simulation
282   
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));
293   fpadefficiency  = 0.995 ;
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
297   fEdgeTails      = 0   ;
298   fHparameter     = 0.4 ;
299   fH2parameter    = 0.15;
300   fKparameter     = 0.9 ;
301   fK2parameter    = 0.55;
302   fEffCenter      = fpadefficiency;
303   fEffBoundary    = 0.833;
304   fEff2Boundary   = 0.94;
305   fEff3Boundary   = 0.1;
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)
308   // 30^2+20^2+40^2+50^2+50^2+50^2 = 10400 ps^2 (very old value)
309   fResCenter      = 35. ; //50. ; // OLD
310   fResBoundary    = 70. ;
311   fResSlope       = 37. ; //40. ; // OLD
312   fTimeWalkCenter = 0.  ;
313   fTimeWalkBoundary=0.  ;
314   fTimeWalkSlope  = 0.  ;
315   fTimeDelayFlag  = 0   ;
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    ;
324
325   fAdcBin   = 0.25;    // 1 ADC bin = 0.25 pC (or 0.03 pC)
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
330 }
331
332 //__________________________________________________________________
333 Double_t TimeWithTail(const Double_t * const x, const Double_t * const par)
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;
346 }
347
348 //____________________________________________________________________________
349 void AliTOFSDigitizer::Digitize(Option_t *verboseOption) { 
350   //execute TOF sdigitization
351   if (strstr(verboseOption,"tim") || strstr(verboseOption,"all"))
352     gBenchmark->Start("TOFSDigitizer");
353
354   if (fEdgeTails) ftail = new TF1("tail",TimeWithTail,-2,2,3);
355   
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;
364
365   Bool_t thereIsNotASelection=(fSelectedSector==-1) && (fSelectedPlate==-1);
366
367   if (fRunLoader->GetAliRun() == 0x0) fRunLoader->LoadgAlice();
368   gAlice = fRunLoader->GetAliRun();
369
370   fRunLoader->LoadKinematics();
371   
372   AliTOF *tof = (AliTOF *) gAlice->GetDetector("TOF");
373   
374   if (!tof) {
375     AliError("TOF not found");
376     return;
377   }
378
379   fTOFLoader->LoadHits("read");
380   fTOFLoader->LoadSDigits("recreate");
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
384   
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
391   for (Int_t iEvent=fEvent1; iEvent<fEvent2; iEvent++) {
392     //AliInfo(Form("------------------- %s -------------", GetName()));
393     //AliInfo(Form("Sdigitizing event %i", iEvent));
394
395     fRunLoader->GetEvent(iEvent);
396
397     TTree *hitTree = fTOFLoader->TreeH();
398     if (!hitTree) return;
399
400     if (fTOFLoader->TreeS () == 0) fTOFLoader->MakeTree ("S");
401     
402     //Make branch for digits
403     tof->MakeBranch("S");
404     
405     // recreate TClonesArray fSDigits - for backward compatibility
406     if (tof->SDigits() == 0) {
407       tof->CreateSDigitsArray();
408     } else {
409       tof->RecreateSDigitsArray();
410     }
411
412     tof->SetTreeAddress();
413
414     Int_t version=tof->IsVersion();
415
416     nselectedHitsinEv=0;
417     ntotalsdigitsinEv=0;
418     ntotalupdatesinEv=0;
419     nnoisesdigitsinEv=0;
420     nsignalsdigitsinEv=0;
421
422     TParticle *particle;
423     //AliTOFhit *tofHit;
424     TClonesArray *tofHitArray = tof->Hits();
425
426     // create hit map
427     //AliTOFHitMap *hitMap = new AliTOFHitMap(tof->SDigits(), fTOFGeometry);
428     AliTOFHitMap *hitMap = new AliTOFHitMap(tof->SDigits());
429
430     TBranch * tofHitsBranch = hitTree->GetBranch("TOF");
431
432     Int_t ntracks = static_cast<Int_t>(hitTree->GetEntries());
433     for (Int_t track = 0; track < ntracks; track++)
434     {
435       gAlice->GetMCApp()->ResetHits();
436       tofHitsBranch->GetEvent(track);
437
438       AliMC *mcApplication = (AliMC*)gAlice->GetMCApp();
439
440       particle = (TParticle*)mcApplication->Particle(track);
441       Int_t nhits = tofHitArray->GetEntriesFast();
442       // cleaning all hits of the same track in the same pad volume
443       // it is a rare event, however it happens
444
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;
451
452       for (Int_t hit = 0; hit < nhits; hit++) {
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;
456         Float_t dxPad;
457         Float_t dzPad;
458         Float_t geantTime;
459
460         // fp: really sorry for this, it is a temporary trick to have
461         // track length too
462         if (version<6) { //(version!=6 && version!=7)
463           AliTOFhit *tofHit = (AliTOFhit *) tofHitArray->UncheckedAt(hit);
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();
470           dxPad = tofHit->GetDx();
471           dzPad = tofHit->GetDz();
472           geantTime = tofHit->GetTof(); // unit [s] // already corrected per event_time smearing
473         } else {
474           AliTOFhitT0 *tofHit = (AliTOFhitT0 *) tofHitArray->UncheckedAt(hit);
475           tracknum = tofHit->GetTrack();
476           vol[0] = tofHit->GetSector();
477           vol[1] = tofHit->GetPlate();
478           vol[2] = tofHit->GetStrip();
479           vol[3] = tofHit->GetPadx();
480           vol[4] = tofHit->GetPadz();
481           dxPad = tofHit->GetDx();
482           dzPad = tofHit->GetDz();
483           geantTime = tofHit->GetTof(); // unit [s] // already corrected per event_time_smearing
484         }
485         
486         geantTime *= 1.e+09;  // conversion from [s] to [ns]
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         }
493
494         // selection case for sdigitizing only hits in a given plate of a given sector
495         if(thereIsNotASelection || (vol[0]==fSelectedSector && vol[1]==fSelectedPlate)){
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           
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))));
502           
503           if(!isCloneOfThePrevious && !isNeighOfThePrevious){
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++;
515             if (particle->GetFirstMother() < 0) nHitsFromPrim++; // counts hits due to primary particles
516             
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;
519
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
530
531                   Float_t timediff=geantTime-tofAfterSimul[indexOfPad];
532
533                   // TOF matching window (~200ns) control
534                   if (tofAfterSimul[indexOfPad]>=AliTOFGeometry::MatchingWindow()*1E-3) {
535                     AliDebug(2,Form("Time measurement (%f) greater than the matching window (%f)",
536                                     tofAfterSimul[indexOfPad], AliTOFGeometry::MatchingWindow()*1E-3));
537                     continue;
538                   }
539
540                   if(timediff>=0.2) nlargeTofDiff++; // greater than 200ps
541                   
542                   digit[0] = TMath::Nint((tofAfterSimul[indexOfPad]*1.e+03)/AliTOFGeometry::TdcBinWidth()); // TDC bin number (each bin -> 24.4 ps)
543                   
544                   Float_t landauFactor = gRandom->Landau(fAdcMean, fAdcRms); 
545                   digit[1] = TMath::Nint(qInduced[indexOfPad] * landauFactor); // ADC bins (each bin -> 0.25 (or 0.03) pC)
546
547                   // recalculate the volume only for neighbouring pads
548                   if(indexOfPad){
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;
551                   }
552                   // check if two sdigit are on the same pad;
553                   // in that case we sum the two or more sdigits
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];
558                     sdig->Update(AliTOFGeometry::TdcBinWidth(),tdctime,adccharge,tracknum);
559                     ntotalupdatesinEv++;
560                     ntotalupdates++;
561                   } else {
562                     
563                     tof->AddSDigit(tracknum, vol, digit);
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
581       } // end loop on hits for the current track
582     } // end loop on ntracks
583     
584     delete hitMap;
585     
586     fTOFLoader->TreeS()->Reset();
587     fTOFLoader->TreeS()->Fill();
588     fTOFLoader->WriteSDigits("OVERWRITE");
589     
590     if (tof->SDigits()) tof->ResetSDigits();
591     
592     if (strstr(verboseOption,"all") || strstr(verboseOption,"partial")) {
593       AliDebug(2,"----------------------------------------");
594       AliDebug(2,Form("After sdigitizing %d hits in event %d", nselectedHitsinEv, iEvent));
595       //" (" << nHitsFromPrim << " from primaries and " << nHitsFromSec << " from secondaries) TOF hits, " 
596       AliDebug(1,Form("%d sdigits have been created", ntotalsdigitsinEv));
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,"----------------------------------------");
600     }
601
602   } //event loop on events
603
604     fTOFLoader->UnloadSDigits();
605     fTOFLoader->UnloadHits();
606     fRunLoader->UnloadKinematics();
607     //fRunLoader->UnloadgAlice();
608
609   // free used memory
610   if (ftail){
611     delete ftail;
612     ftail = 0;
613   }
614   
615   nHitsFromSec=nselectedHits-nHitsFromPrim;
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,"----------------------------------------");
625   }
626
627
628   if(strstr(verboseOption,"tim") || strstr(verboseOption,"all")){
629     gBenchmark->Stop("TOFSDigitizer");
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(" +++++++++++++++++++++++++++++++++++++++++++++++++++ ");
634   }
635
636 }
637
638 //__________________________________________________________________
639 void AliTOFSDigitizer::Print(Option_t* /*opt*/)const
640 {
641   AliInfo(Form(" ------------------- %s ------------- ", GetName()));
642 }
643
644 //__________________________________________________________________
645 void AliTOFSDigitizer::SelectSectorAndPlate(Int_t sector, Int_t plate)
646 {
647   //Select sector and plate
648   Bool_t isaWrongSelection=(sector < 0) || (sector >= AliTOFGeometry::NSectors()) || (plate < 0) || (plate >= AliTOFGeometry::NPlates());
649   if(isaWrongSelection){
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");
654   } else {
655     fSelectedSector=sector;
656     fSelectedPlate =plate;
657     AliInfo(Form("SDigitizing only hits in plate %d of the sector %d", fSelectedPlate, fSelectedSector));
658   }
659 }
660
661 //__________________________________________________________________
662 void 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   
692   const Float_t kSigmaForTail[2] = {AliTOFGeometry::SigmaForTail1(),AliTOFGeometry::SigmaForTail2()}; //for tail                                                   
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;
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
719   
720   ////// Pad A:
721   nActivatedPads++;
722   nPlace[nActivatedPads-1] = (iz - 1) * AliTOFGeometry::NpadX() + ix;
723   qInduced[nActivatedPads-1] = qCenterPad;
724   padId[nActivatedPads-1] = 1;
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 //__________________________________________________________________
1134 void 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;
1197   
1198   if (fEdgeEffect == 0) {
1199     eff[nActivatedPads-1] = fEffCenter;
1200     if (gRandom->Rndm() < eff[nActivatedPads-1]) {
1201       nFiredPads = 1;
1202       res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + fResCenter * fResCenter); // ns
1203       isFired[nActivatedPads-1] = kTRUE;
1204       tofTime[nActivatedPads-1] = gRandom->Gaus(geantTime + fTimeWalkCenter, res[0]);
1205       averageTime = tofTime[nActivatedPads-1];
1206     }
1207   } else { // if (fEdgeEffet!=0)
1208
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       }
1215       if (fEdgeEffect==1)
1216         resZ = fTimeResolution;
1217       else if (fEdgeEffect==2)
1218         resZ = fResBoundary + (fResCenter - fResBoundary) * z / h;
1219       timeWalkZ = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * z / h;
1220       nTail[nActivatedPads-1] = 1;
1221     } else {
1222       effZ = fEffCenter;
1223       if (fEdgeEffect==1)
1224         resZ = fTimeResolution;
1225       else if (fEdgeEffect==2)
1226         resZ = fResCenter;
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       }
1236       if (fEdgeEffect==1)
1237         resX = fTimeResolution;
1238       else if (fEdgeEffect==2)
1239         resX = fResBoundary + (fResCenter - fResBoundary) * x / h;
1240       timeWalkX = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * x / h;
1241       nTail[nActivatedPads-1] = 1;
1242     } else {
1243       effX = fEffCenter;
1244       if (fEdgeEffect==1)
1245         resX = fTimeResolution;
1246       else if (fEdgeEffect==2)
1247         resX = fResCenter;
1248       timeWalkX = fTimeWalkCenter;
1249     }
1250     
1251     (effZ<effX) ? eff[nActivatedPads-1] = effZ : eff[nActivatedPads-1] = effX;
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
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     }
1265     if (fEdgeEffect==1)
1266       resZ = fTimeResolution;
1267     else if (fEdgeEffect==2)
1268       resZ = fResBoundary + fResSlope * z / k;
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++;
1274         nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX();
1275         eff[nActivatedPads-1] = effZ;
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 
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     }
1302     if (fEdgeEffect==1)
1303       resX = fTimeResolution;
1304     else if (fEdgeEffect==2)
1305       resX = fResBoundary + fResSlope*x/k;
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;
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 
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++;
1335             nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() - 1;
1336             eff[nActivatedPads-1] = effX * effZ;
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
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:
1366       if(ix < AliTOFGeometry::NpadX() && dX > 0) {
1367         nActivatedPads++;
1368         nPlace[nActivatedPads-1] = nPlace[0] + 1;
1369         eff[nActivatedPads-1] = effX;
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
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++;
1392             nPlace[nActivatedPads - 1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() + 1;
1393             eff[nActivatedPads - 1] = effX * effZ;
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
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++) {
1424       if (fEdgeEffect==2 && res[iPad] < fTimeResolution) res[iPad] = fTimeResolution;
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 {
1437           AliDebug(1,Form(" ----------------- TOF time resolution = %f",res[iPad]));
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 //__________________________________________________________________
1454 void AliTOFSDigitizer::PrintParameters()const
1455 {
1456   //
1457   // Print parameters used for sdigitization
1458   //
1459   AliInfo(Form(" ------------------- %s -------------", GetName()));
1460   AliInfo(" Parameters used for TOF SDigitization ");
1461   //  Printing the parameters
1462   
1463   AliInfo(Form(" Number of events:                       %i ", (fEvent2-fEvent1)));
1464   AliInfo(Form(" from event %i to event %i", fEvent1, (fEvent2-1)));
1465   AliInfo(Form(" Time Resolution (ps) %f  Pad Efficiency: %f ", fTimeResolution, fpadefficiency));
1466   AliInfo(Form(" Edge Effect option:  %d", fEdgeEffect));
1467
1468   AliInfo(" Boundary Effect Simulation Parameters ");
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));
1480   AliInfo(" Pulse Heigth Simulation Parameters ");
1481   AliInfo(Form(" Flag for delay due to the PulseHeightEffect  : %d", fTimeDelayFlag));
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));
1488   AliInfo(Form(" Flag for average time                        : %d", fAverageTimeFlag));
1489   AliInfo(Form(" Edge tails option                            : %d", fEdgeTails));
1490   
1491 }