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