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 : }
|