New version compatible with the current HEAD
[u/mrichter/AliRoot.git] / ITS / AliITSsimulationSPDbari.cxx
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 "AliITSsimulationSPDbari.h"
16 #include "AliITSsegmentation.h"
17 #include "AliITSresponse.h"
18
19
20 ClassImp(AliITSsimulationSPDbari)
21 ////////////////////////////////////////////////////////////////////////
22 // Version: 0
23 // Written by Rocco Caliandro
24 // from a model developed with T. Virgili and R.A. Fini
25 // June 15 2000
26 //
27 // AliITSsimulationSPD is the simulation of SPDs
28 //
29 //________________________________________________________________________
30
31 AliITSsimulationSPDbari::AliITSsimulationSPDbari(){
32   // constructor
33   fResponse     = 0;
34   fSegmentation = 0;
35   fHis          = 0;
36   fThresh       = 0.;
37   fSigma        = 0.;
38   fCouplCol     = 0.;
39   fCouplRow     = 0.;
40 }
41 //_____________________________________________________________________________
42
43 AliITSsimulationSPDbari::AliITSsimulationSPDbari(AliITSsegmentation *seg, AliITSresponse *resp) {
44   // constructor
45       fResponse = resp;
46       fSegmentation = seg;
47
48       fResponse->Thresholds(fThresh,fSigma);
49       fResponse->GetNoiseParam(fCouplCol,fCouplRow);
50       
51       fMapA2 = new AliITSMapA2(fSegmentation);
52    
53       // 
54       fNPixelsZ=fSegmentation->Npz();
55       fNPixelsX=fSegmentation->Npx();
56
57 }
58
59 //_____________________________________________________________________________
60
61 AliITSsimulationSPDbari::~AliITSsimulationSPDbari() { 
62   // destructor
63
64   delete fMapA2;
65
66   if (fHis) {
67      fHis->Delete(); 
68      delete fHis;     
69   }                
70 }
71
72 //__________________________________________________________________________
73 AliITSsimulationSPDbari::AliITSsimulationSPDbari(const AliITSsimulationSPDbari &source){
74   //     Copy Constructor 
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;
84   return;
85 }
86
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;
100   return *this;
101   }
102 //_____________________________________________________________________________
103
104 void AliITSsimulationSPDbari::DigitiseModule(AliITSmodule *mod, Int_t module,
105                                              Int_t dummy) {
106   // digitize module
107
108
109   TObjArray *fHits = mod->GetHits();
110   Int_t nhits = fHits->GetEntriesFast();
111   if (!nhits) return;
112
113
114   printf("Module %d (%d hits) \n",module+1,nhits);
115
116
117   Int_t  number=10000;
118   Int_t    *frowpixel = new Int_t[number];
119   Int_t    *fcolpixel = new Int_t[number];
120   Double_t *fenepixel = new Double_t[number];
121
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);
127
128
129   // noise setting
130   SetFluctuations(pList);
131
132
133
134   // loop over hits in the module
135   Int_t hitpos;
136   for (hitpos=0;hitpos<nhits;hitpos++) {  
137      HitToDigit(mod,hitpos,module,frowpixel,fcolpixel,fenepixel,pList);
138   }// end loop over digits
139
140   CreateDigit(nhits,module,pList);
141
142   // clean memory
143   delete[] frowpixel;
144   delete[] fcolpixel;
145   delete[] fenepixel;
146   fMapA2->ClearMap();
147   delete [] pList;
148
149 }
150 //_____________________________________________________________________________
151
152 void AliITSsimulationSPDbari::UpdateMap( Int_t row, Int_t col, Double_t ene) {
153 //
154 // updates the Map of signal, adding the energy  (ene) released by the current track
155 //
156       Double_t signal; 
157       signal = fMapA2->GetSignal(row,col);
158       signal += ene;
159       fMapA2->SetHit(row,col,signal);
160                                          
161  }
162 //_____________________________________________________________________________  
163 void AliITSsimulationSPDbari::HitToDigit(AliITSmodule *mod, Int_t hitpos, Int_t module, 
164                                         Int_t *frowpixel, Int_t *fcolpixel,
165                                         Double_t *fenepixel, Float_t **pList) {
166 //
167 //  Steering function to determine the digits associated to a given hit (hitpos)
168 //  The digits are created by charge sharing (ChargeSharing) and by
169 //  capacitive coupling (SetCoupling). At all the created digits is associated
170 //  the track number of the hit (ntrack)
171 //
172
173
174    static Float_t x1l,y1l,z1l;
175    Float_t x2l,y2l,z2l,etot;
176    Int_t layer,r1,r2,c1,c2,row,col,npixel = 0;
177    Int_t ntrack,idhit;
178    Double_t ene;
179    const Float_t kconv = 10000.;     // cm -> microns
180
181    TObjArray *fHits = mod->GetHits();
182    AliITShit *hit = (AliITShit*) fHits->At(hitpos);
183    layer = hit->GetLayer();
184    etot=hit->GetIonization();
185    ntrack=hit->GetTrack();
186    idhit=mod->GetHitHitIndex(hitpos);     
187
188    /* //debug
189      printf("layer,etot,ntrack,status %d %f %d %d\n",layer,etot,ntrack,hit->GetTrackStatus()); //debug
190     Int_t idtrack; //debug
191     mod->GetHitTrackAndHitIndex(hitpos,idtrack,idhit);     
192     printf("idtrack,idhit %d %d\n",idtrack,idhit); //debug
193     */
194
195
196         if (hit->GetTrackStatus()==66) {
197               hit->GetPositionL(x1l,y1l,z1l);
198           // positions shifted and converted in microns 
199           x1l = x1l*kconv + fSegmentation->Dx()/2.;
200           z1l = z1l*kconv + fSegmentation->Dz()/2.;
201         }
202         else {
203               hit->GetPositionL(x2l,y2l,z2l);         
204           // positions  shifted and converted in microns
205           x2l = x2l*kconv + fSegmentation->Dx()/2.;
206           z2l = z2l*kconv + fSegmentation->Dz()/2.;
207
208
209           // to account for 83750 effective sensitive area
210           // introduced in geometry (Dz=83600)
211           if (z1l>fSegmentation->Dz()) return;
212           if (z2l>fSegmentation->Dz()) return;
213           // to preserve for hit having x>12800
214           if (x1l>fSegmentation->Dx()) return;
215           if (x2l>fSegmentation->Dx()) return;
216
217           //Get the col and row number starting from 1
218           // the x direction is not inverted for the second layer!!!
219               fSegmentation->GetPadIxz(x1l, z1l, c1, r1); 
220               fSegmentation->GetPadIxz(x2l, z2l, c2, r2);
221
222           // to account for unexpected equal entrance and 
223           // exit coordinates
224           if (x1l==x2l) x2l=x2l+x2l*0.000001;
225           if (z1l==z2l) z2l=z2l+z2l*0.000001;
226
227           // to account for tracks at the edge of the sensitive area
228           // of SPDs
229           if (x1l<0) return;
230           if (x2l<0) return;
231           if (z1l<0) return;
232           if (z2l<0) return;
233               
234
235               if ((r1==r2) && (c1==c2)) 
236               {
237              // no charge sharing
238                  npixel = 1;             
239                      frowpixel[npixel-1] = r1;
240                      fcolpixel[npixel-1] = c1;
241                      fenepixel[npixel-1] = etot;
242           }
243               else {
244              // charge sharing
245                  ChargeSharing(x1l,z1l,x2l,z2l,c1,r1,c2,r2,etot,
246                                        npixel,frowpixel,fcolpixel,fenepixel);
247
248           }
249                   
250
251           for (Int_t npix=0;npix<npixel;npix++)
252               {
253                    row = frowpixel[npix];
254                    col = fcolpixel[npix];
255                    ene = fenepixel[npix];
256                    UpdateMap(row,col,ene);                   
257                    GetList(ntrack,idhit,pList,row,col); 
258                    // Starting capacitive coupling effect
259                    SetCoupling(row,col,ntrack,idhit,pList); 
260               }
261             x1l=x2l;
262             y1l=y2l;
263             z1l=z2l;                 
264         }
265 }
266
267 //_________________________________________________________________________
268
269 void AliITSsimulationSPDbari::ChargeSharing(Float_t x1l,Float_t z1l,Float_t x2l,
270                     Float_t z2l,Int_t c1,Int_t r1,Int_t c2,
271                                     Int_t r2,Float_t etot,
272                                     Int_t &npixel,Int_t *frowpixel,
273                                     Int_t *fcolpixel,Double_t *fenepixel){
274   //
275   //  Take into account the geometrical charge sharing when the track
276   //  crosses more than one pixel.
277   //
278   //Begin_Html
279   /*
280   <img src="picts/ITS/barimodel_2.gif">
281   </pre>
282   <br clear=left>
283   <font size=+2 color=red>
284   <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
285   </font>
286   <pre>
287   */
288   //End_Html
289
290
291    Float_t xa,za,xb,zb,dx,dz,dtot,dm,refr,refm,refc;
292    Float_t refn=0.;
293    Float_t arefm, arefr, arefn, arefc, azb, az2l, axb, ax2l;
294    Int_t   dirx,dirz,rb,cb;
295
296
297    Int_t flag,flagrow,flagcol;
298   
299    Double_t epar;
300
301
302    npixel = 0;
303    xa = x1l;
304    za = z1l;
305    dx = TMath::Abs(x1l-x2l);
306    dz = TMath::Abs(z1l-z2l);
307    dtot = TMath::Sqrt((dx*dx)+(dz*dz));   
308    dm = (x2l - x1l) / (z2l - z1l);
309
310    dirx = (Int_t) ((x2l - x1l) / dx);
311    dirz = (Int_t) ((z2l - z1l) / dz);
312    
313    
314    // calculate the x coordinate of  the pixel in the next column    
315    // and the z coordinate of  the pixel in the next row    
316
317    Float_t xpos, zpos;
318
319    fSegmentation->GetPadCxz(c1, r1-1, xpos, zpos); 
320
321    Float_t xsize = fSegmentation->Dpx(0);
322    Float_t zsize = fSegmentation->Dpz(r1);
323
324    if (dirx == 1) refr = xpos+xsize/2.;
325              else refr = xpos-xsize/2.;
326
327    if (dirz == 1) refn = zpos+zsize/2.;
328              else refn = zpos-zsize/2.;
329
330    
331    flag = 0;
332    flagrow = 0;
333    flagcol = 0;
334    do
335    {
336        
337       // calculate the x coordinate of the intersection with the pixel
338       // in the next cell in row  direction
339
340       refm = (refn - z1l)*dm + x1l;
341    
342       // calculate the z coordinate of the intersection with the pixel
343       // in the next cell in column direction 
344
345       refc = (refr - x1l)/dm + z1l;
346       
347       
348       arefm = refm * dirx;
349       arefr = refr * dirx;
350       arefn = refn * dirz;
351       arefc = refc * dirz;
352             
353
354       if ((arefm < arefr) && (arefn < arefc)){
355                  
356          // the track goes in the pixel in the next cell in row direction
357              xb = refm;
358              zb = refn;
359              cb = c1;
360              rb = r1 + dirz;
361              azb = zb * dirz;
362          az2l = z2l * dirz;
363              if (rb == r2) flagrow=1;
364              if (azb > az2l) {
365                 zb = z2l;
366                 xb = x2l;
367              }     
368
369          // shift to the pixel in the next cell in row direction
370          Float_t zsizeNext = fSegmentation->Dpz(rb);
371              refn += zsizeNext*dirz;
372
373       }
374       else {
375          
376          // the track goes in the pixel in the next cell in column direction
377              xb = refr;
378              zb = refc;
379              cb = c1 + dirx;
380              rb = r1;
381              axb = xb * dirx;
382          ax2l = x2l * dirx;
383          if (cb == c2) flagcol=1;
384              if (axb > ax2l) {
385                 zb = z2l;
386                 xb = x2l;
387              }
388
389          // shift to the pixel in the next cell in column direction
390          Float_t xsizeNext = fSegmentation->Dpx(cb);
391              refr += xsizeNext*dirx;
392         
393       }
394       
395       //calculate the energy lost in the crossed pixel      
396       epar = TMath::Sqrt((xb-xa)*(xb-xa)+(zb-za)*(zb-za)); 
397       epar = etot*(epar/dtot);
398
399       //store row, column and energy lost in the crossed pixel
400
401
402       frowpixel[npixel] = r1;
403       fcolpixel[npixel] = c1;
404       fenepixel[npixel] = epar;
405       npixel++;
406  
407       // the exit point of the track is reached
408       if (epar == 0) flag = 1;
409       if ((r1 == r2) && (c1 == c2)) flag = 1;
410       if (flag!=1) {
411         r1 = rb;
412         c1 = cb;
413         xa = xb;
414         za = zb;
415       }
416    
417    } while (flag==0);
418
419 }
420 //___________________________________________________________________________
421 void AliITSsimulationSPDbari::SetCoupling(Int_t row, Int_t col, Int_t ntrack,
422                                           Int_t idhit, Float_t **pList) {
423    //
424    //  Take into account the coupling between adiacent pixels.
425    //  The parameters probcol and probrow are the fractions of the
426    //  signal in one pixel shared in the two adjacent pixels along
427    //  the column and row direction, respectively.
428    //
429    //Begin_Html
430    /*
431    <img src="picts/ITS/barimodel_3.gif">
432    </pre>
433    <br clear=left>
434    <font size=+2 color=red>
435    <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
436    </font>
437    <pre>
438    */
439    //End_Html
440
441
442    Int_t j1,j2,flag=0;
443    Double_t pulse1,pulse2;
444                               
445
446    j1 = row;
447    j2 = col;
448   
449    pulse1 = fMapA2->GetSignal(row,col);
450    pulse2 = pulse1;
451
452    for (Int_t isign=-1;isign<=1;isign+=2)
453    {
454
455 // loop in row direction
456       
457       do
458       {
459          j1 += isign;
460          pulse1 *= fCouplRow;                  
461       
462          if ((j1 < 0) || (j1 > fNPixelsZ-1) || (pulse1 < fThresh))
463          { 
464                pulse1 = fMapA2->GetSignal(row,col);
465                j1 = row;
466                flag = 1;
467          }
468           else{                
469                    UpdateMap(j1,col,pulse1);                   
470                    GetList(ntrack,idhit,pList,j1,col); 
471            flag = 0;
472              }
473          
474       } while(flag == 0);          
475       
476       
477 // loop in column direction
478       
479       do
480       {
481          j2 += isign;
482          pulse2 *= fCouplCol;                  
483       
484          if ((j2 < 0) || (j2 > (fNPixelsX-1)) || (pulse2 < fThresh))
485          {                
486                pulse2 = fMapA2->GetSignal(row,col);
487                j2 = col;
488                flag = 1;
489          }
490           else{                
491                    UpdateMap(row,j2,pulse2);                   
492                    GetList(ntrack,idhit,pList,row,j2); 
493            flag = 0;
494              }
495          
496       } while(flag == 0);          
497    
498    }
499
500 }
501 //___________________________________________________________________________
502 void AliITSsimulationSPDbari::CreateDigit(Int_t nhits, Int_t module, Float_t
503 **pList) {                                   
504   //
505   // The pixels are fired if the energy deposited inside them is above
506   // the threshold parameter ethr. Fired pixed are interpreted as digits
507   // and stored in the file digitfilename.
508   //
509
510    AliITS *aliITS  = (AliITS*)gAlice->GetModule("ITS");   
511  
512    
513    Int_t digits[3];
514    Int_t tracks[3];
515    Int_t hits[3];
516    Float_t charges[3]; 
517    Int_t gi,j1;
518    
519    if (nhits > 0) {
520     
521      for (Int_t r=1;r<=fNPixelsZ;r++) {
522         for (Int_t c=1;c<=fNPixelsX;c++) {
523    
524            // check if the deposited energy in a pixel is above the threshold 
525            Float_t signal = (Float_t) fMapA2->GetSignal(r,c);
526            if ( signal > fThresh) {
527                   digits[0] = r-1;  // digits starts from 0
528               digits[1] = c-1;  // digits starts from 0
529               //digits[2] = 1;  
530               signal = signal*1.0e9;  //signal in eV
531               digits[2] =  (Int_t) signal;  // the signal is stored in eV
532                   gi =r*fNPixelsX+c; // global index
533                   for(j1=0;j1<3;j1++){
534                  tracks[j1] = (Int_t)(*(pList[gi]+j1));
535                  hits[j1] = (Int_t)(*(pList[gi]+j1+6));
536                  charges[j1] = 0;
537               }
538               /* debug
539               printf("digits %d %d %d\n",digits[0],digits[1],digits[2]); //debug
540               printf("tracks %d %d %d\n",tracks[0],tracks[1],tracks[2]); //debug
541               printf("hits %d %d %d\n",hits[0],hits[1],hits[2]); //debug
542               */
543               Float_t phys = 0;        
544                   aliITS->AddSimDigit(0,phys,digits,tracks,hits,charges);
545                   if(pList[gi]) delete [] pList[gi];
546                }//endif of threshold condition
547         }
548      }// enddo on pixels
549     }
550     
551 }
552 //_____________________________________________________________________________
553
554 void AliITSsimulationSPDbari::GetList(Int_t label,Int_t idhit, Float_t **pList,
555                                       Int_t row, Int_t col) {
556   // loop over nonzero digits
557
558   Int_t ix = col;
559   Int_t iz = row;
560   Int_t globalIndex;
561   Float_t signal;
562   Float_t highest,middle,lowest;
563
564           
565   signal=fMapA2->GetSignal(iz,ix);
566
567   globalIndex = iz*fNPixelsX+ix; // globalIndex starts from 1
568
569
570   if(!pList[globalIndex])
571   {
572      // 
573      // Create new list (9 elements - 3 signals and 3 tracks + 3 hits)
574      //
575
576      pList[globalIndex] = new Float_t [9];
577
578
579      // set list to -3 
580      *(pList[globalIndex]) = -3.;
581      *(pList[globalIndex]+1) = -3.;
582      *(pList[globalIndex]+2) = -3.;
583      *(pList[globalIndex]+3) =  0.;
584      *(pList[globalIndex]+4) =  0.;
585      *(pList[globalIndex]+5) =  0.;
586      *(pList[globalIndex]+6) = -1.;
587      *(pList[globalIndex]+7) = -1.;
588      *(pList[globalIndex]+8) = -1.;
589
590      *pList[globalIndex] = (float)label;
591      *(pList[globalIndex]+3) = signal;
592      *(pList[globalIndex]+6) = (float)idhit;
593   }
594   else{
595
596
597           // check the signal magnitude
598       highest = *(pList[globalIndex]+3);
599       middle  = *(pList[globalIndex]+4);
600       lowest  = *(pList[globalIndex]+5);
601
602
603       signal -= (highest+middle+lowest);
604
605
606           //
607           //  compare the new signal with already existing list
608           //
609       if(signal<lowest) return; // neglect this track
610
611       if (signal>highest)
612       {
613          *(pList[globalIndex]+8) = *(pList[globalIndex]+7);
614          *(pList[globalIndex]+7) = *(pList[globalIndex]+6);
615          *(pList[globalIndex]+6) = idhit;
616          *(pList[globalIndex]+5) = middle;
617          *(pList[globalIndex]+4) = highest;
618          *(pList[globalIndex]+3) = signal;
619          *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
620          *(pList[globalIndex]+1) = *pList[globalIndex];
621          *(pList[globalIndex]) = label;
622           }
623         else if (signal>middle)
624       {
625          *(pList[globalIndex]+8) = *(pList[globalIndex]+7);
626          *(pList[globalIndex]+7) = idhit;
627          *(pList[globalIndex]+5) = middle;
628          *(pList[globalIndex]+4) = signal;
629          *(pList[globalIndex]+2) = *(pList[globalIndex]+1);
630          *(pList[globalIndex]+1) = label;
631           }
632         else
633       {
634          *(pList[globalIndex]+8) = idhit;
635          *(pList[globalIndex]+5) = signal;
636          *(pList[globalIndex]+2) = label;
637           }
638   }    
639 }
640 //_________________________________________________________________________ 
641 void AliITSsimulationSPDbari::SetFluctuations(Float_t **pList) {
642   //
643   //  Set the electronic noise and threshold non-uniformities to all the
644   //  pixels in a detector.
645   //  The parameter fSigma is the squared sum of the sigma due to noise
646   //  and the sigma of the threshold distribution among pixels.
647   //
648   //Begin_Html
649   /*
650   <img src="picts/ITS/barimodel_1.gif">
651   </pre>
652   <br clear=left>
653   <font size=+2 color=red>
654   <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
655   </font>
656   <pre>
657   */
658   //End_Html
659   
660   
661   TRandom random; 
662   Double_t signal;
663
664   Int_t iz,ix;
665   for(iz=1;iz<=fNPixelsZ;iz++){
666     for(ix=1;ix<=fNPixelsX;ix++){
667       signal = fSigma*random.Gaus(); 
668       fMapA2->SetHit(iz,ix,signal);
669
670       // insert in the label-signal-hit list the pixels fired only by noise
671       if ( signal > fThresh) {
672         Int_t globalIndex = iz*fNPixelsX+ix; 
673         pList[globalIndex] = new Float_t [9];
674         *(pList[globalIndex]) = -2.;
675         *(pList[globalIndex]+1) = -2.;
676         *(pList[globalIndex]+2) = -2.;
677         *(pList[globalIndex]+3) =  signal;
678         *(pList[globalIndex]+4) =  0.;
679         *(pList[globalIndex]+5) =  0.;
680         *(pList[globalIndex]+6) =  -1.;
681         *(pList[globalIndex]+7) =  -1.;
682         *(pList[globalIndex]+8) =  -1.;
683       }
684     } // end of loop on pixels
685   } // end of loop on pixels
686   
687  }
688 //____________________________________________
689
690 void AliITSsimulationSPDbari::CreateHistograms() {
691   // CreateHistograms
692
693       Int_t i;
694       for(i=0;i<fNPixelsZ;i++) {
695            TString spdname("spd_");
696            Char_t candnum[4];
697            sprintf(candnum,"%d",i+1);
698            spdname.Append(candnum);
699            (*fHis)[i] = new TH1F(spdname.Data(),"SPD maps",
700                               fNPixelsX,0.,(Float_t) fNPixelsX);
701       }
702
703 }
704
705 //____________________________________________
706
707 void AliITSsimulationSPDbari::ResetHistograms() {
708     //
709     // Reset histograms for this detector
710     //
711     Int_t i;
712     for(i=0;i<fNPixelsZ;i++ ) {
713         if ((*fHis)[i])    ((TH1F*)(*fHis)[i])->Reset();
714     }
715
716 }