LCOV - code coverage report
Current view: top level - TOF/TOFsim - AliTOFSDigitizer.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 350 923 37.9 %
Date: 2016-06-14 17:26:59 Functions: 8 19 42.1 %

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

Generated by: LCOV version 1.11