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