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.14 2001/11/23 13:04:07 barbera
19 Some protection added in case of high multiplicity
21 Revision 1.13 2001/11/13 11:13:24 barbera
22 A protection against tracks with the same entrance and exit has been made more strict
24 Revision 1.12 2001/10/04 22:44:31 nilsen
25 Major changes in supppor of PreDigits (SDigits). Changes made with will make
26 it easier to suppor expected changes in AliITSHit class. Added use of new
27 class AliITSpList. Both SPD and SDD have added effects of Dead Channels. Both
28 of these will require addtional work as data bases of detectors and the like
37 #include <TParticle.h>
41 #include "AliITShit.h"
42 #include "AliITSdigit.h"
43 #include "AliITSmodule.h"
44 #include "AliITSMapA2.h"
45 #include "AliITSpList.h"
46 #include "AliITSsimulationSPD.h"
47 #include "AliITSsegmentation.h"
48 #include "AliITSresponse.h"
49 #include "AliITSsegmentationSPD.h"
50 #include "AliITSresponseSPD.h"
53 ClassImp(AliITSsimulationSPD)
54 ////////////////////////////////////////////////////////////////////////
56 // Written by Rocco Caliandro
57 // from a model developed with T. Virgili and R.A. Fini
60 // AliITSsimulationSPD is the simulation of SPDs
62 //______________________________________________________________________
63 AliITSsimulationSPD::AliITSsimulationSPD(){
64 // Default constructor
77 //______________________________________________________________________
78 AliITSsimulationSPD::AliITSsimulationSPD(AliITSsegmentation *seg,
79 AliITSresponse *resp) {
80 // Standard constructor
92 Init((AliITSsegmentationSPD*)seg,(AliITSresponseSPD*)resp);
94 //______________________________________________________________________
95 void AliITSsimulationSPD::Init(AliITSsegmentationSPD *seg,
96 AliITSresponseSPD *resp) {
97 // Initilizes the variables of AliITSsimulation SPD.
102 fMapA2 = new AliITSMapA2(fSegmentation);
103 fpList = new AliITSpList(GetNPixelsZ()+1,GetNPixelsX()+1);
105 fResponse->Thresholds(fThresh,fSigma);
106 fResponse->GetNoiseParam(fCouplCol,fCouplRow);
107 fNPixelsZ = fSegmentation->Npz();
108 fNPixelsX = fSegmentation->Npx();
111 //______________________________________________________________________
112 AliITSsimulationSPD::~AliITSsimulationSPD() {
123 //______________________________________________________________________
124 AliITSsimulationSPD::AliITSsimulationSPD(const AliITSsimulationSPD &source){
127 if(&source == this) return;
129 this->fMapA2 = source.fMapA2;
130 this->fHis = source.fHis;
132 this->fThresh = source.fThresh;
133 this->fSigma = source.fSigma;
134 this->fCouplCol = source.fCouplCol;
135 this->fCouplRow = source.fCouplRow;
136 this->fNPixelsX = source.fNPixelsX;
137 this->fNPixelsZ = source.fNPixelsZ;
141 //______________________________________________________________________
142 AliITSsimulationSPD& AliITSsimulationSPD::operator=(const AliITSsimulationSPD
144 // Assignment operator
146 if(&source == this) return *this;
148 this->fMapA2 = source.fMapA2;
149 this->fHis = source.fHis;
151 this->fThresh = source.fThresh;
152 this->fSigma = source.fSigma;
153 this->fCouplCol = source.fCouplCol;
154 this->fCouplRow = source.fCouplRow;
155 this->fNPixelsX = source.fNPixelsX;
156 this->fNPixelsZ = source.fNPixelsZ;
160 //______________________________________________________________________
161 void AliITSsimulationSPD::InitSimulationModule(Int_t module,Int_t event){
162 // Creates maps to build the list of tracks for each sumable digit
164 // Int_t module // Module number to be simulated
165 // Int_t event // Event number to be simulated
176 //______________________________________________________________________
177 void AliITSsimulationSPD::FinishSDigitiseModule(){
178 // Does the Sdigits to Digits work
186 SDigitsToDigits(fModule,fpList);
188 //______________________________________________________________________
189 void AliITSsimulationSPD::SDigitiseModule(AliITSmodule *mod, Int_t dummy0,
191 // Sum digitize module
192 if (!(mod->GetNhits())) return; // if module has no hits then no Sdigits.
193 Int_t number = 10000;
194 Int_t *frowpixel = new Int_t[number];
195 Int_t *fcolpixel = new Int_t[number];
196 Double_t *fenepixel = new Double_t[number];
198 fModule = mod->GetIndex();
200 // Array of pointers to store the track index of the digits
201 // leave +1, otherwise pList crashes when col=256, row=192
203 HitsToAnalogDigits(mod,frowpixel,fcolpixel,fenepixel,fpList);
205 WriteSDigits(fpList);
214 //______________________________________________________________________
215 void AliITSsimulationSPD::DigitiseModule(AliITSmodule *mod, Int_t dummy0,
217 // digitize module. Also need to digitize modules with only noise.
219 Int_t number = 10000;
220 Int_t *frowpixel = new Int_t[number];
221 Int_t *fcolpixel = new Int_t[number];
222 Double_t *fenepixel = new Double_t[number];
224 // Array of pointers to store the track index of the digits
225 // leave +1, otherwise pList crashes when col=256, row=192
226 fModule = mod->GetIndex();
228 SetFluctuations(fpList,fModule);
230 HitsToAnalogDigits(mod,frowpixel,fcolpixel,fenepixel,fpList);
232 // apply mask to SPD module
235 CreateDigit(fModule,fpList);
244 //______________________________________________________________________
245 void AliITSsimulationSPD::SDigitsToDigits(Int_t module,AliITSpList *pList) {
246 // sum digits to Digits.
247 // cout << "Entering AliITSsimulatinSPD::SDigitsToDigits for module=";
248 // cout << module << endl;
252 SetFluctuations(pList,module);
254 fMapA2->ClearMap(); // since noise is in pList aready. Zero Map so that
255 // noise is not doubled when calling FillMapFrompList.
257 FillMapFrompList(pList);
259 // apply mask to SPD module
262 CreateDigit(module,pList);
267 //______________________________________________________________________
268 void AliITSsimulationSPD::UpdateMapSignal(Int_t row,Int_t col,Int_t trk,
269 Int_t hit,Int_t mod,Double_t ene,
270 AliITSpList *pList) {
271 // updates the Map of signal, adding the energy (ene) released by
274 fMapA2->AddSignal(row,col,ene);
275 pList->AddSignal(row,col,trk,hit,mod,ene);
277 //______________________________________________________________________
278 void AliITSsimulationSPD::UpdateMapNoise(Int_t row,Int_t col,Int_t mod,
279 Double_t ene,AliITSpList *pList) {
280 // updates the Map of noise, adding the energy (ene) give my noise
282 fMapA2->AddSignal(row,col,ene);
283 pList->AddNoise(row,col,mod,ene);
285 //______________________________________________________________________
286 void AliITSsimulationSPD::HitsToAnalogDigits(AliITSmodule *mod,
287 Int_t *frowpixel,Int_t *fcolpixel,
289 AliITSpList *pList) {
290 // Loops over all hits to produce Analog/floting point digits. This
291 // is also the first task in producing standard digits.
293 // loop over hits in the module
294 Int_t hitpos,nhits = mod->GetNhits();
295 for (hitpos=0;hitpos<nhits;hitpos++) {
296 HitToDigit(mod,hitpos,frowpixel,fcolpixel,fenepixel,pList);
297 }// end loop over digits
299 //______________________________________________________________________
300 void AliITSsimulationSPD::HitToDigit(AliITSmodule *mod,Int_t hitpos,
301 Int_t *frowpixel,Int_t *fcolpixel,
302 Double_t *fenepixel,AliITSpList *pList) {
303 // Steering function to determine the digits associated to a given
305 // The digits are created by charge sharing (ChargeSharing) and by
306 // capacitive coupling (SetCoupling). At all the created digits is
307 // associated the track number of the hit (ntrack)
308 Double_t x1l=0.0,y1l=0.0,z1l=0.0,x2l=0.0,y2l=0.0,z2l=0.0;
309 Int_t r1,r2,c1,c2,row,col,npixel = 0;
311 Double_t ene=0.0,etot=0.0;
312 const Float_t kconv = 10000.; // cm -> microns
313 const Float_t kconv1= 0.277e9; // GeV -> electrons equivalent
315 if(!(mod->LineSegmentL(hitpos,x1l,x2l,y1l,y2l,z1l,z2l,etot,ntrack)))return;
317 x2l += x1l; y2l += y1l; z2l += z1l; // Convert to ending coordinate.
318 // positions shifted and converted in microns
319 x1l = x1l*kconv + fSegmentation->Dx()/2.;
320 z1l = z1l*kconv + fSegmentation->Dz()/2.;
321 // positions shifted and converted in microns
322 x2l = x2l*kconv + fSegmentation->Dx()/2.;
323 z2l = z2l*kconv + fSegmentation->Dz()/2.;
324 etot *= kconv1; // convert from GeV to electrons equivalent.
325 Int_t module = mod->GetIndex();
327 // to account for the effective sensitive area
328 // introduced in geometry
329 if (z1l<0 || z1l>fSegmentation->Dz()) return;
330 if (z2l<0 || z2l>fSegmentation->Dz()) return;
331 if (x1l<0 || x1l>fSegmentation->Dx()) return;
332 if (x2l<0 || x2l>fSegmentation->Dx()) return;
334 //Get the col and row number starting from 1
335 // the x direction is not inverted for the second layer!!!
336 fSegmentation->GetPadIxz(x1l, z1l, c1, r1);
337 fSegmentation->GetPadIxz(x2l, z2l, c2, r2);
339 // to account for unexpected equal entrance and
341 if (x1l==x2l) x2l=x2l+x2l*0.1;
342 if (z1l==z2l) z2l=z2l+z2l*0.1;
344 if ((r1==r2) && (c1==c2)){
347 frowpixel[npixel-1] = r1;
348 fcolpixel[npixel-1] = c1;
349 fenepixel[npixel-1] = etot;
352 ChargeSharing(x1l,z1l,x2l,z2l,c1,r1,c2,r2,etot,
353 npixel,frowpixel,fcolpixel,fenepixel);
354 } // end if r1==r2 && c1==c2.
356 for (Int_t npix=0;npix<npixel;npix++){
357 row = frowpixel[npix];
358 col = fcolpixel[npix];
359 ene = fenepixel[npix];
360 UpdateMapSignal(row,col,ntrack,hitpos,module,ene,pList);
361 // Starting capacitive coupling effect
362 SetCoupling(row,col,ntrack,hitpos,module,pList);
365 //______________________________________________________________________
366 void AliITSsimulationSPD::ChargeSharing(Float_t x1l,Float_t z1l,Float_t x2l,
367 Float_t z2l,Int_t c1,Int_t r1,Int_t c2,
368 Int_t r2,Float_t etot,
369 Int_t &npixel,Int_t *frowpixel,
370 Int_t *fcolpixel,Double_t *fenepixel){
371 // Take into account the geometrical charge sharing when the track
372 // crosses more than one pixel.
376 <img src="picts/ITS/barimodel_2.gif">
379 <font size=+2 color=red>
380 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
385 Float_t xa,za,xb,zb,dx,dz,dtot,dm,refr,refm,refc;
387 Float_t arefm, arefr, arefn, arefc, azb, az2l, axb, ax2l;
388 Int_t dirx,dirz,rb,cb;
389 Int_t flag,flagrow,flagcol;
395 dx = TMath::Abs(x1l-x2l);
396 if (dx == 0.) dx = 0.01;
397 dz = TMath::Abs(z1l-z2l);
398 if (dz == 0.) dz = 0.01;
399 dtot = TMath::Sqrt((dx*dx)+(dz*dz));
400 dm = (x2l - x1l) / (z2l - z1l);
401 if (dm == 0.) dm = 0.01;
402 dirx = (Int_t) ((x2l - x1l) / dx);
403 dirz = (Int_t) ((z2l - z1l) / dz);
405 // calculate the x coordinate of the pixel in the next column
406 // and the z coordinate of the pixel in the next row
409 fSegmentation->GetPadCxz(c1, r1-1, xpos, zpos);
411 Float_t xsize = fSegmentation->Dpx(0);
412 Float_t zsize = fSegmentation->Dpz(r1-1);
414 if (dirx == 1) refr = xpos+xsize/2.;
415 else refr = xpos-xsize/2.;
417 if (dirz == 1) refn = zpos+zsize/2.;
418 else refn = zpos-zsize/2.;
424 // calculate the x coordinate of the intersection with the pixel
425 // in the next cell in row direction
426 refm = (refn - z1l)*dm + x1l;
428 // calculate the z coordinate of the intersection with the pixel
429 // in the next cell in column direction
430 refc = (refr - x1l)/dm + z1l;
437 if ((arefm < arefr) && (arefn < arefc)){
438 // the track goes in the pixel in the next cell in row direction
445 if (rb == r2) flagrow=1;
450 // shift to the pixel in the next cell in row direction
451 Float_t zsizeNext = fSegmentation->Dpz(rb-1);
452 //to account for cell at the borders of the detector
453 if(zsizeNext==0) zsizeNext = zsize;
454 refn += zsizeNext*dirz;
456 // the track goes in the pixel in the next cell in column direction
463 if (cb == c2) flagcol=1;
467 } // end ifaxb > ax2l
469 // shift to the pixel in the next cell in column direction
470 Float_t xsizeNext = fSegmentation->Dpx(cb-1);
471 //to account for cell at the borders of the detector
472 if(xsizeNext==0) xsizeNext = xsize;
473 refr += xsizeNext*dirx;
474 } // end if (arefm < arefr) && (arefn < arefc)
476 //calculate the energy lost in the crossed pixel
477 epar = TMath::Sqrt((xb-xa)*(xb-xa)+(zb-za)*(zb-za));
478 epar = etot*(epar/dtot);
480 //store row, column and energy lost in the crossed pixel
481 frowpixel[npixel] = r1;
482 fcolpixel[npixel] = c1;
483 fenepixel[npixel] = epar;
486 // the exit point of the track is reached
487 if (epar == 0) flag = 1;
488 if ((r1 == r2) && (c1 == c2)) flag = 1;
497 //______________________________________________________________________
498 void AliITSsimulationSPD::SetCoupling(Int_t row, Int_t col, Int_t ntrack,
499 Int_t idhit,Int_t module,
500 AliITSpList *pList) {
501 // Take into account the coupling between adiacent pixels.
502 // The parameters probcol and probrow are the fractions of the
503 // signal in one pixel shared in the two adjacent pixels along
504 // the column and row direction, respectively.
508 <img src="picts/ITS/barimodel_3.gif">
511 <font size=+2 color=red>
512 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
518 Double_t pulse1,pulse2;
519 Float_t couplR=0.0,couplC=0.0;
521 GetCouplings(couplR,couplC);
524 pulse1 = fMapA2->GetSignal(row,col);
526 for (Int_t isign=-1;isign<=1;isign+=2){// loop in row direction
530 if ((j1<0) || (j1>GetNPixelsZ()-1) || (pulse1<GetThreshold())){
531 pulse1 = fMapA2->GetSignal(row,col);
535 UpdateMapSignal(j1,col,ntrack,idhit,module,pulse1,pList);
539 // loop in column direction
543 if ((j2<0) || (j2>(GetNPixelsX()-1)) || (pulse2<GetThreshold())){
544 pulse2 = fMapA2->GetSignal(row,col);
548 UpdateMapSignal(row,j2,ntrack,idhit,module,pulse2,pList);
554 //______________________________________________________________________
555 void AliITSsimulationSPD::CreateDigit(Int_t module,AliITSpList *pList) {
556 // The pixels are fired if the energy deposited inside them is above
557 // the threshold parameter ethr. Fired pixed are interpreted as digits
558 // and stored in the file digitfilename. One also needs to write out
559 // cases when there is only noise (nhits==0).
561 static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
569 for (Int_t r=1;r<=GetNPixelsZ();r++) {
570 for (Int_t c=1;c<=GetNPixelsX();c++) {
571 // check if the deposited energy in a pixel is above the
573 Float_t signal = (Float_t) fMapA2->GetSignal(r,c);
574 if ( signal > GetThreshold()) {
575 digits[0] = r-1; // digits starts from 0
576 digits[1] = c-1; // digits starts from 0
578 digits[2] = (Int_t) signal; // the signal is stored in
581 tracks[j1] = pList->GetTrack(r,c,j1);
582 hits[j1] = pList->GetHit(r,c,j1);
586 aliITS->AddSimDigit(0,phys,digits,tracks,hits,charges);
587 // cout << " CreateSPDDigit mod=" << fModule << " r,c=" << r;
588 // cout <<","<<c<< " sig=" << fpList->GetSignalOnly(r,c);
589 // cout << " noise=" << fpList->GetNoise(r,c);
590 // cout << " Msig="<< signal << " Thres=" << GetThreshold()<<endl;
591 } // end if of threshold condition
595 //______________________________________________________________________
596 void AliITSsimulationSPD::SetFluctuations(AliITSpList *pList,Int_t module) {
597 // Set the electronic noise and threshold non-uniformities to all the
598 // pixels in a detector.
599 // The parameter fSigma is the squared sum of the sigma due to noise
600 // and the sigma of the threshold distribution among pixels.
604 <img src="picts/ITS/barimodel_1.gif">
607 <font size=+2 color=red>
608 <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
613 Float_t thr=0.0,sigm=0.0;
614 Double_t signal,sigma;
617 GetThresholds(thr,sigm);
618 sigma = (Double_t) sigm;
619 for(iz=1;iz<=GetNPixelsZ();iz++){
620 for(ix=1;ix<=GetNPixelsX();ix++){
621 signal = sigma*gRandom->Gaus();
622 fMapA2->SetHit(iz,ix,signal);
623 // insert in the label-signal-hit list the pixels fired
625 pList->AddNoise(iz,ix,module,signal);
626 } // end of loop on pixels
627 } // end of loop on pixels
629 //______________________________________________________________________
630 void AliITSsimulationSPD::SetMask() {
631 // Apply a mask to the SPD module. 1% of the pixel channels are
632 // masked. When the database will be ready, the masked pixels
633 // should be read from it.
637 Float_t perc = ((AliITSresponseSPD*)fResponse)->GetFractionDead();
638 // in this way we get the same set of random numbers for all runs.
639 // This is a cluge for now.
640 static TRandom *rnd = new TRandom();
642 totMask= perc*GetNPixelsZ()*GetNPixelsX();
643 for(im=1;im<totMask;im++){
645 ix=(Int_t)(rnd->Rndm()*(GetNPixelsX()-1.) + 1.);
646 } while(ix<=0 || ix>GetNPixelsX());
648 iz=(Int_t)(rnd->Rndm()*(GetNPixelsZ()-1.) + 1.);
649 } while(iz<=0 || iz>GetNPixelsZ());
651 fMapA2->SetHit(iz,ix,signal);
652 } // end loop on masked pixels
654 //______________________________________________________________________
655 void AliITSsimulationSPD::CreateHistograms() {
659 fHis=new TObjArray(GetNPixelsZ());
660 for(i=0;i<GetNPixelsZ();i++) {
661 TString spdname("spd_");
663 sprintf(candnum,"%d",i+1);
664 spdname.Append(candnum);
665 (*fHis)[i] = new TH1F(spdname.Data(),"SPD maps",
666 GetNPixelsX(),0.,(Float_t) GetNPixelsX());
669 //______________________________________________________________________
670 void AliITSsimulationSPD::ResetHistograms() {
671 // Reset histograms for this detector
674 for(i=0;i<GetNPixelsZ();i++ ) {
675 if ((*fHis)[i]) ((TH1F*)(*fHis)[i])->Reset();
678 //______________________________________________________________________
679 void AliITSsimulationSPD::WriteSDigits(AliITSpList *pList){
680 // Fills the Summable digits Tree
682 static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
684 pList->GetMaxMapIndex(ni,nj);
685 for(i=0;i<ni;i++)for(j=0;j<nj;j++){
686 if(pList->GetSignalOnly(i,j)>0.0){
687 aliITS->AddSumDigit(*(pList->GetpListItem(i,j)));
688 // cout << "pListSPD: " << *(pList->GetpListItem(i,j)) << endl;
689 // cout << " CreateSPDSDigit mod=" << fModule << " r,c=";
690 // cout << i <<","<< j << " sig=" << fpList->GetSignalOnly(i,j);
691 // cout << " noise=" << fpList->GetNoise(i,j) <<endl;
696 //______________________________________________________________________
697 void AliITSsimulationSPD::FillMapFrompList(AliITSpList *pList){
698 // Fills fMap2A from the pList of Summable digits
701 for(iz=0;iz<GetNPixelsZ();iz++)for(ix=0;ix<GetNPixelsX();ix++)
702 fMapA2->AddSignal(iz,ix,pList->GetSignal(iz,ix));