]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSsimulationSDD.cxx
Flag for xlC compiler on MacOSX
[u/mrichter/AliRoot.git] / ITS / AliITSsimulationSDD.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 /* $Id$ */
17
18 #include <Riostream.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22
23 #include <TSystem.h>
24 #include <TROOT.h>
25 #include <TStopwatch.h>
26 #include <TCanvas.h>
27 #include <TF1.h>
28 #include <TRandom.h>
29 #include <TH1.h>
30 #include <TFile.h>
31 #include <TVector.h>
32 #include <TArrayI.h>
33 #include <TArrayF.h>
34
35 #include "AliRun.h"
36 #include "AliITS.h"
37 #include "AliITShit.h"
38 #include "AliITSdigitSDD.h"
39 #include "AliITSdigitSPD.h"
40 #include "AliITSmodule.h"
41 #include "AliITSpList.h"
42 #include "AliITSMapA1.h"
43 #include "AliITSMapA2.h"
44 #include "AliITSetfSDD.h"
45 #include "AliITSRawData.h"
46 #include "AliITSHuffman.h"
47 #include "AliITSgeom.h"
48 #include "AliITSsegmentation.h"
49 #include "AliITSresponse.h"
50 #include "AliITSsegmentationSDD.h"
51 #include "AliITSresponseSDD.h"
52 #include "AliITSsimulationSDD.h"
53
54 ClassImp(AliITSsimulationSDD)
55 ////////////////////////////////////////////////////////////////////////
56 // Version: 0
57 // Written by Piergiorgio Cerello
58 // November 23 1999
59 //
60 // AliITSsimulationSDD is the simulation of SDDs.
61   //
62 //Begin_Html
63 /*
64  <img src="picts/ITS/AliITShit_Class_Diagram.gif">
65  </pre>
66  <br clear=left>
67  <font size=+2 color=red>
68  <p>This show the relasionships between the ITS hit class and the rest of Aliroot.
69  </font>
70  <pre>
71  */
72  //End_Html
73
74  //______________________________________________________________________
75   Int_t power(Int_t b, Int_t e) {
76   // compute b to the e power, where both b and e are Int_ts.
77   Int_t power = 1,i;
78
79   for(i=0; i<e; i++) power *= b;
80   return power;
81 }
82 //______________________________________________________________________
83 void FastFourierTransform(AliITSetfSDD *alisddetf,Double_t *real,
84                           Double_t *imag,Int_t direction) {
85   // Do a Fast Fourier Transform
86
87   Int_t samples = alisddetf->GetSamples();
88   Int_t l = (Int_t) ((log((Float_t) samples)/log(2.))+0.5);
89   Int_t m1 = samples;
90   Int_t m  = samples/2;
91   Int_t m2 = samples/m1;
92   Int_t i,j,k;
93   for(i=1; i<=l; i++) {
94     for(j=0; j<samples; j += m1) {
95       Int_t p = 0;
96       for(k=j; k<= j+m-1; k++) {
97         Double_t wsr = alisddetf->GetWeightReal(p);
98         Double_t wsi = alisddetf->GetWeightImag(p);
99         if(direction == -1) wsi = -wsi;
100         Double_t xr = *(real+k+m);
101         Double_t xi = *(imag+k+m);
102         *(real+k+m) = wsr*(*(real+k)-xr) - wsi*(*(imag+k)-xi);
103         *(imag+k+m) = wsr*(*(imag+k)-xi) + wsi*(*(real+k)-xr);
104         *(real+k) += xr;
105         *(imag+k) += xi;
106         p += m2;
107       } // end for k
108     } // end for j
109     m1 = m;
110     m /= 2;
111     m2 += m2;
112   } // end for i
113   
114   for(j=0; j<samples; j++) {
115     Int_t j1 = j;
116     Int_t p = 0;
117     Int_t i1;
118     for(i1=1; i1<=l; i1++) {
119       Int_t j2 = j1;
120       j1 /= 2;
121       p = p + p + j2 - j1 - j1;
122     } // end for i1
123     if(p >= j) {
124       Double_t xr = *(real+j);
125       Double_t xi = *(imag+j);
126       *(real+j) = *(real+p);
127       *(imag+j) = *(imag+p);
128       *(real+p) = xr;
129       *(imag+p) = xi;
130     } // end if p>=j
131   } // end for j
132   if(direction == -1) {
133     for(i=0; i<samples; i++) {
134       *(real+i) /= samples;
135       *(imag+i) /= samples;
136     } // end for i
137   } // end if direction == -1
138   return;
139 }
140 //______________________________________________________________________
141 AliITSsimulationSDD::AliITSsimulationSDD() {
142   // Default constructor
143
144   fResponse      = 0;
145   fSegmentation  = 0;
146   fHis           = 0;
147   //    fpList         = 0;
148   fHitMap2       = 0;
149   fHitSigMap2    = 0;
150   fHitNoiMap2    = 0;
151   fElectronics   = 0;
152   fStream        = 0;
153   fInZR          = 0;
154   fInZI          = 0;
155   fOutZR         = 0;
156   fOutZI         = 0;
157   fNofMaps       = 0;
158   fMaxNofSamples = 0;
159   fITS           = 0;
160   fTreeB         = 0;
161   fAnodeFire     = 0;
162   SetScaleFourier();
163   SetPerpendTracksFlag();
164   SetCrosstalkFlag();
165   SetDoFFT();
166   SetCheckNoise();
167 }
168 //______________________________________________________________________
169 AliITSsimulationSDD::AliITSsimulationSDD(AliITSsimulationSDD &source) :
170   AliITSsimulation(source){
171   // Copy constructor to satify Coding roules only.
172
173   if(this==&source) return;
174   Error("AliITSsimulationSSD","Not allowed to make a copy of "
175         "AliITSsimulationSDD Using default creater instead");
176   AliITSsimulationSDD();
177 }
178 //______________________________________________________________________
179 AliITSsimulationSDD& AliITSsimulationSDD::operator=(AliITSsimulationSDD &src){
180   // Assignment operator to satify Coding roules only.
181
182   if(this==&src) return *this;
183   Error("AliITSsimulationSSD","Not allowed to make a = with "
184         "AliITSsimulationSDD Using default creater instead");
185   return *this ;
186 }
187 //______________________________________________________________________
188 AliITSsimulationSDD::AliITSsimulationSDD(AliITSsegmentation *seg,
189                                          AliITSresponse *resp){
190   // Standard Constructor
191
192   fResponse      = 0;
193   fSegmentation  = 0;
194   fHis           = 0;
195   //    fpList         = 0;
196   fHitMap2       = 0;
197   fHitSigMap2    = 0;
198   fHitNoiMap2    = 0;
199   fElectronics   = 0;
200   fStream        = 0;
201   fInZR          = 0;
202   fInZI          = 0;
203   fOutZR         = 0;
204   fOutZI         = 0;
205   fNofMaps       = 0;
206   fMaxNofSamples = 0;
207   fITS           = 0;
208   fTreeB         = 0;
209   SetDebug(kFALSE);
210
211   Init((AliITSsegmentationSDD*)seg,(AliITSresponseSDD*)resp);
212 }
213 //______________________________________________________________________
214 void AliITSsimulationSDD::Init(AliITSsegmentationSDD *seg,
215                                AliITSresponseSDD *resp){
216   // Standard Constructor
217
218   fResponse     = resp;
219   fSegmentation = seg;
220   SetScaleFourier();
221   SetPerpendTracksFlag();
222   SetCrosstalkFlag();
223   SetDoFFT();
224   SetCheckNoise();
225
226   fpList = new AliITSpList( fSegmentation->Npz(),
227                             fScaleSize*fSegmentation->Npx() );
228   fHitSigMap2 = new AliITSMapA2(fSegmentation,fScaleSize,1);
229   fHitNoiMap2 = new AliITSMapA2(fSegmentation,fScaleSize,1);
230   fHitMap2 = fHitSigMap2;
231
232   fNofMaps = fSegmentation->Npz();
233   fMaxNofSamples = fSegmentation->Npx();
234   fAnodeFire = new Bool_t [fNofMaps];
235     
236   Float_t sddLength = fSegmentation->Dx();
237   Float_t sddWidth  = fSegmentation->Dz();
238
239   Int_t dummy        = 0;
240   Float_t anodePitch = fSegmentation->Dpz(dummy);
241   Double_t timeStep  = (Double_t)fSegmentation->Dpx(dummy);
242   Float_t driftSpeed = fResponse->DriftSpeed();
243
244   if(anodePitch*(fNofMaps/2) > sddWidth) {
245     Warning("AliITSsimulationSDD",
246             "Too many anodes %d or too big pitch %f \n",
247             fNofMaps/2,anodePitch);
248   } // end if
249
250   if(timeStep*fMaxNofSamples < sddLength/driftSpeed) {
251     Error("AliITSsimulationSDD",
252           "Time Interval > Allowed Time Interval: exit\n");
253     return;
254   } // end if
255
256   fElectronics = new AliITSetfSDD(timeStep/fScaleSize,
257                                   fResponse->Electronics());
258
259   char opt1[20], opt2[20];
260   fResponse->ParamOptions(opt1,opt2);
261   fParam = opt2;
262   char *same = strstr(opt1,"same");
263   if (same) {
264     fNoise.Set(0);
265     fBaseline.Set(0);
266   } else {
267     fNoise.Set(fNofMaps);
268     fBaseline.Set(fNofMaps);
269   } // end if
270
271   const char *kopt=fResponse->ZeroSuppOption();
272   if (strstr(fParam.Data(),"file") ) {
273     fD.Set(fNofMaps);
274     fT1.Set(fNofMaps);
275     if (strstr(kopt,"2D")) {
276       fT2.Set(fNofMaps);
277       fTol.Set(0);
278       Init2D();       // desactivate if param change module by module
279     } else if(strstr(kopt,"1D"))  {
280       fT2.Set(2);
281       fTol.Set(2);
282       Init1D();      // desactivate if param change module by module
283     } // end if strstr
284   } else {
285     fD.Set(2);
286     fTol.Set(2);
287     fT1.Set(2);
288     fT2.Set(2);
289     SetCompressParam();
290   } // end if else strstr
291
292   Bool_t write = fResponse->OutputOption();
293   if(write && strstr(kopt,"2D")) MakeTreeB();
294
295   // call here if baseline does not change by module
296   // ReadBaseline();
297
298   fITS       = (AliITS*)gAlice->GetModule("ITS");
299   Int_t size = fNofMaps*fMaxNofSamples;
300   fStream    = new AliITSInStream(size);
301
302   fInZR  = new Double_t [fScaleSize*fMaxNofSamples];
303   fInZI  = new Double_t [fScaleSize*fMaxNofSamples];
304   fOutZR = new Double_t [fScaleSize*fMaxNofSamples];
305   fOutZI = new Double_t [fScaleSize*fMaxNofSamples];  
306
307 }
308 //______________________________________________________________________
309 AliITSsimulationSDD::~AliITSsimulationSDD() { 
310   // destructor
311
312   //    delete fpList;
313   delete fHitSigMap2;
314   delete fHitNoiMap2;
315   delete fStream;
316   delete fElectronics;
317
318   fITS = 0;
319
320   if (fHis) {
321     fHis->Delete(); 
322     delete fHis;     
323   } // end if fHis
324   if(fTreeB) delete fTreeB;           
325   if(fInZR)  delete [] fInZR;
326   if(fInZI)  delete [] fInZI;        
327   if(fOutZR) delete [] fOutZR;
328   if(fOutZI) delete [] fOutZI;
329   if(fAnodeFire) delete [] fAnodeFire;
330 }
331 //______________________________________________________________________
332 void AliITSsimulationSDD::InitSimulationModule( Int_t module, Int_t event ) {
333   // create maps to build the lists of tracks for each summable digit
334   fModule = module;
335   fEvent  = event;
336   ClearMaps();
337   memset(fAnodeFire,0,sizeof(Bool_t)*fNofMaps);    
338 }
339 //______________________________________________________________________
340 void AliITSsimulationSDD::ClearMaps() {
341   // clear maps
342   fpList->ClearMap();
343   fHitSigMap2->ClearMap();
344   fHitNoiMap2->ClearMap();
345 }
346 //______________________________________________________________________
347 void AliITSsimulationSDD::SDigitiseModule( AliITSmodule *mod, Int_t md, Int_t ev){
348   // digitize module using the "slow" detector simulator creating
349   // summable digits.
350
351   TObjArray *fHits = mod->GetHits();
352   Int_t nhits      = fHits->GetEntriesFast();
353   if( !nhits ) return;
354
355   InitSimulationModule( md, ev );
356   HitsToAnalogDigits( mod );
357   ChargeToSignal( kFALSE ); // - Process signal without add noise
358   fHitMap2 = fHitNoiMap2;   // - Swap to noise map
359   ChargeToSignal( kTRUE );  // - Process only noise
360   fHitMap2 = fHitSigMap2;   // - Return to signal map
361   WriteSDigits();
362   ClearMaps();
363 }
364 //______________________________________________________________________
365 Bool_t AliITSsimulationSDD::AddSDigitsToModule( TClonesArray *pItemArray, Int_t mask ) {
366   // Add Summable digits to module maps.
367   Int_t    nItems = pItemArray->GetEntries();
368   Double_t maxadc = fResponse->MaxAdc();
369   //Bool_t sig = kFALSE;
370     
371   // cout << "Adding "<< nItems <<" SDigits to module " << fModule << endl;
372   for( Int_t i=0; i<nItems; i++ ) {
373     AliITSpListItem * pItem = (AliITSpListItem *)(pItemArray->At( i ));
374     if( pItem->GetModule() != fModule ) {
375       Error( "AliITSsimulationSDD",
376              "Error reading, SDigits module %d != current module %d: exit\n",
377              pItem->GetModule(), fModule );
378       return kFALSE;
379     } // end if
380
381       //  if(pItem->GetSignal()>0.0 ) sig = kTRUE;
382         
383     fpList->AddItemTo( mask, pItem ); // Add SignalAfterElect + noise
384     AliITSpListItem * pItem2 = fpList->GetpListItem( pItem->GetIndex() );
385     Double_t sigAE = pItem2->GetSignalAfterElect();
386     if( sigAE >= maxadc ) sigAE = maxadc-1; // avoid overflow signal
387     Int_t ia;
388     Int_t it;
389     fpList->GetMapIndex( pItem->GetIndex(), ia, it );
390     fHitMap2->SetHit( ia, it, sigAE );
391     fAnodeFire[ia] = kTRUE;
392   }
393   return kTRUE;
394 }
395 //______________________________________________________________________
396 void AliITSsimulationSDD::FinishSDigitiseModule() {
397   // digitize module using the "slow" detector simulator from
398   // the sum of summable digits.
399   FinishDigits() ;
400   ClearMaps();
401 }
402 //______________________________________________________________________
403 void AliITSsimulationSDD::DigitiseModule(AliITSmodule *mod,Int_t md,Int_t ev){
404   // create maps to build the lists of tracks for each digit
405
406   TObjArray *fHits = mod->GetHits();
407   Int_t nhits      = fHits->GetEntriesFast();
408
409   InitSimulationModule( md, ev );
410
411   if( !nhits && fCheckNoise ) {
412     ChargeToSignal( kTRUE );  // process noise
413     GetNoise();
414     ClearMaps();
415     return;
416   } else 
417     if( !nhits ) return;
418         
419   HitsToAnalogDigits( mod );
420   ChargeToSignal( kTRUE );  // process signal + noise
421
422   for( Int_t i=0; i<fNofMaps; i++ ) {
423     for( Int_t j=0; j<fMaxNofSamples; j++ ) {
424       Int_t jdx = j*fScaleSize;
425       Int_t index = fpList->GetHitIndex( i, j );
426       AliITSpListItem pItemTmp2( fModule, index, 0. );
427       // put the fScaleSize analog digits in only one
428       for( Int_t ik=0; ik<fScaleSize; ik++ ) {
429         AliITSpListItem *pItemTmp = fpList->GetpListItem( i, jdx+ik );
430         if( pItemTmp == 0 ) continue;
431         pItemTmp2.Add( pItemTmp );
432       }
433       fpList->DeleteHit( i, j );
434       fpList->AddItemTo( 0, &pItemTmp2 );
435     }
436   }
437
438   FinishDigits();
439   ClearMaps();
440 }
441 //______________________________________________________________________
442 void AliITSsimulationSDD::FinishDigits() {
443   // introduce the electronics effects and do zero-suppression if required
444
445   ApplyDeadChannels();
446   if( fCrosstalkFlag ) ApplyCrosstalk();
447
448   const char *kopt = fResponse->ZeroSuppOption();
449   ZeroSuppression( kopt );
450 }
451 //______________________________________________________________________
452 void AliITSsimulationSDD::HitsToAnalogDigits( AliITSmodule *mod ) {
453   // create maps to build the lists of tracks for each digit
454
455   TObjArray *fHits    = mod->GetHits();
456   Int_t      nhits    = fHits->GetEntriesFast();
457   //    Int_t      arg[6]   = {0,0,0,0,0,0};
458   Int_t    dummy      = 0;
459   Int_t    nofAnodes  = fNofMaps/2;
460   Float_t  sddLength  = fSegmentation->Dx();
461   Float_t  sddWidth   = fSegmentation->Dz();
462   Float_t  anodePitch = fSegmentation->Dpz(dummy);
463   Float_t  timeStep   = fSegmentation->Dpx(dummy);
464   Float_t  driftSpeed = fResponse->DriftSpeed();
465   Float_t  maxadc     = fResponse->MaxAdc();    
466   Float_t  topValue   = fResponse->DynamicRange();
467   Float_t  cHloss     = fResponse->ChargeLoss();
468   Float_t  norm       = maxadc/topValue;
469   Float_t  dfCoeff, s1; fResponse->DiffCoeff(dfCoeff,s1); // Signal 2d Shape
470   Double_t eVpairs    = 3.6;  // electron pair energy eV.
471   Float_t  nsigma     = fResponse->NSigmaIntegration(); //
472   Int_t    nlookups   = fResponse->GausNLookUp();       //
473   Float_t  jitter     = ((AliITSresponseSDD*)fResponse)->JitterError(); // 
474
475   // Piergiorgio's part (apart for few variables which I made float
476   // when i thought that can be done
477   // Fill detector maps with GEANT hits
478   // loop over hits in the module
479
480   const Float_t kconv = 1.0e+6;  // GeV->KeV
481   Int_t    itrack      = 0;
482   Int_t    hitDetector; // detector number (lay,lad,hitDetector)
483   Int_t    iWing;       // which detector wing/side.
484   Int_t    detector;    // 2*(detector-1)+iWing
485   Int_t    ii,kk,ka,kt; // loop indexs
486   Int_t    ia,it,index; // sub-pixel integration indexies
487   Int_t    iAnode;      // anode number.
488   Int_t    timeSample;  // time buckett.
489   Int_t    anodeWindow; // anode direction charge integration width
490   Int_t    timeWindow;  // time direction charge integration width
491   Int_t    jamin,jamax; // anode charge integration window
492   Int_t    jtmin,jtmax; // time charge integration window
493   Int_t    ndiv;        // Anode window division factor.
494   Int_t    nsplit;      // the number of splits in anode and time windows==1.
495   Int_t    nOfSplits;   // number of times track length is split into
496   Float_t  nOfSplitsF;  // Floating point version of nOfSplits.
497   Float_t  kkF;         // Floating point version of loop index kk.
498   Float_t  pathInSDD; // Track length in SDD.
499   Float_t  drPath; // average position of track in detector. in microns
500   Float_t  drTime; // Drift time
501   Float_t  nmul;   // drift time window multiplication factor.
502   Float_t  avDrft;  // x position of path length segment in cm.
503   Float_t  avAnode; // Anode for path length segment in Anode number (float)
504   Float_t  xAnode;  // Floating point anode number.
505   Float_t  driftPath; // avDrft in microns.
506   Float_t  width;     // width of signal at anodes.
507   Double_t  depEnergy; // Energy deposited in this GEANT step.
508   Double_t  xL[3],dxL[3]; // local hit coordinates and diff.
509   Double_t sigA; // sigma of signal at anode.
510   Double_t sigT; // sigma in time/drift direction for track segment
511   Double_t aStep,aConst; // sub-pixel size and offset anode
512   Double_t tStep,tConst; // sub-pixel size and offset time
513   Double_t amplitude; // signal amplitude for track segment in nanoAmpere
514   Double_t chargeloss; // charge loss for track segment.
515   Double_t anodeAmplitude; // signal amplitude in anode direction
516   Double_t aExpo;          // exponent of Gaussian anode direction
517   Double_t timeAmplitude;  // signal amplitude in time direction
518   Double_t tExpo;          // exponent of Gaussian time direction
519   //  Double_t tof;            // Time of flight in ns of this step.    
520
521   for(ii=0; ii<nhits; ii++) {
522     if(!mod->LineSegmentL(ii,xL[0],dxL[0],xL[1],dxL[1],xL[2],dxL[2],
523                           depEnergy,itrack)) continue;
524     xL[0] += 0.0001*gRandom->Gaus( 0, jitter ); //
525     depEnergy  *= kconv;
526     hitDetector = mod->GetDet();
527     //tof         = 1.E+09*(mod->GetHit(ii)->GetTOF()); // tof in ns.
528     //if(tof>sddLength/driftSpeed) continue; // hit happed too late.
529
530     // scale path to simulate a perpendicular track
531     // continue if the particle did not lose energy
532     // passing through detector
533     if (!depEnergy) {
534       if(GetDebug()){ 
535         Warning("HitsToAnalogDigits", 
536                 "fTrack = %d hit=%d module=%d This particle has"
537                 " passed without losing energy!",
538                 itrack,ii,mod->GetIndex());
539       }
540       continue;
541     } // end if !depEnergy
542
543     pathInSDD = TMath::Sqrt(dxL[0]*dxL[0]+dxL[1]*dxL[1]+dxL[2]*dxL[2]);
544
545     if (fFlag && pathInSDD) { depEnergy *= (0.03/pathInSDD); }
546     drPath = 10000.*(dxL[0]+2.*xL[0])*0.5;
547     if(drPath < 0) drPath = -drPath;
548     drPath = sddLength-drPath;
549     if(drPath < 0) {
550       if(GetDebug()){ // this should be fixed at geometry level
551         Warning("HitsToAnalogDigits",
552                 "negative drift path drPath=%e sddLength=%e dxL[0]=%e "
553                 "xL[0]=%e",
554                 drPath,sddLength,dxL[0],xL[0]);
555       }
556       continue;
557     } // end if drPath < 0
558
559     // Compute number of segments to brake step path into
560     drTime = drPath/driftSpeed;  //   Drift Time
561     sigA   = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1);// Sigma along the anodes
562     // calcuate the number of time the path length should be split into.
563     nOfSplits = (Int_t) (1. + 10000.*pathInSDD/sigA);
564     if(fFlag) nOfSplits = 1;
565
566     // loop over path segments, init. some variables.
567     depEnergy /= nOfSplits;
568     nOfSplitsF = (Float_t) nOfSplits;
569     for(kk=0;kk<nOfSplits;kk++) { // loop over path segments
570       kkF       = (Float_t) kk + 0.5;
571       avDrft    = xL[0]+dxL[0]*kkF/nOfSplitsF;
572       avAnode   = xL[2]+dxL[2]*kkF/nOfSplitsF;
573       driftPath = 10000.*avDrft;
574
575       iWing = 2;  // Assume wing is 2
576       if(driftPath < 0) { // if wing is not 2 it is 1.
577         iWing     = 1;
578         driftPath = -driftPath;
579       } // end if driftPath < 0
580       driftPath = sddLength-driftPath;
581       detector  = 2*(hitDetector-1) + iWing;
582       if(driftPath < 0) {
583         if(GetDebug()){ // this should be fixed at geometry level
584           Warning("HitsToAnalogDigits","negative drift path "
585                   "driftPath=%e sddLength=%e avDrft=%e dxL[0]=%e "
586                   "xL[0]=%e",driftPath,sddLength,avDrft,dxL[0],xL[0]);
587         }
588         continue;
589       } // end if driftPath < 0
590
591       //   Drift Time
592       drTime     = driftPath/driftSpeed; // drift time for segment.
593       timeSample = (Int_t) (fScaleSize*drTime/timeStep + 1);
594       // compute time Sample including tof information. The tof only 
595       // effects the time of the signal is recoreded and not the
596       // the defusion.
597       // timeSample = (Int_t) (fScaleSize*(drTime+tof)/timeStep + 1);
598       if(timeSample > fScaleSize*fMaxNofSamples) {
599         Warning("HitsToAnalogDigits","Wrong Time Sample: %e",
600                 timeSample);
601         continue;
602       } // end if timeSample > fScaleSize*fMaxNoofSamples
603
604       //   Anode
605       xAnode = 10000.*(avAnode)/anodePitch + nofAnodes/2;  // +1?
606       if(xAnode*anodePitch > sddWidth || xAnode*anodePitch < 0.) 
607         Warning("HitsToAnalogDigits",
608                 "Exceedubg sddWidth=%e Z = %e",
609                 sddWidth,xAnode*anodePitch);
610       iAnode = (Int_t) (1.+xAnode); // xAnode?
611       if(iAnode < 1 || iAnode > nofAnodes) {
612         Warning("HitToAnalogDigits","Wrong iAnode: 1<%d>%d",
613                 iAnode,nofAnodes);
614         continue;
615       } // end if iAnode < 1 || iAnode > nofAnodes
616
617       // store straight away the particle position in the array
618       // of particles and take idhit=ii only when part is entering (this
619       // requires FillModules() in the macro for analysis) :
620     
621       // Sigma along the anodes for track segment.
622       sigA       = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1);
623       sigT       = sigA/driftSpeed;
624       // Peak amplitude in nanoAmpere
625       amplitude  = fScaleSize*160.*depEnergy/
626         (timeStep*eVpairs*2.*acos(-1.)*sigT*sigA);
627       amplitude *= timeStep/25.; // WARNING!!!!! Amplitude scaling to 
628       // account for clock variations 
629       // (reference value: 40 MHz)
630       chargeloss = 1.-cHloss*driftPath/1000;
631       amplitude *= chargeloss;
632       width  = 2.*nsigma/(nlookups-1);
633       // Spread the charge 
634       // Pixel index
635       ndiv = 2;
636       nmul = 3.; 
637       if(drTime > 1200.) { 
638         ndiv = 4;
639         nmul = 1.5;
640       } // end if drTime > 1200.
641       // Sub-pixel index
642       nsplit = 4; // hard-wired //nsplit=4;nsplit = (nsplit+1)/2*2;
643       // Sub-pixel size see computation of aExpo and tExpo.
644       aStep  = anodePitch/(nsplit*fScaleSize*sigA);
645       aConst = xAnode*anodePitch/sigA;
646       tStep  = timeStep/(nsplit*fScaleSize*sigT);
647       tConst = drTime/sigT;
648       // Define SDD window corresponding to the hit
649       anodeWindow = (Int_t)(fScaleSize*nsigma*sigA/anodePitch+1);
650       timeWindow  = (Int_t) (fScaleSize*nsigma*sigT/timeStep+1.);
651       jamin = (iAnode - anodeWindow/ndiv - 1)*fScaleSize*nsplit +1;
652       jamax = (iAnode + anodeWindow/ndiv)*fScaleSize*nsplit;
653       if(jamin <= 0) jamin = 1;
654       if(jamax > fScaleSize*nofAnodes*nsplit) 
655         jamax = fScaleSize*nofAnodes*nsplit;
656       // jtmin and jtmax are Hard-wired
657       jtmin = (Int_t)(timeSample-timeWindow*nmul-1)*nsplit+1;
658       jtmax = (Int_t)(timeSample+timeWindow*nmul)*nsplit;
659       if(jtmin <= 0) jtmin = 1;
660       if(jtmax > fScaleSize*fMaxNofSamples*nsplit) 
661         jtmax = fScaleSize*fMaxNofSamples*nsplit;
662       // Spread the charge in the anode-time window
663       for(ka=jamin; ka <=jamax; ka++) {
664         ia = (ka-1)/(fScaleSize*nsplit) + 1;
665         if(ia <= 0) {
666           Warning("HitsToAnalogDigits","ia < 1: ");
667           continue;
668         } // end if
669         if(ia > nofAnodes) ia = nofAnodes;
670         aExpo     = (aStep*(ka-0.5)-aConst);
671         if(TMath::Abs(aExpo) > nsigma)  anodeAmplitude = 0.;
672         else {
673           dummy          = (Int_t) ((aExpo+nsigma)/width);
674           anodeAmplitude = amplitude*fResponse->GausLookUp(dummy);
675         } // end if TMath::Abs(aEspo) > nsigma
676         // index starts from 0
677         index = ((detector+1)%2)*nofAnodes+ia-1;
678         if(anodeAmplitude) for(kt=jtmin; kt<=jtmax; kt++) {
679           it = (kt-1)/nsplit+1;  // it starts from 1
680           if(it<=0){
681             Warning("HitsToAnalogDigits","it < 1:");
682             continue;
683           } // end if 
684           if(it>fScaleSize*fMaxNofSamples)
685             it = fScaleSize*fMaxNofSamples;
686           tExpo    = (tStep*(kt-0.5)-tConst);
687           if(TMath::Abs(tExpo) > nsigma) timeAmplitude = 0.;
688           else {
689             dummy         = (Int_t) ((tExpo+nsigma)/width);
690             timeAmplitude = anodeAmplitude*
691               fResponse->GausLookUp(dummy);
692           } // end if TMath::Abs(tExpo) > nsigma
693           // build the list of Sdigits for this module        
694           //                    arg[0]         = index;
695           //                    arg[1]         = it;
696           //                    arg[2]         = itrack; // track number
697           //                    arg[3]         = ii-1; // hit number.
698           timeAmplitude *= norm;
699           timeAmplitude *= 10;
700           //                    ListOfFiredCells(arg,timeAmplitude,alst,padr);
701           Double_t charge = timeAmplitude;
702           charge += fHitMap2->GetSignal(index,it-1);
703           fHitMap2->SetHit(index, it-1, charge);
704           fpList->AddSignal(index,it-1,itrack,ii-1,
705                             mod->GetIndex(),timeAmplitude);
706           fAnodeFire[index] = kTRUE;                 
707         } // end if anodeAmplitude and loop over time in window
708       } // loop over anodes in window
709     } // end loop over "sub-hits"
710   } // end loop over hits
711 }
712
713 /*
714 //______________________________________________________________________
715 void AliITSsimulationSDD::ListOfFiredCells(Int_t *arg,Double_t timeAmplitude,
716                                            TObjArray *alist,TClonesArray *padr){
717   // Returns the list of "fired" cells.
718
719   Int_t index     = arg[0];
720   Int_t ik        = arg[1];
721   Int_t idtrack   = arg[2];
722   Int_t idhit     = arg[3];
723   Int_t counter   = arg[4];
724   Int_t countadr  = arg[5];
725   Double_t charge = timeAmplitude;
726   charge += fHitMap2->GetSignal(index,ik-1);
727   fHitMap2->SetHit(index, ik-1, charge);
728
729   Int_t digits[3];
730   Int_t it = (Int_t)((ik-1)/fScaleSize);
731   digits[0] = index;
732   digits[1] = it;
733   digits[2] = (Int_t)timeAmplitude;
734   Float_t phys;
735   if (idtrack >= 0) phys = (Float_t)timeAmplitude;
736   else phys = 0;
737
738   Double_t cellcharge = 0.;
739   AliITSTransientDigit* pdigit;
740   // build the list of fired cells and update the info
741   if (!fHitMap1->TestHit(index, it)) {
742     new((*padr)[countadr++]) TVector(3);
743     TVector &trinfo=*((TVector*) (*padr)[countadr-1]);
744     trinfo(0) = (Float_t)idtrack;
745     trinfo(1) = (Float_t)idhit;
746     trinfo(2) = (Float_t)timeAmplitude;
747
748     alist->AddAtAndExpand(new AliITSTransientDigit(phys,digits),counter);
749     fHitMap1->SetHit(index, it, counter);
750     counter++;
751     pdigit=(AliITSTransientDigit*)alist->At(alist->GetLast());
752     // list of tracks
753     TObjArray *trlist=(TObjArray*)pdigit->TrackList();
754     trlist->Add(&trinfo);
755   } else {
756     pdigit = (AliITSTransientDigit*) fHitMap1->GetHit(index, it);
757     for(Int_t kk=0;kk<fScaleSize;kk++) {
758       cellcharge += fHitMap2->GetSignal(index,fScaleSize*it+kk);
759     }  // end for kk
760     // update charge
761     (*pdigit).fSignal = (Int_t)cellcharge;
762     (*pdigit).fPhysics += phys;                        
763     // update list of tracks
764     TObjArray* trlist = (TObjArray*)pdigit->TrackList();
765     Int_t lastentry = trlist->GetLast();
766     TVector *ptrkp = (TVector*)trlist->At(lastentry);
767     TVector &trinfo = *ptrkp;
768     Int_t lasttrack = Int_t(trinfo(0));
769     Float_t lastcharge=(trinfo(2));
770     if (lasttrack==idtrack ) {
771       lastcharge += (Float_t)timeAmplitude;
772       trlist->RemoveAt(lastentry);
773       trinfo(0) = lasttrack;
774       trinfo(1) = idhit;
775       trinfo(2) = lastcharge;
776       trlist->AddAt(&trinfo,lastentry);
777     } else {                  
778       new((*padr)[countadr++]) TVector(3);
779       TVector &trinfo=*((TVector*) (*padr)[countadr-1]);
780       trinfo(0) = (Float_t)idtrack;
781       trinfo(1) = (Float_t)idhit;
782       trinfo(2) = (Float_t)timeAmplitude;
783       trlist->Add(&trinfo);
784     } // end if lasttrack==idtrack
785
786 #ifdef print
787     // check the track list - debugging
788     Int_t trk[20], htrk[20];
789     Float_t chtrk[20];  
790     Int_t nptracks = trlist->GetEntriesFast();
791     if (nptracks > 2) {
792       Int_t tr;
793       for (tr=0;tr<nptracks;tr++) {
794         TVector *pptrkp = (TVector*)trlist->At(tr);
795         TVector &pptrk  = *pptrkp;
796         trk[tr]   = Int_t(pptrk(0));
797         htrk[tr]  = Int_t(pptrk(1));
798         chtrk[tr] = (pptrk(2));
799         cout << "nptracks "<<nptracks << endl;
800       } // end for tr
801     } // end if nptracks
802 #endif
803   } //  end if pdigit
804
805   // update counter and countadr for next call.
806   arg[4] = counter;
807   arg[5] = countadr;
808 }
809 */
810
811 //____________________________________________
812 void AliITSsimulationSDD::AddDigit( Int_t i, Int_t j, Int_t signal ) {
813   // Adds a Digit.
814   Int_t size = AliITSdigitSPD::GetNTracks();
815   Int_t digits[3];
816   Int_t * tracks = new Int_t[size];
817   Int_t * hits = new Int_t[size];
818   Float_t phys;
819   Float_t * charges = new Float_t[size];
820
821   digits[0] = i;
822   digits[1] = j;
823   digits[2] = signal;
824
825   AliITSpListItem *pItem = fpList->GetpListItem( i, j );
826   if( pItem == 0 ) {
827     phys = 0.0;
828     for( Int_t l=0; l<size; l++ ) {
829       tracks[l]  = 0;
830       hits[l]    = 0;
831       charges[l] = 0.0;
832     }
833   } else {
834     Int_t idtrack =  pItem->GetTrack( 0 );
835     if( idtrack >= 0 ) phys = pItem->GetSignal();  
836     else phys = 0.0;
837
838     for( Int_t l=0; l<size; l++ ) if(l<pItem->GetMaxKept()) {
839       tracks[l]  = pItem->GetTrack( l );
840       hits[l]    = pItem->GetHit( l );
841       charges[l] = pItem->GetSignal( l );
842     }else{
843       tracks[l]  = -3;
844       hits[l]    = -1;
845       charges[l] = 0.0;
846     }// end for if
847   }
848
849   fITS->AddSimDigit( 1, phys, digits, tracks, hits, charges ); 
850   delete [] tracks;
851   delete [] hits;
852   delete [] charges;
853 }
854
855 //______________________________________________________________________
856 void AliITSsimulationSDD::ChargeToSignal(Bool_t bAddNoise) {
857   // add baseline, noise, electronics and ADC saturation effects
858
859   char opt1[20], opt2[20];
860   fResponse->ParamOptions(opt1,opt2);
861   char *read = strstr(opt1,"file");
862   Float_t baseline, noise; 
863
864   if (read) {
865     static Bool_t readfile=kTRUE;
866     //read baseline and noise from file
867     if (readfile) ReadBaseline();
868     readfile=kFALSE;
869   } else fResponse->GetNoiseParam(noise,baseline);
870
871   Float_t contrib=0;
872   Int_t i,k,kk;
873   Float_t maxadc = fResponse->MaxAdc();    
874   if(!fDoFFT) {
875     for (i=0;i<fNofMaps;i++) {
876       if( !fAnodeFire[i] ) continue;
877       if (read && i<fNofMaps) GetAnodeBaseline(i,baseline,noise);
878       for(k=0; k<fScaleSize*fMaxNofSamples; k++) {
879         fInZR[k]  = fHitMap2->GetSignal(i,k);
880         if( bAddNoise ) {
881           contrib   = (baseline + noise*gRandom->Gaus());
882           fInZR[k] += contrib;
883         }
884       } // end for k
885       for(k=0; k<fMaxNofSamples; k++) {
886         Double_t newcont = 0.;
887         Double_t maxcont = 0.;
888         for(kk=0;kk<fScaleSize;kk++) {
889           newcont = fInZR[fScaleSize*k+kk];
890           if(newcont > maxcont) maxcont = newcont;
891         } // end for kk
892         newcont = maxcont;
893         if (newcont >= maxadc) newcont = maxadc -1;
894         if(newcont >= baseline){
895           Warning("","newcont=%d>=baseline=%d",newcont,baseline);
896         } // end if
897         // back to analog: ?
898         fHitMap2->SetHit(i,k,newcont);
899       }  // end for k
900     } // end for i loop over anodes
901     return;
902   } // end if DoFFT
903
904   for (i=0;i<fNofMaps;i++) {
905     if( !fAnodeFire[i] ) continue;
906     if  (read && i<fNofMaps) GetAnodeBaseline(i,baseline,noise);
907     for(k=0; k<fScaleSize*fMaxNofSamples; k++) {
908       fInZR[k]  = fHitMap2->GetSignal(i,k);
909       if( bAddNoise ) {
910         contrib   = (baseline + noise*gRandom->Gaus());
911         fInZR[k] += contrib;
912       }
913       fInZI[k]  = 0.;
914     } // end for k
915     FastFourierTransform(fElectronics,&fInZR[0],&fInZI[0],1);
916     for(k=0; k<fScaleSize*fMaxNofSamples; k++) {
917       Double_t rw = fElectronics->GetTraFunReal(k);
918       Double_t iw = fElectronics->GetTraFunImag(k);
919       fOutZR[k]   = fInZR[k]*rw - fInZI[k]*iw;
920       fOutZI[k]   = fInZR[k]*iw + fInZI[k]*rw;
921     } // end for k
922     FastFourierTransform(fElectronics,&fOutZR[0],&fOutZI[0],-1);
923     for(k=0; k<fMaxNofSamples; k++) {
924       Double_t newcont1 = 0.;
925       Double_t maxcont1 = 0.;
926       for(kk=0;kk<fScaleSize;kk++) {
927         newcont1 = fOutZR[fScaleSize*k+kk];
928         if(newcont1 > maxcont1) maxcont1 = newcont1;
929       } // end for kk
930       newcont1 = maxcont1;
931       if (newcont1 >= maxadc) newcont1 = maxadc -1;
932       fHitMap2->SetHit(i,k,newcont1);
933     } // end for k
934   } // end for i loop over anodes
935   return;
936 }
937 //____________________________________________________________________
938 void AliITSsimulationSDD::ApplyDeadChannels() {    
939   // Set dead channel signal to zero
940   AliITSresponseSDD * response = (AliITSresponseSDD *)fResponse;
941     
942   // nothing to do
943   if( response->GetDeadModules() == 0 && 
944       response->GetDeadChips() == 0 && 
945       response->GetDeadChannels() == 0 )
946     return;  
947     
948   static AliITS *iTS = (AliITS*)gAlice->GetModule( "ITS" );
949
950   Int_t fMaxNofSamples = fSegmentation->Npx();    
951   AliITSgeom *geom = iTS->GetITSgeom();
952   Int_t firstSDDMod = geom->GetStartDet( 1 );
953   // loop over wings
954   for( Int_t j=0; j<2; j++ ) {
955     Int_t mod = (fModule-firstSDDMod)*2 + j;
956     for( Int_t u=0; u<response->Chips(); u++ )
957       for( Int_t v=0; v<response->Channels(); v++ ) {
958         Float_t Gain = response->Gain( mod, u, v );
959         for( Int_t k=0; k<fMaxNofSamples; k++ ) {
960           Int_t i = j*response->Chips()*response->Channels() +
961             u*response->Channels() + 
962             v;
963           Double_t signal =  Gain * fHitMap2->GetSignal( i, k );
964           fHitMap2->SetHit( i, k, signal );  ///
965         }
966       }
967   }    
968 }
969 //______________________________________________________________________
970 void AliITSsimulationSDD::ApplyCrosstalk() {
971   // function add the crosstalk effect to signal
972   // temporal function, should be checked...!!!
973     
974   Int_t fNofMaps = fSegmentation->Npz();
975   Int_t fMaxNofSamples = fSegmentation->Npx();
976
977   // create and inizialice crosstalk map
978   Float_t* ctk = new Float_t[fNofMaps*fMaxNofSamples+1];
979   if( ctk == NULL ) {
980     Error( "ApplyCrosstalk", "no memory for temporal map: exit \n" );
981     return;
982   }
983   memset( ctk, 0, sizeof(Float_t)*(fNofMaps*fMaxNofSamples+1) );
984     
985   Float_t noise, baseline;
986   fResponse->GetNoiseParam( noise, baseline );
987     
988   for( Int_t z=0; z<fNofMaps; z++ ) {
989     Bool_t on = kFALSE;
990     Int_t tstart = 0;
991     Int_t tstop = 0;
992     Int_t nTsteps = 0;
993         
994     for( Int_t l=0; l<fMaxNofSamples; l++ ) {
995       Float_t fadc = (Float_t)fHitMap2->GetSignal( z, l );
996       if( fadc > baseline ) {
997         if( on == kFALSE && l<fMaxNofSamples-4 ) {
998           Float_t fadc1 = (Float_t)fHitMap2->GetSignal( z, l+1 );
999           if( fadc1 < fadc ) continue;
1000           on = kTRUE;
1001           nTsteps = 0;
1002           tstart = l;
1003         }
1004         nTsteps++;
1005       }
1006       else { // end fadc > baseline
1007         if( on == kTRUE ) {        
1008           if( nTsteps > 2 ) {
1009             tstop = l;
1010             // make smooth derivative
1011             Float_t* dev = new Float_t[fMaxNofSamples+1];
1012             memset( dev, 0, sizeof(Float_t)*(fMaxNofSamples+1) );
1013             if( ctk == NULL ) {
1014               Error( "ApplyCrosstalk", 
1015                      "no memory for temporal array: exit \n" );
1016               return;
1017             }
1018             for( Int_t i=tstart; i<tstop; i++ ) {   
1019               if( i > 2 && i < fMaxNofSamples-2 )
1020                 dev[i] = -0.2*fHitMap2->GetSignal( z,i-2 ) 
1021                   -0.1*fHitMap2->GetSignal( z,i-1 ) 
1022                   +0.1*fHitMap2->GetSignal( z,i+1 ) 
1023                   +0.2*fHitMap2->GetSignal( z,i+2 );
1024             }
1025                         
1026             // add crosstalk contribution to neibourg anodes  
1027             for( Int_t i=tstart; i<tstop; i++ ) {
1028               Int_t anode = z - 1;
1029               Int_t i1 = (Int_t)((i-tstart)*.61+tstart+0.5); // 
1030               Float_t ctktmp =  -dev[i1] * 0.25;
1031               if( anode > 0 ) {
1032                 ctk[anode*fMaxNofSamples+i] += ctktmp;           
1033               }
1034               anode = z + 1;
1035               if( anode < fNofMaps ) {
1036                 ctk[anode*fMaxNofSamples+i] += ctktmp;
1037               }
1038             }
1039             delete [] dev;
1040                         
1041           } // if( nTsteps > 2 )
1042           on = kFALSE;
1043         }  // if( on == kTRUE )
1044       }  // else
1045     }
1046   }
1047     
1048   for( Int_t a=0; a<fNofMaps; a++ )
1049     for( Int_t t=0; t<fMaxNofSamples; t++ ) {     
1050       Float_t signal = fHitMap2->GetSignal( a, t ) + ctk[a*fMaxNofSamples+t];
1051       fHitMap2->SetHit( a, t, signal );
1052     }
1053     
1054   delete [] ctk;
1055 }
1056 //______________________________________________________________________
1057 void AliITSsimulationSDD::GetAnodeBaseline(Int_t i,Float_t &baseline,
1058                                            Float_t &noise){
1059   // Returns the Baseline for a particular anode.
1060   baseline = fBaseline[i];
1061   noise    = fNoise[i];
1062 }
1063 //______________________________________________________________________
1064 void AliITSsimulationSDD::CompressionParam(Int_t i,Int_t &db,Int_t &tl,
1065                                            Int_t &th){
1066   // Returns the compression alogirthm parameters
1067   Int_t size = fD.GetSize();
1068   if (size > 2 ) {
1069     db=fD[i]; tl=fT1[i]; th=fT2[i];
1070   } else {
1071     if (size <= 2 && i>=fNofMaps/2) {
1072       db=fD[1]; tl=fT1[1]; th=fT2[1];
1073     } else {
1074       db=fD[0]; tl=fT1[0]; th=fT2[0];
1075     } // end if size <=2 && i>=fNofMaps/2
1076   } // end if size >2
1077 }
1078 //______________________________________________________________________
1079 void AliITSsimulationSDD::CompressionParam(Int_t i,Int_t &db,Int_t &tl){
1080   // returns the compression alogirthm parameters
1081   Int_t size = fD.GetSize();
1082
1083   if (size > 2 ) {
1084     db=fD[i]; tl=fT1[i];
1085   } else {
1086     if (size <= 2 && i>=fNofMaps/2) {
1087       db=fD[1]; tl=fT1[1]; 
1088     } else {
1089       db=fD[0]; tl=fT1[0]; 
1090     } // end if size <=2 && i>=fNofMaps/2
1091     //  Warning("CompressionParam","\n Size= %d . Values i=%d ; db= %d ; tl= %d",size,i,db,tl);
1092   } // end if size > 2
1093 }
1094 //______________________________________________________________________
1095 void AliITSsimulationSDD::SetCompressParam(){
1096   // Sets the compression alogirthm parameters  
1097   Int_t cp[8],i;
1098
1099   fResponse->GiveCompressParam(cp);
1100   for (i=0; i<2; i++) {
1101     fD[i]   = cp[i];
1102     fT1[i]  = cp[i+2];
1103     fT2[i]  = cp[i+4];
1104     fTol[i] = cp[i+6];
1105   } // end for i
1106 }
1107 //______________________________________________________________________
1108 void AliITSsimulationSDD::ReadBaseline(){
1109   // read baseline and noise from file - either a .root file and in this
1110   // case data should be organised in a tree with one entry for each
1111   // module => reading should be done accordingly
1112   // or a classic file and do smth. like this:
1113   // Read baselines and noise for SDD
1114
1115   Int_t na,pos;
1116   Float_t bl,n;
1117   char input[100], base[100], param[100];
1118   char *filtmp;
1119
1120   fResponse->Filenames(input,base,param);
1121   fFileName=base;
1122   //
1123   filtmp = gSystem->ExpandPathName(fFileName.Data());
1124   FILE *bline = fopen(filtmp,"r");
1125   na = 0;
1126
1127   if(bline) {
1128     while(fscanf(bline,"%d %f %f",&pos, &bl, &n) != EOF) {
1129       if (pos != na+1) {
1130         Error("ReadBaseline","Anode number not in increasing order!",
1131               filtmp);
1132         exit(1);
1133       } // end if pos != na+1
1134       fBaseline[na]=bl;
1135       fNoise[na]=n;
1136       na++;
1137     } // end while
1138   } else {
1139     Error("ReadBaseline"," THE BASELINE FILE %s DOES NOT EXIST !",filtmp);
1140     exit(1);
1141   } // end if(bline)
1142
1143   fclose(bline);
1144   delete [] filtmp;
1145 }
1146 //______________________________________________________________________
1147 Int_t AliITSsimulationSDD::Convert10to8(Int_t signal) const {
1148   // To the 10 to 8 bit lossive compression.
1149   // code from Davide C. and Albert W.
1150
1151   if (signal < 128)  return signal;
1152   if (signal < 256)  return (128+((signal-128)>>1));
1153   if (signal < 512)  return (192+((signal-256)>>3));
1154   if (signal < 1024) return (224+((signal-512)>>4));
1155   return 0;
1156 }
1157
1158 /*
1159 //______________________________________________________________________
1160 AliITSMap*   AliITSsimulationSDD::HitMap(Int_t i){
1161   //Return the correct map.
1162
1163   return ((i==0)? fHitMap1 : fHitMap2);
1164 }
1165 */
1166
1167 //______________________________________________________________________
1168 void AliITSsimulationSDD::ZeroSuppression(const char *option) {
1169   // perform the zero suppresion
1170
1171   if (strstr(option,"2D")) {
1172     //Init2D();              // activate if param change module by module
1173     Compress2D();
1174   } else if (strstr(option,"1D")) {
1175     //Init1D();              // activate if param change module by module
1176     Compress1D();  
1177   } else StoreAllDigits();
1178 }
1179 //______________________________________________________________________
1180 void AliITSsimulationSDD::Init2D(){
1181   // read in and prepare arrays: fD, fT1, fT2
1182   //                         savemu[nanodes], savesigma[nanodes] 
1183   // read baseline and noise from file - either a .root file and in this
1184   // case data should be organised in a tree with one entry for each
1185   // module => reading should be done accordingly
1186   // or a classic file and do smth. like this ( code from Davide C. and
1187   // Albert W.) :
1188   // Read 2D zero-suppression parameters for SDD
1189
1190   if (!strstr(fParam.Data(),"file")) return;
1191
1192   Int_t na,pos,tempTh;
1193   Float_t mu,sigma;
1194   Float_t *savemu    = new Float_t [fNofMaps];
1195   Float_t *savesigma = new Float_t [fNofMaps];
1196   char input[100],basel[100],par[100];
1197   char *filtmp;
1198   Float_t tmp1,tmp2;
1199   fResponse->Thresholds(tmp1,tmp2);
1200   Int_t minval = static_cast<Int_t>(tmp1);
1201
1202   fResponse->Filenames(input,basel,par);
1203   fFileName = par;
1204   //
1205   filtmp = gSystem->ExpandPathName(fFileName.Data());
1206   FILE *param = fopen(filtmp,"r");
1207   na = 0;
1208
1209   if(param) {
1210     while(fscanf(param,"%d %f %f",&pos, &mu, &sigma) != EOF) {
1211       if (pos != na+1) {
1212         Error("Init2D","Anode number not in increasing order!",filtmp);
1213         exit(1);
1214       } // end if pos != na+1
1215       savemu[na] = mu;
1216       savesigma[na] = sigma;
1217       if ((2.*sigma) < mu) {
1218         fD[na] = (Int_t)floor(mu - 2.0*sigma + 0.5);
1219         mu = 2.0 * sigma;
1220       } else fD[na] = 0;
1221       tempTh = (Int_t)floor(mu+2.25*sigma+0.5) - minval;
1222       if (tempTh < 0) tempTh=0;
1223       fT1[na] = tempTh;
1224       tempTh = (Int_t)floor(mu+3.0*sigma+0.5) - minval;
1225       if (tempTh < 0) tempTh=0;
1226       fT2[na] = tempTh;
1227       na++;
1228     } // end while
1229   } else {
1230     Error("Init2D","THE FILE %s DOES NOT EXIST !",filtmp);
1231     exit(1);
1232   } // end if(param)
1233
1234   fclose(param);
1235   delete [] filtmp;
1236   delete [] savemu;
1237   delete [] savesigma;
1238 }
1239 //______________________________________________________________________
1240 void AliITSsimulationSDD::Compress2D(){
1241   // simple ITS cluster finder -- online zero-suppression conditions
1242
1243   Int_t db,tl,th; 
1244   Float_t tmp1,tmp2;
1245   fResponse->Thresholds(tmp1,tmp2); 
1246   Int_t minval   = static_cast<Int_t>(tmp1);
1247   Bool_t write   = fResponse->OutputOption();   
1248   Bool_t do10to8 = fResponse->Do10to8();
1249   Int_t nz, nl, nh, low, i, j; 
1250
1251   for (i=0; i<fNofMaps; i++) {
1252     CompressionParam(i,db,tl,th);
1253     nz  = 0; 
1254     nl  = 0;
1255     nh  = 0;
1256     low = 0;
1257     for (j=0; j<fMaxNofSamples; j++) {
1258       Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
1259       signal -= db; // if baseline eq. is done here
1260       if (signal <= 0) {nz++; continue;}
1261       if ((signal - tl) < minval) low++;
1262       if ((signal - th) >= minval) {
1263         nh++;
1264         Bool_t cond=kTRUE;
1265         FindCluster(i,j,signal,minval,cond);
1266         if(cond && j &&
1267            ((TMath::Abs(fHitMap2->GetSignal(i,j-1))-th)>=minval)){
1268           if(do10to8) signal = Convert10to8(signal);
1269           AddDigit(i,j,signal);
1270         } // end if cond&&j&&()
1271       } else if ((signal - tl) >= minval) nl++;
1272     } // end for j loop time samples
1273     if (write) TreeB()->Fill(nz,nl,nh,low,i+1);
1274   } //end for i loop anodes
1275
1276   char hname[30];
1277   if (write) {
1278     sprintf(hname,"TNtuple%d_%d",fModule,fEvent);
1279     TreeB()->Write(hname);
1280     // reset tree
1281     TreeB()->Reset();
1282   } // end if write
1283 }
1284 //______________________________________________________________________
1285 void  AliITSsimulationSDD::FindCluster(Int_t i,Int_t j,Int_t signal,
1286                                        Int_t minval,Bool_t &cond){
1287   // Find clusters according to the online 2D zero-suppression algorithm
1288   Bool_t do10to8 = fResponse->Do10to8();
1289   Bool_t high    = kFALSE;
1290
1291   fHitMap2->FlagHit(i,j);
1292   //
1293   //  check the online zero-suppression conditions
1294   //  
1295   const Int_t kMaxNeighbours = 4;
1296   Int_t nn;
1297   Int_t dbx,tlx,thx;  
1298   Int_t xList[kMaxNeighbours], yList[kMaxNeighbours];
1299   fSegmentation->Neighbours(i,j,&nn,xList,yList);
1300   Int_t in,ix,iy,qns;
1301   for (in=0; in<nn; in++) {
1302     ix=xList[in];
1303     iy=yList[in];
1304     if (fHitMap2->TestHit(ix,iy)==kUnused) {
1305       CompressionParam(ix,dbx,tlx,thx);
1306       Int_t qn = (Int_t)(fHitMap2->GetSignal(ix,iy));
1307       qn -= dbx; // if baseline eq. is done here
1308       if ((qn-tlx) < minval) {
1309         fHitMap2->FlagHit(ix,iy);
1310         continue;
1311       } else {
1312         if ((qn - thx) >= minval) high=kTRUE;
1313         if (cond) {
1314           if(do10to8) signal = Convert10to8(signal);
1315           AddDigit(i,j,signal);
1316         } // end if cond
1317         if(do10to8) qns = Convert10to8(qn);
1318         else qns=qn;
1319         if (!high) AddDigit(ix,iy,qns);
1320         cond=kFALSE;
1321         if(!high) fHitMap2->FlagHit(ix,iy);
1322       } // end if qn-tlx < minval
1323     } // end if  TestHit
1324   } // end for in loop over neighbours
1325 }
1326 //______________________________________________________________________
1327 void AliITSsimulationSDD::Init1D(){
1328   // this is just a copy-paste of input taken from 2D algo
1329   // Torino people should give input
1330   // Read 1D zero-suppression parameters for SDD
1331
1332   if (!strstr(fParam.Data(),"file")) return;
1333
1334   Int_t na,pos,tempTh;
1335   Float_t mu,sigma;
1336   Float_t *savemu    = new Float_t [fNofMaps];
1337   Float_t *savesigma = new Float_t [fNofMaps];
1338   char input[100],basel[100],par[100];
1339   char *filtmp;
1340   Float_t tmp1,tmp2;
1341   fResponse->Thresholds(tmp1,tmp2);
1342   Int_t minval = static_cast<Int_t>(tmp1);
1343
1344   fResponse->Filenames(input,basel,par);
1345   fFileName=par;
1346
1347   //  set first the disable and tol param
1348   SetCompressParam();
1349   //
1350   filtmp = gSystem->ExpandPathName(fFileName.Data());
1351   FILE *param = fopen(filtmp,"r");
1352   na = 0;
1353
1354   if (param) {
1355     fscanf(param,"%d %d %d %d ", &fT2[0], &fT2[1], &fTol[0], &fTol[1]);
1356     while(fscanf(param,"%d %f %f",&pos, &mu, &sigma) != EOF) {
1357       if (pos != na+1) {
1358         Error("Init1D","Anode number not in increasing order!",filtmp);
1359         exit(1);
1360       } // end if pos != na+1
1361       savemu[na]=mu;
1362       savesigma[na]=sigma;
1363       if ((2.*sigma) < mu) {
1364         fD[na] = (Int_t)floor(mu - 2.0*sigma + 0.5);
1365         mu = 2.0 * sigma;
1366       } else fD[na] = 0;
1367       tempTh = (Int_t)floor(mu+2.25*sigma+0.5) - minval;
1368       if (tempTh < 0) tempTh=0;
1369       fT1[na] = tempTh;
1370       na++;
1371     } // end while
1372   } else {
1373     Error("Init1D","THE FILE %s DOES NOT EXIST !",filtmp);
1374     exit(1);
1375   } // end if(param)
1376
1377   fclose(param);
1378   delete [] filtmp;
1379   delete [] savemu;
1380   delete [] savesigma;
1381
1382 //______________________________________________________________________
1383 void AliITSsimulationSDD::Compress1D(){
1384   // 1D zero-suppression algorithm (from Gianluca A.)
1385   Int_t    dis,tol,thres,decr,diff;
1386   UChar_t *str=fStream->Stream();
1387   Int_t    counter=0;
1388   Bool_t   do10to8=fResponse->Do10to8();
1389   Int_t    last=0;
1390   Int_t    k,i,j;
1391
1392   for (k=0; k<2; k++) {
1393     tol = Tolerance(k);
1394     dis = Disable(k);  
1395     for (i=0; i<fNofMaps/2; i++) {
1396       Bool_t firstSignal=kTRUE;
1397       Int_t idx=i+k*fNofMaps/2;
1398       if( !fAnodeFire[idx] ) continue;
1399       CompressionParam(idx,decr,thres); 
1400
1401       for (j=0; j<fMaxNofSamples; j++) {
1402         Int_t signal=(Int_t)(fHitMap2->GetSignal(idx,j));
1403         signal -= decr;  // if baseline eq.
1404         if(do10to8) signal = Convert10to8(signal);
1405         if (signal <= thres) {
1406           signal=0;
1407           diff=128; 
1408           last=0; 
1409           // write diff in the buffer for HuffT
1410           str[counter]=(UChar_t)diff;
1411           counter++;
1412           continue;
1413         } // end if signal <= thres
1414         diff=signal-last;
1415         if (diff > 127) diff=127;
1416         if (diff < -128) diff=-128;
1417         if (signal < dis) {
1418           // tol has changed to 8 possible cases ? - one can write
1419           // this if(TMath::Abs(diff)<tol) ... else ...
1420           if(TMath::Abs(diff)<tol) diff=0;
1421           // or keep it as it was before
1422           AddDigit(idx,j,last+diff);
1423         } else {
1424           AddDigit(idx,j,signal);
1425         } // end if singal < dis
1426         diff += 128;
1427         // write diff in the buffer used to compute Huffman tables
1428         if (firstSignal) str[counter]=(UChar_t)signal;
1429         else str[counter]=(UChar_t)diff;
1430         counter++;
1431         last=signal;
1432         firstSignal=kFALSE;
1433       } // end for j loop time samples
1434     } // end for i loop anodes  one half of detector 
1435   } //  end for k
1436
1437     // check
1438   fStream->CheckCount(counter);
1439
1440   // open file and write out the stream of diff's
1441   static Bool_t open=kTRUE;
1442   static TFile *outFile;
1443   Bool_t write = fResponse->OutputOption();
1444   TDirectory *savedir = gDirectory;
1445  
1446   if (write ) {
1447     if(open) {
1448       SetFileName("stream.root");
1449       cout<<"filename "<<fFileName<<endl;
1450       outFile=new TFile(fFileName,"recreate");
1451       cout<<"I have opened "<<fFileName<<" file "<<endl;
1452     } // end if open
1453     open = kFALSE;
1454     outFile->cd();
1455     fStream->Write();
1456   }  // endif write        
1457
1458   fStream->ClearStream();
1459
1460   // back to galice.root file
1461   if(savedir) savedir->cd();
1462 }
1463 //______________________________________________________________________
1464 void AliITSsimulationSDD::StoreAllDigits(){
1465   // if non-zero-suppressed data
1466   Bool_t do10to8 = fResponse->Do10to8();
1467   Int_t i, j, digits[3];
1468
1469   for (i=0; i<fNofMaps; i++) {
1470     for (j=0; j<fMaxNofSamples; j++) {
1471       Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
1472       if(do10to8) signal = Convert10to8(signal);
1473       digits[0] = i;
1474       digits[1] = j;
1475       digits[2] = signal;
1476       fITS->AddRealDigit(1,digits);
1477     } // end for j
1478   } // end for i
1479
1480 //______________________________________________________________________
1481 void AliITSsimulationSDD::CreateHistograms(Int_t scale){
1482   // Creates histograms of maps for debugging
1483   Int_t i;
1484
1485   fHis=new TObjArray(fNofMaps);
1486   for (i=0;i<fNofMaps;i++) {
1487     TString sddName("sdd_");
1488     Char_t candNum[4];
1489     sprintf(candNum,"%d",i+1);
1490     sddName.Append(candNum);
1491     fHis->AddAt(new TH1F(sddName.Data(),"SDD maps",scale*fMaxNofSamples,
1492                          0.,(Float_t) scale*fMaxNofSamples), i);
1493   } // end for i
1494 }
1495 //______________________________________________________________________
1496 void AliITSsimulationSDD::FillHistograms(){
1497   // fill 1D histograms from map
1498
1499   if (!fHis) return;
1500
1501   for( Int_t i=0; i<fNofMaps; i++) {
1502     TH1F *hist =(TH1F *)fHis->UncheckedAt(i);
1503     Int_t nsamples = hist->GetNbinsX();
1504     for( Int_t j=0; j<nsamples; j++) {
1505       Double_t signal=fHitMap2->GetSignal(i,j);
1506       hist->Fill((Float_t)j,signal);
1507     } // end for j
1508   } // end for i
1509 }
1510 //______________________________________________________________________
1511 void AliITSsimulationSDD::ResetHistograms(){
1512   // Reset histograms for this detector
1513   Int_t i;
1514
1515   for (i=0;i<fNofMaps;i++ ) {
1516     if (fHis->At(i))    ((TH1F*)fHis->At(i))->Reset();
1517   } // end for i
1518 }
1519 //______________________________________________________________________
1520 TH1F *AliITSsimulationSDD::GetAnode(Int_t wing, Int_t anode) { 
1521   // Fills a histogram from a give anode.  
1522
1523   if (!fHis) return 0;
1524
1525   if(wing <=0 || wing > 2) {
1526     Warning("GetAnode","Wrong wing number: %d",wing);
1527     return NULL;
1528   } // end if wing <=0 || wing >2
1529   if(anode <=0 || anode > fNofMaps/2) {
1530     Warning("GetAnode","Wrong anode number: %d",anode);
1531     return NULL;
1532   } // end if ampde <=0 || andoe > fNofMaps/2
1533
1534   Int_t index = (wing-1)*fNofMaps/2 + anode-1;
1535   return (TH1F*)(fHis->At(index));
1536 }
1537 //______________________________________________________________________
1538 void AliITSsimulationSDD::WriteToFile(TFile *hfile) {
1539   // Writes the histograms to a file
1540
1541   if (!fHis) return;
1542
1543   hfile->cd();
1544   Int_t i;
1545   for(i=0; i<fNofMaps; i++)  fHis->At(i)->Write(); //fAdcs[i]->Write();
1546   return;
1547 }
1548 //______________________________________________________________________
1549 Float_t AliITSsimulationSDD::GetNoise() {  
1550   // Returns the noise value
1551   //Bool_t do10to8=fResponse->Do10to8();
1552   //noise will always be in the liniar part of the signal
1553   Int_t decr;
1554   Int_t threshold = fT1[0];
1555   char opt1[20], opt2[20];
1556
1557   fResponse->ParamOptions(opt1,opt2);
1558   fParam=opt2;
1559   char *same = strstr(opt1,"same");
1560   Float_t noise,baseline;
1561   if (same) {
1562     fResponse->GetNoiseParam(noise,baseline);
1563   } else {
1564     static Bool_t readfile=kTRUE;
1565     //read baseline and noise from file
1566     if (readfile) ReadBaseline();
1567     readfile=kFALSE;
1568   } // end if same
1569
1570   TCanvas *c2 = (TCanvas*)gROOT->GetListOfCanvases()->FindObject("c2");
1571   if(c2) delete c2->GetPrimitive("noisehist");
1572   if(c2) delete c2->GetPrimitive("anode");
1573   else     c2=new TCanvas("c2");
1574   c2->cd();
1575   c2->SetFillColor(0);
1576
1577   TH1F *noisehist = new TH1F("noisehist","noise",100,0.,(float)2*threshold);
1578   TH1F *anode = new TH1F("anode","Anode Projection",fMaxNofSamples,0.,
1579                          (float)fMaxNofSamples);
1580   Int_t i,k;
1581   for (i=0;i<fNofMaps;i++) {
1582     CompressionParam(i,decr,threshold); 
1583     if  (!same) GetAnodeBaseline(i,baseline,noise);
1584     anode->Reset();
1585     for (k=0;k<fMaxNofSamples;k++) {
1586       Float_t signal=(Float_t)fHitMap2->GetSignal(i,k);
1587       //if (signal <= (float)threshold) noisehist->Fill(signal-baseline);
1588       if (signal <= (float)(threshold+decr)) noisehist->Fill(signal);
1589       anode->Fill((float)k,signal);
1590     } // end for k
1591     anode->Draw();
1592     c2->Update();
1593   } // end for i
1594   TF1 *gnoise = new TF1("gnoise","gaus",0.,threshold);
1595   noisehist->Fit("gnoise","RQ");
1596   noisehist->Draw();
1597   c2->Update();
1598   Float_t mnoise = gnoise->GetParameter(1);
1599   cout << "mnoise : " << mnoise << endl;
1600   Float_t rnoise = gnoise->GetParameter(2);
1601   cout << "rnoise : " << rnoise << endl;
1602   delete noisehist;
1603   return rnoise;
1604 }
1605 //______________________________________________________________________
1606 void AliITSsimulationSDD::WriteSDigits(){
1607   // Fills the Summable digits Tree
1608   static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
1609
1610   for( Int_t i=0; i<fNofMaps; i++ ) {
1611     if( !fAnodeFire[i] ) continue;
1612     for( Int_t j=0; j<fMaxNofSamples; j++ ) {
1613       Double_t sig = fHitMap2->GetSignal( i, j );
1614       if( sig > 0.2 ) {
1615         Int_t jdx = j*fScaleSize;
1616         Int_t index = fpList->GetHitIndex( i, j );
1617         AliITSpListItem pItemTmp2( fModule, index, 0. );
1618         // put the fScaleSize analog digits in only one
1619         for( Int_t ik=0; ik<fScaleSize; ik++ ) {
1620           AliITSpListItem *pItemTmp = fpList->GetpListItem( i, jdx+ik );
1621           if( pItemTmp == 0 ) continue;
1622           pItemTmp2.Add( pItemTmp );
1623         }
1624         pItemTmp2.AddSignalAfterElect( fModule, index, sig );
1625         pItemTmp2.AddNoise( fModule, index, fHitNoiMap2->GetSignal( i, j ) );         
1626         aliITS->AddSumDigit( pItemTmp2 );
1627       } // end if (sig > 0.2)
1628     }
1629   }
1630   return;
1631 }
1632 //______________________________________________________________________
1633 void AliITSsimulationSDD::Print() {
1634   // Print SDD simulation Parameters
1635
1636   cout << "**************************************************" << endl;
1637   cout << "   Silicon Drift Detector Simulation Parameters   " << endl;
1638   cout << "**************************************************" << endl;
1639   cout << "Flag for Perpendicular tracks: " << (Int_t) fFlag << endl;
1640   cout << "Flag for noise checking: " << (Int_t) fCheckNoise << endl;
1641   cout << "Flag to switch off electronics: " << (Int_t) fDoFFT << endl;
1642   cout << "Number pf Anodes used: " << fNofMaps << endl;
1643   cout << "Number of Time Samples: " << fMaxNofSamples << endl;
1644   cout << "Scale size factor: " << fScaleSize << endl;
1645   cout << "**************************************************" << endl;
1646 }