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