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