1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 //__________________________________________________________//
20 // This is a TTask that constructs SDigits out of Hits //
21 // A Summable Digits is the "sum" of all hits in a pad //
22 // Detector response has been simulated via the method //
23 // SimulateDetectorResponse //
25 // -- Authors: F. Pierella, A. De Caro //
26 // Use case: see AliTOFhits2sdigits.C macro in the CVS //
27 //__________________________________________________________//
29 #include <TBenchmark.h>
30 #include <TClonesArray.h>
33 #include <TParticle.h>
38 #include "AliLoader.h"
41 #include "AliRunLoader.h"
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"
56 ClassImp(AliTOFSDigitizer)
58 //____________________________________________________________________________
59 AliTOFSDigitizer::AliTOFSDigitizer():
60 TTask("TOFSDigitizer",""),
69 fTimeResolution(100.),
93 fLogChargeSmearing(0),
99 fCalib(new AliTOFcalib())
105 //------------------------------------------------------------------------
106 AliTOFSDigitizer::AliTOFSDigitizer(const AliTOFSDigitizer &source):
116 fTimeResolution(100.),
133 fTimeWalkBoundary(0),
136 fPulseHeightSlope(0),
140 fLogChargeSmearing(0),
142 fAverageTimeFlag(-1),
146 fCalib(new AliTOFcalib())
149 //this->fTOFGeometry=source.fTOFGeometry;
153 //____________________________________________________________________________
154 AliTOFSDigitizer& AliTOFSDigitizer::operator=(const AliTOFSDigitizer &/*source*/)
161 //____________________________________________________________________________
162 AliTOFSDigitizer::AliTOFSDigitizer(const char* HeaderFile, Int_t evNumber1, Int_t nEvents):
163 TTask("TOFSDigitizer",""),
167 fHeadersFile(HeaderFile), // input filename (with hits)
170 fSelectedSector(-1), // by default we sdigitize all sectors
171 fSelectedPlate(-1), // by default we sdigitize all plates in all sectors
172 fTimeResolution(100.),
189 fTimeWalkBoundary(0),
192 fPulseHeightSlope(0),
196 fLogChargeSmearing(0),
198 fAverageTimeFlag(-1),
202 fCalib(new AliTOFcalib())
204 //ctor, reading from input file
206 TFile * file = (TFile*) gROOT->GetFile(fHeadersFile.Data());
208 //File was not opened yet open file and get alirun object
210 file = TFile::Open(fHeadersFile.Data(),"update") ;
211 gAlice = (AliRun *) file->Get("gAlice") ;
214 // add Task to //root/Tasks folder
215 TString evfoldname = AliConfig::GetDefaultEventFolderName();
216 fRunLoader = AliRunLoader::GetRunLoader(evfoldname);
218 fRunLoader = AliRunLoader::Open(HeaderFile);//open session and mount on default event folder
219 if (fRunLoader == 0x0)
221 AliFatal("Event is not loaded. Exiting");
226 fRunLoader->CdGAFile();
227 TDirectory *savedir=gDirectory;
228 TFile *in=(TFile*)gFile;
231 // when fTOFGeometry was needed
233 AliWarning("Geometry file is not open default TOF geometry will be used");
234 fTOFGeometry = new AliTOFGeometry();
238 fTOFGeometry = (AliTOFGeometry*)in->Get("TOFgeometry");
243 if (fRunLoader->TreeE() == 0x0) fRunLoader->LoadHeader();
245 if (evNumber1>=0) fEvent1 = evNumber1;
248 if (nEvents==0) fEvent2 = (Int_t)(fRunLoader->GetNumberOfEvents());
249 else if (nEvents>0) fEvent2 = evNumber1+nEvents;
252 if (!(fEvent2>fEvent1)) {
253 AliError(Form("fEvent2 = %d <= fEvent1 = %d", fEvent2, fEvent1));
256 AliError(Form("Correction: fEvent2 = %d <= fEvent1 = %d", fEvent2, fEvent1));
259 // init parameters for sdigitization
262 fTOFLoader = fRunLoader->GetLoader("TOFLoader");
263 if (fTOFLoader == 0x0)
265 AliFatal("Can not find TOF loader in event. Exiting.");
268 fTOFLoader->PostSDigitizer(this);
272 //____________________________________________________________________________
273 AliTOFSDigitizer::~AliTOFSDigitizer()
276 fTOFLoader->CleanSDigitizer();
278 if (fCalib) delete fCalib;
282 //____________________________________________________________________________
283 void AliTOFSDigitizer::InitParameters()
285 // set parameters for detector simulation
289 //fTimeResolution = 80.; //120.; OLD
290 AliTOFRecoParam *recoParams = (AliTOFRecoParam*)fCalib->ReadRecParFromCDB("TOF/Calib",fRunLoader->GetRunNumber());
291 fTimeResolution = recoParams->GetTimeResolution(); // now from OCDB
292 if (fTimeResolution==0.) {
293 AliWarning("In OCDB found 0ps for TOF time resolution. It is set to 100ps.");
294 fTimeResolution = 100.;
296 AliDebug(1,Form(" TOF time resolution read from OCDB = %f ps",fTimeResolution));
297 fpadefficiency = 0.995 ;
298 //fEdgeEffect = 2 ; // edge effects according to test beam results
299 fEdgeEffect = 1 ; // edge effects according to test beam results
300 // but with fixed time resolution, i.e. fTimeResolution
306 fEffCenter = fpadefficiency;
307 fEffBoundary = 0.833;
308 fEff2Boundary = 0.94;
310 fAddTRes = 68. ; // \sqrt{2x20^2 + 15^2 + 2x10^2 + 30^2 + 50^2} (p-p)
311 //fAddTRes = 48. ; // \sqrt{2x20^2 + 15^2 + 2x10^2 + 30^2 + 15^2} (Pb-Pb)
312 // 30^2+20^2+40^2+50^2+50^2+50^2 = 10400 ps^2 (very old value)
313 fResCenter = 35. ; //50. ; // OLD
315 fResSlope = 37. ; //40. ; // OLD
316 fTimeWalkCenter = 0. ;
317 fTimeWalkBoundary=0. ;
318 fTimeWalkSlope = 0. ;
320 fPulseHeightSlope=2.0 ;
321 fTimeDelaySlope =0.060;
322 // was fMinimumCharge = TMath::Exp(fPulseHeightSlope*fKparameter/2.);
323 fMinimumCharge = TMath::Exp(-fPulseHeightSlope*fHparameter);
324 fChargeSmearing=0.0 ;
325 fLogChargeSmearing=0.13;
326 fTimeSmearing =0.022;
329 fAdcBin = 0.25; // 1 ADC bin = 0.25 pC (or 0.03 pC)
330 fAdcMean = 50.; // ADC distribution mpv value for Landau (in bins)
331 // it corresponds to a mean value of ~100 bins
332 fAdcRms = 25.; // ADC distribution rms value (in bins)
333 // it corresponds to distribution rms ~50 bins
336 //__________________________________________________________________
337 Double_t TimeWithTail(const Double_t * const x, const Double_t * const par)
339 // sigma - par[0], alpha - par[1], part - par[2]
340 // at x<part*sigma - gauss
341 // at x>part*sigma - TMath::Exp(-x/alpha)
344 if(xx<par[0]*par[2]) {
345 f = TMath::Exp(-xx*xx/(2*par[0]*par[0]));
347 f = TMath::Exp(-(xx-par[0]*par[2])/par[1]-0.5*par[2]*par[2]);
352 //____________________________________________________________________________
353 void AliTOFSDigitizer::Exec(Option_t *verboseOption) {
354 //execute TOF sdigitization
355 if (strstr(verboseOption,"tim") || strstr(verboseOption,"all"))
356 gBenchmark->Start("TOFSDigitizer");
358 if (fEdgeTails) ftail = new TF1("tail",TimeWithTail,-2,2,3);
360 Int_t nselectedHits=0;
361 Int_t ntotalsdigits=0;
362 Int_t ntotalupdates=0;
363 Int_t nnoisesdigits=0;
364 Int_t nsignalsdigits=0;
365 Int_t nHitsFromPrim=0;
366 Int_t nHitsFromSec=0;
367 Int_t nlargeTofDiff=0;
369 Bool_t thereIsNotASelection=(fSelectedSector==-1) && (fSelectedPlate==-1);
371 if (fRunLoader->GetAliRun() == 0x0) fRunLoader->LoadgAlice();
372 gAlice = fRunLoader->GetAliRun();
374 fRunLoader->LoadKinematics();
376 AliTOF *tof = (AliTOF *) gAlice->GetDetector("TOF");
379 AliError("TOF not found");
383 fTOFLoader->LoadHits("read");
384 fTOFLoader->LoadSDigits("recreate");
386 Int_t vol[5]={-1,-1,-1,-1,-1}; // location for a digit
387 Int_t digit[2]={0,0}; // TOF digit variables
389 Int_t nselectedHitsinEv=0;
390 Int_t ntotalsdigitsinEv=0;
391 Int_t ntotalupdatesinEv=0;
392 Int_t nnoisesdigitsinEv=0;
393 Int_t nsignalsdigitsinEv=0;
395 for (Int_t iEvent=fEvent1; iEvent<fEvent2; iEvent++) {
396 //AliInfo(Form("------------------- %s -------------", GetName()));
397 //AliInfo(Form("Sdigitizing event %i", iEvent));
399 fRunLoader->GetEvent(iEvent);
401 TTree *hitTree = fTOFLoader->TreeH();
402 if (!hitTree) return;
404 if (fTOFLoader->TreeS () == 0) fTOFLoader->MakeTree ("S");
406 //Make branch for digits
407 tof->MakeBranch("S");
409 // recreate TClonesArray fSDigits - for backward compatibility
410 if (tof->SDigits() == 0) {
411 tof->CreateSDigitsArray();
413 tof->RecreateSDigitsArray();
416 tof->SetTreeAddress();
418 Int_t version=tof->IsVersion();
424 nsignalsdigitsinEv=0;
428 TClonesArray *tofHitArray = tof->Hits();
431 //AliTOFHitMap *hitMap = new AliTOFHitMap(tof->SDigits(), fTOFGeometry);
432 AliTOFHitMap *hitMap = new AliTOFHitMap(tof->SDigits());
434 TBranch * tofHitsBranch = hitTree->GetBranch("TOF");
436 Int_t ntracks = static_cast<Int_t>(hitTree->GetEntries());
437 for (Int_t track = 0; track < ntracks; track++)
439 gAlice->GetMCApp()->ResetHits();
440 tofHitsBranch->GetEvent(track);
442 AliMC *mcApplication = (AliMC*)gAlice->GetMCApp();
444 particle = (TParticle*)mcApplication->Particle(track);
445 Int_t nhits = tofHitArray->GetEntriesFast();
446 // cleaning all hits of the same track in the same pad volume
447 // it is a rare event, however it happens
449 Int_t previousTrack =-1;
450 Int_t previousSector=-1;
451 Int_t previousPlate =-1;
452 Int_t previousStrip =-1;
453 Int_t previousPadX =-1;
454 Int_t previousPadZ =-1;
456 for (Int_t hit = 0; hit < nhits; hit++) {
457 for (Int_t aa=0; aa<5;aa++) vol[aa]=-1; // location for a digit
458 for (Int_t aa=0; aa<2;aa++) digit[aa]=0; // TOF digit variables
464 // fp: really sorry for this, it is a temporary trick to have
466 if (version<6) { //(version!=6 && version!=7)
467 AliTOFhit *tofHit = (AliTOFhit *) tofHitArray->UncheckedAt(hit);
468 tracknum = tofHit->GetTrack();
469 vol[0] = tofHit->GetSector();
470 vol[1] = tofHit->GetPlate();
471 vol[2] = tofHit->GetStrip();
472 vol[3] = tofHit->GetPadx();
473 vol[4] = tofHit->GetPadz();
474 dxPad = tofHit->GetDx();
475 dzPad = tofHit->GetDz();
476 geantTime = tofHit->GetTof(); // unit [s] // already corrected per event_time smearing
478 AliTOFhitT0 *tofHit = (AliTOFhitT0 *) tofHitArray->UncheckedAt(hit);
479 tracknum = tofHit->GetTrack();
480 vol[0] = tofHit->GetSector();
481 vol[1] = tofHit->GetPlate();
482 vol[2] = tofHit->GetStrip();
483 vol[3] = tofHit->GetPadx();
484 vol[4] = tofHit->GetPadz();
485 dxPad = tofHit->GetDx();
486 dzPad = tofHit->GetDz();
487 geantTime = tofHit->GetTof(); // unit [s] // already corrected per event_time_smearing
490 geantTime *= 1.e+09; // conversion from [s] to [ns]
491 // TOF matching window (~200ns) control
492 if (geantTime>=AliTOFGeometry::MatchingWindow()*1E-3) {
493 AliDebug(2,Form("Time measurement (%f) greater than the matching window (%f)",
494 geantTime, AliTOFGeometry::MatchingWindow()*1E-3));
498 // selection case for sdigitizing only hits in a given plate of a given sector
499 if(thereIsNotASelection || (vol[0]==fSelectedSector && vol[1]==fSelectedPlate)){
501 Bool_t dummy=((tracknum==previousTrack) && (vol[0]==previousSector) && (vol[1]==previousPlate) && (vol[2]==previousStrip));
503 Bool_t isCloneOfThePrevious=dummy && ((vol[3]==previousPadX) && (vol[4]==previousPadZ));
505 Bool_t isNeighOfThePrevious=dummy && ((((vol[3]==previousPadX-1) || (vol[3]==previousPadX+1)) && (vol[4]==previousPadZ)) || ((vol[3]==previousPadX) && ((vol[4]==previousPadZ+1) || (vol[4]==previousPadZ-1))));
507 if(!isCloneOfThePrevious && !isNeighOfThePrevious){
508 // update "previous" values
509 // in fact, we are yet in the future, so the present is past
510 previousTrack=tracknum;
511 previousSector=vol[0];
512 previousPlate=vol[1];
513 previousStrip=vol[2];
519 if (particle->GetFirstMother() < 0) nHitsFromPrim++; // counts hits due to primary particles
521 Float_t xStrip=AliTOFGeometry::XPad()*(vol[3]+0.5-0.5*AliTOFGeometry::NpadX())+dxPad;
522 Float_t zStrip=AliTOFGeometry::ZPad()*(vol[4]+0.5-0.5*AliTOFGeometry::NpadZ())+dzPad;
524 Int_t nActivatedPads = 0, nFiredPads = 0;
525 Bool_t isFired[4] = {kFALSE, kFALSE, kFALSE, kFALSE};
526 Float_t tofAfterSimul[4] = {0., 0., 0., 0.};
527 Float_t qInduced[4] = {0.,0.,0.,0.};
528 Int_t nPlace[4] = {0, 0, 0, 0};
529 Float_t averageTime = 0.;
530 SimulateDetectorResponse(zStrip,xStrip,geantTime,nActivatedPads,nFiredPads,isFired,nPlace,qInduced,tofAfterSimul,averageTime);
532 for(Int_t indexOfPad=0; indexOfPad<nActivatedPads; indexOfPad++) {
533 if(isFired[indexOfPad]){ // the pad has fired
535 Float_t timediff=geantTime-tofAfterSimul[indexOfPad];
537 // TOF matching window (~200ns) control
538 if (tofAfterSimul[indexOfPad]>=AliTOFGeometry::MatchingWindow()*1E-3) {
539 AliDebug(2,Form("Time measurement (%f) greater than the matching window (%f)",
540 tofAfterSimul[indexOfPad], AliTOFGeometry::MatchingWindow()*1E-3));
544 if(timediff>=0.2) nlargeTofDiff++; // greater than 200ps
546 digit[0] = (Int_t) ((tofAfterSimul[indexOfPad]*1.e+03)/AliTOFGeometry::TdcBinWidth()); // TDC bin number (each bin -> 24.4 ps)
548 Float_t landauFactor = gRandom->Landau(fAdcMean, fAdcRms);
549 digit[1] = (Int_t) (qInduced[indexOfPad] * landauFactor); // ADC bins (each bin -> 0.25 (or 0.03) pC)
551 // recalculate the volume only for neighbouring pads
553 (nPlace[indexOfPad]<=AliTOFGeometry::NpadX()) ? vol[4] = 0 : vol[4] = 1;
554 (nPlace[indexOfPad]<=AliTOFGeometry::NpadX()) ? vol[3] = nPlace[indexOfPad] - 1 : vol[3] = nPlace[indexOfPad] - AliTOFGeometry::NpadX() - 1;
556 // check if two sdigit are on the same pad;
557 // in that case we sum the two or more sdigits
558 if (hitMap->TestHit(vol) != kEmpty) {
559 AliTOFSDigit *sdig = static_cast<AliTOFSDigit*>(hitMap->GetHit(vol));
560 Int_t tdctime = (Int_t) digit[0];
561 Int_t adccharge = (Int_t) digit[1];
562 sdig->Update(AliTOFGeometry::TdcBinWidth(),tdctime,adccharge,tracknum);
567 tof->AddSDigit(tracknum, vol, digit);
574 nsignalsdigitsinEv++;
579 } // if (hitMap->TestHit(vol) != kEmpty)
580 } // if(isFired[indexOfPad])
581 } // end loop on nActivatedPads
582 } // if(nFiredPads) i.e. if some pads has fired
583 } // close if(!isCloneOfThePrevious)
584 } // close the selection on sector and plate
585 } // end loop on hits for the current track
586 } // end loop on ntracks
590 fTOFLoader->TreeS()->Reset();
591 fTOFLoader->TreeS()->Fill();
592 fTOFLoader->WriteSDigits("OVERWRITE");
594 if (tof->SDigits()) tof->ResetSDigits();
596 if (strstr(verboseOption,"all") || strstr(verboseOption,"partial")) {
597 AliDebug(2,"----------------------------------------");
598 AliDebug(2,Form("After sdigitizing %d hits in event %d", nselectedHitsinEv, iEvent));
599 //" (" << nHitsFromPrim << " from primaries and " << nHitsFromSec << " from secondaries) TOF hits, "
600 AliDebug(1,Form("%d sdigits have been created", ntotalsdigitsinEv));
601 AliDebug(2,Form("(%d due to signals and %d due to border effect)", nsignalsdigitsinEv, nnoisesdigitsinEv));
602 AliDebug(2,Form("%d total updates of the hit map have been performed in current event", ntotalupdatesinEv));
603 AliDebug(2,"----------------------------------------");
606 } //event loop on events
608 fTOFLoader->UnloadSDigits();
609 fTOFLoader->UnloadHits();
610 fRunLoader->UnloadKinematics();
611 //fRunLoader->UnloadgAlice();
619 nHitsFromSec=nselectedHits-nHitsFromPrim;
620 if (strstr(verboseOption,"all") || strstr(verboseOption,"partial")) {
621 AliDebug(2,"----------------------------------------");
622 AliDebug(2,Form("After sdigitizing %d hits in %d events ", nselectedHits, fEvent2-fEvent1));
623 //" (" << nHitsFromPrim << " from primaries and " << nHitsFromSec << " from secondaries) TOF hits, "
624 AliDebug(2,Form("%d sdigits have been created", ntotalsdigits));
625 AliDebug(2,Form("(%d due to signals and %d due to border effect)", nsignalsdigits, nnoisesdigits));
626 AliDebug(2,Form("%d total updates of the hit map have been performed", ntotalupdates));
627 AliDebug(2,Form("in %d cases the time of flight difference is greater than 200 ps", nlargeTofDiff));
628 AliDebug(2,"----------------------------------------");
632 if(strstr(verboseOption,"tim") || strstr(verboseOption,"all")){
633 gBenchmark->Stop("TOFSDigitizer");
634 AliInfo("AliTOFSDigitizer:");
635 AliInfo(Form(" took %f seconds in order to make sdigits "
636 "%f seconds per event", gBenchmark->GetCpuTime("TOFSDigitizer"), gBenchmark->GetCpuTime("TOFSDigitizer")/(fEvent2-fEvent1)));
637 AliInfo(" +++++++++++++++++++++++++++++++++++++++++++++++++++ ");
642 //__________________________________________________________________
643 void AliTOFSDigitizer::Print(Option_t* /*opt*/)const
645 AliInfo(Form(" ------------------- %s ------------- ", GetName()));
648 //__________________________________________________________________
649 void AliTOFSDigitizer::SelectSectorAndPlate(Int_t sector, Int_t plate)
651 //Select sector and plate
652 Bool_t isaWrongSelection=(sector < 0) || (sector >= AliTOFGeometry::NSectors()) || (plate < 0) || (plate >= AliTOFGeometry::NPlates());
653 if(isaWrongSelection){
654 AliError("You have selected an invalid value for sector or plate ");
655 AliError(Form("The correct range for sector is [0,%d]", AliTOFGeometry::NSectors()-1));
656 AliError(Form("The correct range for plate is [0,%d]", AliTOFGeometry::NPlates()-1));
657 AliError("By default we continue sdigitizing all hits in all plates of all sectors");
659 fSelectedSector=sector;
660 fSelectedPlate =plate;
661 AliInfo(Form("SDigitizing only hits in plate %d of the sector %d", fSelectedPlate, fSelectedSector));
665 //__________________________________________________________________
666 void AliTOFSDigitizer::SimulateDetectorResponse(Float_t z0, Float_t x0, Float_t geantTime, Int_t& nActivatedPads, Int_t& nFiredPads, Bool_t* isFired, Int_t* nPlace, Float_t* qInduced, Float_t* tofTime, Float_t& averageTime)
669 // Input: z0, x0 - hit position in the strip system (0,0 - center of the strip), cm
670 // geantTime - time generated by Geant, ns
671 // Output: nActivatedPads - the number of pads activated by the hit (1 || 2 || 4)
672 // nFiredPads - the number of pads fired (really activated) by the hit (nFiredPads <= nActivatedPads)
673 // qInduced[iPad]- charge induced on pad, arb. units
674 // this array is initialized at zero by the caller
675 // tofAfterSimul[iPad] - time calculated with edge effect algorithm, ns
676 // this array is initialized at zero by the caller
677 // averageTime - time given by pad hited by the Geant track taking into account the times (weighted) given by the pads fired for edge effect also.
678 // The weight is given by the qInduced[iPad]/qCenterPad
679 // this variable is initialized at zero by the caller
680 // nPlace[iPad] - the number of the pad place, iPad = 0, 1, 2, 3
681 // this variable is initialized at zero by the caller
683 // Description of used variables:
684 // eff[iPad] - efficiency of the pad
685 // res[iPad] - resolution of the pad, ns
686 // timeWalk[iPad] - time walk of the pad, ns
687 // timeDelay[iPad] - time delay for neighbouring pad to hited pad, ns
688 // PadId[iPad] - Pad Identifier
689 // E | F --> PadId[iPad] = 5 | 6
690 // A | B --> PadId[iPad] = 1 | 2
691 // C | D --> PadId[iPad] = 3 | 4
692 // nTail[iPad] - the tail number, = 1 for tailA, = 2 for tailB
693 // qCenterPad - charge extimated for each pad, arb. units
694 // weightsSum - sum of weights extimated for each pad fired, arb. units
696 const Float_t kSigmaForTail[2] = {AliTOFGeometry::SigmaForTail1(),AliTOFGeometry::SigmaForTail2()}; //for tail
697 Int_t iz = 0, ix = 0;
698 Float_t dX = 0., dZ = 0., x = 0., z = 0.;
699 Float_t h = fHparameter, h2 = fH2parameter, k = fKparameter, k2 = fK2parameter;
700 Float_t effX = 0., effZ = 0., resX = 0., resZ = 0., timeWalkX = 0., timeWalkZ = 0.;
701 Float_t logOfqInd = 0.;
702 Float_t weightsSum = 0.;
703 Int_t nTail[4] = {0,0,0,0};
704 Int_t padId[4] = {0,0,0,0};
705 Float_t eff[4] = {0.,0.,0.,0.};
706 Float_t res[4] = {0.,0.,0.,0.};
707 // Float_t qCenterPad = fMinimumCharge * fMinimumCharge;
708 Float_t qCenterPad = 1.;
709 Float_t timeWalk[4] = {0.,0.,0.,0.};
710 Float_t timeDelay[4] = {0.,0.,0.,0.};
715 (z0 <= 0) ? iz = 0 : iz = 1;
716 dZ = z0 + (0.5 * AliTOFGeometry::NpadZ() - iz - 0.5) * AliTOFGeometry::ZPad(); // hit position in the pad frame, (0,0) - center of the pad
717 z = 0.5 * AliTOFGeometry::ZPad() - TMath::Abs(dZ); // variable for eff., res. and timeWalk. functions
718 iz++; // z row: 1, ..., AliTOFGeometry::NpadZ = 2
719 ix = (Int_t)((x0 + 0.5 * AliTOFGeometry::NpadX() * AliTOFGeometry::XPad()) / AliTOFGeometry::XPad());
720 dX = x0 + (0.5 * AliTOFGeometry::NpadX() - ix - 0.5) * AliTOFGeometry::XPad(); // hit position in the pad frame, (0,0) - center of the pad
721 x = 0.5 * AliTOFGeometry::XPad() - TMath::Abs(dX); // variable for eff., res. and timeWalk. functions;
722 ix++; // x row: 1, ..., AliTOFGeometry::NpadX = 48
726 nPlace[nActivatedPads-1] = (iz - 1) * AliTOFGeometry::NpadX() + ix;
727 qInduced[nActivatedPads-1] = qCenterPad;
728 padId[nActivatedPads-1] = 1;
730 switch (fEdgeEffect) {
732 eff[nActivatedPads-1] = fEffCenter;
733 if (gRandom->Rndm() < eff[nActivatedPads-1]) {
735 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + fResCenter * fResCenter); // ns
736 isFired[nActivatedPads-1] = kTRUE;
737 tofTime[nActivatedPads-1] = gRandom->Gaus(geantTime + fTimeWalkCenter, res[0]);
738 averageTime = tofTime[nActivatedPads-1];
745 effZ = fEffBoundary + (fEff2Boundary - fEffBoundary) * z / h2;
747 effZ = fEff2Boundary + (fEffCenter - fEff2Boundary) * (z - h2) / (h - h2);
749 //resZ = fTimeResolution;
751 nTail[nActivatedPads-1] = 1;
754 //resZ = fTimeResolution;
760 effX = fEffBoundary + (fEff2Boundary - fEffBoundary) * x / h2;
762 effX = fEff2Boundary + (fEffCenter - fEff2Boundary) * (x - h2) / (h - h2);
764 //resX = fTimeResolution;
766 nTail[nActivatedPads-1] = 1;
769 //resX = fTimeResolution;
773 (effZ<effX) ? eff[nActivatedPads-1] = effZ : eff[nActivatedPads-1] = effX;
774 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
775 timeWalk[nActivatedPads-1] = 0.; // ns
780 effZ = fEffBoundary - (fEffBoundary - fEff3Boundary) * (z / k2);
782 effZ = fEff3Boundary * (k - z) / (k - k2);
784 //resZ = fTimeResolution;
788 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
790 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX();
791 eff[nActivatedPads-1] = effZ;
792 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
793 timeWalk[nActivatedPads-1] = 0.; // ns
794 nTail[nActivatedPads-1] = 2;
795 if (fTimeDelayFlag) {
796 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
797 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
798 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
800 timeDelay[nActivatedPads-1] = 0.;
802 padId[nActivatedPads-1] = 2;
807 ////// Pad C, D, E, F:
809 effX = fEffBoundary - (fEffBoundary - fEff3Boundary) * (x / k2);
811 effX = fEff3Boundary * (k - x) / (k - k2);
813 //resX = fTimeResolution;
818 if(ix > 1 && dX < 0) {
820 nPlace[nActivatedPads-1] = nPlace[0] - 1;
821 eff[nActivatedPads-1] = effX;
822 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
823 timeWalk[nActivatedPads-1] = 0.; // ns
824 nTail[nActivatedPads-1] = 2;
825 if (fTimeDelayFlag) {
826 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
827 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
828 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
830 timeDelay[nActivatedPads-1] = 0.;
832 padId[nActivatedPads-1] = 3;
836 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
838 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() - 1;
839 eff[nActivatedPads-1] = effX * effZ;
840 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
841 timeWalk[nActivatedPads-1] = 0.; // ns
843 nTail[nActivatedPads-1] = 2;
844 if (fTimeDelayFlag) {
845 if (TMath::Abs(x) < TMath::Abs(z)) {
846 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
847 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
849 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
850 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
852 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
854 timeDelay[nActivatedPads-1] = 0.;
856 padId[nActivatedPads-1] = 4;
862 if(ix < AliTOFGeometry::NpadX() && dX > 0) {
864 nPlace[nActivatedPads-1] = nPlace[0] + 1;
865 eff[nActivatedPads-1] = effX;
866 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
867 timeWalk[nActivatedPads-1] = 0.; // ns
868 nTail[nActivatedPads-1] = 2;
869 if (fTimeDelayFlag) {
870 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
871 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
872 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
874 timeDelay[nActivatedPads-1] = 0.;
876 padId[nActivatedPads-1] = 5;
881 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
883 nPlace[nActivatedPads - 1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() + 1;
884 eff[nActivatedPads - 1] = effX * effZ;
885 res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns
886 timeWalk[nActivatedPads-1] = 0.; // ns
887 nTail[nActivatedPads-1] = 2;
888 if (fTimeDelayFlag) {
889 if (TMath::Abs(x) < TMath::Abs(z)) {
890 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
891 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
893 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
894 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
896 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
898 timeDelay[nActivatedPads-1] = 0.;
900 padId[nActivatedPads-1] = 6;
907 for (Int_t iPad = 0; iPad < nActivatedPads; iPad++) {
908 if(gRandom->Rndm() < eff[iPad]) {
909 isFired[iPad] = kTRUE;
912 if(nTail[iPad] == 0) {
913 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
915 ftail->SetParameters(res[iPad], 2. * res[iPad], kSigmaForTail[nTail[iPad]-1]);
916 Double_t timeAB = ftail->GetRandom();
917 tofTime[iPad] = geantTime + timeWalk[iPad] + timeDelay[iPad] + timeAB;
920 //AliDebug(1,Form(" ----------------- TOF time resolution = %f",res[iPad]));
921 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
923 if (fAverageTimeFlag) {
924 averageTime += tofTime[iPad] * qInduced[iPad];
925 weightsSum += qInduced[iPad];
927 averageTime += tofTime[iPad];
931 AliDebug(1,Form(" Activated pad %d: geantTime=%f, tw=%fns, td=%fns, tofTime=%fns, sigma=%fps",iPad,geantTime,timeWalk[iPad],timeDelay[iPad],tofTime[iPad],1000.*res[iPad]));
936 if (weightsSum!=0) averageTime /= weightsSum;
943 effZ = fEffBoundary + (fEff2Boundary - fEffBoundary) * z / h2;
945 effZ = fEff2Boundary + (fEffCenter - fEff2Boundary) * (z - h2) / (h - h2);
947 resZ = fResBoundary + (fResCenter - fResBoundary) * z / h;
948 timeWalkZ = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * z / h;
949 nTail[nActivatedPads-1] = 1;
953 timeWalkZ = fTimeWalkCenter;
958 effX = fEffBoundary + (fEff2Boundary - fEffBoundary) * x / h2;
960 effX = fEff2Boundary + (fEffCenter - fEff2Boundary) * (x - h2) / (h - h2);
962 resX = fResBoundary + (fResCenter - fResBoundary) * x / h;
963 timeWalkX = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * x / h;
964 nTail[nActivatedPads-1] = 1;
968 timeWalkX = fTimeWalkCenter;
971 (effZ<effX) ? eff[nActivatedPads-1] = effZ : eff[nActivatedPads-1] = effX;
972 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
973 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
978 effZ = fEffBoundary - (fEffBoundary - fEff3Boundary) * (z / k2);
980 effZ = fEff3Boundary * (k - z) / (k - k2);
982 resZ = fResBoundary + fResSlope * z / k;
983 timeWalkZ = fTimeWalkBoundary + fTimeWalkSlope * z / k;
986 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
988 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX();
989 eff[nActivatedPads-1] = effZ;
990 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
991 timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ; // ns
992 nTail[nActivatedPads-1] = 2;
993 if (fTimeDelayFlag) {
994 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
995 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
996 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
998 timeDelay[nActivatedPads-1] = 0.;
1000 padId[nActivatedPads-1] = 2;
1005 ////// Pad C, D, E, F:
1007 effX = fEffBoundary - (fEffBoundary - fEff3Boundary) * (x / k2);
1009 effX = fEff3Boundary * (k - x) / (k - k2);
1011 resX = fResBoundary + fResSlope*x/k;
1012 timeWalkX = fTimeWalkBoundary + fTimeWalkSlope*x/k;
1014 if(x < k && x > 0) {
1016 if(ix > 1 && dX < 0) {
1018 nPlace[nActivatedPads-1] = nPlace[0] - 1;
1019 eff[nActivatedPads-1] = effX;
1020 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX); // ns
1021 timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1022 nTail[nActivatedPads-1] = 2;
1023 if (fTimeDelayFlag) {
1024 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1025 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1026 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1028 timeDelay[nActivatedPads-1] = 0.;
1030 padId[nActivatedPads-1] = 3;
1033 if(z < k && z > 0) {
1034 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
1036 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() - 1;
1037 eff[nActivatedPads-1] = effX * effZ;
1038 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
1039 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1041 nTail[nActivatedPads-1] = 2;
1042 if (fTimeDelayFlag) {
1043 if (TMath::Abs(x) < TMath::Abs(z)) {
1044 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
1045 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
1047 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1048 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1050 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1052 timeDelay[nActivatedPads-1] = 0.;
1054 padId[nActivatedPads-1] = 4;
1060 if(ix < AliTOFGeometry::NpadX() && dX > 0) {
1062 nPlace[nActivatedPads-1] = nPlace[0] + 1;
1063 eff[nActivatedPads-1] = effX;
1064 res[nActivatedPads-1] = 0.001 * (TMath::Sqrt(fAddTRes*fAddTRes + resX * resX)); // ns
1065 timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1066 nTail[nActivatedPads-1] = 2;
1067 if (fTimeDelayFlag) {
1068 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1069 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1070 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1072 timeDelay[nActivatedPads-1] = 0.;
1074 padId[nActivatedPads-1] = 5;
1078 if(z < k && z > 0) {
1079 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
1081 nPlace[nActivatedPads - 1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() + 1;
1082 eff[nActivatedPads - 1] = effX * effZ;
1083 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
1084 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001*timeWalkX; // ns
1085 nTail[nActivatedPads-1] = 2;
1086 if (fTimeDelayFlag) {
1087 if (TMath::Abs(x) < TMath::Abs(z)) {
1088 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
1089 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
1091 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1092 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1094 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1096 timeDelay[nActivatedPads-1] = 0.;
1098 padId[nActivatedPads-1] = 6;
1105 for (Int_t iPad = 0; iPad < nActivatedPads; iPad++) {
1106 if (res[iPad] < fTimeResolution) res[iPad] = fTimeResolution;
1107 if(gRandom->Rndm() < eff[iPad]) {
1108 isFired[iPad] = kTRUE;
1111 if(nTail[iPad] == 0) {
1112 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
1114 ftail->SetParameters(res[iPad], 2. * res[iPad], kSigmaForTail[nTail[iPad]-1]);
1115 Double_t timeAB = ftail->GetRandom();
1116 tofTime[iPad] = geantTime + timeWalk[iPad] + timeDelay[iPad] + timeAB;
1119 AliDebug(1,Form(" ----------------- TOF time resolution = %f",res[iPad]));
1120 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
1122 if (fAverageTimeFlag) {
1123 averageTime += tofTime[iPad] * qInduced[iPad];
1124 weightsSum += qInduced[iPad];
1126 averageTime += tofTime[iPad];
1131 if (weightsSum!=0) averageTime /= weightsSum;
1133 } // switch (fEdgeEffect)
1137 //__________________________________________________________________
1138 void AliTOFSDigitizer::SimulateDetectorResponseOLD(Float_t z0, Float_t x0, Float_t geantTime, Int_t& nActivatedPads, Int_t& nFiredPads, Bool_t* isFired, Int_t* nPlace, Float_t* qInduced, Float_t* tofTime, Float_t& averageTime)
1141 // Input: z0, x0 - hit position in the strip system (0,0 - center of the strip), cm
1142 // geantTime - time generated by Geant, ns
1143 // Output: nActivatedPads - the number of pads activated by the hit (1 || 2 || 4)
1144 // nFiredPads - the number of pads fired (really activated) by the hit (nFiredPads <= nActivatedPads)
1145 // qInduced[iPad]- charge induced on pad, arb. units
1146 // this array is initialized at zero by the caller
1147 // tofAfterSimul[iPad] - time calculated with edge effect algorithm, ns
1148 // this array is initialized at zero by the caller
1149 // averageTime - time given by pad hited by the Geant track taking into account the times (weighted) given by the pads fired for edge effect also.
1150 // The weight is given by the qInduced[iPad]/qCenterPad
1151 // this variable is initialized at zero by the caller
1152 // nPlace[iPad] - the number of the pad place, iPad = 0, 1, 2, 3
1153 // this variable is initialized at zero by the caller
1155 // Description of used variables:
1156 // eff[iPad] - efficiency of the pad
1157 // res[iPad] - resolution of the pad, ns
1158 // timeWalk[iPad] - time walk of the pad, ns
1159 // timeDelay[iPad] - time delay for neighbouring pad to hited pad, ns
1160 // PadId[iPad] - Pad Identifier
1161 // E | F --> PadId[iPad] = 5 | 6
1162 // A | B --> PadId[iPad] = 1 | 2
1163 // C | D --> PadId[iPad] = 3 | 4
1164 // nTail[iPad] - the tail number, = 1 for tailA, = 2 for tailB
1165 // qCenterPad - charge extimated for each pad, arb. units
1166 // weightsSum - sum of weights extimated for each pad fired, arb. units
1168 const Float_t kSigmaForTail[2] = {AliTOFGeometry::SigmaForTail1(),AliTOFGeometry::SigmaForTail2()}; //for tail
1169 Int_t iz = 0, ix = 0;
1170 Float_t dX = 0., dZ = 0., x = 0., z = 0.;
1171 Float_t h = fHparameter, h2 = fH2parameter, k = fKparameter, k2 = fK2parameter;
1172 Float_t effX = 0., effZ = 0., resX = 0., resZ = 0., timeWalkX = 0., timeWalkZ = 0.;
1173 Float_t logOfqInd = 0.;
1174 Float_t weightsSum = 0.;
1175 Int_t nTail[4] = {0,0,0,0};
1176 Int_t padId[4] = {0,0,0,0};
1177 Float_t eff[4] = {0.,0.,0.,0.};
1178 Float_t res[4] = {0.,0.,0.,0.};
1179 // Float_t qCenterPad = fMinimumCharge * fMinimumCharge;
1180 Float_t qCenterPad = 1.;
1181 Float_t timeWalk[4] = {0.,0.,0.,0.};
1182 Float_t timeDelay[4] = {0.,0.,0.,0.};
1187 (z0 <= 0) ? iz = 0 : iz = 1;
1188 dZ = z0 + (0.5 * AliTOFGeometry::NpadZ() - iz - 0.5) * AliTOFGeometry::ZPad(); // hit position in the pad frame, (0,0) - center of the pad
1189 z = 0.5 * AliTOFGeometry::ZPad() - TMath::Abs(dZ); // variable for eff., res. and timeWalk. functions
1190 iz++; // z row: 1, ..., AliTOFGeometry::NpadZ = 2
1191 ix = (Int_t)((x0 + 0.5 * AliTOFGeometry::NpadX() * AliTOFGeometry::XPad()) / AliTOFGeometry::XPad());
1192 dX = x0 + (0.5 * AliTOFGeometry::NpadX() - ix - 0.5) * AliTOFGeometry::XPad(); // hit position in the pad frame, (0,0) - center of the pad
1193 x = 0.5 * AliTOFGeometry::XPad() - TMath::Abs(dX); // variable for eff., res. and timeWalk. functions;
1194 ix++; // x row: 1, ..., AliTOFGeometry::NpadX = 48
1198 nPlace[nActivatedPads-1] = (iz - 1) * AliTOFGeometry::NpadX() + ix;
1199 qInduced[nActivatedPads-1] = qCenterPad;
1200 padId[nActivatedPads-1] = 1;
1202 if (fEdgeEffect == 0) {
1203 eff[nActivatedPads-1] = fEffCenter;
1204 if (gRandom->Rndm() < eff[nActivatedPads-1]) {
1206 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + fResCenter * fResCenter); // ns
1207 isFired[nActivatedPads-1] = kTRUE;
1208 tofTime[nActivatedPads-1] = gRandom->Gaus(geantTime + fTimeWalkCenter, res[0]);
1209 averageTime = tofTime[nActivatedPads-1];
1211 } else { // if (fEdgeEffet!=0)
1215 effZ = fEffBoundary + (fEff2Boundary - fEffBoundary) * z / h2;
1217 effZ = fEff2Boundary + (fEffCenter - fEff2Boundary) * (z - h2) / (h - h2);
1220 resZ = fTimeResolution;
1221 else if (fEdgeEffect==2)
1222 resZ = fResBoundary + (fResCenter - fResBoundary) * z / h;
1223 timeWalkZ = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * z / h;
1224 nTail[nActivatedPads-1] = 1;
1228 resZ = fTimeResolution;
1229 else if (fEdgeEffect==2)
1231 timeWalkZ = fTimeWalkCenter;
1236 effX = fEffBoundary + (fEff2Boundary - fEffBoundary) * x / h2;
1238 effX = fEff2Boundary + (fEffCenter - fEff2Boundary) * (x - h2) / (h - h2);
1241 resX = fTimeResolution;
1242 else if (fEdgeEffect==2)
1243 resX = fResBoundary + (fResCenter - fResBoundary) * x / h;
1244 timeWalkX = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * x / h;
1245 nTail[nActivatedPads-1] = 1;
1249 resX = fTimeResolution;
1250 else if (fEdgeEffect==2)
1252 timeWalkX = fTimeWalkCenter;
1255 (effZ<effX) ? eff[nActivatedPads-1] = effZ : eff[nActivatedPads-1] = effX;
1257 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * resX : res[nActivatedPads-1] = 0.001 * resZ; // ns
1259 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
1260 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1265 effZ = fEffBoundary - (fEffBoundary - fEff3Boundary) * (z / k2);
1267 effZ = fEff3Boundary * (k - z) / (k - k2);
1270 resZ = fTimeResolution;
1271 else if (fEdgeEffect==2)
1272 resZ = fResBoundary + fResSlope * z / k;
1273 timeWalkZ = fTimeWalkBoundary + fTimeWalkSlope * z / k;
1275 if(z < k && z > 0) {
1276 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
1278 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX();
1279 eff[nActivatedPads-1] = effZ;
1281 res[nActivatedPads-1] = 0.001 * resZ; // ns
1283 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
1284 timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ; // ns
1285 nTail[nActivatedPads-1] = 2;
1286 if (fTimeDelayFlag) {
1287 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * z / 2.);
1288 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * z / 2.);
1289 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
1290 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
1291 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1293 timeDelay[nActivatedPads-1] = 0.;
1295 padId[nActivatedPads-1] = 2;
1300 ////// Pad C, D, E, F:
1302 effX = fEffBoundary - (fEffBoundary - fEff3Boundary) * (x / k2);
1304 effX = fEff3Boundary * (k - x) / (k - k2);
1307 resX = fTimeResolution;
1308 else if (fEdgeEffect==2)
1309 resX = fResBoundary + fResSlope*x/k;
1310 timeWalkX = fTimeWalkBoundary + fTimeWalkSlope*x/k;
1312 if(x < k && x > 0) {
1314 if(ix > 1 && dX < 0) {
1316 nPlace[nActivatedPads-1] = nPlace[0] - 1;
1317 eff[nActivatedPads-1] = effX;
1319 res[nActivatedPads-1] = 0.001 * resX; // ns
1320 else if (fEdgeEffect==2)
1321 res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX); // ns
1322 timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1323 nTail[nActivatedPads-1] = 2;
1324 if (fTimeDelayFlag) {
1325 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * x / 2.);
1326 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * x / 2.);
1327 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1328 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1329 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1331 timeDelay[nActivatedPads-1] = 0.;
1333 padId[nActivatedPads-1] = 3;
1336 if(z < k && z > 0) {
1337 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
1339 nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() - 1;
1340 eff[nActivatedPads-1] = effX * effZ;
1342 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * resX : res[nActivatedPads-1] = 0.001 * resZ; // ns
1343 else if (fEdgeEffect==2)
1344 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
1345 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1347 nTail[nActivatedPads-1] = 2;
1348 if (fTimeDelayFlag) {
1349 if (TMath::Abs(x) < TMath::Abs(z)) {
1350 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * z / 2.);
1351 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * z / 2.);
1352 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
1353 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
1355 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * x / 2.);
1356 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * x / 2.);
1357 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1358 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1360 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1362 timeDelay[nActivatedPads-1] = 0.;
1364 padId[nActivatedPads-1] = 4;
1370 if(ix < AliTOFGeometry::NpadX() && dX > 0) {
1372 nPlace[nActivatedPads-1] = nPlace[0] + 1;
1373 eff[nActivatedPads-1] = effX;
1375 res[nActivatedPads-1] = 0.001 * resX; // ns
1376 else if (fEdgeEffect==2)
1377 res[nActivatedPads-1] = 0.001 * (TMath::Sqrt(fAddTRes*fAddTRes + resX * resX)); // ns
1378 timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns
1379 nTail[nActivatedPads-1] = 2;
1380 if (fTimeDelayFlag) {
1381 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * x / 2.);
1382 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * x / 2.);
1383 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1384 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1385 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1387 timeDelay[nActivatedPads-1] = 0.;
1389 padId[nActivatedPads-1] = 5;
1393 if(z < k && z > 0) {
1394 if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) {
1396 nPlace[nActivatedPads - 1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() + 1;
1397 eff[nActivatedPads - 1] = effX * effZ;
1399 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * resX : res[nActivatedPads-1] = 0.001 * resZ; // ns
1400 else if (fEdgeEffect==2)
1401 (resZ<resX) ? res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX) : res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns
1402 (timeWalkZ<timeWalkX) ? timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ : timeWalk[nActivatedPads-1] = 0.001*timeWalkX; // ns
1403 nTail[nActivatedPads-1] = 2;
1404 if (fTimeDelayFlag) {
1405 if (TMath::Abs(x) < TMath::Abs(z)) {
1406 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * z / 2.);
1407 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * z / 2.);
1408 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z);
1409 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing);
1411 // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * x / 2.);
1412 // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * x / 2.);
1413 qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x);
1414 logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing);
1416 timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing);
1418 timeDelay[nActivatedPads-1] = 0.;
1420 padId[nActivatedPads-1] = 6;
1427 for (Int_t iPad = 0; iPad < nActivatedPads; iPad++) {
1428 if (fEdgeEffect==2 && res[iPad] < fTimeResolution) res[iPad] = fTimeResolution;
1429 if(gRandom->Rndm() < eff[iPad]) {
1430 isFired[iPad] = kTRUE;
1433 if(nTail[iPad] == 0) {
1434 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
1436 ftail->SetParameters(res[iPad], 2. * res[iPad], kSigmaForTail[nTail[iPad]-1]);
1437 Double_t timeAB = ftail->GetRandom();
1438 tofTime[iPad] = geantTime + timeWalk[iPad] + timeDelay[iPad] + timeAB;
1441 AliDebug(1,Form(" ----------------- TOF time resolution = %f",res[iPad]));
1442 tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]);
1444 if (fAverageTimeFlag) {
1445 averageTime += tofTime[iPad] * qInduced[iPad];
1446 weightsSum += qInduced[iPad];
1448 averageTime += tofTime[iPad];
1453 if (weightsSum!=0) averageTime /= weightsSum;
1454 } // end else (fEdgeEffect != 0)
1457 //__________________________________________________________________
1458 void AliTOFSDigitizer::PrintParameters()const
1461 // Print parameters used for sdigitization
1463 AliInfo(Form(" ------------------- %s -------------", GetName()));
1464 AliInfo(" Parameters used for TOF SDigitization ");
1465 // Printing the parameters
1467 AliInfo(Form(" Number of events: %i ", (fEvent2-fEvent1)));
1468 AliInfo(Form(" from event %i to event %i", fEvent1, (fEvent2-1)));
1469 AliInfo(Form(" Time Resolution (ps) %f Pad Efficiency: %f ", fTimeResolution, fpadefficiency));
1470 AliInfo(Form(" Edge Effect option: %d", fEdgeEffect));
1472 AliInfo(" Boundary Effect Simulation Parameters ");
1473 AliInfo(Form(" Hparameter: %f H2parameter: %f Kparameter: %f K2parameter: %f", fHparameter, fH2parameter, fKparameter, fK2parameter));
1474 AliInfo(Form(" Efficiency in the central region of the pad: %f", fEffCenter));
1475 AliInfo(Form(" Efficiency at the boundary region of the pad: %f", fEffBoundary));
1476 AliInfo(Form(" Efficiency value at H2parameter %f", fEff2Boundary));
1477 AliInfo(Form(" Efficiency value at K2parameter %f", fEff3Boundary));
1478 AliInfo(Form(" Resolution (ps) in the central region of the pad: %f", fResCenter));
1479 AliInfo(Form(" Resolution (ps) at the boundary of the pad : %f", fResBoundary));
1480 AliInfo(Form(" Slope (ps/K) for neighbouring pad : %f", fResSlope));
1481 AliInfo(Form(" Time walk (ps) in the central region of the pad : %f", fTimeWalkCenter));
1482 AliInfo(Form(" Time walk (ps) at the boundary of the pad : %f", fTimeWalkBoundary));
1483 AliInfo(Form(" Slope (ps/K) for neighbouring pad : %f", fTimeWalkSlope));
1484 AliInfo(" Pulse Heigth Simulation Parameters ");
1485 AliInfo(Form(" Flag for delay due to the PulseHeightEffect : %d", fTimeDelayFlag));
1486 AliInfo(Form(" Pulse Height Slope : %f", fPulseHeightSlope));
1487 AliInfo(Form(" Time Delay Slope : %f", fTimeDelaySlope));
1488 AliInfo(Form(" Minimum charge amount which could be induced : %f", fMinimumCharge));
1489 AliInfo(Form(" Smearing in charge in (q1/q2) vs x plot : %f", fChargeSmearing));
1490 AliInfo(Form(" Smearing in log of charge ratio : %f", fLogChargeSmearing));
1491 AliInfo(Form(" Smearing in time in time vs log(q1/q2) plot : %f", fTimeSmearing));
1492 AliInfo(Form(" Flag for average time : %d", fAverageTimeFlag));
1493 AliInfo(Form(" Edge tails option : %d", fEdgeTails));