]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/UPGRADE/AliITSUSimulationPix.cxx
PHOSHijingEfficiency added
[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)
66 ,fStrobe(kTRUE)
67 ,fStrobeLenght(4)
68 ,fStrobePhase(-12.5e-9)
c92b1537 69 ,fSpreadFun(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)
79 ,fStrobe(kTRUE)
80 ,fStrobeLenght(4)
81 ,fStrobePhase(-12.5e-9)
c92b1537 82 ,fSpreadFun(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)
93 ,fStrobe(s.fStrobe)
94 ,fStrobeLenght(s.fStrobeLenght)
95 ,fStrobePhase(s.fStrobePhase)
c92b1537 96 ,fSpreadFun(s.fSpreadFun)
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);
115 fStrobe = s.fStrobe;
116 fStrobeLenght = s.fStrobeLenght;
117 fStrobePhase = s.fStrobePhase;
c92b1537 118 fSpreadFun = s.fSpreadFun;
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.
451f5018 218 const Double_t kBunchLenght = 25e-9; // LHC clock
c92b1537 219 Int_t nhits = fModule->GetNHits();
451f5018 220 if (!nhits) return;
221 //
222 Int_t h,ix,iz,i;
223 Int_t idtrack;
4fa9d550 224 Float_t x,y,z; // keep coordinates float (required by AliSegmentation)
c92b1537 225 Double_t x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0,de=0.0;
226 Double_t t,tp,st,dt=0.2,el;
29f5e263 227 Double_t thick = 0.5*fSeg->Dy(); // Half Thickness
c92b1537 228
451f5018 229 //
230 for (h=0;h<nhits;h++) {
231 if (fStrobe &&
c92b1537 232 ((fModule->GetHit(h)->GetTOF()<fStrobePhase) ||
233 (fModule->GetHit(h)->GetTOF()>(fStrobePhase+fStrobeLenght*kBunchLenght)))
451f5018 234 ) continue;
235 //
c92b1537 236 if (!fModule->LineSegmentL(h,x0,x1,y0,y1,z0,z1,de,idtrack)) continue;
a11ef2e4 237 st = Sqrt(x1*x1+y1*y1+z1*z1);
451f5018 238 if (st>0.0) {
29f5e263 239 st = (Double_t)((Int_t)(st*1e4)); // number of microns
451f5018 240 if (st<=1.0) st = 1.0;
29f5e263 241 dt = 1.0/st; // RS TODO: do we need 1 micron steps?
c92b1537 242 double dy = dt*thick;
243 y = -0.5*dy;
451f5018 244 for (t=0.0;t<1.0;t+=dt) { // Integrate over t
245 tp = t+0.5*dt;
246 x = x0+x1*tp;
c92b1537 247 y += dy;
451f5018 248 z = z0+z1*tp;
249 if (!(fSeg->LocalToDet(x,z,ix,iz))) continue; // outside
250 el = dt * de / fSimuParam->GetGeVToCharge();
251 //
c92b1537 252 if (fSimuParam->GetPixLorentzDrift()) x += y*fTanLorAng;
253 SpreadCharge2D(x,z,y,ix,iz,el,idtrack,h);
451f5018 254 } // end for t
255 } else { // st == 0.0 deposit it at this point
256 x = x0;
c92b1537 257 y = y0 + 0.5*thick;
451f5018 258 z = z0;
259 if (!(fSeg->LocalToDet(x,z,ix,iz))) continue; // outside
260 el = de / fSimuParam->GetGeVToCharge();
c92b1537 261 if (fSimuParam->GetPixLorentzDrift()) x += y*fTanLorAng;
262 SpreadCharge2D(x,z,y,ix,iz,el,idtrack,h);
451f5018 263 } // end if st>0.0
264 } // Loop over all hits h
265 //
266 // Coupling
267 int nd = fSensMap->GetEntriesUnsorted(); // use unsorted access when possible, since it is faster
268 AliITSUSDigit* dg = 0;
4fa9d550 269 switch (fSimuParam->GetPixCouplingOption()) {
270 case AliITSUSimuParam::kNewCouplingPix :
451f5018 271 for (i=nd;i--;) {
272 dg = (AliITSUSDigit*)fSensMap->AtUnsorted(i);
273 if (fSensMap->IsDisabled(dg)) continue;
274 SetCoupling(dg,idtrack,h);
275 }
276 break;
4fa9d550 277 case AliITSUSimuParam::kOldCouplingPix:
451f5018 278 for (i=nd;i--;) {
279 dg = (AliITSUSDigit*)fSensMap->AtUnsorted(i);
280 if (fSensMap->IsDisabled(dg)) continue;
281 SetCouplingOld(dg,idtrack,h);
282 }
283 break;
284 default:
285 break;
286
287 } // end switch
4fa9d550 288 if (GetDebug(2)) AliInfo(Form("Finished fCoupling=%d",fSimuParam->GetPixCouplingOption()));
451f5018 289}
290
291//______________________________________________________________________
c92b1537 292void AliITSUSimulationPix::Hits2SDigitsFast()
451f5018 293{
294 // Does the charge distributions using Gaussian diffusion charge charing. // Inputs:
295 // AliITSUModule *mod Pointer to this module
c92b1537 296 //
451f5018 297 const Double_t kBunchLenght = 25e-9; // LHC clock
c92b1537 298 TObjArray *hits = fModule->GetHits();
451f5018 299 Int_t nhits = hits->GetEntriesFast();
300 if (nhits<=0) return;
301 //
302 Int_t h,ix,iz,i;
303 Int_t idtrack;
4fa9d550 304 Float_t x,y,z; // keep coordinates float (required by AliSegmentation)
305 Double_t x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0;
c92b1537 306 Double_t t,st,el,de=0.0;
81f2107f 307 Double_t minDim = Min(fSeg->Dpx(1),fSeg->Dpz(1)); // RStmp: smallest pitch
c92b1537 308 Double_t thick = fSeg->Dy();
451f5018 309 //
310 for (h=0;h<nhits;h++) {
311 // Check if the hit is inside readout window
312 if (fStrobe &&
c92b1537 313 ((fModule->GetHit(h)->GetTOF()<fStrobePhase) ||
314 (fModule->GetHit(h)->GetTOF()>(fStrobePhase+fStrobeLenght*kBunchLenght)))
451f5018 315 ) continue;
316 //
c92b1537 317 if (!fModule->LineSegmentL(h,x0,x1,y0,y1,z0,z1,de,idtrack)) continue;
81f2107f 318 st = Sqrt(x1*x1+y1*y1+z1*z1);
319 if (st>0.0) {
320 int np = int(1.5*st/minDim); //RStmp: at the moment neglect kti,kwi: inject the points in such a way that there is ~1.5 point per cell
c92b1537 321 if (np<3) np = 3; //RStmp
322 double dt = 1./np;
323 double dy = dt*thick;
324 y = -0.5*dy;
81f2107f 325 t = -0.5*dt;
326 for (i=0;i<np;i++) { //RStmp Integrate over t
327 // for (i=0;i<kn10;i++) { // Integrate over t
328 t += dt; // RStmp kti[i];
451f5018 329 x = x0+x1*t;
c92b1537 330 y += dy;
451f5018 331 z = z0+z1*t;
332 if (!(fSeg->LocalToDet(x,z,ix,iz))) continue; // outside
c92b1537 333 el = dt*de/fSimuParam->GetGeVToCharge();
334 if (fSimuParam->GetPixLorentzDrift()) x += y*fTanLorAng;
335 SpreadCharge2D(x,z,y,ix,iz,el,idtrack,h);
451f5018 336 } // end for i // End Integrate over t
81f2107f 337 }
451f5018 338 else { // st == 0.0 deposit it at this point
339 x = x0;
c92b1537 340 y = y0+0.5*thick;
451f5018 341 z = z0;
342 if (!(fSeg->LocalToDet(x,z,ix,iz))) continue; // outside
343 el = de / fSimuParam->GetGeVToCharge();
c92b1537 344 if (fSimuParam->GetPixLorentzDrift()) x += y*fTanLorAng;
345 SpreadCharge2D(x,z,y,ix,iz,el,idtrack,h);
451f5018 346 } // end if st>0.0
347
348 } // Loop over all hits h
349
350 // Coupling
351 int nd = fSensMap->GetEntriesUnsorted(); // use unsorted access when possible, since it is faster
352 AliITSUSDigit* dg = 0;
4fa9d550 353 switch (fSimuParam->GetPixCouplingOption()) {
354 case AliITSUSimuParam::kNewCouplingPix :
451f5018 355 for (i=nd;i--;) {
356 dg = (AliITSUSDigit*)fSensMap->AtUnsorted(i);
357 if (fSensMap->IsDisabled(dg)) continue;
358 SetCoupling(dg,idtrack,h);
359 }
4fa9d550 360 case AliITSUSimuParam::kOldCouplingPix:
451f5018 361 for (i=nd;i--;) {
362 dg = (AliITSUSDigit*)fSensMap->AtUnsorted(i);
363 if (fSensMap->IsDisabled(dg)) continue;
364 SetCouplingOld(dg,idtrack,h);
365 }
366 break;
367 default:
368 break;
369 } // end switch
4fa9d550 370 if (GetDebug(2)) AliInfo(Form("Finished fCoupling=%d",fSimuParam->GetPixCouplingOption()));
451f5018 371}
372
373//______________________________________________________________________
c92b1537 374void AliITSUSimulationPix::SpreadCharge2D(Double_t x0,Double_t z0, Double_t dy, Int_t ix0,Int_t iz0,
375 Double_t el, Int_t tID, Int_t hID)
451f5018 376{
377 // Spreads the charge over neighboring cells. Assume charge is distributed
378 // as charge(x,z) = (el/2*pi*sigx*sigz)*exp(-arg)
379 // arg=((x-x0)*(x-x0)/2*sigx*sigx)+((z-z0*z-z0)/2*sigz*sigz)
451f5018 380 // Defined this way, the integral over all x and z is el.
381 // Inputs:
c92b1537 382 // Double_t x0 x position of point where charge is liberated (local)
383 // Double_t z0 z position of point where charge is liberated (local)
384 // Double_t dy distance from the entrance surface (diffusion sigma may depend on it)
451f5018 385 // Int_t ix0 row of cell corresponding to point x0
386 // Int_t iz0 columb of cell corresponding to point z0
387 // Double_t el number of electrons liberated in this step
388 // Double_t sigx Sigma difusion along x for this step (y0 dependent)
4fa9d550 389 // Double_t sigz Sigma difusion along z for this step (z0 dependent)
c92b1537 390 // Int_t tID track number
391 // Int_t hID hit "hit" index number
392 //
451f5018 393 Int_t ix,iz,ixs,ixe,izs,ize;
4fa9d550 394 Float_t x,z; // keep coordinates float (required by AliSegmentation)
c92b1537 395 Double_t s,dtIn[kNDtSpread]; // data transfered to spread function for integral calculation
451f5018 396 //
c92b1537 397 if (GetDebug(2)) AliInfo(Form("(x0=%e,z0=%e,dy=%e, ix0=%d,iz0=%d,el=%e,tID=%d,hID=%d)",
398 x0,z0,dy,ix0,iz0,el,tID,hID));
399 //
400 Double_t &x1 = dtIn[kCellX1];
401 Double_t &x2 = dtIn[kCellX2];
402 Double_t &z1 = dtIn[kCellZ1];
403 Double_t &z2 = dtIn[kCellZ2];
404 //
405 int nx = GetResponseParam()->GetParameter(kSpreadFunParamNXoffs);
406 int nz = GetResponseParam()->GetParameter(kSpreadFunParamNZoffs);
407 //
408 dtIn[kCellYDepth] = dy;
409 ixs = Max(-nx+ix0,0);
410 ixe = Min( nx+ix0,fSeg->Npx()-1);
411 izs = Max(-nz+iz0,0);
412 ize = Min( nz+iz0,fSeg->Npz()-1);
451f5018 413 for (ix=ixs;ix<=ixe;ix++)
414 for (iz=izs;iz<=ize;iz++) {
415 fSeg->DetToLocal(ix,iz,x,z); // pixel center
29f5e263 416 double dxi = 0.5*fSeg->Dpx(ix);
417 double dzi = 0.5*fSeg->Dpz(iz);
c92b1537 418 x1 = x - x0; // calculate distance of cell boundaries from injection center
419 z1 = z - z0;
4fa9d550 420 x2 = x1 + dxi; // Upper
421 x1 -= dxi; // Lower
422 z2 = z1 + dzi; // Upper
423 z1 -= dzi; // Lower
c92b1537 424 s = el* (((AliITSUSimulationPix*)this)->*AliITSUSimulationPix::fSpreadFun)(dtIn);
c92b1537 425 if (s>fSimuParam->GetPixMinElToAdd()) UpdateMapSignal(iz,ix,tID,hID,s);
451f5018 426 } // end for ix, iz
427 //
428}
429
c92b1537 430//______________________________________________________________________
431Double_t AliITSUSimulationPix::SpreadFunDoubleGauss2D(const Double_t *dtIn)
432{
433 // calculate integral of charge in the cell with boundaries at X=dtIn[kCellX1]:dtIn[kCellX2]
434 // and Z=dtIn[kCellZ1]:dtIn[kCellZ2]
435 // The spread function is assumed to be double gaussian in 2D
436 // Parameters should be: mean0,sigma0, mean1,sigma1, relative strenght of 2nd gaussian wrt 1st one
437 //
c92b1537 438 // 1st gaussian
69e0f089 439 double intg1 = GausInt2D(fResponseParam->GetParameter(kG2SigX0), // sigX
69e0f089 440 dtIn[kCellX1]-fResponseParam->GetParameter(kG2MeanX0), // x1-xmean
441 dtIn[kCellX2]-fResponseParam->GetParameter(kG2MeanX0), // x2-xmean
268bb76f 442 fResponseParam->GetParameter(kG2SigZ0), // sigZ
69e0f089 443 dtIn[kCellZ1]-fResponseParam->GetParameter(kG2MeanZ0), // z1-zmean
444 dtIn[kCellZ2]-fResponseParam->GetParameter(kG2MeanZ0)); // z2-zmean
c92b1537 445 // 2nd gaussian
69e0f089 446 double intg2 = GausInt2D(fResponseParam->GetParameter(kG2SigX1), // sigX
69e0f089 447 dtIn[kCellX1]-fResponseParam->GetParameter(kG2MeanX1), // x1-xmean
448 dtIn[kCellX2]-fResponseParam->GetParameter(kG2MeanX1), // x2-xmean
268bb76f 449 fResponseParam->GetParameter(kG2SigZ1), // sigZ
69e0f089 450 dtIn[kCellZ1]-fResponseParam->GetParameter(kG2MeanZ1), // z1-zmean
451 dtIn[kCellZ2]-fResponseParam->GetParameter(kG2MeanZ1)); // z2-zmean
452 double scl = fResponseParam->GetParameter(kG2ScaleG2);
c92b1537 453 return (intg1+intg2*scl)/(1+scl);
454 //
455}
456
457//______________________________________________________________________
458Double_t AliITSUSimulationPix::SpreadFunGauss2D(const Double_t *dtIn)
459{
460 // calculate integral of charge in the cell with boundaries at X=dtIn[kCellX1]:dtIn[kCellX2]
461 // and Z=dtIn[kCellZ1]:dtIn[kCellZ2]
462 // The spread function is assumed to be gaussian in 2D
463 // Parameters should be: mean0,sigma0
69e0f089 464 return GausInt2D(fResponseParam->GetParameter(kG1SigX), // sigX
465 fResponseParam->GetParameter(kG1SigZ), // sigZ
466 dtIn[kCellX1]-fResponseParam->GetParameter(kG1MeanX), // x1-xmean
467 dtIn[kCellX2]-fResponseParam->GetParameter(kG1MeanX), // x2-xmean
468 dtIn[kCellZ1]-fResponseParam->GetParameter(kG1MeanZ), // z1-zmean
469 dtIn[kCellZ2]-fResponseParam->GetParameter(kG1MeanZ)); // z2-zmean
c92b1537 470 //
471}
472
451f5018 473//______________________________________________________________________
474void AliITSUSimulationPix::RemoveDeadPixels()
475{
476 // Removes dead pixels on each module (ladder)
477 // This should be called before going from sdigits to digits (FrompListToDigits)
478
479 AliITSUCalibrationPix* calObj = (AliITSUCalibrationPix*) GetCalibDead();
480 if (!calObj) return;
481 //
482 if (calObj->IsBad()) {ClearMap(); return;} // whole module is masked
483 //
484 // remove single bad pixels one by one
485 int nsingle = calObj->GetNrBadSingle();
486 UInt_t col,row;
487 for (int i=nsingle;i--;) {
488 calObj->GetBadPixelSingle(i,row,col);
489 fSensMap->DeleteItem(col,row);
490 }
491 int nsd = fSensMap->GetEntriesUnsorted();
492 for (int isd=nsd;isd--;) {
493 AliITSUSDigit* sd = (AliITSUSDigit*)fSensMap->AtUnsorted(isd);
494 if (fSensMap->IsDisabled(sd)) continue;
495 fSensMap->GetMapIndex(sd->GetUniqueID(),col,row);
496 int chip = fSeg->GetChipFromChannel(0,col);
497 // if (calObj->IsChipMarkedBad(chip)) fSensMap->Disable(sd); // this will simple mark the hit as bad
498 if (calObj->IsChipMarkedBad(chip)) fSensMap->DeleteItem(sd); // this will suppress hit in the sorted list
499 }
500 //
501}
502
503//______________________________________________________________________
504void AliITSUSimulationPix::AddNoisyPixels()
505{
506 // Adds noisy pixels on each module (ladder)
507 // This should be called before going from sdigits to digits (FrompListToDigits)
508 AliITSUCalibrationPix* calObj = (AliITSUCalibrationPix*) GetCalibNoisy();
509 if (!calObj) return;
510 for (Int_t i=calObj->GetNrBad(); i--;) UpdateMapNoise(calObj->GetBadColAt(i), calObj->GetBadRowAt(i),
c92b1537 511 10*fSimuParam->GetPixThreshold(fModule->GetIndex()));
451f5018 512 //
513}
514
515//______________________________________________________________________
516void AliITSUSimulationPix::FrompListToDigits()
517{
518 // add noise and electronics, perform the zero suppression and add the
519 // digit to the list
520 static AliITSU *aliITS = (AliITSU*)gAlice->GetModule("ITS");
521 UInt_t ix,iz;
522 Double_t sig;
523 const Int_t knmaxtrk=AliITSdigit::GetNTracks();
524 static AliITSUDigitPix dig;
525 // RS: in principle:
526 // 1) for every pixel w/o hit we have to generate a noise and activate the pixel if the noise exceeds the threshold.
527 // 2) for every pixel with hit we should add random noise and check if the total signal exceeds the threshold
528 // With many channels this will be too time consuming, hence I do the following
529 // 1) Precalculate the probability that the nois alone will exceed the threshold.
530 // 2) Chose randomly empty pixels according to this probability and apply the noise above threshold.
531 // 3) For pixels having a hits apply the usual noise and compare with threshold
532 //
533 // RS may use for ordered random sample generation dl.acm.org/ft_gateway.cfm?id=356313&type=pdf
534 //
535 int maxInd = fSensMap->GetMaxIndex();
536 double minProb = 0.1/maxInd;
c92b1537 537 int modId = fModule->GetIndex();
451f5018 538 //
539 int nsd = fSensMap->GetEntries();
540 Int_t prevID=0,curID=0;
541 TArrayI ordSampleInd(100),ordSample(100);
542 //
c92b1537 543 double probNoisy,noiseSig,noiseMean,thresh = fSimuParam->GetPixThreshold(modId);
544 fSimuParam->GetPixNoise(modId, noiseSig, noiseMean);
451f5018 545 probNoisy = AliITSUSimuParam::CalcProbNoiseOverThreshold(noiseMean,noiseSig,thresh); // prob. to have noise above threshold
546 //
547 for (int i=0;i<nsd;i++) {
548 AliITSUSDigit* sd = (AliITSUSDigit*)fSensMap->At(i); // ordered in index
549 if (fSensMap->IsDisabled(sd)) continue;
550 curID = (int)sd->GetUniqueID();
551 //
552 if (probNoisy>minProb) { // generate randomly noisy pixels above the threshold, with ID's between previous hit and current
553 CreateNoisyDigits(prevID,curID,probNoisy, noiseSig, noiseMean);
554 prevID = curID+1;
555 }
556 //
c92b1537 557 if ((sig=sd->GetSumSignal())<=fSimuParam->GetPixThreshold(modId)) continue;
a11ef2e4 558 if (Abs(sig)>2147483647.0) { //RS?
451f5018 559 //PH 2147483647 is the max. integer
560 //PH This apparently is a problem which needs investigation
561 AliWarning(Form("Too big or too small signal value %f",sig));
562 }
563 fSensMap->GetMapIndex(sd->GetUniqueID(),iz,ix);
564 dig.SetCoord1(iz);
565 dig.SetCoord2(ix);
566 dig.SetSignal(1);
567 dig.SetSignalPix((Int_t)sig);
568 int ntr = sd->GetNTracks();
569 for (int j=0;j<ntr;j++) {
570 dig.SetTrack(j,sd->GetTrack(j));
571 dig.SetHit(j,sd->GetHit(j));
572 }
573 for (int j=ntr;j<knmaxtrk;j++) {
574 dig.SetTrack(j,-3);
575 dig.SetHit(j,-1);
576 }
02d6eccc 577 aliITS->AddSimDigit(AliITSUGeomTGeo::kDetTypePix, &dig);
451f5018 578 }
579 // if needed, add noisy pixels with id from last real hit to maxID
580 if (probNoisy>minProb) CreateNoisyDigits(prevID,maxInd,probNoisy, noiseSig, noiseMean);
581 //
582}
583
584//______________________________________________________________________
585Int_t AliITSUSimulationPix::CreateNoisyDigits(Int_t minID,Int_t maxID,double probNoisy, double noise, double base)
586{
587 // create random noisy digits above threshold within id range [minID,maxID[
588 // see FrompListToDigits for details
589 //
590 static AliITSU *aliITS = (AliITSU*)gAlice->GetModule("ITS");
591 UInt_t ix,iz;
592 static AliITSUDigitPix dig;
593 static TArrayI ordSampleInd(100),ordSample(100); //RS!!! static is not thread-safe!!!
594 const Int_t knmaxtrk=AliITSdigit::GetNTracks();
595 //
596 Int_t ncand = 0;
597 int npix = maxID-minID;
598 if (npix<1 || (ncand=gRandom->Poisson(npix*probNoisy))<1) return ncand; // decide how many noisy pixels will be added
599 ncand = GenOrderedSample(npix,ncand,ordSample,ordSampleInd);
600 int* ordV = ordSample.GetArray();
601 int* ordI = ordSampleInd.GetArray();
602 for (int j=0;j<ncand;j++) {
603 fSensMap->GetMapIndex((UInt_t)ordV[ordI[j]],iz,ix); // create noisy digit
604 dig.SetCoord1(iz);
605 dig.SetCoord2(ix);
606 dig.SetSignal(1);
607 dig.SetSignalPix((Int_t)AliITSUSimuParam::GenerateNoiseQFunction(probNoisy,base,noise));
608 for (int k=knmaxtrk;k--;) {
609 dig.SetTrack(k,-3);
610 dig.SetHit(k,-1);
611 }
02d6eccc 612 aliITS->AddSimDigit(AliITSUGeomTGeo::kDetTypePix,&dig);
4fa9d550 613 if (GetDebug(2)) AliInfo(Form("Add noisy pixel %d(%d/%d) Noise=%d",ordV[ordI[j]],iz,ix,dig.GetSignalPix()));
451f5018 614 }
615 return ncand;
616}
617
618//______________________________________________________________________
619void AliITSUSimulationPix::SetCoupling(AliITSUSDigit* old, Int_t ntrack, Int_t idhit)
620{
621 // Take into account the coupling between adiacent pixels.
622 // The parameters probcol and probrow are the probability of the
623 // signal in one pixel shared in the two adjacent pixels along
624 // the column and row direction, respectively.
625 // Note pList is goten via GetMap() and module is not need any more.
626 // Otherwise it is identical to that coded by Tiziano Virgili (BSN).
627 //Begin_Html
628 /*
629 <img src="picts/ITS/barimodel_3.gif">
630 </pre>
631 <br clear=left>
632 <font size=+2 color=red>
633 <a href="mailto:tiziano.virgili@cern.ch"></a>.
634 </font>
635 <pre>
636 */
637 //End_Html
638 // Inputs:
639 // old existing AliITSUSDigit
640 // Int_t ntrack track incex number
641 // Int_t idhit hit index number
642 UInt_t col,row;
643 Double_t pulse1,pulse2;
644 Double_t couplR=0.0,couplC=0.0;
645 Double_t xr=0.;
646 //
647 fSensMap->GetMapIndex(old->GetUniqueID(),col,row);
4fa9d550 648 fSimuParam->GetPixCouplingParam(couplC,couplR);
649 if (GetDebug(2)) AliInfo(Form("(col=%d,row=%d,ntrack=%d,idhit=%d) couplC=%e couplR=%e",
650 col,row,ntrack,idhit,couplC,couplR));
451f5018 651 pulse2 = pulse1 = old->GetSignal();
4fa9d550 652 if (pulse1<fSimuParam->GetPixMinElToAdd()) return; // too small signal
451f5018 653 for (Int_t isign=-1;isign<=1;isign+=2) {
654 //
655 // loop in col direction
656 int j1 = int(col) + isign;
657 xr = gRandom->Rndm();
658 if ( !((j1<0) || (j1>fSeg->Npz()-1) || (xr>couplC)) ) UpdateMapSignal(UInt_t(j1),row,ntrack,idhit,pulse1);
659 //
660 // loop in row direction
661 int j2 = int(row) + isign;
662 xr = gRandom->Rndm();
663 if ( !((j2<0) || (j2>fSeg->Npx()-1) || (xr>couplR)) ) UpdateMapSignal(col,UInt_t(j2),ntrack,idhit,pulse2);
664 }
665 //
666}
667
668//______________________________________________________________________
669void AliITSUSimulationPix::SetCouplingOld(AliITSUSDigit* old, Int_t ntrack,Int_t idhit)
670{
671 // Take into account the coupling between adiacent pixels.
672 // The parameters probcol and probrow are the fractions of the
673 // signal in one pixel shared in the two adjacent pixels along
674 // the column and row direction, respectively.
675 //Begin_Html
676 /*
677 <img src="picts/ITS/barimodel_3.gif">
678 </pre>
679 <br clear=left>
680 <font size=+2 color=red>
681 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
682 </font>
683 <pre>
684 */
685 //End_Html
686 // Inputs:
687 // old existing AliITSUSDigit
688 // ntrack track incex number
689 // idhit hit index number
690 // module module number
691 //
692 UInt_t col,row;
c92b1537 693 Int_t modId = fModule->GetIndex();
451f5018 694 Double_t pulse1,pulse2;
695 Double_t couplR=0.0,couplC=0.0;
696 //
697 fSensMap->GetMapIndex(old->GetUniqueID(),col,row);
4fa9d550 698 fSimuParam->GetPixCouplingParam(couplC,couplR);
699 if (GetDebug(3)) AliInfo(Form("(col=%d,row=%d,ntrack=%d,idhit=%d) couplC=%e couplR=%e",
700 col,row,ntrack,idhit,couplC,couplR));
701 //
702 if (old->GetSignal()<fSimuParam->GetPixMinElToAdd()) return; // too small signal
703 for (Int_t isign=-1;isign<=1;isign+=2) {// loop in col direction
704 pulse2 = pulse1 = old->GetSignal();
705 //
706 int j1 = int(col)+isign;
707 pulse1 *= couplC;
c92b1537 708 if ((j1<0)||(j1>fSeg->Npz()-1)||(pulse1<fSimuParam->GetPixThreshold(modId))) pulse1 = old->GetSignal();
4fa9d550 709 else UpdateMapSignal(UInt_t(j1),row,ntrack,idhit,pulse1);
710
711 // loop in row direction
712 int j2 = int(row) + isign;
713 pulse2 *= couplR;
c92b1537 714 if ((j2<0)||(j2>(fSeg->Npx()-1))||(pulse2<fSimuParam->GetPixThreshold(modId))) pulse2 = old->GetSignal();
4fa9d550 715 else UpdateMapSignal(col,UInt_t(j2),ntrack,idhit,pulse2);
716 } // for isign
451f5018 717}
718
719//______________________________________________________________________
720void AliITSUSimulationPix::GenerateStrobePhase()
721{
722 // Generate randomly the strobe
723 // phase w.r.t to the LHC clock
724 // Done once per event
725 const Double_t kBunchLenght = 25e-9; // LHC clock
c92b1537 726 if (!fStrobe) return;
451f5018 727 fStrobePhase = ((Double_t)gRandom->Integer(fStrobeLenght))*kBunchLenght-
728 (Double_t)fStrobeLenght*kBunchLenght+
729 kBunchLenght/2;
730}
731
c92b1537 732//______________________________________________________________________
733void AliITSUSimulationPix::SetResponseParam(AliParamList* resp)
734{
735 // attach response parameterisation data
736 fResponseParam = resp;
737 switch (fResponseParam->GetID()) {
69e0f089 738 case kSpreadFunDoubleGauss2D: fSpreadFun = &AliITSUSimulationPix::SpreadFunDoubleGauss2D;
c92b1537 739 break;
69e0f089 740 case kSpreadFunGauss2D : fSpreadFun = &AliITSUSimulationPix::SpreadFunGauss2D;
c92b1537 741 break;
742 default: AliFatal(Form("Did not find requested spread function id=%d",fResponseParam->GetID()));
743 }
744 //
745}