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