1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
25 #include "AliITSetfSDD.h"
26 #include "AliITSsimulationSDD.h"
27 #include "AliITSHuffman.h"
29 const Int_t kMaxNeighbours = 4;
31 ClassImp(AliITSsimulationSDD)
32 ////////////////////////////////////////////////////////////////////////
34 // Written by Piergiorgio Cerello
37 // AliITSsimulationSDD is the simulation of SDDs.
41 <img src="picts/ITS/AliITShit_Class_Diagram.gif">
44 <font size=+2 color=red>
45 <p>This show the relasionships between the ITS hit class and the rest of Aliroot.
50 //_____________________________________________________________________________
52 Int_t power(Int_t b, Int_t e) {
53 // copute b to the e power, where bothe b and e are Int_ts.
55 for(i=0; i<e; i++) power *= b;
59 //_____________________________________________
61 void FastFourierTransform(AliITSetfSDD *alisddetf,Double_t *real,
62 Double_t *imag,Int_t direction) {
63 // Do a Fast Fourier Transform
65 Int_t samples = alisddetf->GetSamples();
66 Int_t l = (Int_t) ((log((Float_t) samples)/log(2.))+0.5);
69 Int_t m2 = samples/m1;
72 for(j=0; j<samples; j += m1) {
74 for(k=j; k<= j+m-1; k++) {
75 Double_t wsr = alisddetf->GetWeightReal(p);
76 Double_t wsi = alisddetf->GetWeightImag(p);
77 if(direction == -1) wsi = -wsi;
78 Double_t xr = *(real+k+m);
79 Double_t xi = *(imag+k+m);
80 *(real+k+m) = wsr*(*(real+k)-xr) - wsi*(*(imag+k)-xi);
81 *(imag+k+m) = wsr*(*(imag+k)-xi) + wsi*(*(real+k)-xr);
92 for(j=0; j<samples; j++) {
96 for(i1=1; i1<=l; i1++) {
99 p = p + p + j2 - j1 - j1;
102 Double_t xr = *(real+j);
103 Double_t xi = *(imag+j);
104 *(real+j) = *(real+p);
105 *(imag+j) = *(imag+p);
110 if(direction == -1) {
111 for(i=0; i<samples; i++) {
112 *(real+i) /= samples;
113 *(imag+i) /= samples;
118 //_____________________________________________________________________________
120 AliITSsimulationSDD::AliITSsimulationSDD(){
121 // Default constructor
136 //_____________________________________________________________________________
137 AliITSsimulationSDD::AliITSsimulationSDD(AliITSsimulationSDD &source){
138 // Copy constructor to satify Coding roules only.
139 if(this==&source) return;
140 printf("Not allowed to make a copy of AliITSsimulationSDD "
141 "Using default creater instead\n");
142 AliITSsimulationSDD();
144 //_____________________________________________________________________________
145 AliITSsimulationSDD& AliITSsimulationSDD::operator=(AliITSsimulationSDD
147 // Copy constructor to satify Coding roules only.
148 if(this==&source) return *this;
149 printf("Not allowed to make a = with AliITSsimulationSDD "
150 "Using default creater instead\n");
153 //_____________________________________________________________________________
155 AliITSsimulationSDD::AliITSsimulationSDD(AliITSsegmentation *seg,
156 AliITSresponse *resp) {
161 fHitMap2 = new AliITSMapA2(fSegmentation);
162 fHitMap1 = new AliITSMapA1(fSegmentation);
165 fNofMaps=fSegmentation->Npz();
166 fMaxNofSamples=fSegmentation->Npx();
168 Float_t sddLength = fSegmentation->Dx();
169 Float_t sddWidth = fSegmentation->Dz();
172 Float_t anodePitch = fSegmentation->Dpz(dummy);
173 Double_t timeStep = (Double_t)fSegmentation->Dpx(dummy);
174 Float_t driftSpeed=fResponse->DriftSpeed();
176 if(anodePitch*(fNofMaps/2) > sddWidth) {
177 Warning("AliITSsimulationSDD",
178 "Too many anodes %d or too big pitch %f \n",fNofMaps/2,anodePitch);
181 if(timeStep*fMaxNofSamples < sddLength/driftSpeed) {
182 Error("AliITSsimulationSDD",
183 "Time Interval > Allowed Time Interval: exit\n");
187 fElectronics = new AliITSetfSDD(timeStep);
189 Option_t *opt1, *opt2;
190 fResponse->ParamOptions(opt1,opt2);
192 char *same = strstr(opt1,"same");
197 fNoise.Set(fNofMaps);
198 fBaseline.Set(fNofMaps);
202 Option_t *opt=fResponse->ZeroSuppOption();
203 if (strstr(fParam,"file") ) {
206 if (strstr(opt,"2D")) {
209 Init2D(); // desactivate if param change module by module
210 } else if(strstr(opt,"1D")) {
213 Init1D(); // desactivate if param change module by module
224 Bool_t write=fResponse->OutputOption();
225 if(write && strstr(opt,"2D")) MakeTreeB();
227 // call here if baseline does not change by module
230 fITS = (AliITS*)gAlice->GetModule("ITS");
231 Int_t size=fNofMaps*fMaxNofSamples;
232 fStream = new AliITSInStream(size);
234 fInZR = new Double_t [fMaxNofSamples];
235 fInZI = new Double_t [fMaxNofSamples];
236 fOutZR = new Double_t [fMaxNofSamples];
237 fOutZI = new Double_t [fMaxNofSamples];
242 //_____________________________________________________________________________
244 AliITSsimulationSDD::~AliITSsimulationSDD() {
273 //_____________________________________________________________________________
275 void AliITSsimulationSDD::DigitiseModule(AliITSmodule *mod,Int_t md,Int_t ev){
276 // create maps to build the lists of tracks
282 TObjArray *fHits = mod->GetHits();
283 Int_t nhits = fHits->GetEntriesFast();
287 TObjArray *list=new TObjArray;
288 static TClonesArray *padr=0;
289 if(!padr) padr=new TClonesArray("TVector",1000);
290 Int_t arg[5] = {0,0,0,0,0};
291 fHitMap1->SetArray(list);
294 Int_t NofAnodes=fNofMaps/2;
296 Float_t sddLength = fSegmentation->Dx();
297 Float_t sddWidth = fSegmentation->Dz();
300 Float_t anodePitch = fSegmentation->Dpz(dummy);
301 Float_t timeStep = fSegmentation->Dpx(dummy);
303 Float_t driftSpeed=fResponse->DriftSpeed();
305 // Piergiorgio's part (apart for few variables which I made float
306 // when i thought that can be done
308 // Fill detector maps with GEANT hits
309 // loop over hits in the module
311 const Float_t kconv=1000000.; // GeV->KeV
313 for(ii=0; ii<nhits; ii++) {
314 AliITShit *hit = (AliITShit*) fHits->At(ii);
315 Int_t hitDetector = hit->GetDetector();
317 hit->GetPositionL(xL[0],xL[1],xL[2]);
318 // cout << "hit local coordinates: " << xL[0] << "," << xL[1] << "," << xL[2] << endl;
319 // Deposited energy in keV
322 Float_t depEnergy = kconv*hit->GetIonization();
324 if(depEnergy == 0.) {
327 hit1 = (AliITShit*) fHits->At(ii);
328 hit1->GetPositionL(xL1[0],xL1[1],xL1[2]);
329 //cout << "hit1 local coordinates: " << xL1[0] << "," << xL1[1] << "," << xL1[2] << endl;
330 //cout << "radius1: " << TMath::Sqrt(xL1[0]*xL1[0]+xL1[1]*xL1[1]) << ", azimuth: " << TMath::ATan2(xL1[0],xL1[1]) << endl;
333 depEnergy = kconv*hit1->GetIonization();
335 Float_t avDrft = xL[0]+avpath;
336 Float_t avAnode = xL[2]+avanod;
338 if(avpath != 0.) avDrft /= 2.;
339 if(avanod != 0.) avAnode /= 2.;
341 Float_t driftPath = 10000.*avDrft;
342 //printf("sddLength %f avDrft driftPath %f %f\n",sddLength,avDrft, driftPath);
346 driftPath = -driftPath;
348 driftPath = sddLength-driftPath;
349 Int_t detector = 2*(hitDetector-1) + iWing;
351 cout << "Warning: negative drift path " << driftPath << endl;
356 Float_t driftTime = driftPath/driftSpeed;
357 Int_t timeSample = (Int_t) (driftTime/timeStep + 1);
358 if(timeSample > fMaxNofSamples) {
359 cout << "Warning: Wrong Time Sample: " << timeSample << endl;
364 Float_t xAnode = 10000.*(avAnode)/anodePitch + NofAnodes/2; // +1?
365 // Int_t iAnode = 0.5+xAnode; // xAnode?
366 if(xAnode*anodePitch > sddWidth || xAnode*anodePitch < 0.)
367 { cout << "Warning: Z = " << xAnode*anodePitch << endl; }
368 Int_t iAnode = (Int_t) (1.+xAnode); // xAnode?
369 // cout << "iAnode " << iAnode << endl;
370 if(iAnode < 0 || iAnode > NofAnodes) {
371 cout << "Warning: Wrong iAnode: " << iAnode << endl;
376 // work with the idtrack=entry number in the TreeH
377 // Int_t idtrack=mod->GetHitTrackIndex(ii);
378 // or store straight away the particle position in the array
380 Int_t idtrack = hit->GetTrack();
383 Double_t qRef = (Double_t)fResponse->Qref();
384 Double_t diffCoeff = (Double_t)fResponse->DiffCoeff();
386 Double_t gamma = 1. + 0.155*depEnergy/qRef;
387 // Squared Sigma along the anodes
388 Double_t sigma2A = 2.*diffCoeff*driftTime*gamma;
389 Double_t sigmaT = TMath::Sqrt(sigma2A)/driftSpeed;
391 // Peak amplitude in nanoAmpere
392 Double_t eVpairs = 3.6;
393 Double_t amplitude = 160.*depEnergy/(timeStep*eVpairs*2.*acos(-1.)*sigmaT*TMath::Sqrt(sigma2A));
398 Int_t jt = timeSample;
401 nsplit = (nsplit+1)/2*2;
403 Double_t aStep = anodePitch/nsplit;
404 Double_t tStep = timeStep/nsplit;
405 // Define SDD window corresponding to the hit
406 Int_t anodeWindow = (Int_t) (4.*TMath::Sqrt(sigma2A)/anodePitch + 1);
407 Int_t timeWindow = (Int_t) (4.*sigmaT/timeStep + 1);
408 Int_t jamin = (ja - anodeWindow/2 - 1)*nsplit + 1;
409 Int_t jamax = (ja + anodeWindow/2)*nsplit;
410 if(jamin <= 0) jamin = 1;
411 if(jamax > NofAnodes*nsplit) jamax = NofAnodes*nsplit;
412 Int_t jtmin = (jt - timeWindow/2 - 1)*nsplit + 1;
413 Int_t jtmax = (jt + timeWindow/2)*nsplit;
414 if(jtmin <= 0) jtmin = 1;
415 if(jtmax > fMaxNofSamples*nsplit) jtmax = fMaxNofSamples*nsplit;
416 Double_t rlAnode = log(aStep*amplitude);
417 // Spread the charge in the anode-time window
419 for(ka=jamin; ka <=jamax; ka++) {
420 Int_t ia = (ka-1)/nsplit + 1;
421 if(ia <= 0) { cout << "Warning: ia < 1: " << endl; continue; }
422 if(ia > NofAnodes) ia = NofAnodes;
423 Double_t aExpo = aStep*(ka)-xAnode*anodePitch;
424 Double_t anodeAmplitude = rlAnode - 0.5*aExpo*aExpo/sigma2A;
425 // Protect against overflows
426 if(anodeAmplitude > -87.3)
427 anodeAmplitude = exp(anodeAmplitude);
431 Double_t rlTime = log(tStep*anodeAmplitude);
433 for(kt=jtmin; kt<=jtmax; kt++) {
434 Int_t it = (kt-1)/nsplit+1;
435 if(it<=0) { cout << "Warning: it < 1: " << endl; continue; }
436 if(it>fMaxNofSamples) it = fMaxNofSamples;
437 Double_t tExpo = (tStep*(kt)-driftTime)/sigmaT;
438 Double_t timeAmplitude = rlTime - 0.5*tExpo*tExpo;
439 // Protect against overflows
440 if(timeAmplitude > -87.3)
441 timeAmplitude = exp(timeAmplitude);
445 Int_t index = ((detector+1)%2)*NofAnodes+ia-1;
446 // build the list of digits for this module
450 ListOfFiredCells(arg,timeAmplitude,list,padr);
451 } // loop over time in window
452 } // end if anodeAmplitude
453 } // loop over anodes in window
454 } // end loop over hits
456 Int_t nentries=list->GetEntriesFast();
457 // introduce the electronics effects and do zero-suppression if required
461 Option_t *opt=fResponse->ZeroSuppOption();
462 ZeroSuppression(opt);
471 fHitMap1->ClearMap();
472 fHitMap2->ClearMap();
474 //gObjectTable->Print();
478 //____________________________________________
480 void AliITSsimulationSDD::ListOfFiredCells(Int_t *arg,Double_t timeAmplitude,
481 TObjArray *list,TClonesArray *padr){
482 // Returns the list of "fired" cells.
486 Int_t idtrack=arg[2];
487 Int_t counter=arg[3];
488 Int_t countadr=arg[4];
494 digits[2]=(Int_t)timeAmplitude;
496 if (idtrack >= 0) phys=(Float_t)timeAmplitude;
499 Double_t charge=timeAmplitude;
500 AliITSTransientDigit* pdigit;
501 // build the list of fired cells and update the info
502 if (!fHitMap1->TestHit(index, it-1)) {
504 new((*padr)[countadr++]) TVector(2);
505 TVector &trinfo=*((TVector*) (*padr)[countadr-1]);
506 trinfo(0)=(Float_t)idtrack;
507 trinfo(1)=(Float_t)timeAmplitude;
509 list->AddAtAndExpand(
510 new AliITSTransientDigit(phys,digits),counter);
512 fHitMap1->SetHit(index, it-1, counter);
513 fHitMap2->SetHit(index, it-1, charge);
516 pdigit=(AliITSTransientDigit*)list->
519 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
520 trlist->Add(&trinfo);
524 (AliITSTransientDigit*) fHitMap1->GetHit(index, it-1);
525 charge += fHitMap2->GetSignal(index,it-1);
526 fHitMap2->SetHit(index, it-1, charge);
528 (*pdigit).fSignal=(Int_t)charge;
529 (*pdigit).fPhysics+=phys;
530 // update list of tracks
531 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
532 Int_t lastentry=trlist->GetLast();
533 TVector *ptrkp=(TVector*)trlist->At(lastentry);
534 TVector &trinfo=*ptrkp;
535 Int_t lasttrack=Int_t(trinfo(0));
536 Float_t lastcharge=(trinfo(1));
538 if (lasttrack==idtrack ) {
539 lastcharge+=(Float_t)timeAmplitude;
540 trlist->RemoveAt(lastentry);
542 trinfo(1)=lastcharge;
543 trlist->AddAt(&trinfo,lastentry);
546 new((*padr)[countadr++]) TVector(2);
547 TVector &trinfo=*((TVector*) (*padr)[countadr-1]);
548 trinfo(0)=(Float_t)idtrack;
549 trinfo(1)=(Float_t)timeAmplitude;
551 trlist->Add(&trinfo);
555 // check the track list - debugging
558 Int_t nptracks=trlist->GetEntriesFast();
561 for(tr=0;tr<nptracks;tr++) {
562 TVector *pptrkp=(TVector*)trlist->At(tr);
563 TVector &pptrk=*pptrkp;
564 trk[tr]=Int_t(pptrk(0));
565 chtrk[tr]=(pptrk(1));
566 printf("nptracks %d \n",nptracks);
580 //____________________________________________
582 void AliITSsimulationSDD::AddDigit(Int_t i, Int_t j, Int_t signal){
584 // tag with -1 signals coming from background tracks
585 // tag with -2 signals coming from pure electronic noise
587 Int_t digits[3], tracks[3];
588 Float_t phys, charges[3];
593 signal=Convert8to10(signal); // set a flag in case non-ZS are 10-bit
594 AliITSTransientDigit *obj = (AliITSTransientDigit*)fHitMap1->GetHit(i,j);
598 // printf("module anode, time, signal %d %d %d %d\n",fModule,i,j,signal);
606 fITS->AddDigit(1,phys,digits,tracks,charges);
609 //printf("AddDigit - test: fCoord1 fCoord2 fSignal %d %d %d i j signal %d %d %d \n",obj->fCoord1,obj->fCoord2,obj->fSignal,i,j,signal);
611 TObjArray* trlist=(TObjArray*)obj->TrackList();
612 Int_t nptracks=trlist->GetEntriesFast();
615 cout<<"Attention - nptracks > 20 "<<nptracks<<endl;
619 for(tr=0;tr<nptracks;tr++) {
620 TVector &pp =*((TVector*)trlist->At(tr));
621 trk[tr]=Int_t(pp(0));
625 //printf("AddDigit: nptracks %d\n",nptracks);
626 SortTracks(trk,chtrk,nptracks);
630 for(i=0; i<nptracks; i++) {
634 for(i=nptracks; i<3; i++) {
645 fITS->AddDigit(1,phys,digits,tracks,charges);
651 //____________________________________________
653 void AliITSsimulationSDD::SortTracks(Int_t *tracks,Float_t *charges,Int_t ntr){
655 // Sort the list of tracks contributing to a given digit
656 // Only the 3 most significant tracks are acctually sorted
660 // Loop over signals, only 3 times
666 Int_t idx[3] = {-3,-3,-3};
667 Float_t jch[3] = {-3,-3,-3};
668 Int_t jtr[3] = {-3,-3,-3};
679 if((i == 1 && j == idx[i-1] )
680 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
682 if(charges[j] > qmax) {
690 jch[i]=charges[jmax];
707 //____________________________________________
708 void AliITSsimulationSDD::ChargeToSignal() {
709 // add baseline, noise, electronics and ADC saturation effects
711 // Double_t InZR[fMaxNofSamples];
712 // Double_t InZI[fMaxNofSamples];
713 // Double_t OutZR[fMaxNofSamples];
714 // Double_t OutZI[fMaxNofSamples];
719 Float_t maxadc = fResponse->MaxAdc();
720 Float_t TopValue = fResponse->MagicValue();
721 Float_t norm = maxadc/TopValue;
724 Option_t *opt1, *opt2;
725 fResponse->ParamOptions(opt1,opt2);
726 char *read = strstr(opt1,"file");
728 Float_t baseline, noise;
731 static Bool_t readfile=kTRUE;
732 //read baseline and noise from file
733 if (readfile) ReadBaseline();
735 } else fResponse->GetNoiseParam(noise,baseline);
740 TRandom *random = new TRandom();
742 for(i=0;i<=fNofMaps;i++) {
743 if (read) GetAnodeBaseline(i,baseline,noise);
744 if (!first) FastFourierTransform(fElectronics,&fInZR[0],&fInZI[0],1);
745 for(k=0;k<fMaxNofSamples;k++) {
747 // analog to digital ?
748 Double_t signal = fOutZR[k]*norm;
749 if (signal > maxadc) signal = maxadc;
752 //printf("ChargeToSignal: signal %f\n",signal);
753 fHitMap2->SetHit(i-1,k,signal);
755 Double_t rw = fElectronics->GetTraFunReal(k);
756 Double_t iw = fElectronics->GetTraFunImag(k);
757 fOutZR[k] = fInZR[k]*rw - fInZI[k]*iw;
758 fOutZI[k] = fInZR[k]*iw + fInZI[k]*rw;
759 if(i+1 < fNofMaps) fInZR[k] = fHitMap2->GetSignal(i+1,k);
763 fInZR[k] = fHitMap2->GetSignal(i,k);
766 // add baseline and noise
767 contrib = baseline + noise*random->Gaus();
773 FastFourierTransform(fElectronics,&fInZR[0],&fInZI[0],1);
774 for(k=0; k<fMaxNofSamples; k++) {
775 Double_t rw = fElectronics->GetTraFunReal(k);
776 Double_t iw = fElectronics->GetTraFunImag(k);
777 fOutZR[k] = fInZR[k]*rw - fInZI[k]*iw;
778 fOutZI[k] = fInZR[k]*iw + fInZI[k]*rw;
779 fInZR[k] = fHitMap2->GetSignal(i+1,k);
781 // add baseline and noise
782 contrib = baseline + noise*random->Gaus();
786 FastFourierTransform(fElectronics,&fOutZR[0],&fOutZI[0],-1);
788 } // loop over anodes
792 //____________________________________________
793 void AliITSsimulationSDD::GetAnodeBaseline(Int_t i,Float_t &baseline,
795 // Returns the Baseline for a particular anode.
796 baseline=fBaseline[i];
801 //____________________________________________
802 void AliITSsimulationSDD::CompressionParam(Int_t i,Int_t &db,Int_t &tl,
804 // Returns the compression alogirthm parameters
805 Int_t size = fD.GetSize();
807 db=fD[i]; tl=fT1[i]; th=fT2[i];
809 if (size <= 2 && i>=fNofMaps/2) {
810 db=fD[1]; tl=fT1[1]; th=fT2[1];
812 db=fD[0]; tl=fT1[0]; th=fT2[0];
816 //____________________________________________
817 void AliITSsimulationSDD::CompressionParam(Int_t i,Int_t &db,Int_t &tl){
818 // returns the compression alogirthm parameters
819 Int_t size = fD.GetSize();
823 if (size <= 2 && i>=fNofMaps/2) {
831 //____________________________________________
832 void AliITSsimulationSDD::SetCompressParam(){
833 // Sets the compression alogirthm parameters
836 fResponse->GiveCompressParam(cp);
843 printf("\n i, fD, fT1, fT2, fTol %d %d %d %d %d\n",
844 i,fD[i],fT1[i],fT2[i],fTol[i]);
849 //____________________________________________
850 void AliITSsimulationSDD::ReadBaseline(){
851 // read baseline and noise from file - either a .root file and in this
852 // case data should be organised in a tree with one entry for each
853 // module => reading should be done accordingly
854 // or a classic file and do smth. like this:
856 // Read baselines and noise for SDD
862 const char *kinput, *base,*kparam;
865 fResponse->Filenames(kinput,base,kparam);
868 filtmp = gSystem->ExpandPathName(fFileName.Data());
869 FILE *bline = fopen(filtmp,"r");
870 printf("filtmp %s\n",filtmp);
874 while(fscanf(bline,"%d %f %f",&pos, &bl, &n) != EOF) {
875 //printf("na, pos, bl, n %d %d %f %f\n",na, pos, bl, n);
877 Error("ReadBaseline","Anode number not in increasing order!",
886 Error("ReadBaseline"," THE BASELINE FILE %s DOES NOT EXIST !",
897 //____________________________________________
898 Int_t AliITSsimulationSDD::Convert10to8(Int_t signal) {
899 // To the 10 to 8 bit lossive compression.
900 // code from Davide C. and Albert W.
902 if (signal < 128) return signal;
903 if (signal < 256) return (128+((signal-128)>>1));
904 if (signal < 512) return (192+((signal-256)>>3));
905 if (signal < 1024) return (224+((signal-512)>>4));
910 //____________________________________________
911 Int_t AliITSsimulationSDD::Convert8to10(Int_t signal) {
912 // Undo the lossive 10 to 8 bit compression.
913 // code from Davide C. and Albert W.
914 if (signal < 0 || signal > 255) {
915 printf("<Convert8to10> out of range %d \n",signal);
919 if (signal < 128) return signal;
921 if (TMath::Odd(signal)) return (128+((signal-128)<<1));
922 else return (128+((signal-128)<<1)+1);
925 if (TMath::Odd(signal)) return (256+((signal-192)<<3)+3);
926 else return (256+((signal-192)<<3)+4);
928 if (TMath::Odd(signal)) return (512+((signal-224)<<4)+7);
929 else return (512+((signal-224)<<4)+7);
934 //____________________________________________
935 AliITSMap* AliITSsimulationSDD::HitMap(Int_t i){
936 //Return the correct map.
937 return ((i==0)? fHitMap1 : fHitMap2);
941 //____________________________________________
942 void AliITSsimulationSDD::ZeroSuppression(Option_t *option) {
943 // perform the zero suppresion
944 if (strstr(option,"2D")) {
945 //Init2D(); // activate if param change module by module
947 } else if (strstr(option,"1D")) {
948 //Init1D(); // activate if param change module by module
950 } else StoreAllDigits();
954 //____________________________________________
955 void AliITSsimulationSDD::Init2D(){
956 // read in and prepare arrays: fD, fT1, fT2
957 // savemu[nanodes], savesigma[nanodes]
958 // read baseline and noise from file - either a .root file and in this
959 // case data should be organised in a tree with one entry for each
960 // module => reading should be done accordingly
961 // or a classic file and do smth. like this ( code from Davide C. and
964 // Read 2D zero-suppression parameters for SDD
967 if (!strstr(fParam,"file")) return;
971 Float_t *savemu = new Float_t [fNofMaps];
972 Float_t *savesigma = new Float_t [fNofMaps];
973 const char *kinput,*kbasel,*kpar;
977 Int_t minval = fResponse->MinVal();
979 fResponse->Filenames(kinput,kbasel,kpar);
983 filtmp = gSystem->ExpandPathName(fFileName.Data());
984 FILE *param = fopen(filtmp,"r");
988 while(fscanf(param,"%d %f %f",&pos, &mu, &sigma) != EOF) {
990 Error("Init2D ","Anode number not in increasing order!",
996 if ((2.*sigma) < mu) {
997 fD[na] = (Int_t)floor(mu - 2.0*sigma + 0.5);
1000 tempTh = (Int_t)floor(mu+2.25*sigma+0.5) - minval;
1001 if (tempTh < 0) tempTh=0;
1003 tempTh = (Int_t)floor(mu+3.0*sigma+0.5) - minval;
1004 if (tempTh < 0) tempTh=0;
1010 Error("Init2D "," THE FILE %s DOES NOT EXIST !",
1018 delete [] savesigma;
1025 //____________________________________________
1026 void AliITSsimulationSDD::Compress2D(){
1028 // simple ITS cluster finder -- online zero-suppression conditions
1032 //printf("Compress2D!\n");
1035 Int_t minval = fResponse->MinVal();
1036 Bool_t write=fResponse->OutputOption();
1038 Int_t nz, nl, nh, low, i, j;
1040 for(i=0; i<fNofMaps; i++) {
1041 CompressionParam(i,db,tl,th);
1046 for(j=0; j<fMaxNofSamples; j++) {
1047 Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
1048 signal -= db; // if baseline eq. is done here
1049 if (signal <= 0) {nz++; continue;}
1050 if ((signal - tl) < minval) low++;
1051 if ((signal - th) >= minval) {
1054 //printf("Compress2D : i j %d %d signal %d\n",i,j,signal);
1055 FindCluster(i,j,signal,minval,cond);
1056 } else if ((signal - tl) >= minval) nl++;
1057 } // loop time samples
1058 if (write) TreeB()->Fill(nz,nl,nh,low,i+1);
1059 //if (nz != 256 && low != 256) printf("i, nz, nl, nh low %d %d %d %d %d\n",i,nz,nl,nh,low);
1064 sprintf(hname,"TNtuple%d_%d",fModule,fEvent);
1065 TreeB()->Write(hname);
1072 //_____________________________________________________________________________
1073 void AliITSsimulationSDD::FindCluster(Int_t i,Int_t j,Int_t signal,
1074 Int_t minval,Bool_t cond){
1076 // Find clusters according to the online 2D zero-suppression algorithm
1081 fHitMap2->FlagHit(i,j);
1083 // check the online zero-suppression conditions
1087 Int_t Xlist[kMaxNeighbours], Ylist[kMaxNeighbours];
1088 fSegmentation->Neighbours(i,j,&nn,Xlist,Ylist);
1090 for(in=0; in<nn; in++) {
1093 if (fHitMap2->TestHit(ix,iy)==kUnused) {
1094 CompressionParam(ix,dbx,tlx,thx);
1095 Int_t qn = (Int_t)(fHitMap2->GetSignal(ix,iy));
1096 qn -= dbx; // if baseline eq. is done here
1097 if ((qn-tlx) < minval) {
1098 fHitMap2->FlagHit(ix,iy);
1101 if ((qn - thx) >= minval) high=kTRUE;
1103 signal = Convert10to8(signal);
1104 //printf("FindCl -cond : i j %d %d signal %d\n",i,j,signal);
1105 AddDigit(i,j,signal);
1107 Int_t qns = Convert10to8(qn);
1108 //printf("FindCl : i j %d %d qns %d\n",i,j,qns);
1109 if (!high) AddDigit(ix,iy,qns);
1111 if(!high) fHitMap2->FlagHit(ix,iy);
1114 } // loop over neighbours
1118 //____________________________________________
1119 void AliITSsimulationSDD::Init1D(){
1120 // this is just a copy-paste of input taken from 2D algo
1121 // Torino people should give input
1123 // Read 1D zero-suppression parameters for SDD
1126 if (!strstr(fParam,"file")) return;
1128 Int_t na,pos,tempTh;
1130 Float_t *savemu = new Float_t [fNofMaps];
1131 Float_t *savesigma = new Float_t [fNofMaps];
1132 const char *kinput,*kbasel,*kpar;
1136 Int_t minval = fResponse->MinVal();
1137 fResponse->Filenames(kinput,kbasel,kpar);
1140 // set first the disable and tol param
1143 filtmp = gSystem->ExpandPathName(fFileName.Data());
1144 FILE *param = fopen(filtmp,"r");
1148 fscanf(param,"%d %d %d %d ", &fT2[0], &fT2[1], &fTol[0], &fTol[1]);
1149 while(fscanf(param,"%d %f %f",&pos, &mu, &sigma) != EOF) {
1151 Error("Init1D ","Anode number not in increasing order!",
1156 savesigma[na]=sigma;
1157 if ((2.*sigma) < mu) {
1158 fD[na] = (Int_t)floor(mu - 2.0*sigma + 0.5);
1161 tempTh = (Int_t)floor(mu+2.25*sigma+0.5) - minval;
1162 if (tempTh < 0) tempTh=0;
1167 Error("Init1D "," THE FILE %s DOES NOT EXIST !",
1175 delete [] savesigma;
1181 //____________________________________________
1182 void AliITSsimulationSDD::Compress1D(){
1183 // 1D zero-suppression algorithm (from Gianluca A.)
1185 Int_t dis,tol,thres,decr,diff;
1186 //char *dfile=strstr(fParam,"file");
1188 UChar_t *str=fStream->Stream();
1192 for(k=1; k<=2; k++) {
1193 tol = Tolerance(k-1);
1195 for(i=0; i<fNofMaps/2; i++) {
1196 Bool_t firstSignal=kTRUE;
1197 CompressionParam(k*i,decr,thres);
1198 for(j=0; j<fMaxNofSamples; j++) {
1199 Int_t signal=(Int_t)(fHitMap2->GetSignal(k*i,j));
1200 signal -= decr; // if baseline eq.
1201 signal = Convert10to8(signal);
1202 if (signal < thres) {
1206 // write diff in the buffer for HuffT
1207 str[counter]=(UChar_t)diff;
1212 if (diff > 127) diff=127;
1213 if (diff < -128) diff=-128;
1216 if (tol==1 && (diff >= -2 && diff <= 1)) diff=0;
1217 if (tol==2 && (diff >= -4 && diff <= 3)) diff=0;
1218 if (tol==3 && (diff >= -16 && diff <= 15)) diff=0;
1219 AddDigit(k*i,j,last+diff);
1221 AddDigit(k*i,j,signal);
1225 // write diff in the buffer used to compute Huffman tables
1226 if (firstSignal) str[counter]=(UChar_t)signal;
1227 else str[counter]=(UChar_t)diff;
1232 } // loop time samples
1233 } // loop anodes one half of detector
1237 fStream->CheckCount(counter);
1239 // open file and write out the stream of diff's
1241 static Bool_t open=kTRUE;
1242 static TFile *OutFile;
1243 Bool_t write = fResponse->OutputOption();
1247 SetFileName("stream.root");
1248 cout<<"filename "<<fFileName<<endl;
1249 OutFile=new TFile(fFileName,"recreate");
1250 cout<<"I have opened "<<fFileName<<" file "<<endl;
1257 fStream->ClearStream();
1259 // back to galice.root file
1261 TTree *fAli=gAlice->TreeK();
1264 if (fAli) file =fAli->GetCurrentFile();
1269 //____________________________________________
1270 void AliITSsimulationSDD::StoreAllDigits(){
1271 // if non-zero-suppressed data
1273 Int_t digits[3],i,j;
1275 for(i=0; i<fNofMaps; i++) {
1276 for(j=0; j<fMaxNofSamples; j++) {
1277 Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
1278 signal = Convert10to8(signal);
1279 signal = Convert8to10(signal); // ?
1283 fITS->AddRealDigit(1,digits);
1287 //____________________________________________
1289 void AliITSsimulationSDD::CreateHistograms(){
1290 // Creates histograms of maps for debugging
1293 for(i=0;i<fNofMaps;i++) {
1294 TString *sddName = new TString("sdd_");
1296 sprintf(candNum,"%d",i+1);
1297 sddName->Append(candNum);
1298 (*fHis)[i] = new TH1F(sddName->Data(),"SDD maps",
1299 fMaxNofSamples,0.,(Float_t) fMaxNofSamples);
1304 //____________________________________________
1306 void AliITSsimulationSDD::ResetHistograms(){
1308 // Reset histograms for this detector
1311 for(i=0;i<fNofMaps;i++ ) {
1312 if ((*fHis)[i]) ((TH1F*)(*fHis)[i])->Reset();
1318 //____________________________________________
1320 TH1F *AliITSsimulationSDD::GetAnode(Int_t wing, Int_t anode) {
1321 // Fills a histogram from a give anode.
1322 if (!fHis) return 0;
1324 if(wing <=0 || wing > 2) {
1325 cout << "Wrong wing number: " << wing << endl;
1328 if(anode <=0 || anode > fNofMaps/2) {
1329 cout << "Wrong anode number: " << anode << endl;
1333 Int_t index = (wing-1)*fNofMaps/2 + anode-1;
1334 return (TH1F*)((*fHis)[index]);
1337 //____________________________________________
1339 void AliITSsimulationSDD::WriteToFile(TFile *hfile) {
1340 // Writes the histograms to a file
1345 for(i=0; i<fNofMaps; i++) (*fHis)[i]->Write(); //fAdcs[i]->Write();
1348 //____________________________________________
1349 Float_t AliITSsimulationSDD::GetNoise(Float_t threshold) {
1350 // Returns the noise value
1351 if (!fHis) return 0.;
1353 TH1F *noisehist = new TH1F("noisehist","noise",100,0.,threshold);
1355 for(i=0;i<fNofMaps;i++) {
1356 Int_t nOfBinsA = ((TH1F*)(*fHis)[i])->GetNbinsX();
1357 for(k=0;k<nOfBinsA;k++) {
1358 Float_t content = ((TH1F*)(*fHis)[i])->GetBinContent(k+1);
1359 if (content < threshold) noisehist->Fill(content);
1362 TF1 *gnoise = new TF1("gnoise","gaus",0.,threshold);
1363 noisehist->Fit("gnoise","RQ");
1365 Float_t mnoise = gnoise->GetParameter(1);
1366 cout << "mnoise : " << mnoise << endl;
1367 Float_t rnoise = gnoise->GetParameter(2);
1368 cout << "rnoise : " << rnoise << endl;
1372 void AliITSsimulationSDD::Streamer(TBuffer &R__b)
1374 // Stream an object of class AliITSsimulationSDD.
1376 if (R__b.IsReading()) {
1377 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1378 AliITSsimulation::Streamer(R__b);
1383 R__b >> fElectronics;
1387 fTol.Streamer(R__b);
1388 fBaseline.Streamer(R__b);
1389 fNoise.Streamer(R__b);
1391 //R__b.ReadArray(fParam); // Not to be printed out?
1392 fFileName.Streamer(R__b);
1394 R__b >> fMaxNofSamples;
1399 R__b.WriteVersion(AliITSsimulationSDD::IsA());
1400 AliITSsimulation::Streamer(R__b);
1405 R__b << fElectronics;
1409 fTol.Streamer(R__b);
1410 fBaseline.Streamer(R__b);
1411 fNoise.Streamer(R__b);
1413 //R__b.WriteArray(fParam, __COUNTER__); // Not to be printed out?
1414 fFileName.Streamer(R__b);
1416 R__b << fMaxNofSamples;