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"
22 ClassImp(AliITSsimulationSPDdubna)
23 ////////////////////////////////////////////////////////////////////////
25 // Written by Boris Batyunya
28 // AliITSsimulationSPDdubna is the simulation of SPDs
29 //________________________________________________________________________
32 AliITSsimulationSPDdubna::AliITSsimulationSPDdubna()
46 //_____________________________________________________________________________
48 AliITSsimulationSPDdubna::AliITSsimulationSPDdubna(AliITSsegmentation *seg, AliITSresponse *resp) {
49 // standard constructor
55 fResponse->GetNoiseParam(fNoise,fBaseline);
57 fMapA2 = new AliITSMapA2(fSegmentation);
61 fNPixelsZ=fSegmentation->Npz();
62 fNPixelsX=fSegmentation->Npx();
66 //_____________________________________________________________________________
68 AliITSsimulationSPDdubna::~AliITSsimulationSPDdubna() {
80 //__________________________________________________________________________
81 AliITSsimulationSPDdubna::AliITSsimulationSPDdubna(const AliITSsimulationSPDdubna &source){
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;
93 //_________________________________________________________________________
94 AliITSsimulationSPDdubna&
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;
106 //_____________________________________________________________________________
108 void AliITSsimulationSPDdubna::DigitiseModule(AliITSmodule *mod, Int_t module, Int_t dummy)
112 const Float_t kEnToEl = 2.778e+8; // GeV->charge in electrons
114 const Float_t kconv = 10000.; // cm -> microns
116 Float_t spdLength = fSegmentation->Dz();
117 Float_t spdWidth = fSegmentation->Dx();
119 Float_t difCoef, dum;
120 fResponse->DiffCoeff(difCoef,dum);
122 Float_t zPix0 = 1e+6;
123 Float_t xPix0 = 1e+6;
124 Float_t yPrev = 1e+6;
126 Float_t zPitch = fSegmentation->Dpz(0);
127 Float_t xPitch = fSegmentation->Dpx(0);
129 TObjArray *fHits = mod->GetHits();
130 Int_t nhits = fHits->GetEntriesFast();
133 //cout<<"len,wid,dy,nx,nz,pitchx,pitchz ="<<spdLength<<","<<spdWidth<<","<<fSegmentation->Dy()<<","<<fNPixelsX<<","<<fNPixelsZ<<","<<xPitch<<","<<zPitch<<endl;
134 // Array of pointers to the label-signal list
136 Int_t maxNDigits = fNPixelsX*fNPixelsZ + fNPixelsX ;;
137 Float_t **pList = new Float_t* [maxNDigits];
138 memset(pList,0,sizeof(Float_t*)*maxNDigits);
139 Int_t indexRange[4] = {0,0,0,0};
141 // Fill detector maps with GEANT hits
142 // loop over hits in the module
145 Int_t hit, iZi, jz, jx;
146 //cout<<"SPD: module,nhits ="<<module<<","<<nhits<<endl;
148 for (hit=0;hit<nhits;hit++) {
149 AliITShit *iHit = (AliITShit*) fHits->At(hit);
150 Int_t layer = iHit->GetLayer();
152 if(layer == 1) yPix0 = -77;
154 if(iHit->StatusEntering()) idhit=hit;
155 Int_t itrack = iHit->GetTrack();
158 if (lasttrack != itrack || hit==(nhits-1)) first = kTRUE;
160 // Int_t parent = iHit->GetParticle()->GetFirstMother();
161 Int_t partcode = iHit->GetParticle()->GetPdgCode();
163 // partcode (pdgCode): 11 - e-, 13 - mu-, 22 - gamma, 111 - pi0, 211 - pi+
164 // 310 - K0s, 321 - K+, 2112 - n, 2212 - p, 3122 - lambda
167 Float_t px = iHit->GetPXL(); // the momenta at the
168 Float_t py = iHit->GetPYL(); // each GEANT step
169 Float_t pz = iHit->GetPZL();
170 Float_t ptot = 1000*sqrt(px*px+py*py+pz*pz);
173 Float_t pmod = iHit->GetParticle()->P(); // total momentum at the
178 if(partcode == 11 && pmod < 6) dray = 1; // delta ray is e-
182 // Get hit z and x(r*phi) cordinates for each module (detector)
185 Float_t zPix = kconv*iHit->GetZL();
186 Float_t xPix = kconv*iHit->GetXL();
187 Float_t yPix = kconv*iHit->GetYL();
190 Int_t status = iHit->GetTrackStatus();
191 //cout<<"hit,status,y ="<<hit<<","<<status<<","<<yPix<<endl;
194 if(zPix > spdLength/2) {
195 //cout<<"!!!1 z outside ="<<zPix<<endl;
196 zPix = spdLength/2 - 10;
197 //cout<<"!!!2 z outside ="<<zPix<<endl;
199 if(zPix < 0 && zPix < -spdLength/2) {
200 //cout<<"!!!1 z outside ="<<zPix<<endl;
201 zPix = -spdLength/2 + 10;
202 //cout<<"!!!2 z outside ="<<zPix<<endl;
204 if(xPix > spdWidth/2) {
205 //cout<<"!!!1 x outside ="<<xPix<<endl;
206 xPix = spdWidth/2 - 10;
207 //cout<<"!!!2 x outside ="<<xPix<<endl;
209 if(xPix < 0 && xPix < -spdWidth/2) {
210 //cout<<"!!!1 x outside ="<<xPix<<endl;
211 xPix = -spdWidth/2 + 10;
212 //cout<<"!!!2 x outside ="<<xPix<<endl;
216 // enter Si or after event in Si
223 Float_t depEnergy = iHit->GetIonization();
224 // skip if the input point to Si
226 if(depEnergy <= 0.) continue;
228 // if track returns to the opposite direction:
234 // take into account the holes diffusion inside the Silicon
235 // the straight line between the entrance and exit points in Si is
236 // divided into the several steps; the diffusion is considered
237 // for each end point of step and charge
238 // is distributed between the pixels through the diffusion.
241 // ---------- the diffusion in Z (beam) direction -------
243 Float_t charge = depEnergy*kEnToEl; // charge in e-
246 Float_t sigmaDif = 0.;
247 Float_t zdif = zPix - zPix0;
248 Float_t xdif = xPix - xPix0;
249 Float_t ydif = TMath::Abs(yPix - yPrev);
250 Float_t ydif0 = TMath::Abs(yPrev - yPix0);
252 if(ydif < 1) continue; // ydif is not zero
254 Float_t projDif = sqrt(xdif*xdif + zdif*zdif);
256 Int_t ndZ = (Int_t)TMath::Abs(zdif/zPitch) + 1;
257 Int_t ndX = (Int_t)TMath::Abs(xdif/xPitch) + 1;
259 // number of the steps along the track:
261 if(ndX > ndZ) nsteps = ndX;
262 if(nsteps < 6) nsteps = 6; // minimum number of the steps
265 drPath = (yPix-yPix0)*1.e-4;
266 drPath = TMath::Abs(drPath); // drift path in cm
267 sigmaDif = difCoef*sqrt(drPath); // sigma diffusion in cm
268 sigmaDif = sigmaDif*kconv; // sigma diffusion in microns
272 if(projDif > 5) tang = ydif/projDif;
273 Float_t dCharge = charge/nsteps; // charge in e- for one step
274 Float_t dZ = zdif/nsteps;
275 Float_t dX = xdif/nsteps;
277 for (iZi = 1;iZi <= nsteps;iZi++) {
278 Float_t dZn = iZi*dZ;
279 Float_t dXn = iZi*dX;
280 Float_t zPixn = zPix0 + dZn;
281 Float_t xPixn = xPix0 + dXn;
284 Float_t dProjn = sqrt(dZn*dZn+dXn*dXn);
285 drPath = dProjn*tang*1.e-4; // drift path for iZi step in cm
287 drPath = TMath::Abs(drPath) + ydif0*1.e-4;
290 drPath = ydif0*1.e-4 - TMath::Abs(drPath);
291 drPath = TMath::Abs(drPath);
293 sigmaDif = difCoef*sqrt(drPath);
294 sigmaDif = sigmaDif*kconv; // sigma diffusion in microns
297 zPixn = (zPixn + spdLength/2.);
298 xPixn = (xPixn + spdWidth/2.);
300 fSegmentation->GetPadIxz(xPixn,zPixn,nXpix,nZpix);
301 zPitch = fSegmentation->Dpz(nZpix);
302 fSegmentation->GetPadTxz(xPixn,zPixn);
303 // set the window for the integration
306 if(nZpix == 1) jzmin =2;
307 if(nZpix == fNPixelsZ) jzmax = 2;
311 if(nXpix == 1) jxmin =2;
312 if(nXpix == fNPixelsX) jxmax = 2;
314 Float_t zpix = nZpix;
315 Float_t dZright = zPitch*(zpix - zPixn);
316 Float_t dZleft = zPitch - dZright;
318 Float_t xpix = nXpix;
319 Float_t dXright = xPitch*(xpix - xPixn);
320 Float_t dXleft = xPitch - dXright;
327 for(jz=jzmin; jz <=jzmax; jz++) {
329 dZprev = -zPitch - dZleft;
338 dZnext = dZright + zPitch;
340 // kz changes from 1 to the fNofPixels(270)
341 Int_t kz = nZpix + jz -2;
343 Float_t zArg1 = dZprev/sigmaDif;
344 Float_t zArg2 = dZnext/sigmaDif;
345 Float_t zProb1 = TMath::Erfc(zArg1);
346 Float_t zProb2 = TMath::Erfc(zArg2);
347 Float_t dZCharge =0.5*(zProb1-zProb2)*dCharge;
350 // ----------- holes diffusion in X(r*phi) direction --------
353 for(jx=jxmin; jx <=jxmax; jx++) {
355 dXprev = -xPitch - dXleft;
364 dXnext = dXright + xPitch;
366 Int_t kx = nXpix + jx -2;
368 Float_t xArg1 = dXprev/sigmaDif;
369 Float_t xArg2 = dXnext/sigmaDif;
370 Float_t xProb1 = TMath::Erfc(xArg1);
371 Float_t xProb2 = TMath::Erfc(xArg2);
372 Float_t dXCharge =0.5*(xProb1-xProb2)*dZCharge;
378 indexRange[0]=indexRange[1]=index;
379 indexRange[2]=indexRange[3]=kx-1;
383 indexRange[0]=TMath::Min(indexRange[0],kz-1);
384 indexRange[1]=TMath::Max(indexRange[1],kz-1);
385 indexRange[2]=TMath::Min(indexRange[2],kx-1);
386 indexRange[3]=TMath::Max(indexRange[3],kx-1);
388 // build the list of digits for this module
389 Double_t signal=fMapA2->GetSignal(index,kx-1);
391 fMapA2->SetHit(index,kx-1,(double)signal);
398 if (status == 65) { // the step is inside of Si
405 GetList(itrack,idhit,pList,indexRange);
409 } // hit loop inside the module
412 // introduce the electronics effects and do zero-suppression
413 ChargeToSignal(pList);
422 //---------------------------------------------
423 void AliITSsimulationSPDdubna::GetList(Int_t label,Int_t idhit,Float_t **pList,Int_t *indexRange)
425 // lop over nonzero digits
429 for(int k=0;k<4;k++) {
430 if (indexRange[k] < 0) indexRange[k]=0;
433 for(Int_t iz=indexRange[0];iz<indexRange[1]+1;iz++){
434 for(Int_t ix=indexRange[2];ix<indexRange[3]+1;ix++){
436 Float_t signal=fMapA2->GetSignal(iz,ix);
438 if (!signal) continue;
440 Int_t globalIndex = iz*fNPixelsX+ix; // GlobalIndex starts from 0!
441 if(!pList[globalIndex]){
444 // Create new list (9 elements - 3 signals and 3 tracks + 3 hits)
447 pList[globalIndex] = new Float_t [9];
451 *pList[globalIndex] = -3.;
452 *(pList[globalIndex]+1) = -3.;
453 *(pList[globalIndex]+2) = -3.;
454 *(pList[globalIndex]+3) = 0.;
455 *(pList[globalIndex]+4) = 0.;
456 *(pList[globalIndex]+5) = 0.;
457 *(pList[globalIndex]+6) = -1.;
458 *(pList[globalIndex]+7) = -1.;
459 *(pList[globalIndex]+8) = -1.;
462 *pList[globalIndex] = (float)label;
463 *(pList[globalIndex]+3) = signal;
464 *(pList[globalIndex]+6) = (float)idhit;
468 // check the signal magnitude
470 Float_t highest = *(pList[globalIndex]+3);
471 Float_t middle = *(pList[globalIndex]+4);
472 Float_t lowest = *(pList[globalIndex]+5);
474 signal -= (highest+middle+lowest);
477 // compare the new signal with already existing list
480 if(signal<lowest) continue; // neglect this track
483 *(pList[globalIndex]+5) = middle;
484 *(pList[globalIndex]+4) = highest;
485 *(pList[globalIndex]+3) = signal;
487 *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
488 *(pList[globalIndex]+1) = *pList[globalIndex];
489 *pList[globalIndex] = label;
491 *(pList[globalIndex]+8) = *(pList[globalIndex]+7);
492 *(pList[globalIndex]+7) = *(pList[globalIndex]+6);
493 *(pList[globalIndex]+6) = idhit;
495 else if (signal>middle){
496 *(pList[globalIndex]+5) = middle;
497 *(pList[globalIndex]+4) = signal;
499 *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
500 *(pList[globalIndex]+1) = label;
502 *(pList[globalIndex]+8) = *(pList[globalIndex]+7);
503 *(pList[globalIndex]+7) = idhit;
506 *(pList[globalIndex]+5) = signal;
507 *(pList[globalIndex]+2) = label;
508 *(pList[globalIndex]+8) = idhit;
511 } // end of loop pixels in x
512 } // end of loop over pixels in z
518 //---------------------------------------------
519 void AliITSsimulationSPDdubna::ChargeToSignal(Float_t **pList)
521 // add noise and electronics, perform the zero suppression and add the
524 AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
527 Float_t threshold = (float)fResponse->MinVal();
529 Int_t digits[3], tracks[3], hits[3],gi,j1;
533 for(Int_t iz=0;iz<fNPixelsZ;iz++){
534 for(Int_t ix=0;ix<fNPixelsX;ix++){
535 electronics = fBaseline + fNoise*gRandom->Gaus();
536 signal = (float)fMapA2->GetSignal(iz,ix);
537 signal += electronics;
538 gi =iz*fNPixelsX+ix; // global index
539 if (signal > threshold) {
545 //b.b. tracks[j1]=-3;
546 tracks[j1] = (Int_t)(*(pList[gi]+j1));
547 hits[j1] = (Int_t)(*(pList[gi]+j1+6));
549 tracks[j1]=-2; //noise
555 if(tracks[0] == tracks[1] && tracks[0] == tracks[2]) {
561 if(tracks[0] == tracks[1] && tracks[0] != tracks[2]) {
565 if(tracks[0] == tracks[2] && tracks[0] != tracks[1]) {
569 if(tracks[1] == tracks[2] && tracks[0] != tracks[1]) {
575 aliITS->AddSimDigit(0,phys,digits,tracks,hits,charges);
577 if(pList[gi]) delete [] pList[gi];
585 //____________________________________________
587 void AliITSsimulationSPDdubna::CreateHistograms()
589 // create 1D histograms for tests
591 printf("SPD - create histograms\n");
593 fHis=new TObjArray(fNPixelsZ);
594 for (Int_t i=0;i<fNPixelsZ;i++) {
595 TString spdName("spd_");
597 sprintf(pixelz,"%d",i+1);
598 spdName.Append(pixelz);
599 (*fHis)[i] = new TH1F(spdName.Data(),"SPD maps",
600 fNPixelsX,0.,(Float_t) fNPixelsX);
604 //____________________________________________
606 void AliITSsimulationSPDdubna::ResetHistograms()
609 // Reset histograms for this detector
612 for ( int i=0;i<fNPixelsZ;i++ ) {
613 if ((*fHis)[i]) ((TH1F*)(*fHis)[i])->Reset();