1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.17 2002/07/16 17:00:17 barbera
19 Fixes added to make the slow simulation running with the current HEAD (from M. Masera)
21 Revision 1.16 2002/06/19 16:02:22 hristov
22 Division by zero corrected
24 Revision 1.15 2002/03/15 17:32:14 nilsen
25 Reintroduced SDigitization, and Digitization from SDigits, along with
26 functions InitSimulationModule, and FinishSDigitizModule.
28 Revision 1.14 2001/11/23 13:04:07 barbera
29 Some protection added in case of high multiplicity
31 Revision 1.13 2001/11/13 11:13:24 barbera
32 A protection against tracks with the same entrance and exit has been made more strict
34 Revision 1.12 2001/10/04 22:44:31 nilsen
35 Major changes in supppor of PreDigits (SDigits). Changes made with will make
36 it easier to suppor expected changes in AliITSHit class. Added use of new
37 class AliITSpList. Both SPD and SDD have added effects of Dead Channels. Both
38 of these will require addtional work as data bases of detectors and the like
47 #include <TParticle.h>
51 #include "AliITShit.h"
52 #include "AliITSdigit.h"
53 #include "AliITSmodule.h"
54 #include "AliITSMapA2.h"
55 #include "AliITSpList.h"
56 #include "AliITSsimulationSPD.h"
57 #include "AliITSsegmentation.h"
58 #include "AliITSresponse.h"
59 #include "AliITSsegmentationSPD.h"
60 #include "AliITSresponseSPD.h"
64 ClassImp(AliITSsimulationSPD)
65 ////////////////////////////////////////////////////////////////////////
67 // Written by Rocco Caliandro
68 // from a model developed with T. Virgili and R.A. Fini
71 // AliITSsimulationSPD is the simulation of SPDs
73 //______________________________________________________________________
74 AliITSsimulationSPD::AliITSsimulationSPD(){
75 // Default constructor
88 //______________________________________________________________________
89 AliITSsimulationSPD::AliITSsimulationSPD(AliITSsegmentation *seg,
90 AliITSresponse *resp) {
91 // Standard constructor
103 Init((AliITSsegmentationSPD*)seg,(AliITSresponseSPD*)resp);
105 //______________________________________________________________________
106 void AliITSsimulationSPD::Init(AliITSsegmentationSPD *seg,
107 AliITSresponseSPD *resp) {
108 // Initilizes the variables of AliITSsimulation SPD.
113 fMapA2 = new AliITSMapA2(fSegmentation);
114 fpList = new AliITSpList(GetNPixelsZ()+1,GetNPixelsX()+1);
116 fResponse->Thresholds(fThresh,fSigma);
117 fResponse->GetNoiseParam(fCouplCol,fCouplRow);
118 fNPixelsZ = fSegmentation->Npz();
119 fNPixelsX = fSegmentation->Npx();
122 //______________________________________________________________________
123 AliITSsimulationSPD::~AliITSsimulationSPD() {
134 //______________________________________________________________________
135 AliITSsimulationSPD::AliITSsimulationSPD(const AliITSsimulationSPD &source){
138 if(&source == this) return;
140 this->fMapA2 = source.fMapA2;
141 this->fHis = source.fHis;
143 this->fThresh = source.fThresh;
144 this->fSigma = source.fSigma;
145 this->fCouplCol = source.fCouplCol;
146 this->fCouplRow = source.fCouplRow;
147 this->fNPixelsX = source.fNPixelsX;
148 this->fNPixelsZ = source.fNPixelsZ;
152 //______________________________________________________________________
153 AliITSsimulationSPD& AliITSsimulationSPD::operator=(const AliITSsimulationSPD
155 // Assignment operator
157 if(&source == this) return *this;
159 this->fMapA2 = source.fMapA2;
160 this->fHis = source.fHis;
162 this->fThresh = source.fThresh;
163 this->fSigma = source.fSigma;
164 this->fCouplCol = source.fCouplCol;
165 this->fCouplRow = source.fCouplRow;
166 this->fNPixelsX = source.fNPixelsX;
167 this->fNPixelsZ = source.fNPixelsZ;
171 //______________________________________________________________________
172 void AliITSsimulationSPD::InitSimulationModule(Int_t module,Int_t event){
173 // Creates maps to build the list of tracks for each sumable digit
175 // Int_t module // Module number to be simulated
176 // Int_t event // Event number to be simulated
187 //______________________________________________________________________
188 void AliITSsimulationSPD::FinishSDigitiseModule(){
189 // Does the Sdigits to Digits work
197 SDigitsToDigits(fModule,fpList);
199 //______________________________________________________________________
200 void AliITSsimulationSPD::SDigitiseModule(AliITSmodule *mod, Int_t dummy0,
202 // Sum digitize module
203 if (!(mod->GetNhits())) return; // if module has no hits then no Sdigits.
204 Int_t number = 10000;
205 Int_t *frowpixel = new Int_t[number];
206 Int_t *fcolpixel = new Int_t[number];
207 Double_t *fenepixel = new Double_t[number];
209 fModule = mod->GetIndex();
211 // Array of pointers to store the track index of the digits
212 // leave +1, otherwise pList crashes when col=256, row=192
214 HitsToAnalogDigits(mod,frowpixel,fcolpixel,fenepixel,fpList);
216 WriteSDigits(fpList);
225 //______________________________________________________________________
226 void AliITSsimulationSPD::DigitiseModule(AliITSmodule *mod, Int_t dummy0,
228 // digitize module. Also need to digitize modules with only noise.
230 Int_t number = 10000;
231 Int_t *frowpixel = new Int_t[number];
232 Int_t *fcolpixel = new Int_t[number];
233 Double_t *fenepixel = new Double_t[number];
235 // Array of pointers to store the track index of the digits
236 // leave +1, otherwise pList crashes when col=256, row=192
237 fModule = mod->GetIndex();
239 SetFluctuations(fpList,fModule);
241 HitsToAnalogDigits(mod,frowpixel,fcolpixel,fenepixel,fpList);
243 // apply mask to SPD module
246 CreateDigit(fModule,fpList);
255 //______________________________________________________________________
256 void AliITSsimulationSPD::SDigitsToDigits(Int_t module,AliITSpList *pList) {
257 // sum digits to Digits.
260 cout << "Entering AliITSsimulatinSPD::SDigitsToDigits for module=";
261 cout << module << endl;
266 SetFluctuations(pList,module);
268 fMapA2->ClearMap(); // since noise is in pList aready. Zero Map so that
269 // noise is not doubled when calling FillMapFrompList.
271 FillMapFrompList(pList);
273 // apply mask to SPD module
276 CreateDigit(module,pList);
281 //______________________________________________________________________
282 void AliITSsimulationSPD::UpdateMapSignal(Int_t row,Int_t col,Int_t trk,
283 Int_t hit,Int_t mod,Double_t ene,
284 AliITSpList *pList) {
285 // updates the Map of signal, adding the energy (ene) released by
288 fMapA2->AddSignal(row,col,ene);
289 pList->AddSignal(row,col,trk,hit,mod,ene);
291 //______________________________________________________________________
292 void AliITSsimulationSPD::UpdateMapNoise(Int_t row,Int_t col,Int_t mod,
293 Double_t ene,AliITSpList *pList) {
294 // updates the Map of noise, adding the energy (ene) give my noise
296 fMapA2->AddSignal(row,col,ene);
297 pList->AddNoise(row,col,mod,ene);
299 //______________________________________________________________________
300 void AliITSsimulationSPD::HitsToAnalogDigits(AliITSmodule *mod,
301 Int_t *frowpixel,Int_t *fcolpixel,
303 AliITSpList *pList) {
304 // Loops over all hits to produce Analog/floting point digits. This
305 // is also the first task in producing standard digits.
307 // loop over hits in the module
308 Int_t hitpos,nhits = mod->GetNhits();
309 for (hitpos=0;hitpos<nhits;hitpos++) {
310 HitToDigit(mod,hitpos,frowpixel,fcolpixel,fenepixel,pList);
311 }// end loop over digits
313 //______________________________________________________________________
314 void AliITSsimulationSPD::HitToDigit(AliITSmodule *mod,Int_t hitpos,
315 Int_t *frowpixel,Int_t *fcolpixel,
316 Double_t *fenepixel,AliITSpList *pList) {
317 // Steering function to determine the digits associated to a given
319 // The digits are created by charge sharing (ChargeSharing) and by
320 // capacitive coupling (SetCoupling). At all the created digits is
321 // associated the track number of the hit (ntrack)
322 Double_t x1l=0.0,y1l=0.0,z1l=0.0,x2l=0.0,y2l=0.0,z2l=0.0;
323 Int_t r1,r2,c1,c2,row,col,npixel = 0;
325 Double_t ene=0.0,etot=0.0;
326 const Float_t kconv = 10000.; // cm -> microns
327 const Float_t kconv1= 0.277e9; // GeV -> electrons equivalent
329 if(!(mod->LineSegmentL(hitpos,x1l,x2l,y1l,y2l,z1l,z2l,etot,ntrack)))return;
331 x2l += x1l; y2l += y1l; z2l += z1l; // Convert to ending coordinate.
332 // positions shifted and converted in microns
333 x1l = x1l*kconv + fSegmentation->Dx()/2.;
334 z1l = z1l*kconv + fSegmentation->Dz()/2.;
335 // positions shifted and converted in microns
336 x2l = x2l*kconv + fSegmentation->Dx()/2.;
337 z2l = z2l*kconv + fSegmentation->Dz()/2.;
338 etot *= kconv1; // convert from GeV to electrons equivalent.
339 Int_t module = mod->GetIndex();
341 // to account for the effective sensitive area
342 // introduced in geometry
343 if (z1l<0 || z1l>fSegmentation->Dz()) return;
344 if (z2l<0 || z2l>fSegmentation->Dz()) return;
345 if (x1l<0 || x1l>fSegmentation->Dx()) return;
346 if (x2l<0 || x2l>fSegmentation->Dx()) return;
348 //Get the col and row number starting from 1
349 // the x direction is not inverted for the second layer!!!
350 fSegmentation->GetPadIxz(x1l, z1l, c1, r1);
351 fSegmentation->GetPadIxz(x2l, z2l, c2, r2);
353 // to account for unexpected equal entrance and
355 if (x1l==x2l) x2l=x2l+x2l*0.1;
356 if (z1l==z2l) z2l=z2l+z2l*0.1;
358 if ((r1==r2) && (c1==c2)){
361 frowpixel[npixel-1] = r1;
362 fcolpixel[npixel-1] = c1;
363 fenepixel[npixel-1] = etot;
366 ChargeSharing(x1l,z1l,x2l,z2l,c1,r1,c2,r2,etot,
367 npixel,frowpixel,fcolpixel,fenepixel);
368 } // end if r1==r2 && c1==c2.
370 for (Int_t npix=0;npix<npixel;npix++){
371 row = frowpixel[npix];
372 col = fcolpixel[npix];
373 ene = fenepixel[npix];
374 UpdateMapSignal(row,col,ntrack,hitpos,module,ene,pList);
375 // Starting capacitive coupling effect
376 SetCoupling(row,col,ntrack,hitpos,module,pList);
379 //______________________________________________________________________
380 void AliITSsimulationSPD::ChargeSharing(Float_t x1l,Float_t z1l,Float_t x2l,
381 Float_t z2l,Int_t c1,Int_t r1,Int_t c2,
382 Int_t r2,Float_t etot,
383 Int_t &npixel,Int_t *frowpixel,
384 Int_t *fcolpixel,Double_t *fenepixel){
385 // Take into account the geometrical charge sharing when the track
386 // crosses more than one pixel.
390 <img src="picts/ITS/barimodel_2.gif">
393 <font size=+2 color=red>
394 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
399 Float_t xa,za,xb,zb,dx,dz,dtot,dm,refr,refm,refc;
401 Float_t arefm, arefr, arefn, arefc, azb, az2l, axb, ax2l;
402 Int_t dirx,dirz,rb,cb;
403 Int_t flag,flagrow,flagcol;
413 dtot = TMath::Sqrt((dx*dx)+(dz*dz));
414 if (dtot==0.0) dtot = 0.01;
415 dirx = (Int_t) TMath::Sign((Float_t)1,dx);
416 dirz = (Int_t) TMath::Sign((Float_t)1,dz);
418 // calculate the x coordinate of the pixel in the next column
419 // and the z coordinate of the pixel in the next row
422 fSegmentation->GetPadCxz(c1, r1-1, xpos, zpos);
424 Float_t xsize = fSegmentation->Dpx(0);
425 Float_t zsize = fSegmentation->Dpz(r1-1);
427 if (dirx == 1) refr = xpos+xsize/2.;
428 else refr = xpos-xsize/2.;
430 if (dirz == 1) refn = zpos+zsize/2.;
431 else refn = zpos-zsize/2.;
437 // calculate the x coordinate of the intersection with the pixel
438 // in the next cell in row direction
440 refm = dx*((refn - z1l)/dz) + x1l;
442 refm = refr+dirx*xsize;
444 // calculate the z coordinate of the intersection with the pixel
445 // in the next cell in column direction
447 refc = dz*((refr - x1l)/dx) + z1l;
449 refc = refn+dirz*zsize;
456 if ((arefm < arefr) && (arefn < arefc)){
457 // the track goes in the pixel in the next cell in row direction
464 if (rb == r2) flagrow=1;
469 // shift to the pixel in the next cell in row direction
470 Float_t zsizeNext = fSegmentation->Dpz(rb-1);
471 //to account for cell at the borders of the detector
472 if(zsizeNext==0) zsizeNext = zsize;
473 refn += zsizeNext*dirz;
475 // the track goes in the pixel in the next cell in column direction
482 if (cb == c2) flagcol=1;
486 } // end ifaxb > ax2l
488 // shift to the pixel in the next cell in column direction
489 Float_t xsizeNext = fSegmentation->Dpx(cb-1);
490 //to account for cell at the borders of the detector
491 if(xsizeNext==0) xsizeNext = xsize;
492 refr += xsizeNext*dirx;
493 } // end if (arefm < arefr) && (arefn < arefc)
495 //calculate the energy lost in the crossed pixel
496 epar = TMath::Sqrt((xb-xa)*(xb-xa)+(zb-za)*(zb-za));
497 epar = etot*(epar/dtot);
499 //store row, column and energy lost in the crossed pixel
500 frowpixel[npixel] = r1;
501 fcolpixel[npixel] = c1;
502 fenepixel[npixel] = epar;
505 // the exit point of the track is reached
506 if (epar == 0) flag = 1;
507 if ((r1 == r2) && (c1 == c2)) flag = 1;
516 //______________________________________________________________________
517 void AliITSsimulationSPD::SetCoupling(Int_t row, Int_t col, Int_t ntrack,
518 Int_t idhit,Int_t module,
519 AliITSpList *pList) {
520 // Take into account the coupling between adiacent pixels.
521 // The parameters probcol and probrow are the fractions of the
522 // signal in one pixel shared in the two adjacent pixels along
523 // the column and row direction, respectively.
527 <img src="picts/ITS/barimodel_3.gif">
530 <font size=+2 color=red>
531 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
537 Double_t pulse1,pulse2;
538 Float_t couplR=0.0,couplC=0.0;
540 GetCouplings(couplR,couplC);
543 pulse1 = fMapA2->GetSignal(row,col);
545 for (Int_t isign=-1;isign<=1;isign+=2){// loop in row direction
549 if ((j1<0) || (j1>GetNPixelsZ()-1) || (pulse1<GetThreshold())){
550 pulse1 = fMapA2->GetSignal(row,col);
554 UpdateMapSignal(j1,col,ntrack,idhit,module,pulse1,pList);
558 // loop in column direction
562 if ((j2<0) || (j2>(GetNPixelsX()-1)) || (pulse2<GetThreshold())){
563 pulse2 = fMapA2->GetSignal(row,col);
567 UpdateMapSignal(row,j2,ntrack,idhit,module,pulse2,pList);
573 //______________________________________________________________________
574 void AliITSsimulationSPD::CreateDigit(Int_t module,AliITSpList *pList) {
575 // The pixels are fired if the energy deposited inside them is above
576 // the threshold parameter ethr. Fired pixed are interpreted as digits
577 // and stored in the file digitfilename. One also needs to write out
578 // cases when there is only noise (nhits==0).
580 static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
588 for (Int_t r=1;r<=GetNPixelsZ();r++) {
589 for (Int_t c=1;c<=GetNPixelsX();c++) {
590 // check if the deposited energy in a pixel is above the
592 Float_t signal = (Float_t) fMapA2->GetSignal(r,c);
593 if ( signal > GetThreshold()) {
594 digits[0] = r-1; // digits starts from 0
595 digits[1] = c-1; // digits starts from 0
597 digits[2] = (Int_t) signal; // the signal is stored in
600 tracks[j1] = pList->GetTrack(r,c,j1);
601 hits[j1] = pList->GetHit(r,c,j1);
605 aliITS->AddSimDigit(0,phys,digits,tracks,hits,charges);
607 cout << " CreateSPDDigit mod=" << fModule << " r,c=" << r;
608 cout <<","<<c<< " sig=" << fpList->GetSignalOnly(r,c);
609 cout << " noise=" << fpList->GetNoise(r,c);
610 cout << " Msig="<< signal << " Thres=" << GetThreshold()<<endl;
612 } // end if of threshold condition
616 //______________________________________________________________________
617 void AliITSsimulationSPD::SetFluctuations(AliITSpList *pList,Int_t module) {
618 // Set the electronic noise and threshold non-uniformities to all the
619 // pixels in a detector.
620 // The parameter fSigma is the squared sum of the sigma due to noise
621 // and the sigma of the threshold distribution among pixels.
625 <img src="picts/ITS/barimodel_1.gif">
628 <font size=+2 color=red>
629 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
634 Float_t thr=0.0,sigm=0.0;
635 Double_t signal,sigma;
638 GetThresholds(thr,sigm);
639 sigma = (Double_t) sigm;
640 for(iz=1;iz<=GetNPixelsZ();iz++){
641 for(ix=1;ix<=GetNPixelsX();ix++){
642 signal = sigma*gRandom->Gaus();
643 fMapA2->SetHit(iz,ix,signal);
644 // insert in the label-signal-hit list the pixels fired
646 pList->AddNoise(iz,ix,module,signal);
647 } // end of loop on pixels
648 } // end of loop on pixels
650 //______________________________________________________________________
651 void AliITSsimulationSPD::SetMask() {
652 // Apply a mask to the SPD module. 1% of the pixel channels are
653 // masked. When the database will be ready, the masked pixels
654 // should be read from it.
658 Float_t perc = ((AliITSresponseSPD*)fResponse)->GetFractionDead();
659 // in this way we get the same set of random numbers for all runs.
660 // This is a cluge for now.
661 static TRandom *rnd = new TRandom();
663 totMask= perc*GetNPixelsZ()*GetNPixelsX();
664 for(im=1;im<totMask;im++){
666 ix=(Int_t)(rnd->Rndm()*(GetNPixelsX()-1.) + 1.);
667 } while(ix<=0 || ix>GetNPixelsX());
669 iz=(Int_t)(rnd->Rndm()*(GetNPixelsZ()-1.) + 1.);
670 } while(iz<=0 || iz>GetNPixelsZ());
672 fMapA2->SetHit(iz,ix,signal);
673 } // end loop on masked pixels
675 //______________________________________________________________________
676 void AliITSsimulationSPD::CreateHistograms() {
680 fHis=new TObjArray(GetNPixelsZ());
681 for(i=0;i<GetNPixelsZ();i++) {
682 TString spdname("spd_");
684 sprintf(candnum,"%d",i+1);
685 spdname.Append(candnum);
686 (*fHis)[i] = new TH1F(spdname.Data(),"SPD maps",
687 GetNPixelsX(),0.,(Float_t) GetNPixelsX());
690 //______________________________________________________________________
691 void AliITSsimulationSPD::ResetHistograms() {
692 // Reset histograms for this detector
695 for(i=0;i<GetNPixelsZ();i++ ) {
696 if ((*fHis)[i]) ((TH1F*)(*fHis)[i])->Reset();
699 //______________________________________________________________________
700 void AliITSsimulationSPD::WriteSDigits(AliITSpList *pList){
701 // Fills the Summable digits Tree
703 static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
705 pList->GetMaxMapIndex(ni,nj);
706 for(i=0;i<ni;i++)for(j=0;j<nj;j++){
707 if(pList->GetSignalOnly(i,j)>0.0){
708 aliITS->AddSumDigit(*(pList->GetpListItem(i,j)));
710 cout << "pListSPD: " << *(pList->GetpListItem(i,j)) << endl;
711 cout << " CreateSPDSDigit mod=" << fModule << " r,c=";
712 cout << i <<","<< j << " sig=" << fpList->GetSignalOnly(i,j);
713 cout << " noise=" << fpList->GetNoise(i,j) <<endl;
719 //______________________________________________________________________
720 void AliITSsimulationSPD::FillMapFrompList(AliITSpList *pList){
721 // Fills fMap2A from the pList of Summable digits
724 for(iz=0;iz<GetNPixelsZ();iz++)for(ix=0;ix<GetNPixelsX();ix++)
725 fMapA2->AddSignal(iz,ix,pList->GetSignal(iz,ix));