]>
Commit | Line | Data |
---|---|---|
451f5018 | 1 | /* |
2 | questions to experts: why RemoveDeadPixels should be called before FrompListToDigits ? | |
3 | ||
4 | ||
5 | */ | |
6 | ||
7 | /************************************************************************** | |
8 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
9 | * * | |
10 | * Author: The ALICE Off-line Project. * | |
11 | * Contributors are mentioned in the code where appropriate. * | |
12 | * * | |
13 | * Permission to use, copy, modify and distribute this software and its * | |
14 | * documentation strictly for non-commercial purposes is hereby granted * | |
15 | * without fee, provided that the above copyright notice appears in all * | |
16 | * copies and that both the copyright notice and this permission notice * | |
17 | * appear in the supporting documentation. The authors make no claims * | |
18 | * about the suitability of this software for any purpose. It is * | |
19 | * provided "as is" without express or implied warranty. * | |
20 | **************************************************************************/ | |
21 | ||
451f5018 | 22 | #include <TGeoGlobalMagField.h> |
23 | #include <TH1.h> | |
29ad4146 | 24 | #include <TH2.h> |
451f5018 | 25 | #include <TString.h> |
26 | #include "AliITSU.h" | |
27 | #include "AliITSUDigitPix.h" | |
28 | #include "AliITSUHit.h" | |
29 | #include "AliITSUModule.h" | |
30 | #include "AliITSUSensMap.h" | |
31 | #include "AliITSUCalibrationPix.h" | |
32 | #include "AliITSUSegmentationPix.h" | |
33 | #include "AliITSUSimulationPix.h" | |
34 | #include "AliLog.h" | |
35 | #include "AliRun.h" | |
36 | #include "AliMagF.h" | |
37 | #include "AliMathBase.h" | |
38 | #include "AliITSUSimuParam.h" | |
39 | #include "AliITSUSDigit.h" | |
29ad4146 | 40 | #include "AliITSUParamList.h" |
451f5018 | 41 | |
e61afb80 | 42 | using std::cout; |
43 | using std::endl; | |
a11ef2e4 | 44 | using namespace TMath; |
e61afb80 | 45 | |
451f5018 | 46 | ClassImp(AliITSUSimulationPix) |
47 | //////////////////////////////////////////////////////////////////////// | |
48 | // Version: 1 | |
49 | // Modified by D. Elia, G.E. Bruno, H. Tydesjo | |
50 | // Fast diffusion code by Bjorn S. Nilsen | |
51 | // March-April 2006 | |
52 | // October 2007: GetCalibrationObjects() removed | |
53 | // | |
54 | // Version: 0 | |
55 | // Written by Boris Batyunya | |
56 | // December 20 1999 | |
57 | // | |
58 | // Adapted for pixels of ITS upgrade July 2012, ruben.shahoyan@cern.ch | |
59 | // | |
60 | // AliITSUSimulationPix is to do the simulation of pixels | |
61 | // | |
29ad4146 | 62 | // 2013 Feb: Added MonoPix response and nois calculation al la MIMOSA32 (levente.molnar@cern.ch) |
63 | // | |
451f5018 | 64 | //////////////////////////////////////////////////////////////////////// |
65 | ||
66 | //______________________________________________________________________ | |
67 | AliITSUSimulationPix::AliITSUSimulationPix() | |
68 | : fTanLorAng(0) | |
0ebc85cf | 69 | ,fReadOutCycleLength(25e-6) |
70 | ,fReadOutCycleOffset(0) | |
29ad4146 | 71 | ,fGlobalChargeScale(1.0) |
72 | ,fSpread2DHisto(0) | |
c92b1537 | 73 | ,fSpreadFun(0) |
0ebc85cf | 74 | ,fROTimeFun(0) |
451f5018 | 75 | { |
76 | // Default constructor. | |
c92b1537 | 77 | SetUniqueID(AliITSUGeomTGeo::kDetTypePix); |
451f5018 | 78 | } |
79 | ||
80 | //______________________________________________________________________ | |
81 | AliITSUSimulationPix::AliITSUSimulationPix(AliITSUSimuParam* sim,AliITSUSensMap* map) | |
82 | :AliITSUSimulation(sim,map) | |
83 | ,fTanLorAng(0) | |
0ebc85cf | 84 | ,fReadOutCycleLength(25e-6) |
85 | ,fReadOutCycleOffset(0) | |
29ad4146 | 86 | ,fGlobalChargeScale(1.0) |
87 | ,fSpread2DHisto(0) | |
c92b1537 | 88 | ,fSpreadFun(0) |
0ebc85cf | 89 | ,fROTimeFun(0) |
451f5018 | 90 | { |
91 | // standard constructor | |
c92b1537 | 92 | SetUniqueID(AliITSUGeomTGeo::kDetTypePix); |
451f5018 | 93 | Init(); |
94 | } | |
95 | ||
96 | //______________________________________________________________________ | |
97 | AliITSUSimulationPix::AliITSUSimulationPix(const AliITSUSimulationPix &s) | |
98 | :AliITSUSimulation(s) | |
99 | ,fTanLorAng(s.fTanLorAng) | |
0ebc85cf | 100 | ,fReadOutCycleLength(s.fReadOutCycleLength) |
101 | ,fReadOutCycleOffset(s.fReadOutCycleOffset) | |
29ad4146 | 102 | ,fGlobalChargeScale(s.fGlobalChargeScale) |
103 | ,fSpread2DHisto(s.fSpread2DHisto) | |
c92b1537 | 104 | ,fSpreadFun(s.fSpreadFun) |
0ebc85cf | 105 | ,fROTimeFun(s.fROTimeFun) |
451f5018 | 106 | { |
107 | // Copy Constructor | |
108 | } | |
109 | ||
110 | ||
111 | //______________________________________________________________________ | |
112 | AliITSUSimulationPix::~AliITSUSimulationPix() | |
113 | { | |
114 | // destructor | |
115 | // only the sens map is owned and it is deleted by ~AliITSUSimulation | |
116 | } | |
117 | ||
118 | //______________________________________________________________________ | |
119 | AliITSUSimulationPix& AliITSUSimulationPix::operator=(const AliITSUSimulationPix &s) | |
120 | { | |
121 | // Assignment operator | |
122 | if (&s == this) return *this; | |
123 | AliITSUSimulation::operator=(s); | |
0ebc85cf | 124 | fReadOutCycleLength = s.fReadOutCycleLength; |
125 | fReadOutCycleOffset = s.fReadOutCycleOffset; | |
29ad4146 | 126 | fSpread2DHisto = s.fSpread2DHisto; |
127 | fGlobalChargeScale = s.fGlobalChargeScale; | |
c92b1537 | 128 | fSpreadFun = s.fSpreadFun; |
0ebc85cf | 129 | fROTimeFun = s.fROTimeFun; |
c92b1537 | 130 | // |
451f5018 | 131 | return *this; |
132 | } | |
133 | ||
134 | //______________________________________________________________________ | |
135 | void AliITSUSimulationPix::Init() | |
136 | { | |
137 | // Initilization | |
4fa9d550 | 138 | if (fSimuParam->GetPixLorentzDrift()) SetTanLorAngle(fSimuParam->GetPixLorentzHoleWeight()); |
451f5018 | 139 | } |
140 | ||
141 | //______________________________________________________________________ | |
142 | Bool_t AliITSUSimulationPix::SetTanLorAngle(Double_t weightHole) | |
143 | { | |
144 | // This function set the Tangent of the Lorentz angle. | |
145 | // A weighted average is used for electrons and holes | |
146 | // Input: Double_t weightHole: wheight for hole: it should be in the range [0,1] | |
147 | // output: Bool_t : kTRUE in case of success | |
148 | // | |
149 | if (weightHole<0) { | |
150 | weightHole=0.; | |
151 | AliWarning("You have asked for negative Hole weight"); | |
152 | AliWarning("I'm going to use only electrons"); | |
153 | } | |
154 | if (weightHole>1) { | |
155 | weightHole=1.; | |
156 | AliWarning("You have asked for weight > 1"); | |
157 | AliWarning("I'm going to use only holes"); | |
158 | } | |
159 | Double_t weightEle=1.-weightHole; | |
160 | AliMagF* fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField(); | |
161 | if (!fld) AliFatal("The field is not initialized"); | |
162 | Double_t bz = fld->SolenoidField(); | |
a11ef2e4 | 163 | fTanLorAng = Tan(weightHole*fSimuParam->LorentzAngleHole(bz) + |
451f5018 | 164 | weightEle*fSimuParam->LorentzAngleElectron(bz)); |
165 | return kTRUE; | |
166 | } | |
167 | ||
168 | //_____________________________________________________________________ | |
c92b1537 | 169 | void AliITSUSimulationPix::SDigitiseModule() |
451f5018 | 170 | { |
171 | // This function begins the work of creating S-Digits. | |
29ad4146 | 172 | |
173 | AliDebug(10,Form("In event %d module %d there are %d hits returning.", fEvent, fModule->GetIndex(),fModule->GetNHits())); | |
174 | ||
61ac1a02 | 175 | if (fModule->GetNHits()) Hits2SDigitsFast(); |
c92b1537 | 176 | // |
4fa9d550 | 177 | if (fSimuParam->GetPixAddNoisyFlag()) AddNoisyPixels(); |
61ac1a02 | 178 | if (fSimuParam->GetPixRemoveDeadFlag()) RemoveDeadPixels(); |
179 | if (!fSensMap->GetEntries()) return; | |
451f5018 | 180 | WriteSDigits(); |
181 | ClearMap(); | |
61ac1a02 | 182 | // |
451f5018 | 183 | } |
184 | ||
185 | //______________________________________________________________________ | |
186 | void AliITSUSimulationPix::WriteSDigits() | |
187 | { | |
188 | // This function adds each S-Digit to pList | |
189 | static AliITSU *aliITS = (AliITSU*)gAlice->GetModule("ITS"); | |
190 | int nsd = fSensMap->GetEntries(); | |
191 | for (int i=0;i<nsd;i++) { | |
192 | AliITSUSDigit* sd = (AliITSUSDigit*)fSensMap->At(i); // ordered in index | |
193 | if (!sd->GetSumSignal()>0 || fSensMap->IsDisabled(sd)) continue; | |
194 | aliITS->AddSumDigit(*sd); | |
195 | } | |
196 | return; | |
197 | } | |
198 | ||
199 | //______________________________________________________________________ | |
200 | void AliITSUSimulationPix::FinishSDigitiseModule() | |
201 | { | |
202 | // This function calls SDigitsToDigits which creates Digits from SDigits | |
203 | FrompListToDigits(); | |
204 | ClearMap(); | |
205 | return; | |
206 | } | |
207 | ||
208 | //______________________________________________________________________ | |
c92b1537 | 209 | void AliITSUSimulationPix::DigitiseModule() |
451f5018 | 210 | { |
211 | // This function creates Digits straight from the hits and then adds | |
212 | // electronic noise to the digits before adding them to pList | |
213 | // Each of the input variables is passed along to Hits2SDigits | |
214 | // | |
c92b1537 | 215 | // pick charge spread function |
216 | Hits2SDigitsFast(); | |
451f5018 | 217 | // |
4fa9d550 | 218 | if (fSimuParam->GetPixAddNoisyFlag()) AddNoisyPixels(); |
219 | if (fSimuParam->GetPixRemoveDeadFlag()) RemoveDeadPixels(); | |
451f5018 | 220 | FrompListToDigits(); |
221 | ClearMap(); | |
222 | } | |
223 | ||
224 | //______________________________________________________________________ | |
c92b1537 | 225 | void AliITSUSimulationPix::Hits2SDigits() |
451f5018 | 226 | { |
227 | // Does the charge distributions using Gaussian diffusion charge charing. | |
c92b1537 | 228 | Int_t nhits = fModule->GetNHits(); |
451f5018 | 229 | if (!nhits) return; |
230 | // | |
231 | Int_t h,ix,iz,i; | |
232 | Int_t idtrack; | |
4fa9d550 | 233 | Float_t x,y,z; // keep coordinates float (required by AliSegmentation) |
0ebc85cf | 234 | Double_t tof,x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0,de=0.0; |
c92b1537 | 235 | Double_t t,tp,st,dt=0.2,el; |
29f5e263 | 236 | Double_t thick = 0.5*fSeg->Dy(); // Half Thickness |
c92b1537 | 237 | |
451f5018 | 238 | // |
239 | for (h=0;h<nhits;h++) { | |
451f5018 | 240 | // |
0ebc85cf | 241 | if (!fModule->LineSegmentL(h,x0,x1,y0,y1,z0,z1,de,tof,idtrack)) continue; |
a11ef2e4 | 242 | st = Sqrt(x1*x1+y1*y1+z1*z1); |
451f5018 | 243 | if (st>0.0) { |
29f5e263 | 244 | st = (Double_t)((Int_t)(st*1e4)); // number of microns |
451f5018 | 245 | if (st<=1.0) st = 1.0; |
29f5e263 | 246 | dt = 1.0/st; // RS TODO: do we need 1 micron steps? |
c92b1537 | 247 | double dy = dt*thick; |
248 | y = -0.5*dy; | |
451f5018 | 249 | for (t=0.0;t<1.0;t+=dt) { // Integrate over t |
250 | tp = t+0.5*dt; | |
251 | x = x0+x1*tp; | |
c92b1537 | 252 | y += dy; |
451f5018 | 253 | z = z0+z1*tp; |
254 | if (!(fSeg->LocalToDet(x,z,ix,iz))) continue; // outside | |
255 | el = dt * de / fSimuParam->GetGeVToCharge(); | |
256 | // | |
c92b1537 | 257 | if (fSimuParam->GetPixLorentzDrift()) x += y*fTanLorAng; |
0ebc85cf | 258 | // Check if the hit is inside readout window |
259 | if ( !(((AliITSUSimulationPix*)this)->*AliITSUSimulationPix::fROTimeFun)(ix,iz,tof) ) continue; | |
c92b1537 | 260 | SpreadCharge2D(x,z,y,ix,iz,el,idtrack,h); |
451f5018 | 261 | } // end for t |
262 | } else { // st == 0.0 deposit it at this point | |
263 | x = x0; | |
c92b1537 | 264 | y = y0 + 0.5*thick; |
451f5018 | 265 | z = z0; |
266 | if (!(fSeg->LocalToDet(x,z,ix,iz))) continue; // outside | |
267 | el = de / fSimuParam->GetGeVToCharge(); | |
c92b1537 | 268 | if (fSimuParam->GetPixLorentzDrift()) x += y*fTanLorAng; |
0ebc85cf | 269 | // Check if the hit is inside readout window |
270 | if ( !(((AliITSUSimulationPix*)this)->*AliITSUSimulationPix::fROTimeFun)(ix,iz,tof) ) continue; | |
c92b1537 | 271 | SpreadCharge2D(x,z,y,ix,iz,el,idtrack,h); |
451f5018 | 272 | } // end if st>0.0 |
273 | } // Loop over all hits h | |
274 | // | |
275 | // Coupling | |
276 | int nd = fSensMap->GetEntriesUnsorted(); // use unsorted access when possible, since it is faster | |
277 | AliITSUSDigit* dg = 0; | |
4fa9d550 | 278 | switch (fSimuParam->GetPixCouplingOption()) { |
279 | case AliITSUSimuParam::kNewCouplingPix : | |
451f5018 | 280 | for (i=nd;i--;) { |
281 | dg = (AliITSUSDigit*)fSensMap->AtUnsorted(i); | |
282 | if (fSensMap->IsDisabled(dg)) continue; | |
283 | SetCoupling(dg,idtrack,h); | |
284 | } | |
285 | break; | |
4fa9d550 | 286 | case AliITSUSimuParam::kOldCouplingPix: |
451f5018 | 287 | for (i=nd;i--;) { |
288 | dg = (AliITSUSDigit*)fSensMap->AtUnsorted(i); | |
289 | if (fSensMap->IsDisabled(dg)) continue; | |
290 | SetCouplingOld(dg,idtrack,h); | |
291 | } | |
292 | break; | |
293 | default: | |
294 | break; | |
295 | ||
296 | } // end switch | |
4fa9d550 | 297 | if (GetDebug(2)) AliInfo(Form("Finished fCoupling=%d",fSimuParam->GetPixCouplingOption())); |
451f5018 | 298 | } |
299 | ||
300 | //______________________________________________________________________ | |
c92b1537 | 301 | void AliITSUSimulationPix::Hits2SDigitsFast() |
451f5018 | 302 | { |
303 | // Does the charge distributions using Gaussian diffusion charge charing. // Inputs: | |
304 | // AliITSUModule *mod Pointer to this module | |
c92b1537 | 305 | // |
c92b1537 | 306 | TObjArray *hits = fModule->GetHits(); |
451f5018 | 307 | Int_t nhits = hits->GetEntriesFast(); |
308 | if (nhits<=0) return; | |
309 | // | |
310 | Int_t h,ix,iz,i; | |
311 | Int_t idtrack; | |
4fa9d550 | 312 | Float_t x,y,z; // keep coordinates float (required by AliSegmentation) |
0ebc85cf | 313 | Double_t tof,x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0; |
e0dbadec | 314 | Double_t step,st,el,de=0.0; |
81f2107f | 315 | Double_t minDim = Min(fSeg->Dpx(1),fSeg->Dpz(1)); // RStmp: smallest pitch |
c92b1537 | 316 | Double_t thick = fSeg->Dy(); |
451f5018 | 317 | // |
318 | for (h=0;h<nhits;h++) { | |
451f5018 | 319 | // |
0ebc85cf | 320 | if (!fModule->LineSegmentL(h,x0,x1,y0,y1,z0,z1,de,tof,idtrack)) continue; |
321 | // | |
81f2107f | 322 | st = Sqrt(x1*x1+y1*y1+z1*z1); |
323 | if (st>0.0) { | |
0ebc85cf | 324 | int np = int(1.5*st/minDim); //RStmp: inject the points in such a way that there is ~1.5 point per cell |
29ad4146 | 325 | np = TMath::Max(1.0*np,fResponseParam->GetParameter(kSpreadFunMinSteps)); |
326 | AliDebug(10,Form(" Number of charge injection steps is set to %d ",np)); | |
0ebc85cf | 327 | double dstep = 1./np; |
e0dbadec | 328 | double dy = dstep*thick; |
c92b1537 | 329 | y = -0.5*dy; |
0ebc85cf | 330 | step = -0.5*dstep; |
81f2107f | 331 | for (i=0;i<np;i++) { //RStmp Integrate over t |
332 | // for (i=0;i<kn10;i++) { // Integrate over t | |
0ebc85cf | 333 | step += dstep; // RStmp kti[i]; |
334 | x = x0+x1*step; | |
c92b1537 | 335 | y += dy; |
0ebc85cf | 336 | z = z0+z1*step; |
451f5018 | 337 | if (!(fSeg->LocalToDet(x,z,ix,iz))) continue; // outside |
29ad4146 | 338 | el = fGlobalChargeScale * dstep * de/fSimuParam->GetGeVToCharge(); |
c92b1537 | 339 | if (fSimuParam->GetPixLorentzDrift()) x += y*fTanLorAng; |
0ebc85cf | 340 | // Check if the hit is inside readout window |
341 | if ( !(((AliITSUSimulationPix*)this)->*AliITSUSimulationPix::fROTimeFun)(ix,iz,tof) ) continue; | |
c92b1537 | 342 | SpreadCharge2D(x,z,y,ix,iz,el,idtrack,h); |
451f5018 | 343 | } // end for i // End Integrate over t |
81f2107f | 344 | } |
451f5018 | 345 | else { // st == 0.0 deposit it at this point |
346 | x = x0; | |
c92b1537 | 347 | y = y0+0.5*thick; |
451f5018 | 348 | z = z0; |
349 | if (!(fSeg->LocalToDet(x,z,ix,iz))) continue; // outside | |
350 | el = de / fSimuParam->GetGeVToCharge(); | |
c92b1537 | 351 | if (fSimuParam->GetPixLorentzDrift()) x += y*fTanLorAng; |
0ebc85cf | 352 | // Check if the hit is inside readout window |
353 | if ( !(((AliITSUSimulationPix*)this)->*AliITSUSimulationPix::fROTimeFun)(ix,iz,tof) ) continue; | |
c92b1537 | 354 | SpreadCharge2D(x,z,y,ix,iz,el,idtrack,h); |
451f5018 | 355 | } // end if st>0.0 |
356 | ||
357 | } // Loop over all hits h | |
358 | ||
359 | // Coupling | |
360 | int nd = fSensMap->GetEntriesUnsorted(); // use unsorted access when possible, since it is faster | |
361 | AliITSUSDigit* dg = 0; | |
4fa9d550 | 362 | switch (fSimuParam->GetPixCouplingOption()) { |
363 | case AliITSUSimuParam::kNewCouplingPix : | |
451f5018 | 364 | for (i=nd;i--;) { |
365 | dg = (AliITSUSDigit*)fSensMap->AtUnsorted(i); | |
366 | if (fSensMap->IsDisabled(dg)) continue; | |
367 | SetCoupling(dg,idtrack,h); | |
368 | } | |
4fa9d550 | 369 | case AliITSUSimuParam::kOldCouplingPix: |
451f5018 | 370 | for (i=nd;i--;) { |
371 | dg = (AliITSUSDigit*)fSensMap->AtUnsorted(i); | |
372 | if (fSensMap->IsDisabled(dg)) continue; | |
373 | SetCouplingOld(dg,idtrack,h); | |
374 | } | |
375 | break; | |
376 | default: | |
377 | break; | |
378 | } // end switch | |
4fa9d550 | 379 | if (GetDebug(2)) AliInfo(Form("Finished fCoupling=%d",fSimuParam->GetPixCouplingOption())); |
451f5018 | 380 | } |
381 | ||
382 | //______________________________________________________________________ | |
c92b1537 | 383 | void AliITSUSimulationPix::SpreadCharge2D(Double_t x0,Double_t z0, Double_t dy, Int_t ix0,Int_t iz0, |
384 | Double_t el, Int_t tID, Int_t hID) | |
451f5018 | 385 | { |
386 | // Spreads the charge over neighboring cells. Assume charge is distributed | |
387 | // as charge(x,z) = (el/2*pi*sigx*sigz)*exp(-arg) | |
388 | // arg=((x-x0)*(x-x0)/2*sigx*sigx)+((z-z0*z-z0)/2*sigz*sigz) | |
451f5018 | 389 | // Defined this way, the integral over all x and z is el. |
390 | // Inputs: | |
c92b1537 | 391 | // Double_t x0 x position of point where charge is liberated (local) |
392 | // Double_t z0 z position of point where charge is liberated (local) | |
393 | // Double_t dy distance from the entrance surface (diffusion sigma may depend on it) | |
451f5018 | 394 | // Int_t ix0 row of cell corresponding to point x0 |
395 | // Int_t iz0 columb of cell corresponding to point z0 | |
396 | // Double_t el number of electrons liberated in this step | |
397 | // Double_t sigx Sigma difusion along x for this step (y0 dependent) | |
4fa9d550 | 398 | // Double_t sigz Sigma difusion along z for this step (z0 dependent) |
c92b1537 | 399 | // Int_t tID track number |
400 | // Int_t hID hit "hit" index number | |
401 | // | |
451f5018 | 402 | Int_t ix,iz,ixs,ixe,izs,ize; |
4fa9d550 | 403 | Float_t x,z; // keep coordinates float (required by AliSegmentation) |
29ad4146 | 404 | Float_t xdioshift = 0 , zdioshift = 0 ; |
c92b1537 | 405 | Double_t s,dtIn[kNDtSpread]; // data transfered to spread function for integral calculation |
451f5018 | 406 | // |
29ad4146 | 407 | if (GetDebug(2)) AliInfo(Form("(x0=%e,z0=%e,dy=%e, ix0=%d,iz0=%d,el=%e,tID=%d,hID=%d)",x0,z0,dy,ix0,iz0,el,tID,hID)); |
c92b1537 | 408 | // |
409 | Double_t &x1 = dtIn[kCellX1]; | |
410 | Double_t &x2 = dtIn[kCellX2]; | |
411 | Double_t &z1 = dtIn[kCellZ1]; | |
412 | Double_t &z2 = dtIn[kCellZ2]; | |
413 | // | |
414 | int nx = GetResponseParam()->GetParameter(kSpreadFunParamNXoffs); | |
415 | int nz = GetResponseParam()->GetParameter(kSpreadFunParamNZoffs); | |
416 | // | |
417 | dtIn[kCellYDepth] = dy; | |
418 | ixs = Max(-nx+ix0,0); | |
419 | ixe = Min( nx+ix0,fSeg->Npx()-1); | |
420 | izs = Max(-nz+iz0,0); | |
421 | ize = Min( nz+iz0,fSeg->Npz()-1); | |
451f5018 | 422 | for (ix=ixs;ix<=ixe;ix++) |
423 | for (iz=izs;iz<=ize;iz++) { | |
424 | fSeg->DetToLocal(ix,iz,x,z); // pixel center | |
29ad4146 | 425 | xdioshift = zdioshift = 0; |
426 | CalcDiodeShiftInPixel(ix,iz,xdioshift,zdioshift); // Check and apply diode shift if needed | |
29f5e263 | 427 | double dxi = 0.5*fSeg->Dpx(ix); |
428 | double dzi = 0.5*fSeg->Dpz(iz); | |
29ad4146 | 429 | x1 = (x + xdioshift) - x0; // calculate distance of cell boundaries from injection center |
430 | z1 = (z + zdioshift) - z0; | |
4fa9d550 | 431 | x2 = x1 + dxi; // Upper |
432 | x1 -= dxi; // Lower | |
433 | z2 = z1 + dzi; // Upper | |
434 | z1 -= dzi; // Lower | |
c92b1537 | 435 | s = el* (((AliITSUSimulationPix*)this)->*AliITSUSimulationPix::fSpreadFun)(dtIn); |
c92b1537 | 436 | if (s>fSimuParam->GetPixMinElToAdd()) UpdateMapSignal(iz,ix,tID,hID,s); |
451f5018 | 437 | } // end for ix, iz |
438 | // | |
439 | } | |
440 | ||
c92b1537 | 441 | //______________________________________________________________________ |
442 | Double_t AliITSUSimulationPix::SpreadFunDoubleGauss2D(const Double_t *dtIn) | |
443 | { | |
444 | // calculate integral of charge in the cell with boundaries at X=dtIn[kCellX1]:dtIn[kCellX2] | |
445 | // and Z=dtIn[kCellZ1]:dtIn[kCellZ2] | |
446 | // The spread function is assumed to be double gaussian in 2D | |
447 | // Parameters should be: mean0,sigma0, mean1,sigma1, relative strenght of 2nd gaussian wrt 1st one | |
448 | // | |
c92b1537 | 449 | // 1st gaussian |
69e0f089 | 450 | double intg1 = GausInt2D(fResponseParam->GetParameter(kG2SigX0), // sigX |
69e0f089 | 451 | dtIn[kCellX1]-fResponseParam->GetParameter(kG2MeanX0), // x1-xmean |
452 | dtIn[kCellX2]-fResponseParam->GetParameter(kG2MeanX0), // x2-xmean | |
268bb76f | 453 | fResponseParam->GetParameter(kG2SigZ0), // sigZ |
69e0f089 | 454 | dtIn[kCellZ1]-fResponseParam->GetParameter(kG2MeanZ0), // z1-zmean |
455 | dtIn[kCellZ2]-fResponseParam->GetParameter(kG2MeanZ0)); // z2-zmean | |
c92b1537 | 456 | // 2nd gaussian |
69e0f089 | 457 | double intg2 = GausInt2D(fResponseParam->GetParameter(kG2SigX1), // sigX |
69e0f089 | 458 | dtIn[kCellX1]-fResponseParam->GetParameter(kG2MeanX1), // x1-xmean |
459 | dtIn[kCellX2]-fResponseParam->GetParameter(kG2MeanX1), // x2-xmean | |
268bb76f | 460 | fResponseParam->GetParameter(kG2SigZ1), // sigZ |
69e0f089 | 461 | dtIn[kCellZ1]-fResponseParam->GetParameter(kG2MeanZ1), // z1-zmean |
462 | dtIn[kCellZ2]-fResponseParam->GetParameter(kG2MeanZ1)); // z2-zmean | |
463 | double scl = fResponseParam->GetParameter(kG2ScaleG2); | |
c92b1537 | 464 | return (intg1+intg2*scl)/(1+scl); |
465 | // | |
466 | } | |
467 | ||
29ad4146 | 468 | |
469 | //______________________________________________________________________ | |
470 | Double_t AliITSUSimulationPix::SpreadFrom2DHisto(const Double_t *dtIn) | |
471 | { | |
472 | // calculate integral of charge in the cell with boundaries at X=dtIn[kCellX1]:dtIn[kCellX2] | |
473 | // and Z=dtIn[kCellZ1]:dtIn[kCellZ2] | |
474 | // The spread function integral is taken from fSpread2DHisto extracted from the sensor response parameters | |
475 | // list in the method SetResponseParam. The histo must return the fraction of charge integrates in the | |
476 | // cell whose center is on the distance X=(dtIn[kCellX1]+dtIn[kCellX2])/2 and Z=(dtIn[kCellZ1]+dtIn[kCellZ2])/2 | |
477 | // from the injection point. | |
478 | // | |
479 | Double_t qpixfrac = 0; | |
480 | Double_t xintp = 1e4*(dtIn[kCellX1]+dtIn[kCellX2])/2.0; | |
481 | Double_t zintp = 1e4*(dtIn[kCellZ1]+dtIn[kCellZ2])/2.0; | |
482 | // | |
483 | qpixfrac = fSpread2DHisto->Interpolate(xintp,zintp); //the PSF map is given in um but the dtIn is in cm so we need to convert it | |
484 | // | |
485 | return qpixfrac; | |
486 | } | |
487 | ||
c92b1537 | 488 | //______________________________________________________________________ |
489 | Double_t AliITSUSimulationPix::SpreadFunGauss2D(const Double_t *dtIn) | |
490 | { | |
491 | // calculate integral of charge in the cell with boundaries at X=dtIn[kCellX1]:dtIn[kCellX2] | |
492 | // and Z=dtIn[kCellZ1]:dtIn[kCellZ2] | |
493 | // The spread function is assumed to be gaussian in 2D | |
494 | // Parameters should be: mean0,sigma0 | |
69e0f089 | 495 | return GausInt2D(fResponseParam->GetParameter(kG1SigX), // sigX |
496 | fResponseParam->GetParameter(kG1SigZ), // sigZ | |
497 | dtIn[kCellX1]-fResponseParam->GetParameter(kG1MeanX), // x1-xmean | |
498 | dtIn[kCellX2]-fResponseParam->GetParameter(kG1MeanX), // x2-xmean | |
499 | dtIn[kCellZ1]-fResponseParam->GetParameter(kG1MeanZ), // z1-zmean | |
500 | dtIn[kCellZ2]-fResponseParam->GetParameter(kG1MeanZ)); // z2-zmean | |
c92b1537 | 501 | // |
502 | } | |
503 | ||
451f5018 | 504 | //______________________________________________________________________ |
505 | void AliITSUSimulationPix::RemoveDeadPixels() | |
506 | { | |
507 | // Removes dead pixels on each module (ladder) | |
508 | // This should be called before going from sdigits to digits (FrompListToDigits) | |
509 | ||
510 | AliITSUCalibrationPix* calObj = (AliITSUCalibrationPix*) GetCalibDead(); | |
511 | if (!calObj) return; | |
512 | // | |
513 | if (calObj->IsBad()) {ClearMap(); return;} // whole module is masked | |
514 | // | |
515 | // remove single bad pixels one by one | |
516 | int nsingle = calObj->GetNrBadSingle(); | |
517 | UInt_t col,row; | |
518 | for (int i=nsingle;i--;) { | |
519 | calObj->GetBadPixelSingle(i,row,col); | |
520 | fSensMap->DeleteItem(col,row); | |
521 | } | |
522 | int nsd = fSensMap->GetEntriesUnsorted(); | |
523 | for (int isd=nsd;isd--;) { | |
524 | AliITSUSDigit* sd = (AliITSUSDigit*)fSensMap->AtUnsorted(isd); | |
525 | if (fSensMap->IsDisabled(sd)) continue; | |
526 | fSensMap->GetMapIndex(sd->GetUniqueID(),col,row); | |
527 | int chip = fSeg->GetChipFromChannel(0,col); | |
528 | // if (calObj->IsChipMarkedBad(chip)) fSensMap->Disable(sd); // this will simple mark the hit as bad | |
529 | if (calObj->IsChipMarkedBad(chip)) fSensMap->DeleteItem(sd); // this will suppress hit in the sorted list | |
530 | } | |
531 | // | |
532 | } | |
533 | ||
534 | //______________________________________________________________________ | |
535 | void AliITSUSimulationPix::AddNoisyPixels() | |
536 | { | |
537 | // Adds noisy pixels on each module (ladder) | |
538 | // This should be called before going from sdigits to digits (FrompListToDigits) | |
539 | AliITSUCalibrationPix* calObj = (AliITSUCalibrationPix*) GetCalibNoisy(); | |
29ad4146 | 540 | if (!calObj) { AliDebug(10,Form(" No Calib Object for Noise!!! ")); return;} |
451f5018 | 541 | for (Int_t i=calObj->GetNrBad(); i--;) UpdateMapNoise(calObj->GetBadColAt(i), calObj->GetBadRowAt(i), |
c92b1537 | 542 | 10*fSimuParam->GetPixThreshold(fModule->GetIndex())); |
451f5018 | 543 | // |
544 | } | |
545 | ||
546 | //______________________________________________________________________ | |
547 | void AliITSUSimulationPix::FrompListToDigits() | |
548 | { | |
549 | // add noise and electronics, perform the zero suppression and add the | |
550 | // digit to the list | |
551 | static AliITSU *aliITS = (AliITSU*)gAlice->GetModule("ITS"); | |
552 | UInt_t ix,iz; | |
553 | Double_t sig; | |
554 | const Int_t knmaxtrk=AliITSdigit::GetNTracks(); | |
555 | static AliITSUDigitPix dig; | |
556 | // RS: in principle: | |
557 | // 1) for every pixel w/o hit we have to generate a noise and activate the pixel if the noise exceeds the threshold. | |
558 | // 2) for every pixel with hit we should add random noise and check if the total signal exceeds the threshold | |
559 | // With many channels this will be too time consuming, hence I do the following | |
29ad4146 | 560 | // 1) Precalculate the probability that the nois alone will exceed the threshold (probnoisy). |
561 | // 2) Chose randomly empty pixels according to fakes rate | |
451f5018 | 562 | // 3) For pixels having a hits apply the usual noise and compare with threshold |
563 | // | |
564 | // RS may use for ordered random sample generation dl.acm.org/ft_gateway.cfm?id=356313&type=pdf | |
565 | // | |
566 | int maxInd = fSensMap->GetMaxIndex(); | |
c92b1537 | 567 | int modId = fModule->GetIndex(); |
451f5018 | 568 | // |
569 | int nsd = fSensMap->GetEntries(); | |
570 | Int_t prevID=0,curID=0; | |
571 | TArrayI ordSampleInd(100),ordSample(100); | |
572 | // | |
c92b1537 | 573 | double probNoisy,noiseSig,noiseMean,thresh = fSimuParam->GetPixThreshold(modId); |
574 | fSimuParam->GetPixNoise(modId, noiseSig, noiseMean); | |
451f5018 | 575 | probNoisy = AliITSUSimuParam::CalcProbNoiseOverThreshold(noiseMean,noiseSig,thresh); // prob. to have noise above threshold |
576 | // | |
577 | for (int i=0;i<nsd;i++) { | |
578 | AliITSUSDigit* sd = (AliITSUSDigit*)fSensMap->At(i); // ordered in index | |
579 | if (fSensMap->IsDisabled(sd)) continue; | |
580 | curID = (int)sd->GetUniqueID(); | |
581 | // | |
29ad4146 | 582 | if ( fSimuParam->GetPixAddNoisyFlag() ) { |
451f5018 | 583 | CreateNoisyDigits(prevID,curID,probNoisy, noiseSig, noiseMean); |
584 | prevID = curID+1; | |
970bfd2e | 585 | // |
586 | // add noise also to sdigit with signal | |
587 | sd->AddNoise(AliITSUSimuParam::GenerateNoiseQFunction(0,noiseMean,noiseSig)); | |
451f5018 | 588 | } |
589 | // | |
c92b1537 | 590 | if ((sig=sd->GetSumSignal())<=fSimuParam->GetPixThreshold(modId)) continue; |
a11ef2e4 | 591 | if (Abs(sig)>2147483647.0) { //RS? |
451f5018 | 592 | //PH 2147483647 is the max. integer |
593 | //PH This apparently is a problem which needs investigation | |
594 | AliWarning(Form("Too big or too small signal value %f",sig)); | |
595 | } | |
596 | fSensMap->GetMapIndex(sd->GetUniqueID(),iz,ix); | |
597 | dig.SetCoord1(iz); | |
598 | dig.SetCoord2(ix); | |
29ad4146 | 599 | dig.SetSignal((Int_t)sig); |
451f5018 | 600 | dig.SetSignalPix((Int_t)sig); |
601 | int ntr = sd->GetNTracks(); | |
602 | for (int j=0;j<ntr;j++) { | |
603 | dig.SetTrack(j,sd->GetTrack(j)); | |
604 | dig.SetHit(j,sd->GetHit(j)); | |
605 | } | |
606 | for (int j=ntr;j<knmaxtrk;j++) { | |
607 | dig.SetTrack(j,-3); | |
608 | dig.SetHit(j,-1); | |
609 | } | |
02d6eccc | 610 | aliITS->AddSimDigit(AliITSUGeomTGeo::kDetTypePix, &dig); |
451f5018 | 611 | } |
612 | // if needed, add noisy pixels with id from last real hit to maxID | |
29ad4146 | 613 | if (fSimuParam->GetPixAddNoisyFlag() && |
614 | (nsd>0 || ( nsd==0 && fSimuParam->GetPixNoiseInAllMod()) )) { | |
615 | AliDebug(10,Form("CreateNoisyDigits2( %d ,%d) module %d",prevID,maxInd,modId)); | |
616 | CreateNoisyDigits(prevID,maxInd,probNoisy, noiseSig, noiseMean); | |
617 | } | |
451f5018 | 618 | // |
619 | } | |
620 | ||
621 | //______________________________________________________________________ | |
622 | Int_t AliITSUSimulationPix::CreateNoisyDigits(Int_t minID,Int_t maxID,double probNoisy, double noise, double base) | |
29ad4146 | 623 | {//RS PAYATT2 |
451f5018 | 624 | // create random noisy digits above threshold within id range [minID,maxID[ |
625 | // see FrompListToDigits for details | |
626 | // | |
627 | static AliITSU *aliITS = (AliITSU*)gAlice->GetModule("ITS"); | |
628 | UInt_t ix,iz; | |
629 | static AliITSUDigitPix dig; | |
630 | static TArrayI ordSampleInd(100),ordSample(100); //RS!!! static is not thread-safe!!! | |
631 | const Int_t knmaxtrk=AliITSdigit::GetNTracks(); | |
632 | // | |
633 | Int_t ncand = 0; | |
634 | int npix = maxID-minID; | |
29ad4146 | 635 | if (npix<1 || (ncand=gRandom->Poisson(npix * fSimuParam->GetPixFakeRate() ))<1) return ncand; // decide how many noisy pixels will be added |
451f5018 | 636 | ncand = GenOrderedSample(npix,ncand,ordSample,ordSampleInd); |
637 | int* ordV = ordSample.GetArray(); | |
638 | int* ordI = ordSampleInd.GetArray(); | |
639 | for (int j=0;j<ncand;j++) { | |
640 | fSensMap->GetMapIndex((UInt_t)ordV[ordI[j]],iz,ix); // create noisy digit | |
641 | dig.SetCoord1(iz); | |
642 | dig.SetCoord2(ix); | |
643 | dig.SetSignal(1); | |
644 | dig.SetSignalPix((Int_t)AliITSUSimuParam::GenerateNoiseQFunction(probNoisy,base,noise)); | |
645 | for (int k=knmaxtrk;k--;) { | |
646 | dig.SetTrack(k,-3); | |
647 | dig.SetHit(k,-1); | |
648 | } | |
02d6eccc | 649 | aliITS->AddSimDigit(AliITSUGeomTGeo::kDetTypePix,&dig); |
29ad4146 | 650 | AliDebug(10,Form("Add noisy pixel %d(%d/%d) Noise=%d",ordV[ordI[j]],iz,ix,dig.GetSignalPix())); |
451f5018 | 651 | } |
652 | return ncand; | |
653 | } | |
654 | ||
655 | //______________________________________________________________________ | |
656 | void AliITSUSimulationPix::SetCoupling(AliITSUSDigit* old, Int_t ntrack, Int_t idhit) | |
657 | { | |
658 | // Take into account the coupling between adiacent pixels. | |
659 | // The parameters probcol and probrow are the probability of the | |
660 | // signal in one pixel shared in the two adjacent pixels along | |
661 | // the column and row direction, respectively. | |
662 | // Note pList is goten via GetMap() and module is not need any more. | |
663 | // Otherwise it is identical to that coded by Tiziano Virgili (BSN). | |
664 | //Begin_Html | |
665 | /* | |
666 | <img src="picts/ITS/barimodel_3.gif"> | |
667 | </pre> | |
668 | <br clear=left> | |
669 | <font size=+2 color=red> | |
670 | <a href="mailto:tiziano.virgili@cern.ch"></a>. | |
671 | </font> | |
672 | <pre> | |
673 | */ | |
674 | //End_Html | |
675 | // Inputs: | |
676 | // old existing AliITSUSDigit | |
677 | // Int_t ntrack track incex number | |
678 | // Int_t idhit hit index number | |
679 | UInt_t col,row; | |
680 | Double_t pulse1,pulse2; | |
681 | Double_t couplR=0.0,couplC=0.0; | |
682 | Double_t xr=0.; | |
683 | // | |
684 | fSensMap->GetMapIndex(old->GetUniqueID(),col,row); | |
4fa9d550 | 685 | fSimuParam->GetPixCouplingParam(couplC,couplR); |
686 | if (GetDebug(2)) AliInfo(Form("(col=%d,row=%d,ntrack=%d,idhit=%d) couplC=%e couplR=%e", | |
687 | col,row,ntrack,idhit,couplC,couplR)); | |
451f5018 | 688 | pulse2 = pulse1 = old->GetSignal(); |
4fa9d550 | 689 | if (pulse1<fSimuParam->GetPixMinElToAdd()) return; // too small signal |
451f5018 | 690 | for (Int_t isign=-1;isign<=1;isign+=2) { |
691 | // | |
692 | // loop in col direction | |
693 | int j1 = int(col) + isign; | |
694 | xr = gRandom->Rndm(); | |
695 | if ( !((j1<0) || (j1>fSeg->Npz()-1) || (xr>couplC)) ) UpdateMapSignal(UInt_t(j1),row,ntrack,idhit,pulse1); | |
696 | // | |
697 | // loop in row direction | |
698 | int j2 = int(row) + isign; | |
699 | xr = gRandom->Rndm(); | |
700 | if ( !((j2<0) || (j2>fSeg->Npx()-1) || (xr>couplR)) ) UpdateMapSignal(col,UInt_t(j2),ntrack,idhit,pulse2); | |
701 | } | |
702 | // | |
703 | } | |
704 | ||
705 | //______________________________________________________________________ | |
706 | void AliITSUSimulationPix::SetCouplingOld(AliITSUSDigit* old, Int_t ntrack,Int_t idhit) | |
707 | { | |
708 | // Take into account the coupling between adiacent pixels. | |
709 | // The parameters probcol and probrow are the fractions of the | |
710 | // signal in one pixel shared in the two adjacent pixels along | |
711 | // the column and row direction, respectively. | |
712 | //Begin_Html | |
713 | /* | |
714 | <img src="picts/ITS/barimodel_3.gif"> | |
715 | </pre> | |
716 | <br clear=left> | |
717 | <font size=+2 color=red> | |
718 | <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>. | |
719 | </font> | |
720 | <pre> | |
721 | */ | |
722 | //End_Html | |
723 | // Inputs: | |
724 | // old existing AliITSUSDigit | |
725 | // ntrack track incex number | |
726 | // idhit hit index number | |
727 | // module module number | |
728 | // | |
729 | UInt_t col,row; | |
c92b1537 | 730 | Int_t modId = fModule->GetIndex(); |
451f5018 | 731 | Double_t pulse1,pulse2; |
732 | Double_t couplR=0.0,couplC=0.0; | |
733 | // | |
734 | fSensMap->GetMapIndex(old->GetUniqueID(),col,row); | |
4fa9d550 | 735 | fSimuParam->GetPixCouplingParam(couplC,couplR); |
736 | if (GetDebug(3)) AliInfo(Form("(col=%d,row=%d,ntrack=%d,idhit=%d) couplC=%e couplR=%e", | |
737 | col,row,ntrack,idhit,couplC,couplR)); | |
738 | // | |
739 | if (old->GetSignal()<fSimuParam->GetPixMinElToAdd()) return; // too small signal | |
740 | for (Int_t isign=-1;isign<=1;isign+=2) {// loop in col direction | |
741 | pulse2 = pulse1 = old->GetSignal(); | |
742 | // | |
743 | int j1 = int(col)+isign; | |
744 | pulse1 *= couplC; | |
c92b1537 | 745 | if ((j1<0)||(j1>fSeg->Npz()-1)||(pulse1<fSimuParam->GetPixThreshold(modId))) pulse1 = old->GetSignal(); |
4fa9d550 | 746 | else UpdateMapSignal(UInt_t(j1),row,ntrack,idhit,pulse1); |
747 | ||
748 | // loop in row direction | |
749 | int j2 = int(row) + isign; | |
750 | pulse2 *= couplR; | |
c92b1537 | 751 | if ((j2<0)||(j2>(fSeg->Npx()-1))||(pulse2<fSimuParam->GetPixThreshold(modId))) pulse2 = old->GetSignal(); |
4fa9d550 | 752 | else UpdateMapSignal(col,UInt_t(j2),ntrack,idhit,pulse2); |
753 | } // for isign | |
451f5018 | 754 | } |
755 | ||
756 | //______________________________________________________________________ | |
0ebc85cf | 757 | void AliITSUSimulationPix::GenerateReadOutCycleOffset() |
451f5018 | 758 | { |
759 | // Generate randomly the strobe | |
760 | // phase w.r.t to the LHC clock | |
0ebc85cf | 761 | fReadOutCycleOffset = fReadOutCycleLength*gRandom->Rndm(); |
29ad4146 | 762 | // fReadOutCycleOffset = 25e-9*gRandom->Rndm(); // clm: I think this way we shift too much 10-30 us! The global shift should be between the BCs?! |
763 | // RS: 25 ns is too small number, the staggering will not work. Let's at the moment keep fully random shift (still, no particle from correct | |
764 | // collision will be lost) untill real number is specified | |
765 | // | |
451f5018 | 766 | } |
767 | ||
c92b1537 | 768 | //______________________________________________________________________ |
29ad4146 | 769 | void AliITSUSimulationPix::SetResponseParam(AliITSUParamList* resp) |
c92b1537 | 770 | { |
771 | // attach response parameterisation data | |
772 | fResponseParam = resp; | |
29ad4146 | 773 | // |
774 | int spreadID = Nint(fResponseParam->GetParameter(AliITSUSimulationPix::kChargeSpreadType)); | |
775 | const char* hname = 0; | |
776 | fSpread2DHisto = 0; | |
777 | // | |
778 | switch (spreadID) { | |
779 | // | |
780 | case kSpreadFunHisto: | |
781 | fSpreadFun = &AliITSUSimulationPix::SpreadFrom2DHisto; | |
782 | hname = fResponseParam->GetParName(AliITSUSimulationPix::kChargeSpreadType); | |
783 | if (!(fSpread2DHisto=(TH2*)fResponseParam->GetParamObject(hname))) | |
784 | AliFatal(Form("Did not find 2D histo %s for charge spread parameterization",hname)); | |
c92b1537 | 785 | break; |
29ad4146 | 786 | // |
787 | case kSpreadFunDoubleGauss2D: | |
788 | fSpreadFun = &AliITSUSimulationPix::SpreadFunDoubleGauss2D; | |
789 | break; | |
790 | // | |
791 | case kSpreadFunGauss2D: | |
792 | fSpreadFun = &AliITSUSimulationPix::SpreadFunGauss2D; | |
c92b1537 | 793 | break; |
29ad4146 | 794 | // |
795 | default: AliFatal(Form("Did not find requested spread function id=%d",spreadID)); | |
c92b1537 | 796 | } |
797 | // | |
0ebc85cf | 798 | int readoutType = Nint(fResponseParam->GetParameter(kReadOutSchemeType)); |
799 | switch (readoutType) { | |
29ad4146 | 800 | case kReadOutStrobe: |
801 | fROTimeFun = &AliITSUSimulationPix::IsHitInReadOutWindow; | |
0ebc85cf | 802 | break; |
29ad4146 | 803 | case kReadOutRollingShutter: |
804 | fROTimeFun = &AliITSUSimulationPix::IsHitInReadOutWindowRollingShutter; | |
0ebc85cf | 805 | break; |
806 | default: AliFatal(Form("Did not find requested readout time type id=%d",readoutType)); | |
807 | } | |
29ad4146 | 808 | //___ Set the Rolling Shutter read-out window |
0ebc85cf | 809 | fReadOutCycleLength = fResponseParam->GetParameter(kReadOutCycleLength); |
29ad4146 | 810 | //___ Pixel discrimination threshold, and the S/N cut |
811 | fSimuParam->SetPixThreshold(fResponseParam->GetParameter(kPixNoiseMPV) *fResponseParam->GetParameter(kPixSNDisrcCut) , fResponseParam->GetParameter(kPixSNDisrcCut),-1); //for all modules | |
812 | //___ Minimum number of electrons to add | |
813 | fSimuParam->SetPixMinElToAdd(fResponseParam->GetParameter(kPixMinElToAdd)); | |
814 | //___ Set the Pixel Noise MPV and Sigma (the noise distribution is Landau not Gauss due to RTN) | |
815 | fSimuParam->SetPixNoise( fResponseParam->GetParameter(kPixNoiseMPV), fResponseParam->GetParameter(kPixNoiseSigma), -1); //for all modules | |
816 | //___ Pixel fake hit rate | |
817 | fSimuParam->SetPixFakeRate( fResponseParam->GetParameter(kPixFakeRate) ); | |
818 | //___ To apply the noise or not | |
819 | if ( fResponseParam->GetParameter(kPixNoiseIsOn) > 0.01) fSimuParam->SetPixAddNoisyFlag(kTRUE); | |
820 | else fSimuParam->SetPixAddNoisyFlag(kFALSE); | |
821 | // | |
822 | if(fResponseParam->GetParameter(kPixNoiseInAllMod) > 0.01 ) fSimuParam->SetPixNoiseInAllMod(kTRUE); | |
823 | else fSimuParam->SetPixNoiseInAllMod(kFALSE); | |
824 | // | |
825 | // Double_t vGeVToQ = fSimuParam->GetGeVToCharge(); | |
826 | fGlobalChargeScale = fResponseParam->GetParameter(kSpreadFunGlobalQScale); | |
827 | ||
828 | AliDebug(10,Form("=============== Setting the response start ============================")); | |
829 | AliDebug(10,Form("=============== RO type: %d",readoutType)); | |
830 | AliDebug(10,Form("=============== RO cycle lenght: %lf",fReadOutCycleLength)); | |
831 | AliDebug(10,Form("=============== Noise MPV: %lf",fResponseParam->GetParameter(kPixNoiseMPV))); | |
832 | AliDebug(10,Form("=============== Noise Sigma: %lf",fResponseParam->GetParameter(kPixNoiseSigma))); | |
833 | AliDebug(10,Form("=============== Fake rate: %lf",fResponseParam->GetParameter(kPixFakeRate))); | |
834 | AliDebug(10,Form("=============== Noise On/Off: %d",fSimuParam->GetPixAddNoisyFlag())); | |
835 | AliDebug(10,Form("=============== Noise in all mod on/off: %d",fSimuParam->GetPixNoiseInAllMod())); | |
836 | AliDebug(10,Form("=============== Global Charge scale: %lf",fGlobalChargeScale)); | |
837 | AliDebug(10,Form("=============== Setting the response done ============================")); | |
838 | ||
839 | ||
840 | ||
c92b1537 | 841 | } |
0ebc85cf | 842 | |
843 | //______________________________________________________________________ | |
29ad4146 | 844 | Bool_t AliITSUSimulationPix::IsHitInReadOutWindowRollingShutter(Int_t row, Int_t col, Double_t hitTime) |
0ebc85cf | 845 | { |
846 | // | |
847 | // Check whether the hit is in the read out window of the given column/row of the sensor | |
848 | // hitTime is the time of the subhit (hit is divided to nstep charge deposit) in seconds | |
849 | // globalPhaseShift gives the start of the RO for the cycle in pixel wrt the LHC clock | |
850 | // GetRollingShutterWindow give the with of the rolling shutter read out window | |
851 | // | |
852 | double timePerRow = fReadOutCycleLength / fSeg->Npx(); | |
853 | double tmax = fReadOutCycleOffset + timePerRow*(row+1); | |
854 | double tmin = tmax - fReadOutCycleLength; | |
855 | AliDebug(3,Form("Rolling shutter at row%d/col%d: particle time: %e, tmin: %e : %e",row,col,hitTime,tmin,tmax)); | |
856 | return (hitTime<tmin || hitTime>tmax) ? kFALSE : kTRUE; | |
857 | // | |
858 | } | |
859 | ||
860 | //______________________________________________________________________ | |
861 | Bool_t AliITSUSimulationPix::IsHitInReadOutWindow(Int_t row, Int_t col, Double_t hitTime) | |
862 | { | |
863 | // | |
864 | // Check whether the hit is in the read out window of the given column/row of the sensor | |
865 | // | |
866 | AliDebug(3,Form("Strobe readout: row%d/col%d: particle time: %e, tmin: %e, tmax %e", | |
867 | row,col,hitTime,fReadOutCycleOffset,fReadOutCycleOffset+fReadOutCycleLength)); | |
e822b25e | 868 | hitTime -= fReadOutCycleOffset+0.5*fReadOutCycleLength; |
0ebc85cf | 869 | return (hitTime<0 || hitTime>fReadOutCycleLength) ? kFALSE : kTRUE; |
870 | // | |
871 | } | |
872 | ||
29ad4146 | 873 | //_______________________________________________________________________ |
874 | void AliITSUSimulationPix::CalcDiodeShiftInPixel(Int_t xlin, Int_t zcol, Float_t &x, Float_t &) | |
875 | { | |
876 | // | |
877 | // Calculates the shift of the diode wrt the geometric center of the pixel. | |
878 | // It is needed for staggerred pixel layout or double diode pixels with assymetric center | |
879 | // The shift can depend on the column or line or both... | |
880 | // The x and z are passed in cm | |
881 | // | |
882 | ||
883 | TString parTitle = fResponseParam->GetTitle(); | |
884 | ||
885 | // M32terP31 is staggered the diode shift within pixel depends on the column | |
886 | if ( parTitle.Contains("M32terP31") ) | |
887 | { | |
888 | if ( zcol%2 == 0 ) x += 0.30 * fSeg->Dpx(xlin); | |
889 | else x -= 0.19 * fSeg->Dpx(xlin); | |
890 | } | |
891 | ||
892 | ||
893 | } | |
894 | //_______________________________________________________________________ |