]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSsimulationSPDdubna.cxx
Posible memory leak fixed. Changes AliITSpList destructor. Not clear if
[u/mrichter/AliRoot.git] / ITS / AliITSsimulationSPDdubna.cxx
CommitLineData
409f8c84 1#include <iostream.h>
2#include <TRandom.h>
3#include <TH1.h>
4#include <TMath.h>
5#include <TString.h>
6#include <TParticle.h>
7
8
9#include "AliRun.h"
10#include "AliITS.h"
11#include "AliITShit.h"
12#include "AliITSdigit.h"
13#include "AliITSmodule.h"
14#include "AliITSMapA2.h"
15#include "AliITSsimulationSPDdubna.h"
16#include "AliITSsegmentation.h"
17#include "AliITSresponse.h"
18
19
20
21
22ClassImp(AliITSsimulationSPDdubna)
23////////////////////////////////////////////////////////////////////////
24// Version: 0
25// Written by Boris Batyunya
26// December 20 1999
27//
28// AliITSsimulationSPDdubna is the simulation of SPDs
29//________________________________________________________________________
30
31
32AliITSsimulationSPDdubna::AliITSsimulationSPDdubna()
33{
34 // constructor
35 fResponse = 0;
36 fSegmentation = 0;
37 fMapA2=0;
38 fHis = 0;
39 fNoise=0.;
40 fBaseline=0.;
41 fNPixelsZ=0;
42 fNPixelsX=0;
43}
44
45
46//_____________________________________________________________________________
47
48AliITSsimulationSPDdubna::AliITSsimulationSPDdubna(AliITSsegmentation *seg, AliITSresponse *resp) {
49 // standard constructor
50
51 fHis = 0;
52 fResponse = resp;
53 fSegmentation = seg;
54
55 fResponse->GetNoiseParam(fNoise,fBaseline);
56
57 fMapA2 = new AliITSMapA2(fSegmentation);
58
59 //
60
61 fNPixelsZ=fSegmentation->Npz();
62 fNPixelsX=fSegmentation->Npx();
63
64}
65
66//_____________________________________________________________________________
67
68AliITSsimulationSPDdubna::~AliITSsimulationSPDdubna() {
69 // destructor
70
71 delete fMapA2;
72
73 if (fHis) {
74 fHis->Delete();
75 delete fHis;
76 }
77}
78
79
80//__________________________________________________________________________
81AliITSsimulationSPDdubna::AliITSsimulationSPDdubna(const AliITSsimulationSPDdubna &source){
82 // Copy Constructor
83 if(&source == this) return;
84 this->fMapA2 = source.fMapA2;
85 this->fNoise = source.fNoise;
86 this->fBaseline = source.fBaseline;
87 this->fNPixelsX = source.fNPixelsX;
88 this->fNPixelsZ = source.fNPixelsZ;
89 this->fHis = source.fHis;
90 return;
91}
92
93//_________________________________________________________________________
94AliITSsimulationSPDdubna&
95 AliITSsimulationSPDdubna::operator=(const AliITSsimulationSPDdubna &source) {
96 // Assignment operator
97 if(&source == this) return *this;
98 this->fMapA2 = source.fMapA2;
99 this->fNoise = source.fNoise;
100 this->fBaseline = source.fBaseline;
101 this->fNPixelsX = source.fNPixelsX;
102 this->fNPixelsZ = source.fNPixelsZ;
103 this->fHis = source.fHis;
104 return *this;
105 }
106//_____________________________________________________________________________
107
108void AliITSsimulationSPDdubna::DigitiseModule(AliITSmodule *mod, Int_t module, Int_t dummy)
109{
110 // digitize module
111
112 const Float_t kEnToEl = 2.778e+8; // GeV->charge in electrons
113 // for 3.6 eV/pair
114 const Float_t kconv = 10000.; // cm -> microns
115
116 Float_t spdLength = fSegmentation->Dz();
117 Float_t spdWidth = fSegmentation->Dx();
338e4f06 118 Float_t spdThickness = fSegmentation->Dy();
409f8c84 119 Float_t difCoef, dum;
120 fResponse->DiffCoeff(difCoef,dum);
338e4f06 121 if(spdThickness > 290) difCoef = 0.00613;
409f8c84 122
123 Float_t zPix0 = 1e+6;
124 Float_t xPix0 = 1e+6;
125 Float_t yPrev = 1e+6;
126
127 Float_t zPitch = fSegmentation->Dpz(0);
128 Float_t xPitch = fSegmentation->Dpx(0);
129
130 TObjArray *fHits = mod->GetHits();
131 Int_t nhits = fHits->GetEntriesFast();
132 if (!nhits) return;
133
338e4f06 134 cout<<"len,wid,thickness,nx,nz,pitchx,pitchz,difcoef ="<<spdLength<<","<<spdWidth<<","<<spdThickness<<","<<fNPixelsX<<","<<fNPixelsZ<<","<<xPitch<<","<<zPitch<<","<<difCoef<<endl;
409f8c84 135 // Array of pointers to the label-signal list
136
137 Int_t maxNDigits = fNPixelsX*fNPixelsZ + fNPixelsX ;;
138 Float_t **pList = new Float_t* [maxNDigits];
139 memset(pList,0,sizeof(Float_t*)*maxNDigits);
140 Int_t indexRange[4] = {0,0,0,0};
141
142 // Fill detector maps with GEANT hits
143 // loop over hits in the module
144 static Bool_t first;
145 Int_t lasttrack=-2;
146 Int_t hit, iZi, jz, jx;
338e4f06 147 Int_t idhit=-1; //!
148 cout<<"SPDdubna: module,nhits ="<<module<<","<<nhits<<endl;
409f8c84 149 for (hit=0;hit<nhits;hit++) {
150 AliITShit *iHit = (AliITShit*) fHits->At(hit);
338e4f06 151 //Int_t layer = iHit->GetLayer();
152 Float_t yPix0 = -spdThickness/2;
153
154 // work with the idtrack=entry number in the TreeH
155 //Int_t idhit,idtrack; //!
156 //mod->GetHitTrackAndHitIndex(hit,idtrack,idhit); //!
157 //Int_t idtrack=mod->GetHitTrackIndex(hit);
158 // or store straight away the particle position in the array
159 // of particles :
409f8c84 160 if(iHit->StatusEntering()) idhit=hit;
161 Int_t itrack = iHit->GetTrack();
162 Int_t dray = 0;
163
164 if (lasttrack != itrack || hit==(nhits-1)) first = kTRUE;
165
338e4f06 166 //Int_t parent = iHit->GetParticle()->GetFirstMother();
409f8c84 167 Int_t partcode = iHit->GetParticle()->GetPdgCode();
168
169// partcode (pdgCode): 11 - e-, 13 - mu-, 22 - gamma, 111 - pi0, 211 - pi+
170// 310 - K0s, 321 - K+, 2112 - n, 2212 - p, 3122 - lambda
171
172 /*
173 Float_t px = iHit->GetPXL(); // the momenta at the
174 Float_t py = iHit->GetPYL(); // each GEANT step
175 Float_t pz = iHit->GetPZL();
176 Float_t ptot = 1000*sqrt(px*px+py*py+pz*pz);
177 */
178
179 Float_t pmod = iHit->GetParticle()->P(); // total momentum at the
180 // vertex
181 pmod *= 1000;
182
183
184 if(partcode == 11 && pmod < 6) dray = 1; // delta ray is e-
185 // at p < 6 MeV/c
186
187
188 // Get hit z and x(r*phi) cordinates for each module (detector)
189 // in local system.
190
191 Float_t zPix = kconv*iHit->GetZL();
192 Float_t xPix = kconv*iHit->GetXL();
193 Float_t yPix = kconv*iHit->GetYL();
194
195 // Get track status
196 Int_t status = iHit->GetTrackStatus();
409f8c84 197
198 // Check boundaries
199 if(zPix > spdLength/2) {
338e4f06 200 //cout<<"!!! SPD: z outside ="<<zPix<<endl;
409f8c84 201 zPix = spdLength/2 - 10;
409f8c84 202 }
203 if(zPix < 0 && zPix < -spdLength/2) {
338e4f06 204 //cout<<"!!! SPD: z outside ="<<zPix<<endl;
409f8c84 205 zPix = -spdLength/2 + 10;
409f8c84 206 }
207 if(xPix > spdWidth/2) {
338e4f06 208 //cout<<"!!! SPD: x outside ="<<xPix<<endl;
409f8c84 209 xPix = spdWidth/2 - 10;
409f8c84 210 }
211 if(xPix < 0 && xPix < -spdWidth/2) {
338e4f06 212 //cout<<"!!! SPD: x outside ="<<xPix<<endl;
409f8c84 213 xPix = -spdWidth/2 + 10;
409f8c84 214 }
215 Int_t trdown = 0;
216
217 // enter Si or after event in Si
218 if (status == 66 ) {
219 zPix0 = zPix;
220 xPix0 = xPix;
221 yPrev = yPix;
222 }
223
224 Float_t depEnergy = iHit->GetIonization();
225 // skip if the input point to Si
226
227 if(depEnergy <= 0.) continue;
228
229 // if track returns to the opposite direction:
230 if (yPix < yPrev) {
231 trdown = 1;
232 }
233
234
235 // take into account the holes diffusion inside the Silicon
236 // the straight line between the entrance and exit points in Si is
237 // divided into the several steps; the diffusion is considered
238 // for each end point of step and charge
239 // is distributed between the pixels through the diffusion.
240
241
242 // ---------- the diffusion in Z (beam) direction -------
243
244 Float_t charge = depEnergy*kEnToEl; // charge in e-
245 Float_t drPath = 0.;
246 Float_t tang = 0.;
247 Float_t sigmaDif = 0.;
248 Float_t zdif = zPix - zPix0;
249 Float_t xdif = xPix - xPix0;
250 Float_t ydif = TMath::Abs(yPix - yPrev);
251 Float_t ydif0 = TMath::Abs(yPrev - yPix0);
252
253 if(ydif < 1) continue; // ydif is not zero
254
255 Float_t projDif = sqrt(xdif*xdif + zdif*zdif);
256
257 Int_t ndZ = (Int_t)TMath::Abs(zdif/zPitch) + 1;
258 Int_t ndX = (Int_t)TMath::Abs(xdif/xPitch) + 1;
259
260 // number of the steps along the track:
261 Int_t nsteps = ndZ;
262 if(ndX > ndZ) nsteps = ndX;
338e4f06 263 if(nsteps < 20) nsteps = 20; // minimum number of the steps
409f8c84 264
265 if (projDif < 5 ) {
266 drPath = (yPix-yPix0)*1.e-4;
267 drPath = TMath::Abs(drPath); // drift path in cm
268 sigmaDif = difCoef*sqrt(drPath); // sigma diffusion in cm
269 sigmaDif = sigmaDif*kconv; // sigma diffusion in microns
270 nsteps = 1;
271 }
272
273 if(projDif > 5) tang = ydif/projDif;
274 Float_t dCharge = charge/nsteps; // charge in e- for one step
275 Float_t dZ = zdif/nsteps;
276 Float_t dX = xdif/nsteps;
277
278 for (iZi = 1;iZi <= nsteps;iZi++) {
279 Float_t dZn = iZi*dZ;
280 Float_t dXn = iZi*dX;
281 Float_t zPixn = zPix0 + dZn;
282 Float_t xPixn = xPix0 + dXn;
283
284 if(projDif >= 5) {
285 Float_t dProjn = sqrt(dZn*dZn+dXn*dXn);
286 drPath = dProjn*tang*1.e-4; // drift path for iZi step in cm
287 if(trdown == 0) {
288 drPath = TMath::Abs(drPath) + ydif0*1.e-4;
289 }
290 if(trdown == 1) {
291 drPath = ydif0*1.e-4 - TMath::Abs(drPath);
292 drPath = TMath::Abs(drPath);
293 }
294 sigmaDif = difCoef*sqrt(drPath);
295 sigmaDif = sigmaDif*kconv; // sigma diffusion in microns
296 }
297
298 zPixn = (zPixn + spdLength/2.);
299 xPixn = (xPixn + spdWidth/2.);
300 Int_t nZpix, nXpix;
301 fSegmentation->GetPadIxz(xPixn,zPixn,nXpix,nZpix);
302 zPitch = fSegmentation->Dpz(nZpix);
303 fSegmentation->GetPadTxz(xPixn,zPixn);
304 // set the window for the integration
305 Int_t jzmin = 1;
306 Int_t jzmax = 3;
307 if(nZpix == 1) jzmin =2;
308 if(nZpix == fNPixelsZ) jzmax = 2;
309
310 Int_t jxmin = 1;
311 Int_t jxmax = 3;
312 if(nXpix == 1) jxmin =2;
313 if(nXpix == fNPixelsX) jxmax = 2;
314
315 Float_t zpix = nZpix;
316 Float_t dZright = zPitch*(zpix - zPixn);
317 Float_t dZleft = zPitch - dZright;
318
319 Float_t xpix = nXpix;
320 Float_t dXright = xPitch*(xpix - xPixn);
321 Float_t dXleft = xPitch - dXright;
322
323 Float_t dZprev = 0.;
324 Float_t dZnext = 0.;
325 Float_t dXprev = 0.;
326 Float_t dXnext = 0.;
327
328 for(jz=jzmin; jz <=jzmax; jz++) {
329 if(jz == 1) {
330 dZprev = -zPitch - dZleft;
331 dZnext = -dZleft;
332 }
333 if(jz == 2) {
334 dZprev = -dZleft;
335 dZnext = dZright;
336 }
337 if(jz == 3) {
338 dZprev = dZright;
339 dZnext = dZright + zPitch;
340 }
341 // kz changes from 1 to the fNofPixels(270)
342 Int_t kz = nZpix + jz -2;
343
344 Float_t zArg1 = dZprev/sigmaDif;
345 Float_t zArg2 = dZnext/sigmaDif;
346 Float_t zProb1 = TMath::Erfc(zArg1);
347 Float_t zProb2 = TMath::Erfc(zArg2);
348 Float_t dZCharge =0.5*(zProb1-zProb2)*dCharge;
349
350
351 // ----------- holes diffusion in X(r*phi) direction --------
352
353 if(dZCharge > 1.) {
354 for(jx=jxmin; jx <=jxmax; jx++) {
355 if(jx == 1) {
356 dXprev = -xPitch - dXleft;
357 dXnext = -dXleft;
358 }
359 if(jx == 2) {
360 dXprev = -dXleft;
361 dXnext = dXright;
362 }
363 if(jx == 3) {
364 dXprev = dXright;
365 dXnext = dXright + xPitch;
366 }
367 Int_t kx = nXpix + jx -2;
368
369 Float_t xArg1 = dXprev/sigmaDif;
370 Float_t xArg2 = dXnext/sigmaDif;
371 Float_t xProb1 = TMath::Erfc(xArg1);
372 Float_t xProb2 = TMath::Erfc(xArg2);
373 Float_t dXCharge =0.5*(xProb1-xProb2)*dZCharge;
374
375 if(dXCharge > 1.) {
376 Int_t index = kz-1;
377
378 if (first) {
379 indexRange[0]=indexRange[1]=index;
380 indexRange[2]=indexRange[3]=kx-1;
381 first=kFALSE;
382 }
383
384 indexRange[0]=TMath::Min(indexRange[0],kz-1);
385 indexRange[1]=TMath::Max(indexRange[1],kz-1);
386 indexRange[2]=TMath::Min(indexRange[2],kx-1);
387 indexRange[3]=TMath::Max(indexRange[3],kx-1);
388
389 // build the list of digits for this module
390 Double_t signal=fMapA2->GetSignal(index,kx-1);
391 signal+=dXCharge;
392 fMapA2->SetHit(index,kx-1,(double)signal);
393 } // dXCharge > 1 e-
394 } // jx loop
395 } // dZCharge > 1 e-
396 } // jz loop
397 } // iZi loop
398
399 if (status == 65) { // the step is inside of Si
400 zPix0 = zPix;
401 xPix0 = xPix;
402 }
403 yPrev = yPix;
404
405 if(dray == 0) {
406 GetList(itrack,idhit,pList,indexRange);
407 }
408
409 lasttrack=itrack;
410 } // hit loop inside the module
411
412
413 // introduce the electronics effects and do zero-suppression
414 ChargeToSignal(pList);
415
416 // clean memory
417
418 fMapA2->ClearMap();
419
420
421}
422
423//---------------------------------------------
424void AliITSsimulationSPDdubna::GetList(Int_t label,Int_t idhit,Float_t **pList,Int_t *indexRange)
425{
426 // lop over nonzero digits
427
428
429 //set protection
430 for(int k=0;k<4;k++) {
431 if (indexRange[k] < 0) indexRange[k]=0;
432 }
433
434 for(Int_t iz=indexRange[0];iz<indexRange[1]+1;iz++){
435 for(Int_t ix=indexRange[2];ix<indexRange[3]+1;ix++){
436
437 Float_t signal=fMapA2->GetSignal(iz,ix);
438
439 if (!signal) continue;
440
441 Int_t globalIndex = iz*fNPixelsX+ix; // GlobalIndex starts from 0!
442 if(!pList[globalIndex]){
443
444 //
445 // Create new list (9 elements - 3 signals and 3 tracks + 3 hits)
446 //
447
448 pList[globalIndex] = new Float_t [9];
449
450 // set list to -3
451
452 *pList[globalIndex] = -3.;
453 *(pList[globalIndex]+1) = -3.;
454 *(pList[globalIndex]+2) = -3.;
455 *(pList[globalIndex]+3) = 0.;
456 *(pList[globalIndex]+4) = 0.;
457 *(pList[globalIndex]+5) = 0.;
458 *(pList[globalIndex]+6) = -1.;
459 *(pList[globalIndex]+7) = -1.;
460 *(pList[globalIndex]+8) = -1.;
461
462
463 *pList[globalIndex] = (float)label;
464 *(pList[globalIndex]+3) = signal;
465 *(pList[globalIndex]+6) = (float)idhit;
466 }
467 else{
468
469 // check the signal magnitude
470
471 Float_t highest = *(pList[globalIndex]+3);
472 Float_t middle = *(pList[globalIndex]+4);
473 Float_t lowest = *(pList[globalIndex]+5);
474
475 signal -= (highest+middle+lowest);
476
477 //
478 // compare the new signal with already existing list
479 //
480
481 if(signal<lowest) continue; // neglect this track
482
483 if (signal>highest){
484 *(pList[globalIndex]+5) = middle;
485 *(pList[globalIndex]+4) = highest;
486 *(pList[globalIndex]+3) = signal;
487
488 *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
489 *(pList[globalIndex]+1) = *pList[globalIndex];
490 *pList[globalIndex] = label;
491
492 *(pList[globalIndex]+8) = *(pList[globalIndex]+7);
493 *(pList[globalIndex]+7) = *(pList[globalIndex]+6);
494 *(pList[globalIndex]+6) = idhit;
495 }
496 else if (signal>middle){
497 *(pList[globalIndex]+5) = middle;
498 *(pList[globalIndex]+4) = signal;
499
500 *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
501 *(pList[globalIndex]+1) = label;
502
503 *(pList[globalIndex]+8) = *(pList[globalIndex]+7);
504 *(pList[globalIndex]+7) = idhit;
505 }
506 else{
507 *(pList[globalIndex]+5) = signal;
508 *(pList[globalIndex]+2) = label;
509 *(pList[globalIndex]+8) = idhit;
510 }
511 }
512 } // end of loop pixels in x
513 } // end of loop over pixels in z
514
515
516}
517
518
519//---------------------------------------------
520void AliITSsimulationSPDdubna::ChargeToSignal(Float_t **pList)
521{
522 // add noise and electronics, perform the zero suppression and add the
523 // digit to the list
524
525 AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
526
338e4f06 527
409f8c84 528 Float_t threshold = (float)fResponse->MinVal();
529
530 Int_t digits[3], tracks[3], hits[3],gi,j1;
531 Float_t charges[3];
532 Float_t electronics;
533 Float_t signal,phys;
534 for(Int_t iz=0;iz<fNPixelsZ;iz++){
535 for(Int_t ix=0;ix<fNPixelsX;ix++){
536 electronics = fBaseline + fNoise*gRandom->Gaus();
537 signal = (float)fMapA2->GetSignal(iz,ix);
538 signal += electronics;
539 gi =iz*fNPixelsX+ix; // global index
540 if (signal > threshold) {
541 digits[0]=iz;
542 digits[1]=ix;
543 digits[2]=1;
544 for(j1=0;j1<3;j1++){
545 if (pList[gi]) {
546 //b.b. tracks[j1]=-3;
547 tracks[j1] = (Int_t)(*(pList[gi]+j1));
548 hits[j1] = (Int_t)(*(pList[gi]+j1+6));
549 }else {
550 tracks[j1]=-2; //noise
551 hits[j1] = -1;
552 }
553 charges[j1] = 0;
554 }
555
556 if(tracks[0] == tracks[1] && tracks[0] == tracks[2]) {
557 tracks[1] = -3;
558 hits[1] = -1;
559 tracks[2] = -3;
560 hits[2] = -1;
561 }
562 if(tracks[0] == tracks[1] && tracks[0] != tracks[2]) {
563 tracks[1] = -3;
564 hits[1] = -1;
565 }
566 if(tracks[0] == tracks[2] && tracks[0] != tracks[1]) {
567 tracks[2] = -3;
568 hits[2] = -1;
569 }
570 if(tracks[1] == tracks[2] && tracks[0] != tracks[1]) {
571 tracks[2] = -3;
572 hits[2] = -1;
573 }
574
575 phys=0;
576 aliITS->AddSimDigit(0,phys,digits,tracks,hits,charges);
577 }
578 if(pList[gi]) delete [] pList[gi];
579 }
580 }
581 delete [] pList;
582
583}
584
585
586//____________________________________________
587
588void AliITSsimulationSPDdubna::CreateHistograms()
589{
590 // create 1D histograms for tests
591
592 printf("SPD - create histograms\n");
593
594 fHis=new TObjArray(fNPixelsZ);
338e4f06 595 TString spdName("spd_");
409f8c84 596 for (Int_t i=0;i<fNPixelsZ;i++) {
409f8c84 597 Char_t pixelz[4];
598 sprintf(pixelz,"%d",i+1);
599 spdName.Append(pixelz);
2682e810 600 //PH (*fHis)[i] = new TH1F(spdName.Data(),"SPD maps",
601 //PH fNPixelsX,0.,(Float_t) fNPixelsX);
602 fHis->AddAt(new TH1F(spdName.Data(),"SPD maps",
603 fNPixelsX,0.,(Float_t) fNPixelsX), i);
409f8c84 604 }
605}
606
607//____________________________________________
608
609void AliITSsimulationSPDdubna::ResetHistograms()
610{
611 //
612 // Reset histograms for this detector
613 //
614
615 for ( int i=0;i<fNPixelsZ;i++ ) {
2682e810 616 //PH if ((*fHis)[i]) ((TH1F*)(*fHis)[i])->Reset();
617 if (fHis->At(i)) ((TH1F*)fHis->At(i))->Reset();
409f8c84 618 }
619
620}
621
622
623
624
625
626
627
628
629