]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSsimulationSPD.cxx
Merging the VirtualMC branch to the main development branch (HEAD)
[u/mrichter/AliRoot.git] / ITS / AliITSsimulationSPD.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.15.4.3  2002/10/14 13:14:08  hristov
19 Updating VirtualMC to v3-09-02
20
21 Revision 1.20  2002/09/11 10:32:41  hristov
22 Use new for arrays with variable size
23
24 Revision 1.19  2002/09/09 17:23:28  nilsen
25 Minor changes in support of changes to AliITSdigitS?D class'.
26
27 Revision 1.18  2002/08/21 22:11:13  nilsen
28 Debug output now settable via a DEBUG flag.
29
30 Revision 1.17  2002/07/16 17:00:17  barbera
31 Fixes added to make the slow simulation running with the current HEAD (from M. Masera)
32
33 Revision 1.16  2002/06/19 16:02:22  hristov
34 Division by zero corrected
35
36 Revision 1.15  2002/03/15 17:32:14  nilsen
37 Reintroduced SDigitization, and Digitization from SDigits, along with
38 functions InitSimulationModule, and FinishSDigitizModule.
39
40 Revision 1.14  2001/11/23 13:04:07  barbera
41 Some protection added in case of high multiplicity
42
43 Revision 1.13  2001/11/13 11:13:24  barbera
44 A protection against tracks with the same entrance and exit has been made more strict
45
46 Revision 1.12  2001/10/04 22:44:31  nilsen
47 Major changes in supppor of PreDigits (SDigits). Changes made with will make
48 it easier to suppor expected changes in AliITSHit class. Added use of new
49 class AliITSpList. Both SPD and SDD have added effects of Dead Channels. Both
50 of these will require addtional work as data bases of detectors and the like
51 are developed.
52
53 */
54 #include <iostream.h>
55 #include <TRandom.h>
56 #include <TH1.h>
57 #include <TMath.h>
58 #include <TString.h>
59 #include <TParticle.h>
60
61 #include "AliRun.h"
62 #include "AliITS.h"
63 #include "AliITShit.h"
64 #include "AliITSdigit.h"
65 #include "AliITSmodule.h"
66 #include "AliITSMapA2.h"
67 #include "AliITSpList.h"
68 #include "AliITSsimulationSPD.h"
69 #include "AliITSsegmentation.h"
70 #include "AliITSresponse.h"
71 #include "AliITSsegmentationSPD.h"
72 #include "AliITSresponseSPD.h"
73
74 //#define DEBUG
75
76 ClassImp(AliITSsimulationSPD)
77 ////////////////////////////////////////////////////////////////////////
78 // Version: 0
79 // Written by Rocco Caliandro
80 // from a model developed with T. Virgili and R.A. Fini
81 // June 15 2000
82 //
83 // AliITSsimulationSPD is the simulation of SPDs
84 //
85 //______________________________________________________________________
86 AliITSsimulationSPD::AliITSsimulationSPD(){
87     // Default constructor
88
89     fResponse     = 0;
90     fSegmentation = 0;
91     fHis          = 0;
92     fMapA2        = 0;
93
94 /*
95     fThresh       = 0.;
96     fSigma        = 0.;
97     fCouplCol     = 0.;
98     fCouplRow     = 0.; */
99 }
100 //______________________________________________________________________
101 AliITSsimulationSPD::AliITSsimulationSPD(AliITSsegmentation *seg,
102                                          AliITSresponse *resp) {
103     // Standard constructor
104
105     fResponse     = 0;
106     fSegmentation = 0;
107     fHis          = 0;
108     fMapA2        = 0;
109
110 /*
111     fThresh       = 0.;
112     fSigma        = 0.;
113     fCouplCol     = 0.;
114     fCouplRow     = 0.*/
115     Init((AliITSsegmentationSPD*)seg,(AliITSresponseSPD*)resp);
116 }
117 //______________________________________________________________________
118 void AliITSsimulationSPD::Init(AliITSsegmentationSPD *seg,
119                                AliITSresponseSPD *resp) {
120     // Initilizes the variables of AliITSsimulation SPD.
121
122     fHis = 0;
123     fResponse     = resp;
124     fSegmentation = seg;
125     fMapA2  = new AliITSMapA2(fSegmentation);
126     fpList  = new AliITSpList(GetNPixelsZ()+1,GetNPixelsX()+1);
127 /*
128     fResponse->Thresholds(fThresh,fSigma);
129     fResponse->GetNoiseParam(fCouplCol,fCouplRow);
130     fNPixelsZ = fSegmentation->Npz();
131     fNPixelsX = fSegmentation->Npx();
132 */
133 }
134 //______________________________________________________________________
135 AliITSsimulationSPD::~AliITSsimulationSPD() { 
136     // destructor
137
138     delete fMapA2;
139 //    delete fpList;
140
141     if (fHis) {
142         fHis->Delete(); 
143         delete fHis;     
144     } // end if
145 }
146 //______________________________________________________________________
147 AliITSsimulationSPD::AliITSsimulationSPD(const AliITSsimulationSPD &source){
148     // Copy Constructor
149
150     if(&source == this) return;
151
152     this->fMapA2    = source.fMapA2;
153     this->fHis      = source.fHis;
154 /*
155     this->fThresh   = source.fThresh;
156     this->fSigma    = source.fSigma;
157     this->fCouplCol = source.fCouplCol;
158     this->fCouplRow = source.fCouplRow;
159     this->fNPixelsX = source.fNPixelsX;
160     this->fNPixelsZ = source.fNPixelsZ;
161 */
162     return;
163 }
164 //______________________________________________________________________
165 AliITSsimulationSPD& AliITSsimulationSPD::operator=(const AliITSsimulationSPD 
166                                                     &source) {
167     //    Assignment operator
168
169     if(&source == this) return *this;
170
171     this->fMapA2    = source.fMapA2;
172     this->fHis      = source.fHis;
173 /*
174     this->fThresh   = source.fThresh;
175     this->fSigma    = source.fSigma;
176     this->fCouplCol = source.fCouplCol;
177     this->fCouplRow = source.fCouplRow;
178     this->fNPixelsX = source.fNPixelsX;
179     this->fNPixelsZ = source.fNPixelsZ;
180 */
181     return *this;
182
183 //______________________________________________________________________
184 void AliITSsimulationSPD::InitSimulationModule(Int_t module,Int_t event){
185     // Creates maps to build the list of tracks for each sumable digit
186     // Inputs:
187     //   Int_t module    // Module number to be simulated
188     //   Int_t event     // Event number to be simulated
189     // Outputs:
190     //   none.
191     // Return
192     //    none.
193  
194     fModule = module;
195     fEvent  = event;
196     fMapA2->ClearMap();
197     fpList->ClearMap();
198 }
199 //______________________________________________________________________
200 void AliITSsimulationSPD::FinishSDigitiseModule(){
201     // Does the Sdigits to Digits work
202     // Inputs:
203     //   none.
204     // Outputs:
205     //   none.
206     // Return:
207     //   none.
208
209     SDigitsToDigits(fModule,fpList);
210 }
211 //______________________________________________________________________
212 void AliITSsimulationSPD::SDigitiseModule(AliITSmodule *mod, Int_t dummy0,
213                                              Int_t dummy1) {
214     // Sum digitize module
215     if (!(mod->GetNhits())) return; // if module has no hits then no Sdigits.
216     Int_t    number     = 10000;
217     Int_t    *frowpixel = new Int_t[number];
218     Int_t    *fcolpixel = new Int_t[number];
219     Double_t *fenepixel = new Double_t[number];
220
221     fModule = mod->GetIndex();
222
223     // Array of pointers to store the track index of the digits
224     // leave +1, otherwise pList crashes when col=256, row=192
225
226     HitsToAnalogDigits(mod,frowpixel,fcolpixel,fenepixel,fpList);
227
228     WriteSDigits(fpList);
229
230     // clean memory
231     delete[] frowpixel;
232     delete[] fcolpixel;
233     delete[] fenepixel;
234     fMapA2->ClearMap();
235     fpList->ClearMap();
236 }
237 //______________________________________________________________________
238 void AliITSsimulationSPD::DigitiseModule(AliITSmodule *mod, Int_t dummy0,
239                                              Int_t dummy1) {
240     // digitize module. Also need to digitize modules with only noise.
241
242     Int_t    number     = 10000;
243     Int_t    *frowpixel = new Int_t[number];
244     Int_t    *fcolpixel = new Int_t[number];
245     Double_t *fenepixel = new Double_t[number];
246
247     // Array of pointers to store the track index of the digits
248     // leave +1, otherwise pList crashes when col=256, row=192
249     fModule = mod->GetIndex();
250     // noise setting
251     SetFluctuations(fpList,fModule);
252
253     HitsToAnalogDigits(mod,frowpixel,fcolpixel,fenepixel,fpList);
254
255     // apply mask to SPD module
256     SetMask();
257
258     CreateDigit(fModule,fpList);
259
260     // clean memory
261     delete[] frowpixel;
262     delete[] fcolpixel;
263     delete[] fenepixel;
264     fMapA2->ClearMap();
265     fpList->ClearMap();
266 }
267 //______________________________________________________________________
268 void AliITSsimulationSPD::SDigitsToDigits(Int_t module,AliITSpList *pList) {
269     // sum digits to Digits.
270
271 #ifdef DEBUG
272     cout << "Entering AliITSsimulatinSPD::SDigitsToDigits for module=";
273     cout << module << endl;
274 #endif
275     fModule = module;
276
277     // noise setting
278     SetFluctuations(pList,module);
279
280     fMapA2->ClearMap(); // since noise is in pList aready. Zero Map so that
281     // noise is not doubled when calling FillMapFrompList.
282
283     FillMapFrompList(pList);
284
285     // apply mask to SPD module
286     SetMask();
287
288     CreateDigit(module,pList);
289
290     fMapA2->ClearMap();
291     pList->ClearMap();
292 }
293 //______________________________________________________________________
294 void AliITSsimulationSPD::UpdateMapSignal(Int_t row,Int_t col,Int_t trk,
295                                           Int_t hit,Int_t mod,Double_t ene,
296                                           AliITSpList *pList) {
297     // updates the Map of signal, adding the energy  (ene) released by
298     // the current track
299
300     fMapA2->AddSignal(row,col,ene);
301     pList->AddSignal(row,col,trk,hit,mod,ene);
302 }
303 //______________________________________________________________________
304 void AliITSsimulationSPD::UpdateMapNoise(Int_t row,Int_t col,Int_t mod,
305                                          Double_t ene,AliITSpList *pList) {
306     // updates the Map of noise, adding the energy  (ene) give my noise
307
308     fMapA2->AddSignal(row,col,ene);
309     pList->AddNoise(row,col,mod,ene);
310 }
311 //______________________________________________________________________
312 void AliITSsimulationSPD::HitsToAnalogDigits(AliITSmodule *mod,
313                                              Int_t *frowpixel,Int_t *fcolpixel,
314                                              Double_t *fenepixel,
315                                              AliITSpList *pList) {
316     // Loops over all hits to produce Analog/floting point digits. This
317     // is also the first task in producing standard digits.
318     
319     // loop over hits in the module
320     Int_t hitpos,nhits = mod->GetNhits();
321     for (hitpos=0;hitpos<nhits;hitpos++) {
322         HitToDigit(mod,hitpos,frowpixel,fcolpixel,fenepixel,pList);
323     }// end loop over digits
324 }
325 //______________________________________________________________________
326 void AliITSsimulationSPD::HitToDigit(AliITSmodule *mod,Int_t hitpos,
327                                      Int_t *frowpixel,Int_t *fcolpixel,
328                                      Double_t *fenepixel,AliITSpList *pList) {
329     //  Steering function to determine the digits associated to a given
330     // hit (hitpos)
331     // The digits are created by charge sharing (ChargeSharing) and by
332     // capacitive coupling (SetCoupling). At all the created digits is
333     // associated the track number of the hit (ntrack)
334     Double_t x1l=0.0,y1l=0.0,z1l=0.0,x2l=0.0,y2l=0.0,z2l=0.0;
335     Int_t r1,r2,c1,c2,row,col,npixel = 0;
336     Int_t ntrack;
337     Double_t ene=0.0,etot=0.0;
338     const Float_t kconv = 10000.;     // cm -> microns
339     const Float_t kconv1= 0.277e9;    // GeV -> electrons equivalent
340
341     if(!(mod->LineSegmentL(hitpos,x1l,x2l,y1l,y2l,z1l,z2l,etot,ntrack)))return;
342
343     x2l += x1l; y2l += y1l; z2l += z1l; // Convert to ending coordinate.
344     // positions shifted and converted in microns
345     x1l   = x1l*kconv + fSegmentation->Dx()/2.;
346     z1l   = z1l*kconv + fSegmentation->Dz()/2.;
347     // positions  shifted and converted in microns
348     x2l   = x2l*kconv + fSegmentation->Dx()/2.;
349     z2l   = z2l*kconv + fSegmentation->Dz()/2.;
350     etot *= kconv1; // convert from GeV to electrons equivalent.
351     Int_t module = mod->GetIndex();
352
353     // to account for the effective sensitive area
354     // introduced in geometry 
355     if (z1l<0 || z1l>fSegmentation->Dz()) return;
356     if (z2l<0 || z2l>fSegmentation->Dz()) return;
357     if (x1l<0 || x1l>fSegmentation->Dx()) return;
358     if (x2l<0 || x2l>fSegmentation->Dx()) return;
359
360     //Get the col and row number starting from 1
361     // the x direction is not inverted for the second layer!!!
362     fSegmentation->GetPadIxz(x1l, z1l, c1, r1); 
363     fSegmentation->GetPadIxz(x2l, z2l, c2, r2);
364
365     // to account for unexpected equal entrance and 
366     // exit coordinates
367     if (x1l==x2l) x2l=x2l+x2l*0.1;
368     if (z1l==z2l) z2l=z2l+z2l*0.1;
369
370     if ((r1==r2) && (c1==c2)){
371         // no charge sharing
372         npixel = 1;              
373         frowpixel[npixel-1] = r1;
374         fcolpixel[npixel-1] = c1;
375         fenepixel[npixel-1] = etot;
376     } else {
377         // charge sharing
378         ChargeSharing(x1l,z1l,x2l,z2l,c1,r1,c2,r2,etot,
379                       npixel,frowpixel,fcolpixel,fenepixel);
380     } // end if r1==r2 && c1==c2.
381
382     for (Int_t npix=0;npix<npixel;npix++){
383         row = frowpixel[npix];
384         col = fcolpixel[npix];
385         ene = fenepixel[npix];
386         UpdateMapSignal(row,col,ntrack,hitpos,module,ene,pList); 
387         // Starting capacitive coupling effect
388         SetCoupling(row,col,ntrack,hitpos,module,pList); 
389     } // end for npix
390 }
391 //______________________________________________________________________
392 void AliITSsimulationSPD::ChargeSharing(Float_t x1l,Float_t z1l,Float_t x2l,
393                                         Float_t z2l,Int_t c1,Int_t r1,Int_t c2,
394                                         Int_t r2,Float_t etot,
395                                         Int_t &npixel,Int_t *frowpixel,
396                                         Int_t *fcolpixel,Double_t *fenepixel){
397     //  Take into account the geometrical charge sharing when the track
398     //  crosses more than one pixel.
399     //
400     //Begin_Html
401     /*
402       <img src="picts/ITS/barimodel_2.gif">
403       </pre>
404       <br clear=left>
405       <font size=+2 color=red>
406       <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
407       </font>
408       <pre>
409     */
410     //End_Html
411     //Float_t dm;
412     Float_t xa,za,xb,zb,dx,dz,dtot,refr,refm,refc;
413     Float_t refn=0.;
414     Float_t arefm, arefr, arefn, arefc, azb, az2l, axb, ax2l;
415     Int_t   dirx,dirz,rb,cb;
416     Int_t flag,flagrow,flagcol;
417     Double_t epar;
418
419     npixel = 0;
420     xa     = x1l;
421     za     = z1l;
422 //    dx     = x1l-x2l;
423 //    dz     = z1l-z2l;
424     dx     = x2l-x1l;
425     dz     = z2l-z1l;
426     dtot   = TMath::Sqrt((dx*dx)+(dz*dz));   
427     if (dtot==0.0) dtot = 0.01;
428     dirx   = (Int_t) TMath::Sign((Float_t)1,dx);
429     dirz   = (Int_t) TMath::Sign((Float_t)1,dz);
430
431     // calculate the x coordinate of  the pixel in the next column    
432     // and the z coordinate of  the pixel in the next row
433     Float_t xpos, zpos;
434
435     fSegmentation->GetPadCxz(c1, r1-1, xpos, zpos); 
436
437     Float_t xsize = fSegmentation->Dpx(0);
438     Float_t zsize = fSegmentation->Dpz(r1-1);
439     
440     if (dirx == 1) refr = xpos+xsize/2.;
441     else refr = xpos-xsize/2.;
442
443     if (dirz == 1) refn = zpos+zsize/2.;
444     else refn = zpos-zsize/2.;
445
446     flag = 0;
447     flagrow = 0;
448     flagcol = 0;
449     do{
450         // calculate the x coordinate of the intersection with the pixel
451         // in the next cell in row  direction
452       if(dz!=0)
453         refm = dx*((refn - z1l)/dz) + x1l;
454       else
455         refm = refr+dirx*xsize;
456    
457         // calculate the z coordinate of the intersection with the pixel
458         // in the next cell in column direction
459       if (dx!=0)
460         refc = dz*((refr - x1l)/dx) + z1l;
461       else
462         refc = refn+dirz*zsize;
463
464         arefm = refm * dirx;
465         arefr = refr * dirx;
466         arefn = refn * dirz;
467         arefc = refc * dirz;
468
469         if ((arefm < arefr) && (arefn < arefc)){
470             // the track goes in the pixel in the next cell in row direction
471             xb = refm;
472             zb = refn;
473             cb = c1;
474             rb = r1 + dirz;
475             azb = zb * dirz;
476             az2l = z2l * dirz;
477             if (rb == r2) flagrow=1;
478             if (azb > az2l) {
479                 zb = z2l;
480                 xb = x2l;
481             } // end if
482             // shift to the pixel in the next cell in row direction
483             Float_t zsizeNext = fSegmentation->Dpz(rb-1);
484             //to account for cell at the borders of the detector
485             if(zsizeNext==0) zsizeNext = zsize;
486             refn += zsizeNext*dirz;
487         }else {
488             // the track goes in the pixel in the next cell in column direction
489             xb = refr;
490             zb = refc;
491             cb = c1 + dirx;
492             rb = r1;
493             axb = xb * dirx;
494             ax2l = x2l * dirx;
495             if (cb == c2) flagcol=1;
496             if (axb > ax2l) {
497                 zb = z2l;
498                 xb = x2l;
499             } // end ifaxb > ax2l
500
501             // shift to the pixel in the next cell in column direction
502             Float_t xsizeNext = fSegmentation->Dpx(cb-1);
503             //to account for cell at the borders of the detector
504             if(xsizeNext==0) xsizeNext = xsize;
505             refr += xsizeNext*dirx;
506         } // end if (arefm < arefr) && (arefn < arefc)
507
508         //calculate the energy lost in the crossed pixel      
509         epar = TMath::Sqrt((xb-xa)*(xb-xa)+(zb-za)*(zb-za)); 
510         epar = etot*(epar/dtot);
511
512         //store row, column and energy lost in the crossed pixel
513         frowpixel[npixel] = r1;
514         fcolpixel[npixel] = c1;
515         fenepixel[npixel] = epar;
516         npixel++;
517  
518         // the exit point of the track is reached
519         if (epar == 0) flag = 1;
520         if ((r1 == r2) && (c1 == c2)) flag = 1;
521         if (flag!=1) {
522             r1 = rb;
523             c1 = cb;
524             xa = xb;
525             za = zb;
526         } // end if flag!=1
527     } while (flag==0);
528 }
529 //______________________________________________________________________
530 void AliITSsimulationSPD::SetCoupling(Int_t row, Int_t col, Int_t ntrack,
531                                       Int_t idhit,Int_t module,
532                                       AliITSpList *pList) {
533     //  Take into account the coupling between adiacent pixels.
534     //  The parameters probcol and probrow are the fractions of the
535     //  signal in one pixel shared in the two adjacent pixels along
536     //  the column and row direction, respectively.
537     //
538     //Begin_Html
539     /*
540       <img src="picts/ITS/barimodel_3.gif">
541       </pre>
542       <br clear=left>
543       <font size=+2 color=red>
544       <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
545       </font>
546       <pre>
547     */
548     //End_Html
549     Int_t j1,j2,flag=0;
550     Double_t pulse1,pulse2;
551     Float_t couplR=0.0,couplC=0.0;
552
553     GetCouplings(couplR,couplC);
554     j1 = row;
555     j2 = col;
556     pulse1 = fMapA2->GetSignal(row,col);
557     pulse2 = pulse1;
558     for (Int_t isign=-1;isign<=1;isign+=2){// loop in row direction
559         do{
560             j1 += isign;
561             pulse1 *= couplR;
562             if ((j1<0) || (j1>GetNPixelsZ()-1) || (pulse1<GetThreshold())){
563                 pulse1 = fMapA2->GetSignal(row,col);
564                 j1 = row;
565                 flag = 1;
566             }else{
567                 UpdateMapSignal(j1,col,ntrack,idhit,module,pulse1,pList);
568                 flag = 0;
569             } // end if
570         } while(flag == 0);
571         // loop in column direction
572       do{
573           j2 += isign;
574           pulse2 *= couplC;
575           if ((j2<0) || (j2>(GetNPixelsX()-1)) || (pulse2<GetThreshold())){
576               pulse2 = fMapA2->GetSignal(row,col);
577               j2 = col;
578               flag = 1;
579           }else{
580               UpdateMapSignal(row,j2,ntrack,idhit,module,pulse2,pList);
581               flag = 0;
582           } // end if
583       } while(flag == 0);
584     } // for isign
585 }
586 //______________________________________________________________________
587 void AliITSsimulationSPD::CreateDigit(Int_t module,AliITSpList *pList) {
588     // The pixels are fired if the energy deposited inside them is above
589     // the threshold parameter ethr. Fired pixed are interpreted as digits
590     // and stored in the file digitfilename. One also needs to write out
591     // cases when there is only noise (nhits==0).
592
593     static AliITS *aliITS  = (AliITS*)gAlice->GetModule("ITS");
594
595     Int_t size = AliITSdigitSPD::GetNTracks();
596     Int_t * digits = new Int_t[size];
597     Int_t * tracks = new Int_t[size];
598     Int_t * hits = new Int_t[size];
599     Float_t * charges = new Float_t[size]; 
600     Int_t j1;
601
602     for (Int_t r=1;r<=GetNPixelsZ();r++) {
603         for (Int_t c=1;c<=GetNPixelsX();c++) {
604             // check if the deposited energy in a pixel is above the
605             // threshold 
606             Float_t signal = (Float_t) fMapA2->GetSignal(r,c);
607             if ( signal > GetThreshold()) {
608                 digits[0] = r-1;  // digits starts from 0
609                 digits[1] = c-1;  // digits starts from 0
610                 //digits[2] = 1;  
611                 digits[2] =  (Int_t) signal;  // the signal is stored in
612                                               //  electrons
613                 for(j1=0;j1<size;j1++){
614                     if(j1<pList->GetNEnteries()){
615                         tracks[j1] = pList->GetTrack(r,c,j1);
616                         hits[j1]   = pList->GetHit(r,c,j1);
617                     }else{
618                         tracks[j1] = -3;
619                         hits[j1]   = -1;
620                     } // end if
621                     charges[j1] = 0;
622                 } // end for j1
623                 Float_t phys = 0;
624                 aliITS->AddSimDigit(0,phys,digits,tracks,hits,charges);
625 #ifdef DEBUG
626                 cout << " CreateSPDDigit mod=" << fModule << " r,c=" << r;
627                 cout <<","<<c<< " sig=" << fpList->GetSignalOnly(r,c);
628                 cout << " noise=" << fpList->GetNoise(r,c);
629                 cout << " Msig="<< signal << " Thres=" << GetThreshold()<<endl;
630 #endif
631             } // end if of threshold condition
632         } // for c
633     }// end do on pixels
634     delete [] digits;
635     delete [] tracks;
636     delete [] hits;
637     delete [] charges;
638
639 }
640 //______________________________________________________________________
641 void AliITSsimulationSPD::SetFluctuations(AliITSpList *pList,Int_t module) {
642     //  Set the electronic noise and threshold non-uniformities to all the
643     //  pixels in a detector.
644     //  The parameter fSigma is the squared sum of the sigma due to noise
645     //  and the sigma of the threshold distribution among pixels.
646     //
647     //Begin_Html
648     /*
649       <img src="picts/ITS/barimodel_1.gif">
650       </pre>
651       <br clear=left>
652       <font size=+2 color=red>
653       <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
654       </font>
655       <pre>
656     */
657     //End_Html
658     Float_t  thr=0.0,sigm=0.0;
659     Double_t signal,sigma;
660     Int_t iz,ix;
661
662     GetThresholds(thr,sigm);
663     sigma = (Double_t) sigm;
664     for(iz=1;iz<=GetNPixelsZ();iz++){
665         for(ix=1;ix<=GetNPixelsX();ix++){
666             signal = sigma*gRandom->Gaus(); 
667             fMapA2->SetHit(iz,ix,signal);
668             // insert in the label-signal-hit list the pixels fired
669             // only by noise
670             pList->AddNoise(iz,ix,module,signal);
671         } // end of loop on pixels
672     } // end of loop on pixels
673 }
674 //______________________________________________________________________
675 void AliITSsimulationSPD::SetMask() {
676     //  Apply a mask to the SPD module. 1% of the pixel channels are
677     //  masked. When the database will be ready, the masked pixels
678     //  should be read from it.
679     Double_t signal;
680     Int_t iz,ix,im;
681     Float_t totMask;
682     Float_t perc = ((AliITSresponseSPD*)fResponse)->GetFractionDead();
683     // in this way we get the same set of random numbers for all runs.
684     // This is a cluge for now.
685     static TRandom *rnd = new TRandom();
686
687     totMask= perc*GetNPixelsZ()*GetNPixelsX();
688     for(im=1;im<totMask;im++){
689         do{
690             ix=(Int_t)(rnd->Rndm()*(GetNPixelsX()-1.) + 1.);
691         } while(ix<=0 || ix>GetNPixelsX());
692         do{
693             iz=(Int_t)(rnd->Rndm()*(GetNPixelsZ()-1.) + 1.);
694         } while(iz<=0 || iz>GetNPixelsZ());
695         signal = -1.;
696         fMapA2->SetHit(iz,ix,signal);
697     } // end loop on masked pixels
698 }
699 //______________________________________________________________________
700 void AliITSsimulationSPD::CreateHistograms() {
701     // Create Histograms
702     Int_t i;
703
704     fHis=new TObjArray(GetNPixelsZ());
705     for(i=0;i<GetNPixelsZ();i++) {
706         TString spdname("spd_");
707         Char_t candnum[4];
708         sprintf(candnum,"%d",i+1);
709         spdname.Append(candnum);
710         (*fHis)[i] = new TH1F(spdname.Data(),"SPD maps",
711                               GetNPixelsX(),0.,(Float_t) GetNPixelsX());
712     } // end for i
713 }
714 //______________________________________________________________________
715 void AliITSsimulationSPD::ResetHistograms() {
716     // Reset histograms for this detector
717     Int_t i;
718
719     for(i=0;i<GetNPixelsZ();i++ ) {
720         if ((*fHis)[i])    ((TH1F*)(*fHis)[i])->Reset();
721     } // end for i
722 }
723 //______________________________________________________________________
724 void AliITSsimulationSPD::WriteSDigits(AliITSpList *pList){
725     // Fills the Summable digits Tree
726     Int_t i,ni,j,nj;
727     static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
728
729     pList->GetMaxMapIndex(ni,nj);
730     for(i=0;i<ni;i++)for(j=0;j<nj;j++){
731         if(pList->GetSignalOnly(i,j)>0.0){
732             aliITS->AddSumDigit(*(pList->GetpListItem(i,j)));
733 #ifdef DEBUG
734             cout << "pListSPD: " << *(pList->GetpListItem(i,j)) << endl;
735             cout << " CreateSPDSDigit mod=" << fModule << " r,c=";
736             cout << i  <<","<< j << " sig=" << fpList->GetSignalOnly(i,j);
737             cout << " noise=" << fpList->GetNoise(i,j) <<endl;
738 #endif
739         } // end if
740     } // end for i,j
741     return;
742 }
743 //______________________________________________________________________
744 void AliITSsimulationSPD::FillMapFrompList(AliITSpList *pList){
745     // Fills fMap2A from the pList of Summable digits
746     Int_t ix,iz;
747
748     for(iz=0;iz<GetNPixelsZ();iz++)for(ix=0;ix<GetNPixelsX();ix++) 
749         fMapA2->AddSignal(iz,ix,pList->GetSignal(iz,ix));
750     return;
751 }