]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSsimulationSPD.cxx
Additional protection to avoid rare problem related to the simulation of
[u/mrichter/AliRoot.git] / ITS / AliITSsimulationSPD.cxx
CommitLineData
c7a4dac0 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
5bfe44ce 16/*
17$Id$
18*/
f8d9a5b8 19
5bfe44ce 20#include <Riostream.h>
b0f5e3fc 21#include <TH1.h>
5bfe44ce 22#include <TMath.h>
23#include <TParticle.h>
24#include <TRandom.h>
9f033001 25#include <TString.h>
e8189707 26#include "AliITS.h"
5bfe44ce 27#include "AliITSMapA2.h"
e869281d 28#include "AliITSdigitSPD.h"
5bfe44ce 29#include "AliITSgeom.h"
30#include "AliITShit.h"
9f033001 31#include "AliITSmodule.h"
c7a4dac0 32#include "AliITSpList.h"
5bfe44ce 33#include "AliITSCalibrationSPD.h"
34#include "AliITSsegmentationSPD.h"
b0f5e3fc 35#include "AliITSsimulationSPD.h"
f77f13c8 36#include "AliLog.h"
5bfe44ce 37#include "AliRun.h"
9f033001 38
bb6b39bf 39//#define DEBUG
e8189707 40
b0f5e3fc 41ClassImp(AliITSsimulationSPD)
42////////////////////////////////////////////////////////////////////////
5bfe44ce 43// Version: 1
44// Modified by Bjorn S. Nilsen, G.E. Bruno, H. Tydesjo
45// March-April 2006
b0f5e3fc 46//
5bfe44ce 47// Version: 0
48// Written by Boris Batyunya
49// December 20 1999
21b825a4 50//
5bfe44ce 51//
52// AliITSsimulationSPD is to do the simulation of SPDs.
53//
54////////////////////////////////////////////////////////////////////////
55
c7a4dac0 56//______________________________________________________________________
5bfe44ce 57AliITSsimulationSPD::AliITSsimulationSPD():
58AliITSsimulation(),
59fHis(0),
60fSPDname(),
61fCoupling(){
62 // Default constructor.
63 // Inputs:
aacedc3e 64 // none.
65 // Outputs:
66 // none.
67 // Return:
68 // A default constructed AliITSsimulationSPD class.
5bfe44ce 69
70 AliDebug(1,Form("Calling default constructor"));
71// Init();
b0f5e3fc 72}
c7a4dac0 73//______________________________________________________________________
8ba39da9 74AliITSsimulationSPD::AliITSsimulationSPD(AliITSDetTypeSim *dettyp):
75AliITSsimulation(dettyp),
5bfe44ce 76fHis(0),
77fSPDname(),
78fCoupling(){
79 // standard constructor
80 // Inputs:
81 // AliITSsegmentation *seg A pointer to the segmentation class
82 // to be used for this simulation
83 // AliITSCalibration *resp A pointer to the responce class to
84 // be used for this simulation
aacedc3e 85 // Outputs:
86 // none.
87 // Return:
5bfe44ce 88 // A default constructed AliITSsimulationSPD class.
aacedc3e 89
5bfe44ce 90 AliDebug(1,Form("Calling standard constructor "));
91// AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
92// res->SetTemperature(0.0);
93// res->SetDistanceOverVoltage(0.0);
aacedc3e 94 Init();
95}
96//______________________________________________________________________
5bfe44ce 97void AliITSsimulationSPD::Init(){
98 // Initilization
aacedc3e 99 // Inputs:
100 // none.
101 // Outputs:
102 // none.
103 // Return:
104 // none.
5bfe44ce 105 const Double_t kmictocm = 1.0e-4; // convert microns to cm.
c7a4dac0 106
5bfe44ce 107 SetModuleNumber(0);
108 SetEventNumber(0);
109 SetMap(new AliITSpList(GetNPixelsZ(),GetNPixelsX()));
110 AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
8ba39da9 111 AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
5bfe44ce 112 Double_t bias = res->GetBiasVoltage();
113// cout << "Bias Voltage --> " << bias << endl; // dom
114 res->SetDistanceOverVoltage(kmictocm*seg->Dy(),bias);
115// set kind of coupling ("old" or "new")
116 char opt[20];
117 res->GetCouplingOption(opt);
118 char *old = strstr(opt,"old");
119 if (old) {
120 fCoupling=2;
121 } else {
122 fCoupling=1;
123 } // end if
124
125 // Get the calibration objects for each module(ladder)
126 GetCalibrationObjects(0); //RunNr 0 hard coded for now
c7a4dac0 127
c7a4dac0 128}
129//______________________________________________________________________
5bfe44ce 130AliITSsimulationSPD::~AliITSsimulationSPD(){
c7a4dac0 131 // destructor
5bfe44ce 132 // Inputs:
aacedc3e 133 // none.
134 // Outputs:
135 // none.
136 // Return:
5bfe44ce 137 // none.
b0f5e3fc 138
c7a4dac0 139 if (fHis) {
aacedc3e 140 fHis->Delete();
141 delete fHis;
5bfe44ce 142 } // end if fHis
b0f5e3fc 143}
c7a4dac0 144//______________________________________________________________________
5bfe44ce 145AliITSsimulationSPD::AliITSsimulationSPD(const
146 AliITSsimulationSPD
147 &s) : AliITSsimulation(s){
148 // Copy Constructor
149 // Inputs:
150 // AliITSsimulationSPD &s The original class for which
151 // this class is a copy of
aacedc3e 152 // Outputs:
153 // none.
154 // Return:
c7a4dac0 155
5bfe44ce 156 *this = s;
c7a4dac0 157 return;
b0f5e3fc 158}
c7a4dac0 159//______________________________________________________________________
5bfe44ce 160AliITSsimulationSPD& AliITSsimulationSPD::operator=(const
161 AliITSsimulationSPD &s){
c7a4dac0 162 // Assignment operator
5bfe44ce 163 // Inputs:
164 // AliITSsimulationSPD &s The original class for which
165 // this class is a copy of
aacedc3e 166 // Outputs:
167 // none.
168 // Return:
c7a4dac0 169
5bfe44ce 170 if(&s == this) return *this;
171 this->fHis = s.fHis;
172 fCoupling = s.fCoupling;
173 fSPDname = s.fSPDname;
c7a4dac0 174 return *this;
5bfe44ce 175}
d2f55a22 176//______________________________________________________________________
5bfe44ce 177AliITSsimulation& AliITSsimulationSPD::operator=(const
178 AliITSsimulation &s){
d2f55a22 179 // Assignment operator
5bfe44ce 180 // Inputs:
181 // AliITSsimulationSPD &s The original class for which
182 // this class is a copy of
d2f55a22 183 // Outputs:
184 // none.
185 // Return:
d2f55a22 186
5bfe44ce 187 if(&s == this) return *this;
d2f55a22 188 Error("AliITSsimulationSPD","Not allowed to make a = with "
5bfe44ce 189 "AliITSsimulationSPD","Using default creater instead");
d2f55a22 190
191 return *this;
5bfe44ce 192}
d2f55a22 193
3a97c582 194//______________________________________________________________________
5bfe44ce 195void AliITSsimulationSPD::GetCalibrationObjects(Int_t RunNr) {
196 AliCDBManager* man = AliCDBManager::Instance();
197 if(!man->IsDefaultStorageSet()) {
198 man->SetDefaultStorage("local://$ALICE_ROOT");
199 }
200 AliCDBEntry *entrySPD = man->Get("ITS/Calib/CalibSPD", RunNr);
201 if(!entrySPD){
202 AliWarning("Cannot find SPD calibration entry!");
203 return;
204 }
205 TObjArray *respSPD = (TObjArray *)entrySPD->GetObject();
206 if ((! respSPD)) {
207 AliWarning("Cannot get data from SPD database entry!");
208 return;
209 }
210 for (Int_t mod=0; mod<240; mod++) {
211 calObj[mod] = (AliITSCalibrationSPD*) respSPD->At(mod);
212 }
213}
214
215//______________________________________________________________________
216void AliITSsimulationSPD::InitSimulationModule(Int_t module, Int_t event){
217 // This function creates maps to build the list of tracks for each
218 // summable digit. Inputs defined by base class.
219 // Inputs:
220 // Int_t module // Module number to be simulated
221 // Int_t event // Event number to be simulated
222 // Outputs:
223 // none
224 // Returns:
225 // none
226
227 AliDebug(1,Form("(module=%d,event=%d)",module,event));
228 SetModuleNumber(module);
229 SetEventNumber(event);
230 ClearMap();
231}
232//_____________________________________________________________________
233void AliITSsimulationSPD::SDigitiseModule(AliITSmodule *mod,Int_t,
234 Int_t event){
235 // This function begins the work of creating S-Digits. Inputs defined
236 // by base class.
237 // Inputs:
238 // AliITSmodule *mod // module
239 // Int_t // not used
240 // Int_t event // Event number
241 // Outputs:
242 // none
243 // Return:
244 // test // test returns kTRUE if the module contained hits
245 // // test returns kFALSE if it did not contain hits
246
247 AliDebug(1,Form("(mod=%p, ,event=%d)",mod,event));
248 if(!(mod->GetNhits())){
249 AliDebug(1,Form("In event %d module %d there are %d hits returning.",
250 event, mod->GetIndex(),mod->GetNhits()));
251 return;// if module has no hits don't create Sdigits
252 } // end if
253 SetModuleNumber(mod->GetIndex());
254 SetEventNumber(event);
255 // HitToSDigit(mod);
256 HitToSDigitFast(mod);
257 WriteSDigits();
258 ClearMap();
259}
260//______________________________________________________________________
261void AliITSsimulationSPD::WriteSDigits(){
262 // This function adds each S-Digit to pList
263 // Inputs:
3a97c582 264 // none.
5bfe44ce 265 // Outputs:
266 // none.
267 // Return:
268 // none
269 Int_t ix, nix, iz, niz;
270 static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
271
272 AliDebug(1,Form("Writing SDigits for module %d",GetModuleNumber()));
273 GetMap()->GetMaxMapIndex(niz, nix);
274 for(iz=0; iz<niz; iz++)for(ix=0; ix<nix; ix++){
275 if(GetMap()->GetSignalOnly(iz,ix)>0.0){
276 aliITS->AddSumDigit(*(GetMap()->GetpListItem(iz,ix)));
277 if(AliDebugLevel()>0) {
278 AliDebug(1,Form("%d, %d",iz,ix));
279 cout << *(GetMap()->GetpListItem(iz,ix)) << endl;
280 } // end if GetDebug
281 } // end if GetMap()->GetSignalOnly(iz,ix)>0.0
282 } // end for iz,ix
283 return;
3a97c582 284}
285//______________________________________________________________________
286void AliITSsimulationSPD::FinishSDigitiseModule(){
5bfe44ce 287 // This function calls SDigitsToDigits which creates Digits from SDigits
288 // Inputs:
289 // none
290 // Outputs:
291 // none
292 // Return
293 // none
294
295 AliDebug(1,"()");
296 pListToDigits(); // Charge To Signal both adds noise and
297 ClearMap();
298 return;
299}
300//______________________________________________________________________
301void AliITSsimulationSPD::DigitiseModule(AliITSmodule *mod,Int_t,
302 Int_t){
303 // This function creates Digits straight from the hits and then adds
304 // electronic noise to the digits before adding them to pList
305 // Each of the input variables is passed along to HitToSDigit
306 // Inputs:
307 // AliITSmodule *mod module
308 // Int_t Dummy.
309 // Int_t Dummy
310 // Outputs:
311 // none.
312 // Return:
313 // none.
3a97c582 314
5bfe44ce 315 AliDebug(1,Form("(mod=%p,,)",mod));
316 // HitToSDigit(mod);
317 HitToSDigitFast(mod);
318 RemoveDeadPixels(mod);
319 pListToDigits();
320 ClearMap();
c7a4dac0 321}
322//______________________________________________________________________
5bfe44ce 323void AliITSsimulationSPD::HitToSDigit(AliITSmodule *mod){
324 // Does the charge distributions using Gaussian diffusion charge charing.
aacedc3e 325 // Inputs:
5bfe44ce 326 // AliITSmodule *mod Pointer to this module
327 // Output:
328 // none.
aacedc3e 329 // Return:
5bfe44ce 330 // none.
331 const Double_t kmictocm = 1.0e-4; // convert microns to cm.
332 TObjArray *hits = mod->GetHits();
333 Int_t nhits = hits->GetEntriesFast();
334 Int_t h,ix,iz,i;
335 Int_t idtrack;
336 Double_t x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0,de=0.0;
337 Double_t x,y,z,t,tp,st,dt=0.2,el,sig,sigx,sigz,fda;
338 AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
339 AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
340 Double_t thick = 0.5*kmictocm*seg->Dy(); // Half Thickness
341 res->GetSigmaDiffusionAsymmetry(fda);
342
343 AliDebug(1,Form("(mod=%p) fCoupling=%d",mod,fCoupling));
344 if(nhits<=0) return;
345 for(h=0;h<nhits;h++){
346 if(AliDebugLevel()>0) {
347 AliDebug(1,Form("Hits, %d", h));
348 cout << *(mod->GetHit(h)) << endl;
349 } // end if GetDebug
350 if(!mod->LineSegmentL(h,x0,x1,y0,y1,z0,z1,de,idtrack)) continue;
351 st = TMath::Sqrt(x1*x1+y1*y1+z1*z1);
352 if(st>0.0){
353 st = (Double_t)((Int_t)(st/kmictocm)); // number of microns
354 if(st<=1.0) st = 1.0;
355 dt = 1.0/st;
356 for(t=0.0;t<1.0;t+=dt){ // Integrate over t
357 tp = t+0.5*dt;
358 x = x0+x1*tp;
359 y = y0+y1*tp;
360 z = z0+z1*tp;
361 if(!(seg->LocalToDet(x,z,ix,iz))) continue; // outside
362 el = res->GeVToCharge((Double_t)(dt*de));
363 if(GetDebug(1)){
364 if(el<=0.0) cout<<"el="<<el<<" dt="<<dt
365 <<" de="<<de<<endl;
366 } // end if GetDebug
367 sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
368 // SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
369 sigx=sig;
370 sigz=sig*fda;
371 SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
372 cout << "sigx, sigz, y "<< sigx << " " << sigz<< " " << TMath::Abs(thick + y) << endl;// ciccio
373 } // end for t
374 } else { // st == 0.0 deposit it at this point
375 x = x0;
376 y = y0;
377 z = z0;
378 if(!(seg->LocalToDet(x,z,ix,iz))) continue; // outside
379 el = res->GeVToCharge((Double_t)de);
380 sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
381 // SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
382 sigx=sig;
383 sigz=sig*fda;
384 SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
385 } // end if st>0.0
386 // Coupling
387 switch (fCoupling) {
388 default:
389 break;
390 case 1: //case 3:
391 // x is column and z is row (see AliITSsegmentationSPD::GetPadIxz)
392 for(i=0;i<GetMap()->GetEntries();i++)
393 if(GetMap()->GetpListItem(i)==0) continue;
394 else{
395 GetMap()->GetMapIndex(
396 GetMap()->GetpListItem(i)->GetIndex(),iz,ix);
397 SetCoupling(iz,ix,idtrack,h);
398 } // end for i
399 break;
400 case 2: // case 4:
401 // x is column and z is row (see AliITSsegmentationSPD::GetPadIxz)
402 for(i=0;i<GetMap()->GetEntries();i++)
403 if(GetMap()->GetpListItem(i)==0) continue;
404 else{
405 GetMap()->GetMapIndex(
406 GetMap()->GetpListItem(i)->GetIndex(),iz,ix);
407 SetCouplingOld(iz,ix,idtrack,h);
408 } // end for i
409 break;
410 } // end switch
411 } // Loop over all hits h
412 if(GetDebug(2))Info("HitToSDigit","Finished fCoupling=%d",fCoupling);
c7a4dac0 413}
414//______________________________________________________________________
5bfe44ce 415void AliITSsimulationSPD::HitToSDigitFast(AliITSmodule *mod){
416 // Does the charge distributions using Gaussian diffusion charge charing. // Inputs:
417 // AliITSmodule *mod Pointer to this module
418 // Output:
419 // none.
aacedc3e 420 // Return:
5bfe44ce 421 // none.
422 const Double_t kmictocm = 1.0e-4; // convert microns to cm.
423 const Int_t n10=10;
424 const Double_t ti[n10]={7.443716945e-3,2.166976971e-1,3.397047841e-1,
425 4.325316833e-1,4.869532643e-1,5.130467358e-1,
426 5.674683167e-1,6.602952159e-1,7.833023029e-1,
427 9.255628306e-1};
428 const Double_t wi[n10]={1.477621124e-1,1.346333597e-1,1.095431813e-1,
429 7.472567455e-2,3.333567215e-2,3.333567215e-2,
430 7.472567455e-2,1.095431813e-1,1.346333597e-1,
431 1.477621124e-1};
432 TObjArray *hits = mod->GetHits();
433 Int_t nhits = hits->GetEntriesFast();
434 Int_t h,ix,iz,i;
435 Int_t idtrack;
436 Double_t x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0,de=0.0;
437 Double_t x,y,z,t,st,el,sig,sigx,sigz,fda;
438 AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
439 AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
440 Double_t thick = 0.5*kmictocm*seg->Dy(); // Half thickness
441 res->GetSigmaDiffusionAsymmetry(fda);
442// cout << "Half Thickness " << thick << endl; // dom
443// cout << "Diffusion asymm " << fda << endl; // dom
444
445 AliDebug(1,Form("(mod=%p) fCoupling=%d",mod,fCoupling));
446 if(nhits<=0) return;
447 for(h=0;h<nhits;h++){
448 if(AliDebugLevel()>0) {
449 AliDebug(1,Form("Hits, %d", h));
450 cout << *(mod->GetHit(h)) << endl;
451 } // end if GetDebug
452 if(!mod->LineSegmentL(h,x0,x1,y0,y1,z0,z1,de,idtrack)) continue;
453 st = TMath::Sqrt(x1*x1+y1*y1+z1*z1);
454 if(st>0.0) for(i=0;i<n10;i++){ // Integrate over t
455 t = ti[i];
456 x = x0+x1*t;
457 y = y0+y1*t;
458 z = z0+z1*t;
459 if(!(seg->LocalToDet(x,z,ix,iz))) continue; // outside
460 // el = res->GeVToCharge((Double_t)(dt*de));
461 // el = 1./n10*res->GeVToCharge((Double_t)de);
462 el = wi[i]*res->GeVToCharge((Double_t)de);
463 if(GetDebug(1)){
464 if(el<=0.0) cout<<"el="<<el<<" wi["<<i<<"]="<<wi[i]
465 <<" de="<<de<<endl;
466 } // end if GetDebug
467 sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
468 sigx=sig;
469 sigz=sig*fda;
470 //SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
471 SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
472 // cout << "sigx sigz " << sigx << " " << sigz << endl; // dom
473 } // end for i // End Integrate over t
474 else { // st == 0.0 deposit it at this point
475 x = x0;
476 y = y0;
477 z = z0;
478 if(!(seg->LocalToDet(x,z,ix,iz))) continue; // outside
479 el = res->GeVToCharge((Double_t)de);
480 sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
481 //SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
482 sigx=sig;
483 sigz=sig*fda;
484 SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
485 } // end if st>0.0
486 // Coupling
487 switch (fCoupling) {
488 default:
489 break;
490 case 1: // case 3:
491 // x is column and z is row (see AliITSsegmentationSPD::GetPadIxz)
492 for(i=0;i<GetMap()->GetEntries();i++)
493 if(GetMap()->GetpListItem(i)==0) continue;
494 else{
495 GetMap()->GetMapIndex(
496 GetMap()->GetpListItem(i)->GetIndex(),iz,ix);
497 SetCoupling(iz,ix,idtrack,h);
498 } // end for i
499 break;
500 case 2: // case 4:
501 // x is column and z is row (see AliITSsegmentationSPD::GetPadIxz)
502 for(i=0;i<GetMap()->GetEntries();i++)
503 if(GetMap()->GetpListItem(i)==0) continue;
504 else{
505 GetMap()->GetMapIndex(
506 GetMap()->GetpListItem(i)->GetIndex(),iz,ix); SetCouplingOld(iz,ix,idtrack,h);
507 } // end for i
508 break;
509 } // end switch
510 } // Loop over all hits h
511 if(GetDebug(2))Info("HitToSDigit","Finished fCoupling=%d",fCoupling);
21b825a4 512}
c7a4dac0 513//______________________________________________________________________
5bfe44ce 514void AliITSsimulationSPD::SpreadCharge(Double_t x0,Double_t z0,
515 Int_t ix0,Int_t iz0,
516 Double_t el,Double_t sig,Int_t t,
517 Int_t hi){
518 // Spreads the charge over neighboring cells. Assume charge is distributed
519 // as charge(x,z) = (el/2*pi*sig*sig)*exp(-arg)
520 // arg=((x-x0)*(x-x0)/2*sig*sig)+((z-z0*z-z0)/2*sig*sig)
521 // Defined this way, the integral over all x and z is el.
aacedc3e 522 // Inputs:
5bfe44ce 523 // Double_t x0 x position of point where charge is liberated
524 // Double_t y0 y position of point where charge is liberated
525 // Double_t z0 z position of point where charge is liberated
526 // Int_t ix0 row of cell corresponding to point x0
527 // Int_t iz0 columb of cell corresponding to point z0
528 // Double_t el number of electrons liberated in this step
529 // Double_t sig Sigma difusion for this step (y0 dependent)
530 // Int_t t track number
531 // Int_t ti hit track index number
532 // Int_t hi hit "hit" index number
aacedc3e 533 // Outputs:
5bfe44ce 534 // none.
aacedc3e 535 // Return:
5bfe44ce 536 // none.
537 const Int_t knx = 3,knz = 2;
538 const Double_t kRoot2 = 1.414213562; // Sqrt(2).
539 const Double_t kmictocm = 1.0e-4; // convert microns to cm.
540 Int_t ix,iz,ixs,ixe,izs,ize;
541 Float_t x,z;
542 Double_t x1,x2,z1,z2,s,sp;
543 AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
21b825a4 544
3a97c582 545
5bfe44ce 546 if(GetDebug(4)) Info("SpreadCharge","(x0=%e,z0=%e,ix0=%d,iz0=%d,el=%e,"
547 "sig=%e,t=%d,i=%d)",x0,z0,ix0,iz0,el,sig,t,hi);
548 if(sig<=0.0) { // if sig<=0 No diffusion to simulate.
549 GetMap()->AddSignal(iz0,ix0,t,hi,GetModuleNumber(),el);
550 if(GetDebug(2)){
551 cout << "sig<=0.0=" << sig << endl;
552 } // end if GetDebug
553 return;
554 } // end if
555 sp = 1.0/(sig*kRoot2);
556 if(GetDebug(2)){
557 cout << "sig=" << sig << " sp=" << sp << endl;
558 } // end if GetDebug
559 ixs = TMath::Max(-knx+ix0,0);
560 ixe = TMath::Min(knx+ix0,seg->Npx()-1);
561 izs = TMath::Max(-knz+iz0,0);
562 ize = TMath::Min(knz+iz0,seg->Npz()-1);
563 for(ix=ixs;ix<=ixe;ix++) for(iz=izs;iz<=ize;iz++){
564 seg->DetToLocal(ix,iz,x,z); // pixel center
565 x1 = x;
566 z1 = z;
567 x2 = x1 + 0.5*kmictocm*seg->Dpx(ix); // Upper
568 x1 -= 0.5*kmictocm*seg->Dpx(ix); // Lower
569 z2 = z1 + 0.5*kmictocm*seg->Dpz(iz); // Upper
570 z1 -= 0.5*kmictocm*seg->Dpz(iz); // Lower
571 x1 -= x0; // Distance from where track traveled
572 x2 -= x0; // Distance from where track traveled
573 z1 -= z0; // Distance from where track traveled
574 z2 -= z0; // Distance from where track traveled
575 s = 0.25; // Correction based on definision of Erfc
576 s *= TMath::Erfc(sp*x1) - TMath::Erfc(sp*x2);
577 if(GetDebug(3)){
578 cout <<"el="<<el<<" ix0="<<ix0<<" ix="<<ix<<" x0="<<x<<
579 " iz0="<<iz0<<" iz="<<iz<<" z0="<<z<<
580 " sp*x1="<<sp*x1<<" sp*x2="<<sp*x2<<" s="<<s;
581 } // end if GetDebug
582 s *= TMath::Erfc(sp*z1) - TMath::Erfc(sp*z2);
583 if(GetDebug(3)){
584 cout<<" sp*z1="<<sp*z1<<" sp*z2="<<sp*z2<<" s="<<s<< endl;
585 } // end if GetDebug
586 GetMap()->AddSignal(iz,ix,t,hi,GetModuleNumber(),s*el);
587 } // end for ix, iz
c7a4dac0 588}
589//______________________________________________________________________
5bfe44ce 590void AliITSsimulationSPD::SpreadChargeAsym(Double_t x0,Double_t z0,
591 Int_t ix0,Int_t iz0,
592 Double_t el,Double_t sigx,Double_t sigz,
593 Int_t t,Int_t hi){
594 // Spreads the charge over neighboring cells. Assume charge is distributed
595 // as charge(x,z) = (el/2*pi*sigx*sigz)*exp(-arg)
596 // arg=((x-x0)*(x-x0)/2*sigx*sigx)+((z-z0*z-z0)/2*sigz*sigz)
597 // Defined this way, the integral over all x and z is el.
aacedc3e 598 // Inputs:
5bfe44ce 599 // Double_t x0 x position of point where charge is liberated
600 // Double_t y0 y position of point where charge is liberated
601 // Double_t z0 z position of point where charge is liberated
602 // Int_t ix0 row of cell corresponding to point x0
603 // Int_t iz0 columb of cell corresponding to point z0
604 // Double_t el number of electrons liberated in this step
605 // Double_t sigx Sigma difusion along x for this step (y0 dependent)
606 // Double_t sigz Sigma difusion along z for this step (y0 dependent)
607 // Int_t t track number
608 // Int_t ti hit track index number
609 // Int_t hi hit "hit" index number
aacedc3e 610 // Outputs:
5bfe44ce 611 // none.
aacedc3e 612 // Return:
5bfe44ce 613 // none.
614 const Int_t knx = 3,knz = 2;
615 const Double_t kRoot2 = 1.414213562; // Sqrt(2).
616 const Double_t kmictocm = 1.0e-4; // convert microns to cm.
617 Int_t ix,iz,ixs,ixe,izs,ize;
618 Float_t x,z;
619 Double_t x1,x2,z1,z2,s,spx,spz;
620 AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
621
c7a4dac0 622
5bfe44ce 623 if(GetDebug(4)) Info("SpreadCharge","(x0=%e,z0=%e,ix0=%d,iz0=%d,el=%e,"
624 "sig=%e,t=%d,i=%d)",x0,z0,ix0,iz0,el,sigx,sigz,t,hi);
625 if(sigx<=0.0 || sigz<=0.0) { // if sig<=0 No diffusion to simulate.
626 GetMap()->AddSignal(iz0,ix0,t,hi,GetModuleNumber(),el);
627 if(GetDebug(2)){
628 cout << "sigx<=0.0=" << sigx << endl;
629 cout << "sigz<=0.0=" << sigz << endl;
630 } // end if GetDebug
631 return;
632 } // end if
633 spx = 1.0/(sigx*kRoot2); spz = 1.0/(sigz*kRoot2);
634 if(GetDebug(2)){
635 cout << "sigx=" << sigx << " spx=" << spx << endl;
636 cout << "sigz=" << sigz << " spz=" << spz << endl;
637 } // end if GetDebug
638 ixs = TMath::Max(-knx+ix0,0);
639 ixe = TMath::Min(knx+ix0,seg->Npx()-1);
640 izs = TMath::Max(-knz+iz0,0);
641 ize = TMath::Min(knz+iz0,seg->Npz()-1);
642 for(ix=ixs;ix<=ixe;ix++) for(iz=izs;iz<=ize;iz++){
643 seg->DetToLocal(ix,iz,x,z); // pixel center
644 x1 = x;
645 z1 = z;
646 x2 = x1 + 0.5*kmictocm*seg->Dpx(ix); // Upper
647 x1 -= 0.5*kmictocm*seg->Dpx(ix); // Lower
648 z2 = z1 + 0.5*kmictocm*seg->Dpz(iz); // Upper
649 z1 -= 0.5*kmictocm*seg->Dpz(iz); // Lower
650 x1 -= x0; // Distance from where track traveled
651 x2 -= x0; // Distance from where track traveled
652 z1 -= z0; // Distance from where track traveled
653 z2 -= z0; // Distance from where track traveled
654 s = 0.25; // Correction based on definision of Erfc
655 s *= TMath::Erfc(spx*x1) - TMath::Erfc(spx*x2);
656 if(GetDebug(3)){
657 cout <<"el="<<el<<" ix0="<<ix0<<" ix="<<ix<<" x0="<<x<<
658 " iz0="<<iz0<<" iz="<<iz<<" z0="<<z<<
659 " spx*x1="<<spx*x1<<" spx*x2="<<spx*x2<<" s="<<s;
660 } // end if GetDebug
661 s *= TMath::Erfc(spz*z1) - TMath::Erfc(spz*z2);
662 if(GetDebug(3)){
663 cout<<" spz*z1="<<spz*z1<<" spz*z2="<<spz*z2<<" s="<<s<< endl;
664 } // end if GetDebug
665 GetMap()->AddSignal(iz,ix,t,hi,GetModuleNumber(),s*el);
666 } // end for ix, iz
c7a4dac0 667}
668//______________________________________________________________________
5bfe44ce 669void AliITSsimulationSPD::RemoveDeadPixels(AliITSmodule *mod){
670 Int_t module_nr = mod->GetIndex();
671 Int_t nr_dead = calObj[module_nr]->GetNrDead();
672 for (Int_t i=0; i<nr_dead; i++) {
673 GetMap()->DeleteHit(calObj[module_nr]->GetDeadColAt(i),calObj[module_nr]->GetDeadRowAt(i));
674 }
675}
676//______________________________________________________________________
677void AliITSsimulationSPD::pListToDigits(){
678 // add noise and electronics, perform the zero suppression and add the
679 // digit to the list
aacedc3e 680 // Inputs:
5bfe44ce 681 // none.
aacedc3e 682 // Outputs:
5bfe44ce 683 // none.
aacedc3e 684 // Return:
5bfe44ce 685 // none.
686 static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
687 Int_t j,ix,iz;
688 Double_t electronics;
689 Double_t sig;
690 const Int_t nmaxtrk=AliITSdigitSPD::GetNTracks();
691 static AliITSdigitSPD dig;
692 AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
693 if(GetDebug(1)) Info("pListToDigits","()");
694 for(iz=0; iz<GetNPixelsZ(); iz++) for(ix=0; ix<GetNPixelsX(); ix++){
695// NEW (for the moment plugged by hand, in the future possibly read from Data Base)
696// here parametrize the efficiency of the pixel along the row for the test columns (1,9,17,25)
697// if(iz==1 || iz == 9 || iz == 17 || iz == 25) {
698// Double_t eff,p1=0.,p2=0.;
699// Double_t x=ix;
700// switch (iz) {
701// case 1: p1=0.63460;p2=0.42438E-01;break;
702// case 9: p1=0.41090;p2=0.75914E-01;break;
703// case 17: p1=0.31883;p2=0.91502E-01;break;
704// case 25: p1=0.48828;p2=0.57975E-01;break;
705// } // end switch
706// eff=1.-p1*exp(-p2*x);
707// if (gRandom->Rndm() >= eff) continue;
708// } // end if
709 // END parametrize the efficiency
710 //
711 electronics = res->ApplyBaselineAndNoise();
712 UpdateMapNoise(ix,iz,electronics);
713 //
714 // Apply Threshold and write Digits.
715 sig = GetMap()->GetSignalOnly(iz,ix);
716 FillHistograms(ix,iz,sig+electronics);
717 if(GetDebug(3)){
718 cout<<sig<<"+"<<electronics<<">threshold("<<ix<<","<<iz
719 <<")="<<GetThreshold() <<endl;
720 } // end if GetDebug
721 if (sig+electronics <= GetThreshold()) continue;
722 dig.SetCoord1(iz);
723 dig.SetCoord2(ix);
724 dig.SetSignal(1);
7143d86b 725 Double_t aSignal = GetMap()->GetSignal(iz,ix);
726 if (TMath::Abs(aSignal)>2147483647.0) {
727 //PH 2147483647 is the max. integer
728 //PH This apparently is a problem which needs investigation
729 AliWarning(Form("Too big or too small signal value %f",aSignal));
730 aSignal = TMath::Sign((Double_t)2147483647,aSignal);
731 }
732 dig.SetSignalSPD((Int_t)aSignal);
5bfe44ce 733 for(j=0;j<nmaxtrk;j++){
734 if (j<GetMap()->GetNEntries()) {
735 dig.SetTrack(j,GetMap()->GetTrack(iz,ix,j));
736 dig.SetHit(j,GetMap()->GetHit(iz,ix,j));
737 }else { // Default values
738 dig.SetTrack(j,-3);
739 dig.SetHit(j,-1);
740 } // end if GetMap()
741 } // end for j
742 if(GetDebug(3)){
743 cout<<iz<<","<<ix<<","<<*(GetMap()->GetpListItem(iz,ix))<<endl;
744 } // end if GetDebug
745 aliITS->AddSimDigit(0,&dig);
746 } // for ix/iz
c7a4dac0 747}
748//______________________________________________________________________
5bfe44ce 749void AliITSsimulationSPD::CreateHistograms(){
750 // create 1D histograms for tests
aacedc3e 751 // Inputs:
5bfe44ce 752 // none.
aacedc3e 753 // Outputs:
5bfe44ce 754 // none.
aacedc3e 755 // Return:
5bfe44ce 756 // none.
757
758 if(GetDebug(1)) Info("CreateHistograms","create histograms");
759
760 fHis = new TObjArray(GetNPixelsZ());
761 TString fSPDname("spd_");
762 for(Int_t i=0;i<GetNPixelsZ();i++) {
763 Char_t pixelz[4];
764 sprintf(pixelz,"%d",i);
765 fSPDname.Append(pixelz);
766 fHis->AddAt(new TH1F(fSPDname.Data(),"SPD maps",
767 GetNPixelsX(),0.,(Double_t)GetNPixelsX()),i);
768 } // end for i
c7a4dac0 769}
770//______________________________________________________________________
5bfe44ce 771void AliITSsimulationSPD::FillHistograms(Int_t ix,Int_t iz,Double_t v){
772 // Fill the histogram
aacedc3e 773 // Inputs:
5bfe44ce 774 // none.
aacedc3e 775 // Outputs:
5bfe44ce 776 // none.
aacedc3e 777 // Return:
5bfe44ce 778 // none.
779
780 if(!GetHistArray()) return; // Only fill if setup.
781 if(GetDebug(2)) Info("FillHistograms","fill histograms");
782 GetHistogram(iz)->Fill(ix,v);
c7a4dac0 783}
784//______________________________________________________________________
5bfe44ce 785void AliITSsimulationSPD::ResetHistograms(){
786 // Reset histograms for this detector
aacedc3e 787 // Inputs:
5bfe44ce 788 // none.
aacedc3e 789 // Outputs:
5bfe44ce 790 // none.
aacedc3e 791 // Return:
5bfe44ce 792 // none.
793
794 if(!GetHistArray()) return; // Only fill if setup.
795 if(GetDebug(2)) Info("FillHistograms","fill histograms");
796 for ( int i=0;i<GetNPixelsZ();i++ ) {
797 if (fHis->At(i)) ((TH1F*)fHis->At(i))->Reset();
798 } // end for i
21b825a4 799}
5bfe44ce 800
c7a4dac0 801//______________________________________________________________________
21b825a4 802void AliITSsimulationSPD::SetCoupling(Int_t row, Int_t col, Int_t ntrack,
5bfe44ce 803 Int_t idhit) {
c7a4dac0 804 // Take into account the coupling between adiacent pixels.
f8d9a5b8 805 // The parameters probcol and probrow are the probability of the
806 // signal in one pixel shared in the two adjacent pixels along
807 // the column and row direction, respectively.
5bfe44ce 808 // Note pList is goten via GetMap() and module is not need any more.
809 // Otherwise it is identical to that coded by Tiziano Virgili (BSN).
f8d9a5b8 810 //Begin_Html
811 /*
812 <img src="picts/ITS/barimodel_3.gif">
813 </pre>
814 <br clear=left>
815 <font size=+2 color=red>
816 <a href="mailto:tiziano.virgili@cern.ch"></a>.
817 </font>
818 <pre>
819 */
820 //End_Html
5bfe44ce 821 // Inputs:
822 // Int_t row z cell index
823 // Int_t col x cell index
824 // Int_t ntrack track incex number
825 // Int_t idhit hit index number
826 // Outputs:
827 // none.
828 // Return:
829 // none.
f8d9a5b8 830 Int_t j1,j2,flag=0;
831 Double_t pulse1,pulse2;
aacedc3e 832 Double_t couplR=0.0,couplC=0.0;
f8d9a5b8 833 Double_t xr=0.;
834
5bfe44ce 835 GetCouplings(couplC,couplR);
836 if(GetDebug(3)) Info("SetCoupling","(row=%d,col=%d,ntrack=%d,idhit=%d) "
837 "Calling SetCoupling couplR=%e couplC=%e",
838 row,col,ntrack,idhit,couplR,couplC);
f8d9a5b8 839 j1 = row;
840 j2 = col;
5bfe44ce 841 pulse1 = GetMap()->GetSignalOnly(row,col);
f8d9a5b8 842 pulse2 = pulse1;
843 for (Int_t isign=-1;isign<=1;isign+=2){// loop in row direction
aacedc3e 844 do{
845 j1 += isign;
846 // pulse1 *= couplR;
847 xr = gRandom->Rndm();
5bfe44ce 848 //if ((j1<0)||(j1>GetNPixelsZ()-1)||(pulse1<GetThreshold())){
aacedc3e 849 if ((j1<0) || (j1>GetNPixelsZ()-1) || (xr>couplR)){
850 j1 = row;
851 flag = 1;
852 }else{
5bfe44ce 853 UpdateMapSignal(col,j1,ntrack,idhit,pulse1);
aacedc3e 854 // flag = 0;
855 flag = 1; // only first next!!
856 } // end if
857 } while(flag == 0);
858 // loop in column direction
859 do{
860 j2 += isign;
861 // pulse2 *= couplC;
862 xr = gRandom->Rndm();
5bfe44ce 863 //if((j2<0)||j2>(GetNPixelsX()-1)||pulse2<GetThreshold()){
aacedc3e 864 if ((j2<0) || (j2>GetNPixelsX()-1) || (xr>couplC)){
865 j2 = col;
866 flag = 1;
867 }else{
5bfe44ce 868 UpdateMapSignal(j2,row,ntrack,idhit,pulse2);
aacedc3e 869 // flag = 0;
870 flag = 1; // only first next!!
871 } // end if
872 } while(flag == 0);
f8d9a5b8 873 } // for isign
874}
875//______________________________________________________________________
5bfe44ce 876void AliITSsimulationSPD::SetCouplingOld(Int_t row, Int_t col,
877 Int_t ntrack,Int_t idhit) {
f8d9a5b8 878 // Take into account the coupling between adiacent pixels.
c7a4dac0 879 // The parameters probcol and probrow are the fractions of the
880 // signal in one pixel shared in the two adjacent pixels along
881 // the column and row direction, respectively.
c7a4dac0 882 //Begin_Html
883 /*
884 <img src="picts/ITS/barimodel_3.gif">
885 </pre>
886 <br clear=left>
887 <font size=+2 color=red>
888 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
889 </font>
890 <pre>
891 */
892 //End_Html
5bfe44ce 893 // Inputs:
894 // Int_t row z cell index
895 // Int_t col x cell index
896 // Int_t ntrack track incex number
897 // Int_t idhit hit index number
898 // Int_t module module number
899 // Outputs:
900 // none.
901 // Return:
902 // none.
c7a4dac0 903 Int_t j1,j2,flag=0;
904 Double_t pulse1,pulse2;
aacedc3e 905 Double_t couplR=0.0,couplC=0.0;
c7a4dac0 906
5bfe44ce 907 GetCouplings(couplC,couplR);
908
909 // Debugging ...
910// cout << "Threshold --> " << GetThreshold() << endl; // dom
911// cout << "Couplings --> " << couplC << " " << couplR << endl; //dom
912
913
914 if(GetDebug(3)) Info("SetCouplingOld","(row=%d,col=%d,ntrack=%d,idhit=%d) "
915 "Calling SetCoupling couplR=%e couplC=%e",
916 row,col,ntrack,idhit,couplR,couplC);
917 for (Int_t isign=-1;isign<=1;isign+=2){// loop in row direction
918 pulse1 = GetMap()->GetSignalOnly(row,col);
919 pulse2 = pulse1;
c7a4dac0 920 j1 = row;
921 j2 = col;
aacedc3e 922 do{
923 j1 += isign;
924 pulse1 *= couplR;
5bfe44ce 925 if ((j1<0)||(j1>GetNPixelsZ()-1)||(pulse1<GetThreshold())){
926 pulse1 = GetMap()->GetSignalOnly(row,col);
aacedc3e 927 j1 = row;
928 flag = 1;
929 }else{
5bfe44ce 930 UpdateMapSignal(col,j1,ntrack,idhit,pulse1);
931 // flag = 0;
932 flag = 1; // only first next !!
aacedc3e 933 } // end if
934 } while(flag == 0);
935 // loop in column direction
936 do{
937 j2 += isign;
938 pulse2 *= couplC;
5bfe44ce 939 if((j2<0)||(j2>(GetNPixelsX()-1))||(pulse2<GetThreshold())){
940 pulse2 = GetMap()->GetSignalOnly(row,col);
aacedc3e 941 j2 = col;
942 flag = 1;
943 }else{
5bfe44ce 944 UpdateMapSignal(j2,row,ntrack,idhit,pulse2);
945 // flag = 0;
946 flag = 1; // only first next!!
aacedc3e 947 } // end if
948 } while(flag == 0);
c7a4dac0 949 } // for isign
21b825a4 950}