11 #include "AliITShit.h"
12 #include "AliITSdigit.h"
13 #include "AliITSmodule.h"
14 #include "AliITSMapA2.h"
15 #include "AliITSsimulationSPDbari.h"
16 #include "AliITSsegmentation.h"
17 #include "AliITSresponse.h"
20 ClassImp(AliITSsimulationSPDbari)
21 ////////////////////////////////////////////////////////////////////////
23 // Written by Rocco Caliandro
24 // from a model developed with T. Virgili and R.A. Fini
27 // AliITSsimulationSPD is the simulation of SPDs
29 //________________________________________________________________________
31 AliITSsimulationSPDbari::AliITSsimulationSPDbari(){
41 //_____________________________________________________________________________
43 AliITSsimulationSPDbari::AliITSsimulationSPDbari(AliITSsegmentation *seg, AliITSresponse *resp) {
48 fResponse->Thresholds(fThresh,fSigma);
49 fResponse->GetNoiseParam(fCouplCol,fCouplRow);
51 fMapA2 = new AliITSMapA2(fSegmentation);
54 fNPixelsZ=fSegmentation->Npz();
55 fNPixelsX=fSegmentation->Npx();
59 //_____________________________________________________________________________
61 AliITSsimulationSPDbari::~AliITSsimulationSPDbari() {
72 //__________________________________________________________________________
73 AliITSsimulationSPDbari::AliITSsimulationSPDbari(const AliITSsimulationSPDbari &source){
75 if(&source == this) return;
76 this->fMapA2 = source.fMapA2;
77 this->fThresh = source.fThresh;
78 this->fSigma = source.fSigma;
79 this->fCouplCol = source.fCouplCol;
80 this->fCouplRow = source.fCouplRow;
81 this->fNPixelsX = source.fNPixelsX;
82 this->fNPixelsZ = source.fNPixelsZ;
83 this->fHis = source.fHis;
87 //_________________________________________________________________________
88 AliITSsimulationSPDbari&
89 AliITSsimulationSPDbari::operator=(const AliITSsimulationSPDbari &source) {
90 // Assignment operator
91 if(&source == this) return *this;
92 this->fMapA2 = source.fMapA2;
93 this->fThresh = source.fThresh;
94 this->fSigma = source.fSigma;
95 this->fCouplCol = source.fCouplCol;
96 this->fCouplRow = source.fCouplRow;
97 this->fNPixelsX = source.fNPixelsX;
98 this->fNPixelsZ = source.fNPixelsZ;
99 this->fHis = source.fHis;
102 //_____________________________________________________________________________
104 void AliITSsimulationSPDbari::DigitiseModule(AliITSmodule *mod, Int_t module,
109 TObjArray *fHits = mod->GetHits();
110 Int_t nhits = fHits->GetEntriesFast();
114 printf("Module %d (%d hits) \n",module+1,nhits);
118 Int_t *frowpixel = new Int_t[number];
119 Int_t *fcolpixel = new Int_t[number];
120 Double_t *fenepixel = new Double_t[number];
122 // Array of pointers to store the track index of the digits
123 // leave +1, otherwise pList crashes when col=256, row=192
124 Int_t maxNdigits = fNPixelsX*fNPixelsZ+fNPixelsX+1;
125 Float_t **pList = new Float_t* [maxNdigits];
126 memset(pList,0,sizeof(Float_t*)*maxNdigits);
130 SetFluctuations(pList);
133 // loop over hits in the module
135 for (hitpos=0;hitpos<nhits;hitpos++) {
137 HitToDigit(mod,hitpos,module,frowpixel,fcolpixel,fenepixel,pList);
140 }// end loop over digits
142 CreateDigit(nhits,module,pList);
152 //_____________________________________________________________________________
154 void AliITSsimulationSPDbari::UpdateMap( Int_t row, Int_t col, Double_t ene) {
156 // updates the Map of signal, adding the energy (ene) released by the current track
159 signal = fMapA2->GetSignal(row,col);
161 fMapA2->SetHit(row,col,signal);
164 //_____________________________________________________________________________
165 void AliITSsimulationSPDbari::HitToDigit(AliITSmodule *mod, Int_t hitpos, Int_t module,
166 Int_t *frowpixel, Int_t *fcolpixel,
167 Double_t *fenepixel, Float_t **pList) {
169 // Steering function to determine the digits associated to a given hit (hitpos)
170 // The digits are created by charge sharing (ChargeSharing) and by
171 // capacitive coupling (SetCoupling). At all the created digits is associated
172 // the track number of the hit (ntrack)
176 static Float_t x1l,y1l,z1l;
177 Float_t x2l,y2l,z2l,etot;
178 Int_t layer,r1,r2,c1,c2,row,col,npixel = 0;
181 const Float_t kconv = 10000.; // cm -> microns
183 TObjArray *fHits = mod->GetHits();
184 AliITShit *hit = (AliITShit*) fHits->At(hitpos);
185 layer = hit->GetLayer();
186 etot=hit->GetIonization();
187 ntrack=hit->GetTrack();
190 if (hit->GetTrackStatus()==66) {
191 hit->GetPositionL(x1l,y1l,z1l);
192 // positions shifted and converted in microns
193 x1l = x1l*kconv + fSegmentation->Dx()/2.;
194 z1l = z1l*kconv + fSegmentation->Dz()/2.;
197 hit->GetPositionL(x2l,y2l,z2l);
198 // positions shifted and converted in microns
199 x2l = x2l*kconv + fSegmentation->Dx()/2.;
200 z2l = z2l*kconv + fSegmentation->Dz()/2.;
203 // to account for 83750 effective sensitive area
204 // introduced in geometry (Dz=83600)
205 if (z1l>fSegmentation->Dz()) return;
206 if (z2l>fSegmentation->Dz()) return;
207 // to preserve for hit having x>12800
208 if (x1l>fSegmentation->Dx()) return;
209 if (x2l>fSegmentation->Dx()) return;
211 //Get the col and row number starting from 1
212 // the x direction is not inverted for the second layer!!!
213 fSegmentation->GetPadIxz(x1l, z1l, c1, r1);
214 fSegmentation->GetPadIxz(x2l, z2l, c2, r2);
216 // to account for unexpected equal entrance and
218 if (x1l==x2l) x2l=x2l+x2l*0.000001;
219 if (z1l==z2l) z2l=z2l+z2l*0.000001;
221 // to account for tracks at the edge of the sensitive area
229 if ((r1==r2) && (c1==c2))
233 frowpixel[npixel-1] = r1;
234 fcolpixel[npixel-1] = c1;
235 fenepixel[npixel-1] = etot;
239 ChargeSharing(x1l,z1l,x2l,z2l,c1,r1,c2,r2,etot,
240 npixel,frowpixel,fcolpixel,fenepixel);
245 for (Int_t npix=0;npix<npixel;npix++)
247 row = frowpixel[npix];
248 col = fcolpixel[npix];
249 ene = fenepixel[npix];
250 UpdateMap(row,col,ene);
251 GetList(ntrack,pList,row,col);
252 // Starting capacitive coupling effect
253 SetCoupling(row,col,ntrack,pList);
261 //_________________________________________________________________________
263 void AliITSsimulationSPDbari::ChargeSharing(Float_t x1l,Float_t z1l,Float_t x2l,
264 Float_t z2l,Int_t c1,Int_t r1,Int_t c2,
265 Int_t r2,Float_t etot,
266 Int_t &npixel,Int_t *frowpixel,
267 Int_t *fcolpixel,Double_t *fenepixel){
269 // Take into account the geometrical charge sharing when the track
270 // crosses more than one pixel.
274 <img src="picts/ITS/barimodel_2.gif">
277 <font size=+2 color=red>
278 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
285 Float_t xa,za,xb,zb,dx,dz,dtot,dm,refr,refm,refc;
287 Float_t arefm, arefr, arefn, arefc, azb, az2l, axb, ax2l;
288 Int_t dirx,dirz,rb,cb;
291 Int_t flag,flagrow,flagcol;
299 dx = TMath::Abs(x1l-x2l);
300 dz = TMath::Abs(z1l-z2l);
301 dtot = TMath::Sqrt((dx*dx)+(dz*dz));
302 dm = (x2l - x1l) / (z2l - z1l);
304 dirx = (Int_t) ((x2l - x1l) / dx);
305 dirz = (Int_t) ((z2l - z1l) / dz);
308 // calculate the x coordinate of the pixel in the next column
309 // and the z coordinate of the pixel in the next row
313 fSegmentation->GetPadCxz(c1, r1-1, xpos, zpos);
315 Float_t xsize = fSegmentation->Dpx(0);
316 Float_t zsize = fSegmentation->Dpz(r1);
318 if (dirx == 1) refr = xpos+xsize/2.;
319 else refr = xpos-xsize/2.;
321 if (dirz == 1) refn = zpos+zsize/2.;
322 else refn = zpos-zsize/2.;
331 // calculate the x coordinate of the intersection with the pixel
332 // in the next cell in row direction
334 refm = (refn - z1l)*dm + x1l;
336 // calculate the z coordinate of the intersection with the pixel
337 // in the next cell in column direction
339 refc = (refr - x1l)/dm + z1l;
348 if ((arefm < arefr) && (arefn < arefc)){
350 // the track goes in the pixel in the next cell in row direction
357 if (rb == r2) flagrow=1;
363 // shift to the pixel in the next cell in row direction
364 Float_t zsizeNext = fSegmentation->Dpz(rb);
365 refn += zsizeNext*dirz;
370 // the track goes in the pixel in the next cell in column direction
377 if (cb == c2) flagcol=1;
383 // shift to the pixel in the next cell in column direction
384 Float_t xsizeNext = fSegmentation->Dpx(cb);
385 refr += xsizeNext*dirx;
389 //calculate the energy lost in the crossed pixel
390 epar = TMath::Sqrt((xb-xa)*(xb-xa)+(zb-za)*(zb-za));
391 epar = etot*(epar/dtot);
393 //store row, column and energy lost in the crossed pixel
396 frowpixel[npixel] = r1;
397 fcolpixel[npixel] = c1;
398 fenepixel[npixel] = epar;
401 // the exit point of the track is reached
402 if (epar == 0) flag = 1;
403 if ((r1 == r2) && (c1 == c2)) flag = 1;
414 //___________________________________________________________________________
415 void AliITSsimulationSPDbari::SetCoupling(Int_t row, Int_t col, Int_t ntrack,
418 // Take into account the coupling between adiacent pixels.
419 // The parameters probcol and probrow are the fractions of the
420 // signal in one pixel shared in the two adjacent pixels along
421 // the column and row direction, respectively.
425 <img src="picts/ITS/barimodel_3.gif">
428 <font size=+2 color=red>
429 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
437 Double_t pulse1,pulse2;
443 pulse1 = fMapA2->GetSignal(row,col);
446 for (Int_t isign=-1;isign<=1;isign+=2)
449 // loop in row direction
456 if ((j1 < 0) || (j1 > fNPixelsZ-1) || (pulse1 < fThresh))
458 pulse1 = fMapA2->GetSignal(row,col);
463 UpdateMap(j1,col,pulse1);
464 GetList(ntrack,pList,j1,col);
471 // loop in column direction
478 if ((j2 < 0) || (j2 > (fNPixelsX-1)) || (pulse2 < fThresh))
480 pulse2 = fMapA2->GetSignal(row,col);
485 UpdateMap(row,j2,pulse2);
486 GetList(ntrack,pList,row,j2);
495 //___________________________________________________________________________
496 void AliITSsimulationSPDbari::CreateDigit(Int_t nhits, Int_t module, Float_t
499 // The pixels are fired if the energy deposited inside them is above
500 // the threshold parameter ethr. Fired pixed are interpreted as digits
501 // and stored in the file digitfilename.
504 AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
516 for (Int_t r=1;r<=fNPixelsZ;r++) {
517 for (Int_t c=1;c<=fNPixelsX;c++) {
519 // check if the deposited energy in a pixel is above the threshold
520 Float_t signal = (Float_t) fMapA2->GetSignal(r,c);
521 if ( signal > fThresh) {
522 digits[0] = r-1; // digits starts from 0
523 digits[1] = c-1; // digits starts from 0
525 gi =r*fNPixelsX+c; // global index
527 tracks[j1] = (Int_t)(*(pList[gi]+j1));
531 aliITS->AddSimDigit(0,phys,digits,tracks,hits,charges);
532 if(pList[gi]) delete [] pList[gi];
533 }//endif of threshold condition
539 //_____________________________________________________________________________
541 void AliITSsimulationSPDbari::GetList(Int_t label,Float_t **pList,
542 Int_t row, Int_t col) {
543 // loop over nonzero digits
549 Float_t highest,middle,lowest;
552 signal=fMapA2->GetSignal(iz,ix);
554 globalIndex = iz*fNPixelsX+ix; // globalIndex starts from 1
557 if(!pList[globalIndex])
560 // Create new list (6 elements - 3 signals and 3 tracks + total sig)
563 pList[globalIndex] = new Float_t [6];
567 *(pList[globalIndex]) = -2.;
568 *(pList[globalIndex]+1) = -2.;
569 *(pList[globalIndex]+2) = -2.;
570 *(pList[globalIndex]+3) = 0.;
571 *(pList[globalIndex]+4) = 0.;
572 *(pList[globalIndex]+5) = 0.;
574 *pList[globalIndex] = (float)label;
575 *(pList[globalIndex]+3) = signal;
580 // check the signal magnitude
581 highest = *(pList[globalIndex]+3);
582 middle = *(pList[globalIndex]+4);
583 lowest = *(pList[globalIndex]+5);
586 signal -= (highest+middle+lowest);
590 // compare the new signal with already existing list
592 if(signal<lowest) return; // neglect this track
596 *(pList[globalIndex]+5) = middle;
597 *(pList[globalIndex]+4) = highest;
598 *(pList[globalIndex]+3) = signal;
599 *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
600 *(pList[globalIndex]+1) = *pList[globalIndex];
601 *(pList[globalIndex]) = label;
603 else if (signal>middle)
605 *(pList[globalIndex]+5) = middle;
606 *(pList[globalIndex]+4) = signal;
607 *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
608 *(pList[globalIndex]+1) = label;
612 *(pList[globalIndex]+5) = signal;
613 *(pList[globalIndex]+2) = label;
617 //_________________________________________________________________________
618 void AliITSsimulationSPDbari::SetFluctuations(Float_t **pList) {
620 // Set the electronic noise and threshold non-uniformities to all the
621 // pixels in a detector.
622 // The parameter fSigma is the squared sum of the sigma due to noise
623 // and the sigma of the threshold distribution among pixels.
627 <img src="picts/ITS/barimodel_1.gif">
630 <font size=+2 color=red>
631 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
642 for(iz=1;iz<=fNPixelsZ;iz++){
643 for(ix=1;ix<=fNPixelsX;ix++){
644 signal = fSigma*random.Gaus();
645 fMapA2->SetHit(iz,ix,signal);
647 // insert in the label-signal list the pixels fired only by noise
648 if ( signal > fThresh) {
649 Int_t globalIndex = iz*fNPixelsX+ix;
650 pList[globalIndex] = new Float_t [6];
651 *(pList[globalIndex]) = -2.;
652 *(pList[globalIndex]+1) = -2.;
653 *(pList[globalIndex]+2) = -2.;
654 *(pList[globalIndex]+3) = signal;
655 *(pList[globalIndex]+4) = 0.;
656 *(pList[globalIndex]+5) = 0.;
658 } // end of loop on pixels
659 } // end of loop on pixels
662 //____________________________________________
664 void AliITSsimulationSPDbari::CreateHistograms() {
668 for(i=0;i<fNPixelsZ;i++) {
669 TString spdname("spd_");
671 sprintf(candnum,"%d",i+1);
672 spdname.Append(candnum);
673 (*fHis)[i] = new TH1F(spdname.Data(),"SPD maps",
674 fNPixelsX,0.,(Float_t) fNPixelsX);
679 //____________________________________________
681 void AliITSsimulationSPDbari::ResetHistograms() {
683 // Reset histograms for this detector
686 for(i=0;i<fNPixelsZ;i++ ) {
687 if ((*fHis)[i]) ((TH1F*)(*fHis)[i])->Reset();