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