]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSsimulationSPD.cxx
Remove AliTRDv2
[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 $Id$
18 */
19
20 #include <Riostream.h>
21 #include <TH1.h>
22 #include <TString.h>
23 #include "AliITS.h"
24 #include "AliITSdigitSPD.h"
25 #include "AliITShit.h"
26 #include "AliITSmodule.h"
27 #include "AliITSpList.h"
28 #include "AliITSCalibrationSPD.h"
29 #include "AliITSsegmentationSPD.h"
30 #include "AliITSsimulationSPD.h"
31 #include "AliLog.h"
32 #include "AliRun.h"
33 #include "AliCDBEntry.h"
34 #include "AliCDBLocal.h"
35
36 //#define DEBUG
37
38 ClassImp(AliITSsimulationSPD)
39 ////////////////////////////////////////////////////////////////////////
40 //  Version: 1
41 //  Modified by D. Elia, G.E. Bruno, H. Tydesjo 
42 //  Fast diffusion code by Bjorn S. Nilsen
43 //  March-April 2006
44 //
45 //  Version: 0
46 //  Written by Boris Batyunya
47 //  December 20 1999
48 //
49 //
50 // AliITSsimulationSPD is to do the simulation of SPDs.
51 //
52 ////////////////////////////////////////////////////////////////////////
53
54 //______________________________________________________________________
55 AliITSsimulationSPD::AliITSsimulationSPD():
56 AliITSsimulation(),
57 fHis(0),
58 fSPDname(),
59 fCoupling(){
60     // Default constructor.
61     // Inputs:
62     //    none.
63     // Outputs:
64     //    none.
65     // Return:
66     //    A default constructed AliITSsimulationSPD class.
67
68     AliDebug(1,Form("Calling default constructor"));
69 //    Init();
70 }
71 //______________________________________________________________________
72 AliITSsimulationSPD::AliITSsimulationSPD(AliITSDetTypeSim *dettyp):
73 AliITSsimulation(dettyp),
74 fHis(0),
75 fSPDname(),
76 fCoupling(){
77     // standard constructor
78     // Inputs:
79     //    AliITSsegmentation *seg  A pointer to the segmentation class
80     //                             to be used for this simulation
81     //    AliITSCalibration     *resp A pointer to the responce class to
82     //                             be used for this simulation
83     // Outputs:
84     //    none.
85     // Return:
86     //    A default constructed AliITSsimulationSPD class.
87
88     AliDebug(1,Form("Calling standard constructor "));
89 //      AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
90 //      res->SetTemperature(0.0);
91 //      res->SetDistanceOverVoltage(0.0);
92     Init();
93 }
94 //______________________________________________________________________
95 void AliITSsimulationSPD::Init(){
96     // Initilization
97     // Inputs:
98     //    none.
99     // Outputs:
100     //    none.
101     // Return:
102     //    none.
103     const Double_t kmictocm = 1.0e-4; // convert microns to cm.
104
105     SetModuleNumber(0);
106     SetEventNumber(0);
107     SetMap(new AliITSpList(GetNPixelsZ(),GetNPixelsX()));
108     AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
109     AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
110     Double_t bias = res->GetBiasVoltage();
111 //    cout << "Bias Voltage --> " << bias << endl; // dom    
112     res->SetDistanceOverVoltage(kmictocm*seg->Dy(),bias);
113 // set kind of coupling ("old" or "new")
114     char opt[20];
115     res->GetCouplingOption(opt);
116     char *old = strstr(opt,"old");
117     if (old) {
118         fCoupling=2;
119     } else {
120         fCoupling=1;
121     } // end if
122
123     // Get the calibration objects for each module(ladder)
124     GetCalibrationObjects(0); //RunNr 0 hard coded for now
125
126 }
127 //______________________________________________________________________
128 AliITSsimulationSPD::~AliITSsimulationSPD(){
129     // destructor
130     // Inputs:
131     //    none.
132     // Outputs:
133     //    none.
134     // Return:
135     //     none.
136
137     if (fHis) {
138         fHis->Delete(); 
139         delete fHis;     
140     } // end if fHis
141 }
142 //______________________________________________________________________
143 AliITSsimulationSPD::AliITSsimulationSPD(const 
144                                                    AliITSsimulationSPD 
145                                                    &s) : AliITSsimulation(s){
146     //     Copy Constructor
147     // Inputs:
148     //    AliITSsimulationSPD &s The original class for which
149     //                                this class is a copy of
150     // Outputs:
151     //    none.
152     // Return:
153
154     *this = s;
155     return;
156 }
157 //______________________________________________________________________
158 AliITSsimulationSPD&  AliITSsimulationSPD::operator=(const 
159                                            AliITSsimulationSPD &s){
160     //    Assignment operator
161     // Inputs:
162     //    AliITSsimulationSPD &s The original class for which
163     //                                this class is a copy of
164     // Outputs:
165     //    none.
166     // Return:
167
168     if(&s == this) return *this;
169     this->fHis = s.fHis;
170     fCoupling  = s.fCoupling;
171     fSPDname   = s.fSPDname;
172     return *this;
173 }
174 //______________________________________________________________________
175 AliITSsimulation&  AliITSsimulationSPD::operator=(const 
176                                            AliITSsimulation &s){
177     //    Assignment operator
178     // Inputs:
179     //    AliITSsimulationSPD &s The original class for which
180     //                                this class is a copy of
181     // Outputs:
182     //    none.
183     // Return:
184
185     if(&s == this) return *this;
186     Error("AliITSsimulationSPD","Not allowed to make a = with "
187           "AliITSsimulationSPD","Using default creater instead");
188
189     return *this;
190 }
191
192 //______________________________________________________________________
193 void AliITSsimulationSPD::GetCalibrationObjects(Int_t RunNr) {
194     //    Gets the calibration objects for each module (ladder) 
195     // Inputs:
196     //    RunNr: hard coded to RunNr=0 for now
197     // Outputs:
198     //    none.
199     // Return:
200     //    none.
201
202   AliCDBManager* man = AliCDBManager::Instance();
203   if(!man->IsDefaultStorageSet()) {
204     man->SetDefaultStorage("local://$ALICE_ROOT");
205   }
206   AliCDBEntry *entrySPD = man->Get("ITS/Calib/CalibSPD", RunNr);
207   if(!entrySPD){
208     AliWarning("Cannot find SPD calibration entry!");
209     return;
210   }
211   TObjArray *respSPD = (TObjArray *)entrySPD->GetObject();
212   if ((! respSPD)) {
213     AliWarning("Cannot get data from SPD database entry!");
214     return;
215   }
216   for (Int_t mod=0; mod<240; mod++) {
217     fCalObj[mod] = (AliITSCalibrationSPD*) respSPD->At(mod);
218   }
219 }
220
221 //______________________________________________________________________
222 void AliITSsimulationSPD::InitSimulationModule(Int_t module, Int_t event){
223     //  This function creates maps to build the list of tracks for each
224     //  summable digit. Inputs defined by base class.
225     //  Inputs:
226     //    Int_t module   // Module number to be simulated
227     //    Int_t event    // Event number to be simulated
228     //  Outputs:
229     //    none
230     //  Returns:
231     //    none
232
233     AliDebug(1,Form("(module=%d,event=%d)",module,event));
234     SetModuleNumber(module);
235     SetEventNumber(event);
236     ClearMap();
237 }
238 //_____________________________________________________________________
239 void AliITSsimulationSPD::SDigitiseModule(AliITSmodule *mod,Int_t,
240                                                Int_t event){
241     //  This function begins the work of creating S-Digits.  Inputs defined
242     //  by base class.
243     //  Inputs:
244     //    AliITSmodule *mod  //  module
245     //    Int_t              //  not used
246     //    Int_t event        //  Event number
247     //  Outputs:
248     //    none
249     //  Return:
250     //    test              //  test returns kTRUE if the module contained hits
251     //                      //  test returns kFALSE if it did not contain hits
252
253     AliDebug(1,Form("(mod=%p, ,event=%d)",mod,event));
254     if(!(mod->GetNhits())){
255         AliDebug(1,Form("In event %d module %d there are %d hits returning.",
256                         event, mod->GetIndex(),mod->GetNhits()));
257         return;// if module has no hits don't create Sdigits
258     } // end if
259     SetModuleNumber(mod->GetIndex());
260     SetEventNumber(event);
261     // HitToSDigit(mod);
262     HitToSDigitFast(mod);
263     RemoveDeadPixels(mod);
264 //    cout << "After Remove in SDigitiseModule !!!!!" << endl; // dom
265 //    cout << "Module " << mod->GetIndex() << " Event " << event << endl; // dom
266     WriteSDigits();
267     ClearMap();
268 }
269 //______________________________________________________________________
270 void AliITSsimulationSPD::WriteSDigits(){
271     //  This function adds each S-Digit to pList
272     //  Inputs:
273     //    none.
274     //  Outputs:
275     //    none.
276     //  Return:
277     //    none
278     Int_t ix, nix, iz, niz;
279     static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
280
281     AliDebug(1,Form("Writing SDigits for module %d",GetModuleNumber()));
282 //    cout << "WriteSDigits for module " << GetModuleNumber() << endl; // dom
283     GetMap()->GetMaxMapIndex(niz, nix);
284     for(iz=0; iz<niz; iz++)for(ix=0; ix<nix; ix++){
285         if(GetMap()->GetSignalOnly(iz,ix)>0.0){
286 //            cout << " Signal gt 0  iz ix " << iz << ix << " Module " << GetModuleNumber() << endl; // dom
287             aliITS->AddSumDigit(*(GetMap()->GetpListItem(iz,ix)));
288             if(AliDebugLevel()>0) {
289               AliDebug(1,Form("%d, %d",iz,ix));
290               cout << *(GetMap()->GetpListItem(iz,ix)) << endl;
291             } // end if GetDebug
292         } // end if GetMap()->GetSignalOnly(iz,ix)>0.0
293     } // end for iz,ix
294     return; 
295 }
296 //______________________________________________________________________
297 void AliITSsimulationSPD::FinishSDigitiseModule(){
298     //  This function calls SDigitsToDigits which creates Digits from SDigits
299     //  Inputs:
300     //    none
301     //  Outputs:
302     //    none
303     //  Return
304     //    none
305
306     AliDebug(1,"()");
307 //    cout << "FinishSDigitiseModule for module " << GetModuleNumber() << endl; // dom
308     FrompListToDigits(); // Charge To Signal both adds noise and
309     ClearMap();
310     return;
311 }
312 //______________________________________________________________________
313 void AliITSsimulationSPD::DigitiseModule(AliITSmodule *mod,Int_t,
314                                               Int_t){
315     //  This function creates Digits straight from the hits and then adds
316     //  electronic noise to the digits before adding them to pList
317     //  Each of the input variables is passed along to HitToSDigit
318     //  Inputs:
319     //    AliITSmodule *mod     module
320     //    Int_t                 Dummy.
321     //    Int_t                 Dummy
322     //  Outputs:
323     //     none.
324     //  Return:
325     //    none.
326
327     AliDebug(1,Form("(mod=%p,,)",mod));
328     // HitToSDigit(mod);
329     HitToSDigitFast(mod);
330     RemoveDeadPixels(mod);
331 //    cout << "After Remove in DigitiseModule in module " << mod->GetIndex() << endl; // dom
332     FrompListToDigits();
333     ClearMap();
334 }
335 //______________________________________________________________________
336 void AliITSsimulationSPD::HitToSDigit(AliITSmodule *mod){
337     // Does the charge distributions using Gaussian diffusion charge charing.
338     // Inputs:
339     //    AliITSmodule *mod  Pointer to this module
340     // Output:
341     //    none.
342     // Return:
343     //    none.
344     const Double_t kmictocm = 1.0e-4; // convert microns to cm.
345     TObjArray *hits = mod->GetHits();
346     Int_t nhits = hits->GetEntriesFast();
347     Int_t h,ix,iz,i;
348     Int_t idtrack;
349     Double_t x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0,de=0.0;
350     Double_t x,y,z,t,tp,st,dt=0.2,el,sig,sigx,sigz,fda;
351     AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
352     AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
353     Double_t thick = 0.5*kmictocm*seg->Dy();  // Half Thickness
354     res->GetSigmaDiffusionAsymmetry(fda);
355
356     AliDebug(1,Form("(mod=%p) fCoupling=%d",mod,fCoupling));
357     if(nhits<=0) return;
358     for(h=0;h<nhits;h++){
359       if(AliDebugLevel()>0) {
360         AliDebug(1,Form("Hits, %d", h));
361         cout << *(mod->GetHit(h)) << endl;
362       } // end if GetDebug
363         if(!mod->LineSegmentL(h,x0,x1,y0,y1,z0,z1,de,idtrack)) continue;
364         st = TMath::Sqrt(x1*x1+y1*y1+z1*z1);
365         if(st>0.0){
366             st = (Double_t)((Int_t)(st/kmictocm)); // number of microns
367             if(st<=1.0) st = 1.0;
368             dt = 1.0/st;
369             for(t=0.0;t<1.0;t+=dt){ // Integrate over t
370                 tp  = t+0.5*dt;
371                 x   = x0+x1*tp;
372                 y   = y0+y1*tp;
373                 z   = z0+z1*tp;
374                 if(!(seg->LocalToDet(x,z,ix,iz))) continue; // outside
375                 el  = res->GeVToCharge((Double_t)(dt*de));
376                 if(GetDebug(1)){
377                     if(el<=0.0) cout<<"el="<<el<<" dt="<<dt
378                                     <<" de="<<de<<endl;
379                 } // end if GetDebug
380                 sig = res->SigmaDiffusion1D(TMath::Abs(thick + y)); 
381                 //  SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
382                 sigx=sig;
383                 sigz=sig*fda;
384                 SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
385                 cout << "sigx, sigz, y "<< sigx << " " << sigz<< " " << TMath::Abs(thick + y) << endl;// ciccio
386             } // end for t
387         } else { // st == 0.0 deposit it at this point
388             x   = x0;
389             y   = y0;
390             z   = z0;
391             if(!(seg->LocalToDet(x,z,ix,iz))) continue; // outside
392             el  = res->GeVToCharge((Double_t)de);
393             sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
394             // SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
395             sigx=sig;
396             sigz=sig*fda;
397             SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
398         } // end if st>0.0
399         // Coupling
400         switch (fCoupling) {
401         default:
402             break;
403         case 1: //case 3:
404             for(i=0;i<GetMap()->GetEntries();i++) 
405                 if(GetMap()->GetpListItem(i)==0) continue;
406                 else{
407                     GetMap()->GetMapIndex(GetMap()->GetpListItem(i)->GetIndex(),iz,ix);
408                     SetCoupling(iz,ix,idtrack,h);
409                 } // end for i
410             break;
411         case 2: // case 4:
412             for(i=0;i<GetMap()->GetEntries();i++) 
413                 if(GetMap()->GetpListItem(i)==0) continue;
414                 else{
415                     GetMap()->GetMapIndex(GetMap()->GetpListItem(i)->GetIndex(),iz,ix);
416                     SetCouplingOld(iz,ix,idtrack,h);
417                 } // end for i
418             break;
419         } // end switch
420     } // Loop over all hits h
421     if(GetDebug(2))Info("HitToSDigit","Finished fCoupling=%d",fCoupling);
422 }
423 //______________________________________________________________________
424 void AliITSsimulationSPD::HitToSDigitFast(AliITSmodule *mod){
425     // Does the charge distributions using Gaussian diffusion charge charing.    // Inputs:
426     //    AliITSmodule *mod  Pointer to this module
427     // Output:
428     //    none.
429     // Return:
430     //    none.
431     const Double_t kmictocm = 1.0e-4; // convert microns to cm.
432     const Int_t kn10=10;
433     const Double_t kti[kn10]={7.443716945e-3,2.166976971e-1,3.397047841e-1,
434                             4.325316833e-1,4.869532643e-1,5.130467358e-1,
435                             5.674683167e-1,6.602952159e-1,7.833023029e-1,
436                             9.255628306e-1};
437     const Double_t kwi[kn10]={1.477621124e-1,1.346333597e-1,1.095431813e-1,
438                             7.472567455e-2,3.333567215e-2,3.333567215e-2,
439                             7.472567455e-2,1.095431813e-1,1.346333597e-1,
440                             1.477621124e-1};
441     TObjArray *hits = mod->GetHits();
442     Int_t nhits = hits->GetEntriesFast();
443     Int_t h,ix,iz,i;
444     Int_t idtrack;
445     Double_t x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0,de=0.0;
446     Double_t x,y,z,t,st,el,sig,sigx,sigz,fda;
447     AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
448     AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
449     Double_t thick = 0.5*kmictocm*seg->Dy();  // Half thickness
450     res->GetSigmaDiffusionAsymmetry(fda);
451 //    cout << "Half Thickness " << thick << endl;  // dom
452 //    cout << "Diffusion asymm " << fda << endl;  // dom
453
454     AliDebug(1,Form("(mod=%p) fCoupling=%d",mod,fCoupling));
455     if(nhits<=0) return;
456     for(h=0;h<nhits;h++){
457       if(AliDebugLevel()>0) {
458         AliDebug(1,Form("Hits, %d", h));
459         cout << *(mod->GetHit(h)) << endl;
460       } // end if GetDebug
461         if(!mod->LineSegmentL(h,x0,x1,y0,y1,z0,z1,de,idtrack)) continue;
462         st = TMath::Sqrt(x1*x1+y1*y1+z1*z1);
463         if(st>0.0) for(i=0;i<kn10;i++){ // Integrate over t
464             t   = kti[i];
465             x   = x0+x1*t;
466             y   = y0+y1*t;
467             z   = z0+z1*t;
468                 if(!(seg->LocalToDet(x,z,ix,iz))) continue; // outside
469                 // el  = res->GeVToCharge((Double_t)(dt*de));
470                 // el  = 1./kn10*res->GeVToCharge((Double_t)de);
471                 el  = kwi[i]*res->GeVToCharge((Double_t)de); 
472                 if(GetDebug(1)){
473                     if(el<=0.0) cout<<"el="<<el<<" kwi["<<i<<"]="<<kwi[i]
474                                     <<" de="<<de<<endl;
475                 } // end if GetDebug
476                 sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
477                 sigx=sig;
478                 sigz=sig*fda;
479                 //SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
480                 SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
481                 // cout << "sigx sigz " << sigx << " " << sigz << endl; // dom
482             } // end for i // End Integrate over t
483         else { // st == 0.0 deposit it at this point
484             x   = x0;
485             y   = y0;
486             z   = z0;
487             if(!(seg->LocalToDet(x,z,ix,iz))) continue; // outside
488             el  = res->GeVToCharge((Double_t)de);
489             sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
490             //SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
491             sigx=sig;
492             sigz=sig*fda;
493             SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
494         } // end if st>0.0
495         // Coupling
496         switch (fCoupling) {
497         default:
498             break;
499         case 1: // case 3:
500             for(i=0;i<GetMap()->GetEntries();i++)
501                 if(GetMap()->GetpListItem(i)==0) continue;
502                 else{
503                     GetMap()->GetMapIndex(GetMap()->GetpListItem(i)->GetIndex(),iz,ix);
504                     SetCoupling(iz,ix,idtrack,h);
505                 } // end for i
506             break;
507         case 2: // case 4:
508             for(i=0;i<GetMap()->GetEntries();i++)
509                 if(GetMap()->GetpListItem(i)==0) continue;
510                 else{
511                     GetMap()->GetMapIndex(GetMap()->GetpListItem(i)->GetIndex(),iz,ix);  
512                     SetCouplingOld(iz,ix,idtrack,h);
513                 } // end for i
514             break;
515         } // end switch
516     } // Loop over all hits h
517     if(GetDebug(2))Info("HitToSDigit","Finished fCoupling=%d",fCoupling);
518 }
519 //______________________________________________________________________
520 void AliITSsimulationSPD::SpreadCharge(Double_t x0,Double_t z0,
521                                             Int_t ix0,Int_t iz0,
522                                             Double_t el,Double_t sig,Int_t t,
523                                             Int_t hi){
524     // Spreads the charge over neighboring cells. Assume charge is distributed
525     // as charge(x,z) = (el/2*pi*sig*sig)*exp(-arg)
526     // arg=((x-x0)*(x-x0)/2*sig*sig)+((z-z0*z-z0)/2*sig*sig)
527     // Defined this way, the integral over all x and z is el.
528     // Inputs:
529     //    Double_t x0   x position of point where charge is liberated
530     //    Double_t y0   y position of point where charge is liberated
531     //    Double_t z0   z position of point where charge is liberated
532     //    Int_t    ix0  row of cell corresponding to point x0
533     //    Int_t    iz0  columb of cell corresponding to point z0
534     //    Double_t el   number of electrons liberated in this step
535     //    Double_t sig  Sigma difusion for this step (y0 dependent)
536     //    Int_t    t    track number
537     //    Int_t    ti   hit track index number
538     //    Int_t    hi   hit "hit" index number
539     // Outputs:
540     //     none.
541     // Return:
542     //     none.
543     const Int_t knx = 3,knz = 2;
544     const Double_t kRoot2 = 1.414213562; // Sqrt(2).
545     const Double_t kmictocm = 1.0e-4; // convert microns to cm.
546     Int_t ix,iz,ixs,ixe,izs,ize;
547     Float_t x,z;
548     Double_t x1,x2,z1,z2,s,sp;
549     AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
550
551
552     if(GetDebug(4)) Info("SpreadCharge","(x0=%e,z0=%e,ix0=%d,iz0=%d,el=%e,"
553                          "sig=%e,t=%d,i=%d)",x0,z0,ix0,iz0,el,sig,t,hi);
554     if(sig<=0.0) { // if sig<=0 No diffusion to simulate.
555         GetMap()->AddSignal(iz0,ix0,t,hi,GetModuleNumber(),el);
556         if(GetDebug(2)){
557             cout << "sig<=0.0=" << sig << endl;
558         } // end if GetDebug
559         return;
560     } // end if
561     sp = 1.0/(sig*kRoot2);
562     if(GetDebug(2)){
563         cout << "sig=" << sig << " sp=" << sp << endl;
564     } // end if GetDebug
565     ixs = TMath::Max(-knx+ix0,0);
566     ixe = TMath::Min(knx+ix0,seg->Npx()-1);
567     izs = TMath::Max(-knz+iz0,0);
568     ize = TMath::Min(knz+iz0,seg->Npz()-1);
569     for(ix=ixs;ix<=ixe;ix++) for(iz=izs;iz<=ize;iz++){
570         seg->DetToLocal(ix,iz,x,z); // pixel center
571         x1  = x;
572         z1  = z;
573         x2  = x1 + 0.5*kmictocm*seg->Dpx(ix); // Upper
574         x1 -= 0.5*kmictocm*seg->Dpx(ix);  // Lower
575         z2  = z1 + 0.5*kmictocm*seg->Dpz(iz); // Upper
576         z1 -= 0.5*kmictocm*seg->Dpz(iz);  // Lower
577         x1 -= x0; // Distance from where track traveled
578         x2 -= x0; // Distance from where track traveled
579         z1 -= z0; // Distance from where track traveled
580         z2 -= z0; // Distance from where track traveled
581         s   = 0.25; // Correction based on definision of Erfc
582         s  *= TMath::Erfc(sp*x1) - TMath::Erfc(sp*x2);
583         if(GetDebug(3)){
584             cout <<"el="<<el<<" ix0="<<ix0<<" ix="<<ix<<" x0="<<x<<
585                 " iz0="<<iz0<<" iz="<<iz<<" z0="<<z<< 
586                 " sp*x1="<<sp*x1<<" sp*x2="<<sp*x2<<" s="<<s;
587         } // end if GetDebug
588         s  *= TMath::Erfc(sp*z1) - TMath::Erfc(sp*z2);
589         if(GetDebug(3)){
590             cout<<" sp*z1="<<sp*z1<<" sp*z2="<<sp*z2<<" s="<<s<< endl;
591         } // end if GetDebug
592         GetMap()->AddSignal(iz,ix,t,hi,GetModuleNumber(),s*el);
593     } // end for ix, iz
594 }
595 //______________________________________________________________________
596 void AliITSsimulationSPD::SpreadChargeAsym(Double_t x0,Double_t z0,
597                                             Int_t ix0,Int_t iz0,
598                                             Double_t el,Double_t sigx,Double_t sigz,
599                                             Int_t t,Int_t hi){
600     // Spreads the charge over neighboring cells. Assume charge is distributed
601     // as charge(x,z) = (el/2*pi*sigx*sigz)*exp(-arg)
602     // arg=((x-x0)*(x-x0)/2*sigx*sigx)+((z-z0*z-z0)/2*sigz*sigz)
603     // Defined this way, the integral over all x and z is el.
604     // Inputs:
605     //    Double_t x0   x position of point where charge is liberated
606     //    Double_t y0   y position of point where charge is liberated
607     //    Double_t z0   z position of point where charge is liberated
608     //    Int_t    ix0  row of cell corresponding to point x0
609     //    Int_t    iz0  columb of cell corresponding to point z0
610     //    Double_t el   number of electrons liberated in this step
611     //    Double_t sigx Sigma difusion along x for this step (y0 dependent)
612     //    Double_t sigz Sigma difusion along z for this step (y0 dependent)
613     //    Int_t    t    track number
614     //    Int_t    ti   hit track index number
615     //    Int_t    hi   hit "hit" index number
616     // Outputs:
617     //     none.
618     // Return:
619     //     none.
620     const Int_t knx = 3,knz = 2;
621     const Double_t kRoot2 = 1.414213562; // Sqrt(2).
622     const Double_t kmictocm = 1.0e-4; // convert microns to cm.
623     Int_t ix,iz,ixs,ixe,izs,ize;
624     Float_t x,z;
625     Double_t x1,x2,z1,z2,s,spx,spz;
626     AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
627
628
629     if(GetDebug(4)) Info("SpreadCharge","(x0=%e,z0=%e,ix0=%d,iz0=%d,el=%e,"
630                          "sig=%e,t=%d,i=%d)",x0,z0,ix0,iz0,el,sigx,sigz,t,hi);
631     if(sigx<=0.0 || sigz<=0.0) { // if sig<=0 No diffusion to simulate.
632         GetMap()->AddSignal(iz0,ix0,t,hi,GetModuleNumber(),el);
633         if(GetDebug(2)){
634             cout << "sigx<=0.0=" << sigx << endl;
635             cout << "sigz<=0.0=" << sigz << endl;
636         } // end if GetDebug
637         return;
638     } // end if
639     spx = 1.0/(sigx*kRoot2);     spz = 1.0/(sigz*kRoot2);
640     if(GetDebug(2)){
641         cout << "sigx=" << sigx << " spx=" << spx << endl;
642         cout << "sigz=" << sigz << " spz=" << spz << endl;
643     } // end if GetDebug
644     ixs = TMath::Max(-knx+ix0,0);
645     ixe = TMath::Min(knx+ix0,seg->Npx()-1);
646     izs = TMath::Max(-knz+iz0,0);
647     ize = TMath::Min(knz+iz0,seg->Npz()-1);
648     for(ix=ixs;ix<=ixe;ix++) for(iz=izs;iz<=ize;iz++){
649         seg->DetToLocal(ix,iz,x,z); // pixel center
650         x1  = x;
651         z1  = z;
652         x2  = x1 + 0.5*kmictocm*seg->Dpx(ix); // Upper
653         x1 -= 0.5*kmictocm*seg->Dpx(ix);  // Lower
654         z2  = z1 + 0.5*kmictocm*seg->Dpz(iz); // Upper
655         z1 -= 0.5*kmictocm*seg->Dpz(iz);  // Lower
656         x1 -= x0; // Distance from where track traveled
657         x2 -= x0; // Distance from where track traveled
658         z1 -= z0; // Distance from where track traveled
659         z2 -= z0; // Distance from where track traveled
660         s   = 0.25; // Correction based on definision of Erfc
661         s  *= TMath::Erfc(spx*x1) - TMath::Erfc(spx*x2);
662         if(GetDebug(3)){
663             cout <<"el="<<el<<" ix0="<<ix0<<" ix="<<ix<<" x0="<<x<<
664                 " iz0="<<iz0<<" iz="<<iz<<" z0="<<z<< 
665                 " spx*x1="<<spx*x1<<" spx*x2="<<spx*x2<<" s="<<s;
666         } // end if GetDebug
667         s  *= TMath::Erfc(spz*z1) - TMath::Erfc(spz*z2);
668         if(GetDebug(3)){
669             cout<<" spz*z1="<<spz*z1<<" spz*z2="<<spz*z2<<" s="<<s<< endl;
670         } // end if GetDebug
671         GetMap()->AddSignal(iz,ix,t,hi,GetModuleNumber(),s*el);
672     } // end for ix, iz
673 }
674 //______________________________________________________________________
675 void AliITSsimulationSPD::RemoveDeadPixels(AliITSmodule *mod){
676     //    Removes dead pixels on each module (ladder)
677     // Inputs:
678     //    Module Index (0,239)
679     // Outputs:
680     //    none.
681     // Return:
682     //    none.
683
684   Int_t moduleNr = mod->GetIndex();
685   Int_t nrDead = fCalObj[moduleNr]->GetNrDead();
686   for (Int_t i=0; i<nrDead; i++) {
687     GetMap()->DeleteHit(fCalObj[moduleNr]->GetDeadColAt(i),fCalObj[moduleNr]->GetDeadRowAt(i));
688   }
689 }
690 //______________________________________________________________________
691 void AliITSsimulationSPD::FrompListToDigits(){
692     // add noise and electronics, perform the zero suppression and add the
693     // digit to the list
694     // Inputs:
695     //    none.
696     // Outputs:
697     //    none.
698     // Return:
699     //    none.
700     static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
701     Int_t j,ix,iz;
702     Double_t  electronics;
703     Double_t sig;
704     const Int_t    knmaxtrk=AliITSdigitSPD::GetNTracks();
705     static AliITSdigitSPD dig;
706     AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
707     if(GetDebug(1)) Info("FrompListToDigits","()");
708     for(iz=0; iz<GetNPixelsZ(); iz++) for(ix=0; ix<GetNPixelsX(); ix++){
709 // NEW (for the moment plugged by hand, in the future possibly read from Data Base)
710 // here parametrize the efficiency of the pixel along the row for the test columns (1,9,17,25)
711 //        if(iz==1 || iz == 9 || iz == 17 || iz == 25) {
712 //        Double_t eff,p1=0.,p2=0.; 
713 //        Double_t x=ix;
714 //        switch (iz) {
715 //          case 1:   p1=0.63460;p2=0.42438E-01;break;  
716 //          case 9:   p1=0.41090;p2=0.75914E-01;break;
717 //        case 17:  p1=0.31883;p2=0.91502E-01;break;
718 //        case 25:  p1=0.48828;p2=0.57975E-01;break;
719 //         } // end switch
720 //          eff=1.-p1*exp(-p2*x);
721 //          if (gRandom->Rndm() >= eff) continue;
722 //        } // end  if 
723  // END parametrize the efficiency
724  // 
725         electronics = res->ApplyBaselineAndNoise();
726         UpdateMapNoise(ix,iz,electronics);
727         //
728         // Apply Threshold and write Digits.
729         sig = GetMap()->GetSignalOnly(iz,ix);
730         FillHistograms(ix,iz,sig+electronics);
731         if(GetDebug(3)){
732             cout<<sig<<"+"<<electronics<<">threshold("<<ix<<","<<iz
733                 <<")="<<GetThreshold() <<endl;
734         } // end if GetDebug
735         if (sig+electronics <= GetThreshold()) continue;
736         dig.SetCoord1(iz);
737         dig.SetCoord2(ix);
738         dig.SetSignal(1);
739
740 //        dig.SetSignalSPD((Int_t) GetMap()->GetSignal(iz,ix));
741         Double_t aSignal =  GetMap()->GetSignal(iz,ix);
742         if (TMath::Abs(aSignal)>2147483647.0) {
743           //PH 2147483647 is the max. integer
744           //PH This apparently is a problem which needs investigation
745           AliWarning(Form("Too big or too small signal value %f",aSignal));
746           aSignal = TMath::Sign((Double_t)2147483647,aSignal);
747         }
748         dig.SetSignalSPD((Int_t)aSignal);
749
750         for(j=0;j<knmaxtrk;j++){
751             if (j<GetMap()->GetNEntries()) {
752                 dig.SetTrack(j,GetMap()->GetTrack(iz,ix,j));
753                 dig.SetHit(j,GetMap()->GetHit(iz,ix,j));
754             }else { // Default values
755                 dig.SetTrack(j,-3);
756                 dig.SetHit(j,-1);
757             } // end if GetMap()
758         } // end for j
759         if(GetDebug(3)){
760             cout<<iz<<","<<ix<<","<<*(GetMap()->GetpListItem(iz,ix))<<endl;
761         } // end if GetDebug
762         aliITS->AddSimDigit(0,&dig);
763     } //  for ix/iz
764 }
765 //______________________________________________________________________
766 void AliITSsimulationSPD::CreateHistograms(){
767     // create 1D histograms for tests
768     // Inputs:
769     //    none.
770     // Outputs:
771     //    none.
772     // Return:
773     //     none.
774
775     if(GetDebug(1)) Info("CreateHistograms","create histograms");
776
777     fHis = new TObjArray(GetNPixelsZ());
778     TString fSPDname("spd_");
779     for(Int_t i=0;i<GetNPixelsZ();i++) {
780         Char_t pixelz[4];
781         sprintf(pixelz,"%d",i);
782         fSPDname.Append(pixelz);
783         fHis->AddAt(new TH1F(fSPDname.Data(),"SPD maps",
784                              GetNPixelsX(),0.,(Double_t)GetNPixelsX()),i);
785     } // end for i
786 }
787 //______________________________________________________________________
788 void AliITSsimulationSPD::FillHistograms(Int_t ix,Int_t iz,Double_t v){
789     // Fill the histogram
790     // Inputs:
791     //    none.
792     // Outputs:
793     //    none.
794     // Return:
795     //     none.
796
797     if(!GetHistArray()) return; // Only fill if setup.
798     if(GetDebug(2)) Info("FillHistograms","fill histograms");
799     GetHistogram(iz)->Fill(ix,v);
800 }
801 //______________________________________________________________________
802 void AliITSsimulationSPD::ResetHistograms(){
803     // Reset histograms for this detector
804     // Inputs:
805     //    none.
806     // Outputs:
807     //    none.
808     // Return:
809     //     none.
810
811     if(!GetHistArray()) return; // Only fill if setup.
812     if(GetDebug(2)) Info("FillHistograms","fill histograms");
813     for ( int i=0;i<GetNPixelsZ();i++ ) {
814         if (fHis->At(i))    ((TH1F*)fHis->At(i))->Reset();
815     } // end for i
816 }
817
818 //______________________________________________________________________
819 void AliITSsimulationSPD::SetCoupling(Int_t col, Int_t row, Int_t ntrack,
820                                       Int_t idhit) {
821     //  Take into account the coupling between adiacent pixels.
822     //  The parameters probcol and probrow are the probability of the
823     //  signal in one pixel shared in the two adjacent pixels along
824     //  the column and row direction, respectively.
825     //  Note pList is goten via GetMap() and module is not need any more.
826     //  Otherwise it is identical to that coded by Tiziano Virgili (BSN).
827     //Begin_Html
828     /*
829       <img src="picts/ITS/barimodel_3.gif">
830       </pre>
831       <br clear=left>
832       <font size=+2 color=red>
833       <a href="mailto:tiziano.virgili@cern.ch"></a>.
834       </font>
835       <pre>
836     */
837     //End_Html
838     // Inputs:
839     //    Int_t col            z cell index
840     //    Int_t row            x cell index
841     //    Int_t ntrack         track incex number
842     //    Int_t idhit          hit index number
843     // Outputs:
844     //    none.
845     // Return:
846     //     none.
847     Int_t j1,j2,flag=0;
848     Double_t pulse1,pulse2;
849     Double_t couplR=0.0,couplC=0.0;
850     Double_t xr=0.;
851
852     GetCouplings(couplC,couplR);
853     if(GetDebug(3)) Info("SetCoupling","(col=%d,row=%d,ntrack=%d,idhit=%d) "
854                          "Calling SetCoupling couplC=%e couplR=%e",
855                          col,row,ntrack,idhit,couplC,couplR);
856     j1 = col;
857     j2 = row;
858     pulse1 = GetMap()->GetSignalOnly(col,row);
859     pulse2 = pulse1;
860     for (Int_t isign=-1;isign<=1;isign+=2){// loop in col direction
861         do{
862             j1 += isign;
863             xr = gRandom->Rndm();
864             if ((j1<0) || (j1>GetNPixelsZ()-1) || (xr>couplC)){
865                 j1 = col;
866                 flag = 1;
867             }else{
868                 UpdateMapSignal(row,j1,ntrack,idhit,pulse1);
869                 //  flag = 0;
870                 flag = 1; // only first next!!
871             } // end if
872         } while(flag == 0);
873         // loop in row direction
874         do{
875             j2 += isign;
876             xr = gRandom->Rndm();
877             if ((j2<0) || (j2>GetNPixelsX()-1) || (xr>couplR)){
878                 j2 = row;
879                 flag = 1;
880             }else{
881                 UpdateMapSignal(j2,col,ntrack,idhit,pulse2);
882                 //  flag = 0;
883                 flag = 1; // only first next!!
884             } // end if
885         } while(flag == 0);
886     } // for isign
887 }
888 //______________________________________________________________________
889 void AliITSsimulationSPD::SetCouplingOld(Int_t col, Int_t row,
890                 Int_t ntrack,Int_t idhit) {
891     //  Take into account the coupling between adiacent pixels.
892     //  The parameters probcol and probrow are the fractions of the
893     //  signal in one pixel shared in the two adjacent pixels along
894     //  the column and row direction, respectively.
895     //Begin_Html
896     /*
897       <img src="picts/ITS/barimodel_3.gif">
898       </pre>
899       <br clear=left>
900       <font size=+2 color=red>
901       <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
902       </font>
903       <pre>
904     */
905     //End_Html
906     // Inputs:
907     //    Int_t col            z cell index
908     //    Int_t row            x cell index
909     //    Int_t ntrack         track incex number
910     //    Int_t idhit          hit index number
911     //    Int_t module         module number
912     // Outputs:
913     //    none.
914     // Return:
915     //     none.
916     Int_t j1,j2,flag=0;
917     Double_t pulse1,pulse2;
918     Double_t couplR=0.0,couplC=0.0;
919
920     GetCouplings(couplC,couplR);
921
922     //  Debugging ...
923 //    cout << "Threshold --> " << GetThreshold() << endl;  // dom
924 //    cout << "Couplings --> " << couplC << " " << couplR << endl;  //dom
925
926
927     if(GetDebug(3)) Info("SetCouplingOld","(col=%d,row=%d,ntrack=%d,idhit=%d) "
928                          "Calling SetCoupling couplC=%e couplR=%e",
929                          col,row,ntrack,idhit,couplC,couplR);
930     for (Int_t isign=-1;isign<=1;isign+=2){// loop in col direction
931     pulse1 = GetMap()->GetSignalOnly(col,row);
932     pulse2 = pulse1;
933     j1 = col;
934     j2 = row;
935         do{
936             j1 += isign;
937             pulse1 *= couplC;
938             if ((j1<0)||(j1>GetNPixelsZ()-1)||(pulse1<GetThreshold())){
939                 pulse1 = GetMap()->GetSignalOnly(col,row);
940                 j1 = col;
941                 flag = 1;
942             }else{
943                 UpdateMapSignal(row,j1,ntrack,idhit,pulse1);
944                 // flag = 0;
945                 flag = 1;  // only first next !!
946             } // end if
947         } while(flag == 0);
948         // loop in row direction
949         do{
950             j2 += isign;
951             pulse2 *= couplR;
952             if((j2<0)||(j2>(GetNPixelsX()-1))||(pulse2<GetThreshold())){
953                 pulse2 = GetMap()->GetSignalOnly(col,row);
954                 j2 = row;
955                 flag = 1;
956             }else{
957                 UpdateMapSignal(j2,col,ntrack,idhit,pulse2);
958                 // flag = 0;
959                 flag = 1; // only first next!!
960             } // end if
961         } while(flag == 0);
962     } // for isign
963 }