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
131 //_____________________________________________________________________________
132 AliITSsimulationSDD::AliITSsimulationSDD(AliITSsimulationSDD &source){
133 // Copy constructor to satify Coding roules only.
134 if(this==&source) return;
135 printf("Not allowed to make a copy of AliITSsimulationSDD "
136 "Using default creater instead\n");
137 AliITSsimulationSDD();
139 //_____________________________________________________________________________
140 AliITSsimulationSDD& AliITSsimulationSDD::operator=(AliITSsimulationSDD
142 // Copy constructor to satify Coding roules only.
143 if(this==&source) return *this;
144 printf("Not allowed to make a = with AliITSsimulationSDD "
145 "Using default creater instead\n");
148 //_____________________________________________________________________________
150 AliITSsimulationSDD::AliITSsimulationSDD(AliITSsegmentation *seg,
151 AliITSresponse *resp) {
156 fHitMap2 = new AliITSMapA2(fSegmentation);
157 fHitMap1 = new AliITSMapA1(fSegmentation);
160 fNofMaps=fSegmentation->Npz();
161 fMaxNofSamples=fSegmentation->Npx();
163 Float_t sddLength = fSegmentation->Dx();
164 Float_t sddWidth = fSegmentation->Dz();
167 Float_t anodePitch = fSegmentation->Dpz(dummy);
168 Double_t timeStep = (Double_t)fSegmentation->Dpx(dummy);
169 Float_t driftSpeed=fResponse->DriftSpeed();
171 if(anodePitch*(fNofMaps/2) > sddWidth) {
172 Warning("AliITSsimulationSDD",
173 "Too many anodes %d or too big pitch %f \n",fNofMaps/2,anodePitch);
176 if(timeStep*fMaxNofSamples < sddLength/driftSpeed) {
177 Error("AliITSsimulationSDD",
178 "Time Interval > Allowed Time Interval: exit\n");
182 fElectronics = new AliITSetfSDD(timeStep);
184 Option_t *opt1, *opt2;
185 fResponse->ParamOptions(opt1,opt2);
187 char *same = strstr(opt1,"same");
192 fNoise.Set(fNofMaps);
193 fBaseline.Set(fNofMaps);
197 Option_t *opt=fResponse->ZeroSuppOption();
198 if (strstr(fParam,"file") ) {
201 if (strstr(opt,"2D")) {
204 Init2D(); // desactivate if param change module by module
205 } else if(strstr(opt,"1D")) {
208 Init1D(); // desactivate if param change module by module
219 Bool_t write=fResponse->OutputOption();
220 if(write && strstr(opt,"2D")) MakeTreeB();
222 // call here if baseline does not change by module
225 fITS = (AliITS*)gAlice->GetModule("ITS");
226 Int_t size=fNofMaps*fMaxNofSamples;
227 fStream = new AliITSInStream(size);
232 //_____________________________________________________________________________
234 AliITSsimulationSDD::~AliITSsimulationSDD() {
253 //_____________________________________________________________________________
255 void AliITSsimulationSDD::DigitiseModule(AliITSmodule *mod,Int_t md,Int_t ev){
256 // create maps to build the lists of tracks
262 TObjArray *fHits = mod->GetHits();
263 Int_t nhits = fHits->GetEntriesFast();
267 TObjArray *list=new TObjArray;
268 static TClonesArray *padr=0;
269 if(!padr) padr=new TClonesArray("TVector",1000);
270 Int_t arg[5] = {0,0,0,0,0};
271 fHitMap1->SetArray(list);
274 Int_t NofAnodes=fNofMaps/2;
276 Float_t sddLength = fSegmentation->Dx();
277 Float_t sddWidth = fSegmentation->Dz();
280 Float_t anodePitch = fSegmentation->Dpz(dummy);
281 Float_t timeStep = fSegmentation->Dpx(dummy);
283 Float_t driftSpeed=fResponse->DriftSpeed();
285 // Piergiorgio's part (apart for few variables which I made float
286 // when i thought that can be done
288 // Fill detector maps with GEANT hits
289 // loop over hits in the module
291 const Float_t kconv=1000000.; // GeV->KeV
293 for(ii=0; ii<nhits; ii++) {
294 AliITShit *hit = (AliITShit*) fHits->At(ii);
295 Int_t hitDetector = hit->GetDetector();
297 hit->GetPositionL(xL[0],xL[1],xL[2]);
298 // cout << "hit local coordinates: " << xL[0] << "," << xL[1] << "," << xL[2] << endl;
299 // Deposited energy in keV
302 Float_t depEnergy = kconv*hit->GetIonization();
304 if(depEnergy == 0.) {
307 hit1 = (AliITShit*) fHits->At(ii);
308 hit1->GetPositionL(xL1[0],xL1[1],xL1[2]);
309 //cout << "hit1 local coordinates: " << xL1[0] << "," << xL1[1] << "," << xL1[2] << endl;
310 //cout << "radius1: " << TMath::Sqrt(xL1[0]*xL1[0]+xL1[1]*xL1[1]) << ", azimuth: " << TMath::ATan2(xL1[0],xL1[1]) << endl;
313 depEnergy = kconv*hit1->GetIonization();
315 Float_t avDrft = xL[0]+avpath;
316 Float_t avAnode = xL[2]+avanod;
318 if(avpath != 0.) avDrft /= 2.;
319 if(avanod != 0.) avAnode /= 2.;
321 Float_t driftPath = 10000.*avDrft;
322 //printf("sddLength %f avDrft driftPath %f %f\n",sddLength,avDrft, driftPath);
326 driftPath = -driftPath;
328 driftPath = sddLength-driftPath;
329 Int_t detector = 2*(hitDetector-1) + iWing;
331 cout << "Warning: negative drift path " << driftPath << endl;
336 Float_t driftTime = driftPath/driftSpeed;
337 Int_t timeSample = (Int_t) (driftTime/timeStep + 1);
338 if(timeSample > fMaxNofSamples) {
339 cout << "Warning: Wrong Time Sample: " << timeSample << endl;
344 Float_t xAnode = 10000.*(avAnode)/anodePitch + NofAnodes/2; // +1?
345 // Int_t iAnode = 0.5+xAnode; // xAnode?
346 if(xAnode*anodePitch > sddWidth || xAnode*anodePitch < 0.)
347 { cout << "Warning: Z = " << xAnode*anodePitch << endl; }
348 Int_t iAnode = (Int_t) (1.+xAnode); // xAnode?
349 // cout << "iAnode " << iAnode << endl;
350 if(iAnode < 0 || iAnode > NofAnodes) {
351 cout << "Warning: Wrong iAnode: " << iAnode << endl;
356 // work with the idtrack=entry number in the TreeH
357 // Int_t idtrack=mod->GetHitTrackIndex(ii);
358 // or store straight away the particle position in the array
360 Int_t idtrack = hit->GetTrack();
363 Double_t qRef = (Double_t)fResponse->Qref();
364 Double_t diffCoeff = (Double_t)fResponse->DiffCoeff();
366 Double_t gamma = 1. + 0.155*depEnergy/qRef;
367 // Squared Sigma along the anodes
368 Double_t sigma2A = 2.*diffCoeff*driftTime*gamma;
369 Double_t sigmaT = TMath::Sqrt(sigma2A)/driftSpeed;
371 // Peak amplitude in nanoAmpere
372 Double_t eVpairs = 3.6;
373 Double_t amplitude = 160.*depEnergy/(timeStep*eVpairs*2.*acos(-1.)*sigmaT*TMath::Sqrt(sigma2A));
378 Int_t jt = timeSample;
381 nsplit = (nsplit+1)/2*2;
383 Double_t aStep = anodePitch/nsplit;
384 Double_t tStep = timeStep/nsplit;
385 // Define SDD window corresponding to the hit
386 Int_t anodeWindow = (Int_t) (4.*TMath::Sqrt(sigma2A)/anodePitch + 1);
387 Int_t timeWindow = (Int_t) (4.*sigmaT/timeStep + 1);
388 Int_t jamin = (ja - anodeWindow/2 - 1)*nsplit + 1;
389 Int_t jamax = (ja + anodeWindow/2)*nsplit;
390 if(jamin <= 0) jamin = 1;
391 if(jamax > NofAnodes*nsplit) jamax = NofAnodes*nsplit;
392 Int_t jtmin = (jt - timeWindow/2 - 1)*nsplit + 1;
393 Int_t jtmax = (jt + timeWindow/2)*nsplit;
394 if(jtmin <= 0) jtmin = 1;
395 if(jtmax > fMaxNofSamples*nsplit) jtmax = fMaxNofSamples*nsplit;
396 Double_t rlAnode = log(aStep*amplitude);
397 // Spread the charge in the anode-time window
399 for(ka=jamin; ka <=jamax; ka++) {
400 Int_t ia = (ka-1)/nsplit + 1;
401 if(ia <= 0) { cout << "Warning: ia < 1: " << endl; continue; }
402 if(ia > NofAnodes) ia = NofAnodes;
403 Double_t aExpo = aStep*(ka)-xAnode*anodePitch;
404 Double_t anodeAmplitude = rlAnode - 0.5*aExpo*aExpo/sigma2A;
405 // Protect against overflows
406 if(anodeAmplitude > -87.3)
407 anodeAmplitude = exp(anodeAmplitude);
411 Double_t rlTime = log(tStep*anodeAmplitude);
413 for(kt=jtmin; kt<=jtmax; kt++) {
414 Int_t it = (kt-1)/nsplit+1;
415 if(it<=0) { cout << "Warning: it < 1: " << endl; continue; }
416 if(it>fMaxNofSamples) it = fMaxNofSamples;
417 Double_t tExpo = (tStep*(kt)-driftTime)/sigmaT;
418 Double_t timeAmplitude = rlTime - 0.5*tExpo*tExpo;
419 // Protect against overflows
420 if(timeAmplitude > -87.3)
421 timeAmplitude = exp(timeAmplitude);
425 Int_t index = ((detector+1)%2)*NofAnodes+ia-1;
426 // build the list of digits for this module
430 ListOfFiredCells(arg,timeAmplitude,list,padr);
431 } // loop over time in window
432 } // end if anodeAmplitude
433 } // loop over anodes in window
434 } // end loop over hits
436 Int_t nentries=list->GetEntriesFast();
437 // introduce the electronics effects and do zero-suppression if required
441 Option_t *opt=fResponse->ZeroSuppOption();
442 ZeroSuppression(opt);
451 fHitMap1->ClearMap();
452 fHitMap2->ClearMap();
454 //gObjectTable->Print();
458 //____________________________________________
460 void AliITSsimulationSDD::ListOfFiredCells(Int_t *arg,Double_t timeAmplitude,
461 TObjArray *list,TClonesArray *padr){
462 // Returns the list of "fired" cells.
466 Int_t idtrack=arg[2];
467 Int_t counter=arg[3];
468 Int_t countadr=arg[4];
474 digits[2]=(Int_t)timeAmplitude;
476 if (idtrack >= 0) phys=(Float_t)timeAmplitude;
479 Double_t charge=timeAmplitude;
480 AliITSTransientDigit* pdigit;
481 // build the list of fired cells and update the info
482 if (!fHitMap1->TestHit(index, it-1)) {
484 new((*padr)[countadr++]) TVector(2);
485 TVector &trinfo=*((TVector*) (*padr)[countadr-1]);
486 trinfo(0)=(Float_t)idtrack;
487 trinfo(1)=(Float_t)timeAmplitude;
489 list->AddAtAndExpand(
490 new AliITSTransientDigit(phys,digits),counter);
492 fHitMap1->SetHit(index, it-1, counter);
493 fHitMap2->SetHit(index, it-1, charge);
496 pdigit=(AliITSTransientDigit*)list->
499 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
500 trlist->Add(&trinfo);
504 (AliITSTransientDigit*) fHitMap1->GetHit(index, it-1);
505 charge += fHitMap2->GetSignal(index,it-1);
506 fHitMap2->SetHit(index, it-1, charge);
508 (*pdigit).fSignal=(Int_t)charge;
509 (*pdigit).fPhysics+=phys;
510 // update list of tracks
511 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
512 Int_t lastentry=trlist->GetLast();
513 TVector *ptrkp=(TVector*)trlist->At(lastentry);
514 TVector &trinfo=*ptrkp;
515 Int_t lasttrack=Int_t(trinfo(0));
516 Float_t lastcharge=(trinfo(1));
518 if (lasttrack==idtrack ) {
519 lastcharge+=(Float_t)timeAmplitude;
520 trlist->RemoveAt(lastentry);
522 trinfo(1)=lastcharge;
523 trlist->AddAt(&trinfo,lastentry);
526 new((*padr)[countadr++]) TVector(2);
527 TVector &trinfo=*((TVector*) (*padr)[countadr-1]);
528 trinfo(0)=(Float_t)idtrack;
529 trinfo(1)=(Float_t)timeAmplitude;
531 trlist->Add(&trinfo);
535 // check the track list - debugging
538 Int_t nptracks=trlist->GetEntriesFast();
541 for(tr=0;tr<nptracks;tr++) {
542 TVector *pptrkp=(TVector*)trlist->At(tr);
543 TVector &pptrk=*pptrkp;
544 trk[tr]=Int_t(pptrk(0));
545 chtrk[tr]=(pptrk(1));
546 printf("nptracks %d \n",nptracks);
560 //____________________________________________
562 void AliITSsimulationSDD::AddDigit(Int_t i, Int_t j, Int_t signal){
564 // tag with -1 signals coming from background tracks
565 // tag with -2 signals coming from pure electronic noise
567 Int_t digits[3], tracks[3];
568 Float_t phys, charges[3];
573 signal=Convert8to10(signal); // set a flag in case non-ZS are 10-bit
574 AliITSTransientDigit *obj = (AliITSTransientDigit*)fHitMap1->GetHit(i,j);
578 // printf("module anode, time, signal %d %d %d %d\n",fModule,i,j,signal);
586 fITS->AddDigit(1,phys,digits,tracks,charges);
589 //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);
591 TObjArray* trlist=(TObjArray*)obj->TrackList();
592 Int_t nptracks=trlist->GetEntriesFast();
595 cout<<"Attention - nptracks > 20 "<<nptracks<<endl;
599 for(tr=0;tr<nptracks;tr++) {
600 TVector &pp =*((TVector*)trlist->At(tr));
601 trk[tr]=Int_t(pp(0));
605 //printf("AddDigit: nptracks %d\n",nptracks);
606 SortTracks(trk,chtrk,nptracks);
610 for(i=0; i<nptracks; i++) {
614 for(i=nptracks; i<3; i++) {
625 fITS->AddDigit(1,phys,digits,tracks,charges);
631 //____________________________________________
633 void AliITSsimulationSDD::SortTracks(Int_t *tracks,Float_t *charges,Int_t ntr){
635 // Sort the list of tracks contributing to a given digit
636 // Only the 3 most significant tracks are acctually sorted
640 // Loop over signals, only 3 times
646 Int_t idx[3] = {-3,-3,-3};
647 Float_t jch[3] = {-3,-3,-3};
648 Int_t jtr[3] = {-3,-3,-3};
659 if((i == 1 && j == idx[i-1] )
660 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
662 if(charges[j] > qmax) {
670 jch[i]=charges[jmax];
687 //____________________________________________
688 void AliITSsimulationSDD::ChargeToSignal() {
689 // add baseline, noise, electronics and ADC saturation effects
691 Double_t InZR[fMaxNofSamples];
692 Double_t InZI[fMaxNofSamples];
693 Double_t OutZR[fMaxNofSamples];
694 Double_t OutZI[fMaxNofSamples];
697 Float_t maxadc = fResponse->MaxAdc();
698 Float_t TopValue = fResponse->MagicValue();
699 Float_t norm = maxadc/TopValue;
702 Option_t *opt1, *opt2;
703 fResponse->ParamOptions(opt1,opt2);
704 char *read = strstr(opt1,"file");
706 Float_t baseline, noise;
709 static Bool_t readfile=kTRUE;
710 //read baseline and noise from file
711 if (readfile) ReadBaseline();
713 } else fResponse->GetNoiseParam(noise,baseline);
718 TRandom *random = new TRandom();
720 for(i=0;i<=fNofMaps;i++) {
721 if (read) GetAnodeBaseline(i,baseline,noise);
722 if (!first) FastFourierTransform(fElectronics,&InZR[0],&InZI[0],1);
723 for(k=0;k<fMaxNofSamples;k++) {
725 // analog to digital ?
726 Double_t signal = OutZR[k]*norm;
727 if (signal > maxadc) signal = maxadc;
730 //printf("ChargeToSignal: signal %f\n",signal);
731 fHitMap2->SetHit(i-1,k,signal);
733 Double_t rw = fElectronics->GetTraFunReal(k);
734 Double_t iw = fElectronics->GetTraFunImag(k);
735 OutZR[k] = InZR[k]*rw - InZI[k]*iw;
736 OutZI[k] = InZR[k]*iw + InZI[k]*rw;
737 if(i+1 < fNofMaps) InZR[k] = fHitMap2->GetSignal(i+1,k);
741 InZR[k] = fHitMap2->GetSignal(i,k);
744 // add baseline and noise
745 contrib = baseline + noise*random->Gaus();
751 FastFourierTransform(fElectronics,&InZR[0],&InZI[0],1);
752 for(k=0; k<fMaxNofSamples; k++) {
753 Double_t rw = fElectronics->GetTraFunReal(k);
754 Double_t iw = fElectronics->GetTraFunImag(k);
755 OutZR[k] = InZR[k]*rw - InZI[k]*iw;
756 OutZI[k] = InZR[k]*iw + InZI[k]*rw;
757 InZR[k] = fHitMap2->GetSignal(i+1,k);
759 // add baseline and noise
760 contrib = baseline + noise*random->Gaus();
764 FastFourierTransform(fElectronics,&OutZR[0],&OutZI[0],-1);
766 } // loop over anodes
770 //____________________________________________
771 void AliITSsimulationSDD::GetAnodeBaseline(Int_t i,Float_t &baseline,
773 // Returns the Baseline for a particular anode.
774 baseline=fBaseline[i];
779 //____________________________________________
780 void AliITSsimulationSDD::CompressionParam(Int_t i,Int_t &db,Int_t &tl,
782 // Returns the compression alogirthm parameters
783 Int_t size = fD.GetSize();
785 db=fD[i]; tl=fT1[i]; th=fT2[i];
787 if (size <= 2 && i>=fNofMaps/2) {
788 db=fD[1]; tl=fT1[1]; th=fT2[1];
790 db=fD[0]; tl=fT1[0]; th=fT2[0];
794 //____________________________________________
795 void AliITSsimulationSDD::CompressionParam(Int_t i,Int_t &db,Int_t &tl){
796 // returns the compression alogirthm parameters
797 Int_t size = fD.GetSize();
801 if (size <= 2 && i>=fNofMaps/2) {
809 //____________________________________________
810 void AliITSsimulationSDD::SetCompressParam(){
811 // Sets the compression alogirthm parameters
814 fResponse->GiveCompressParam(cp);
821 printf("\n i, fD, fT1, fT2, fTol %d %d %d %d %d\n",
822 i,fD[i],fT1[i],fT2[i],fTol[i]);
827 //____________________________________________
828 void AliITSsimulationSDD::ReadBaseline(){
829 // read baseline and noise from file - either a .root file and in this
830 // case data should be organised in a tree with one entry for each
831 // module => reading should be done accordingly
832 // or a classic file and do smth. like this:
834 // Read baselines and noise for SDD
840 const char *kinput, *base,*kparam;
843 fResponse->Filenames(kinput,base,kparam);
846 filtmp = gSystem->ExpandPathName(fFileName.Data());
847 FILE *bline = fopen(filtmp,"r");
848 printf("filtmp %s\n",filtmp);
852 while(fscanf(bline,"%d %f %f",&pos, &bl, &n) != EOF) {
853 //printf("na, pos, bl, n %d %d %f %f\n",na, pos, bl, n);
855 Error("ReadBaseline","Anode number not in increasing order!",
864 Error("ReadBaseline"," THE BASELINE FILE %s DOES NOT EXIST !",
875 //____________________________________________
876 Int_t AliITSsimulationSDD::Convert10to8(Int_t signal) {
877 // To the 10 to 8 bit lossive compression.
878 // code from Davide C. and Albert W.
880 if (signal < 128) return signal;
881 if (signal < 256) return (128+((signal-128)>>1));
882 if (signal < 512) return (192+((signal-256)>>3));
883 if (signal < 1024) return (224+((signal-512)>>4));
888 //____________________________________________
889 Int_t AliITSsimulationSDD::Convert8to10(Int_t signal) {
890 // Undo the lossive 10 to 8 bit compression.
891 // code from Davide C. and Albert W.
892 if (signal < 0 || signal > 255) {
893 printf("<Convert8to10> out of range %d \n",signal);
897 if (signal < 128) return signal;
899 if (TMath::Odd(signal)) return (128+((signal-128)<<1));
900 else return (128+((signal-128)<<1)+1);
903 if (TMath::Odd(signal)) return (256+((signal-192)<<3)+3);
904 else return (256+((signal-192)<<3)+4);
906 if (TMath::Odd(signal)) return (512+((signal-224)<<4)+7);
907 else return (512+((signal-224)<<4)+7);
912 //____________________________________________
913 AliITSMap* AliITSsimulationSDD::HitMap(Int_t i){
914 //Return the correct map.
915 return ((i==0)? fHitMap1 : fHitMap2);
919 //____________________________________________
920 void AliITSsimulationSDD::ZeroSuppression(Option_t *option) {
921 // perform the zero suppresion
922 if (strstr(option,"2D")) {
923 //Init2D(); // activate if param change module by module
925 } else if (strstr(option,"1D")) {
926 //Init1D(); // activate if param change module by module
928 } else StoreAllDigits();
932 //____________________________________________
933 void AliITSsimulationSDD::Init2D(){
934 // read in and prepare arrays: fD, fT1, fT2
935 // savemu[nanodes], savesigma[nanodes]
936 // read baseline and noise from file - either a .root file and in this
937 // case data should be organised in a tree with one entry for each
938 // module => reading should be done accordingly
939 // or a classic file and do smth. like this ( code from Davide C. and
942 // Read 2D zero-suppression parameters for SDD
945 if (!strstr(fParam,"file")) return;
949 Float_t savemu[fNofMaps], savesigma[fNofMaps];
950 const char *kinput,*kbasel,*kpar;
954 Int_t minval = fResponse->MinVal();
956 fResponse->Filenames(kinput,kbasel,kpar);
960 filtmp = gSystem->ExpandPathName(fFileName.Data());
961 FILE *param = fopen(filtmp,"r");
965 while(fscanf(param,"%d %f %f",&pos, &mu, &sigma) != EOF) {
967 Error("Init2D ","Anode number not in increasing order!",
973 if ((2.*sigma) < mu) {
974 fD[na] = (Int_t)floor(mu - 2.0*sigma + 0.5);
977 tempTh = (Int_t)floor(mu+2.25*sigma+0.5) - minval;
978 if (tempTh < 0) tempTh=0;
980 tempTh = (Int_t)floor(mu+3.0*sigma+0.5) - minval;
981 if (tempTh < 0) tempTh=0;
987 Error("Init2D "," THE FILE %s DOES NOT EXIST !",
998 //____________________________________________
999 void AliITSsimulationSDD::Compress2D(){
1001 // simple ITS cluster finder -- online zero-suppression conditions
1005 //printf("Compress2D!\n");
1008 Int_t minval = fResponse->MinVal();
1009 Bool_t write=fResponse->OutputOption();
1011 Int_t nz, nl, nh, low, i, j;
1013 for(i=0; i<fNofMaps; i++) {
1014 CompressionParam(i,db,tl,th);
1019 for(j=0; j<fMaxNofSamples; j++) {
1020 Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
1021 signal -= db; // if baseline eq. is done here
1022 if (signal <= 0) {nz++; continue;}
1023 if ((signal - tl) < minval) low++;
1024 if ((signal - th) >= minval) {
1027 //printf("Compress2D : i j %d %d signal %d\n",i,j,signal);
1028 FindCluster(i,j,signal,minval,cond);
1029 } else if ((signal - tl) >= minval) nl++;
1030 } // loop time samples
1031 if (write) TreeB()->Fill(nz,nl,nh,low,i+1);
1032 //if (nz != 256 && low != 256) printf("i, nz, nl, nh low %d %d %d %d %d\n",i,nz,nl,nh,low);
1037 sprintf(hname,"TNtuple%d_%d",fModule,fEvent);
1038 TreeB()->Write(hname);
1045 //_____________________________________________________________________________
1046 void AliITSsimulationSDD::FindCluster(Int_t i,Int_t j,Int_t signal,
1047 Int_t minval,Bool_t cond){
1049 // Find clusters according to the online 2D zero-suppression algorithm
1054 fHitMap2->FlagHit(i,j);
1056 // check the online zero-suppression conditions
1060 Int_t Xlist[kMaxNeighbours], Ylist[kMaxNeighbours];
1061 fSegmentation->Neighbours(i,j,&nn,Xlist,Ylist);
1063 for(in=0; in<nn; in++) {
1066 if (fHitMap2->TestHit(ix,iy)==kUnused) {
1067 CompressionParam(ix,dbx,tlx,thx);
1068 Int_t qn = (Int_t)(fHitMap2->GetSignal(ix,iy));
1069 qn -= dbx; // if baseline eq. is done here
1070 if ((qn-tlx) < minval) {
1071 fHitMap2->FlagHit(ix,iy);
1074 if ((qn - thx) >= minval) high=kTRUE;
1076 signal = Convert10to8(signal);
1077 //printf("FindCl -cond : i j %d %d signal %d\n",i,j,signal);
1078 AddDigit(i,j,signal);
1080 Int_t qns = Convert10to8(qn);
1081 //printf("FindCl : i j %d %d qns %d\n",i,j,qns);
1082 if (!high) AddDigit(ix,iy,qns);
1084 if(!high) fHitMap2->FlagHit(ix,iy);
1087 } // loop over neighbours
1091 //____________________________________________
1092 void AliITSsimulationSDD::Init1D(){
1093 // this is just a copy-paste of input taken from 2D algo
1094 // Torino people should give input
1096 // Read 1D zero-suppression parameters for SDD
1099 if (!strstr(fParam,"file")) return;
1101 Int_t na,pos,tempTh;
1103 Float_t savemu[fNofMaps], savesigma[fNofMaps];
1104 const char *kinput,*kbasel,*kpar;
1108 Int_t minval = fResponse->MinVal();
1109 fResponse->Filenames(kinput,kbasel,kpar);
1112 // set first the disable and tol param
1115 filtmp = gSystem->ExpandPathName(fFileName.Data());
1116 FILE *param = fopen(filtmp,"r");
1120 fscanf(param,"%d %d %d %d ", &fT2[0], &fT2[1], &fTol[0], &fTol[1]);
1121 while(fscanf(param,"%d %f %f",&pos, &mu, &sigma) != EOF) {
1123 Error("Init1D ","Anode number not in increasing order!",
1128 savesigma[na]=sigma;
1129 if ((2.*sigma) < mu) {
1130 fD[na] = (Int_t)floor(mu - 2.0*sigma + 0.5);
1133 tempTh = (Int_t)floor(mu+2.25*sigma+0.5) - minval;
1134 if (tempTh < 0) tempTh=0;
1139 Error("Init1D "," THE FILE %s DOES NOT EXIST !",
1150 //____________________________________________
1151 void AliITSsimulationSDD::Compress1D(){
1152 // 1D zero-suppression algorithm (from Gianluca A.)
1154 Int_t dis,tol,thres,decr,diff;
1155 //char *dfile=strstr(fParam,"file");
1157 UChar_t *str=fStream->Stream();
1161 for(k=1; k<=2; k++) {
1162 tol = Tolerance(k-1);
1164 for(i=0; i<fNofMaps/2; i++) {
1165 Bool_t firstSignal=kTRUE;
1166 CompressionParam(k*i,decr,thres);
1167 for(j=0; j<fMaxNofSamples; j++) {
1168 Int_t signal=(Int_t)(fHitMap2->GetSignal(k*i,j));
1169 signal -= decr; // if baseline eq.
1170 signal = Convert10to8(signal);
1171 if (signal < thres) {
1175 // write diff in the buffer for HuffT
1176 str[counter]=(UChar_t)diff;
1181 if (diff > 127) diff=127;
1182 if (diff < -128) diff=-128;
1185 if (tol==1 && (diff >= -2 && diff <= 1)) diff=0;
1186 if (tol==2 && (diff >= -4 && diff <= 3)) diff=0;
1187 if (tol==3 && (diff >= -16 && diff <= 15)) diff=0;
1188 AddDigit(k*i,j,last+diff);
1190 AddDigit(k*i,j,signal);
1194 // write diff in the buffer used to compute Huffman tables
1195 if (firstSignal) str[counter]=(UChar_t)signal;
1196 else str[counter]=(UChar_t)diff;
1201 } // loop time samples
1202 } // loop anodes one half of detector
1206 fStream->CheckCount(counter);
1208 // open file and write out the stream of diff's
1210 static Bool_t open=kTRUE;
1211 static TFile *OutFile;
1212 Bool_t write = fResponse->OutputOption();
1216 SetFileName("stream.root");
1217 cout<<"filename "<<fFileName<<endl;
1218 OutFile=new TFile(fFileName,"recreate");
1219 cout<<"I have opened "<<fFileName<<" file "<<endl;
1226 fStream->ClearStream();
1228 // back to galice.root file
1230 TTree *fAli=gAlice->TreeK();
1233 if (fAli) file =fAli->GetCurrentFile();
1238 //____________________________________________
1239 void AliITSsimulationSDD::StoreAllDigits(){
1240 // if non-zero-suppressed data
1242 Int_t digits[3],i,j;
1244 for(i=0; i<fNofMaps; i++) {
1245 for(j=0; j<fMaxNofSamples; j++) {
1246 Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
1247 signal = Convert10to8(signal);
1248 signal = Convert8to10(signal); // ?
1252 fITS->AddRealDigit(1,digits);
1256 //____________________________________________
1258 void AliITSsimulationSDD::CreateHistograms(){
1259 // Creates histograms of maps for debugging
1262 for(i=0;i<fNofMaps;i++) {
1263 TString *sddName = new TString("sdd_");
1265 sprintf(candNum,"%d",i+1);
1266 sddName->Append(candNum);
1267 (*fHis)[i] = new TH1F(sddName->Data(),"SDD maps",
1268 fMaxNofSamples,0.,(Float_t) fMaxNofSamples);
1273 //____________________________________________
1275 void AliITSsimulationSDD::ResetHistograms(){
1277 // Reset histograms for this detector
1280 for(i=0;i<fNofMaps;i++ ) {
1281 if ((*fHis)[i]) ((TH1F*)(*fHis)[i])->Reset();
1287 //____________________________________________
1289 TH1F *AliITSsimulationSDD::GetAnode(Int_t wing, Int_t anode) {
1290 // Fills a histogram from a give anode.
1291 if (!fHis) return 0;
1293 if(wing <=0 || wing > 2) {
1294 cout << "Wrong wing number: " << wing << endl;
1297 if(anode <=0 || anode > fNofMaps/2) {
1298 cout << "Wrong anode number: " << anode << endl;
1302 Int_t index = (wing-1)*fNofMaps/2 + anode-1;
1303 return (TH1F*)((*fHis)[index]);
1306 //____________________________________________
1308 void AliITSsimulationSDD::WriteToFile(TFile *hfile) {
1309 // Writes the histograms to a file
1314 for(i=0; i<fNofMaps; i++) (*fHis)[i]->Write(); //fAdcs[i]->Write();
1317 //____________________________________________
1318 Float_t AliITSsimulationSDD::GetNoise(Float_t threshold) {
1319 // Returns the noise value
1320 if (!fHis) return 0.;
1322 TH1F *noisehist = new TH1F("noisehist","noise",100,0.,threshold);
1324 for(i=0;i<fNofMaps;i++) {
1325 Int_t nOfBinsA = ((TH1F*)(*fHis)[i])->GetNbinsX();
1326 for(k=0;k<nOfBinsA;k++) {
1327 Float_t content = ((TH1F*)(*fHis)[i])->GetBinContent(k+1);
1328 if (content < threshold) noisehist->Fill(content);
1331 TF1 *gnoise = new TF1("gnoise","gaus",0.,threshold);
1332 noisehist->Fit("gnoise","RQ");
1334 Float_t mnoise = gnoise->GetParameter(1);
1335 cout << "mnoise : " << mnoise << endl;
1336 Float_t rnoise = gnoise->GetParameter(2);
1337 cout << "rnoise : " << rnoise << endl;
1341 void AliITSsimulationSDD::Streamer(TBuffer &R__b)
1343 // Stream an object of class AliITSsimulationSDD.
1345 if (R__b.IsReading()) {
1346 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1347 AliITSsimulation::Streamer(R__b);
1352 R__b >> fElectronics;
1356 fTol.Streamer(R__b);
1357 fBaseline.Streamer(R__b);
1358 fNoise.Streamer(R__b);
1360 //R__b.ReadArray(fParam); // Not to be printed out?
1361 fFileName.Streamer(R__b);
1363 R__b >> fMaxNofSamples;
1368 R__b.WriteVersion(AliITSsimulationSDD::IsA());
1369 AliITSsimulation::Streamer(R__b);
1374 R__b << fElectronics;
1378 fTol.Streamer(R__b);
1379 fBaseline.Streamer(R__b);
1380 fNoise.Streamer(R__b);
1382 //R__b.WriteArray(fParam, __COUNTER__); // Not to be printed out?
1383 fFileName.Streamer(R__b);
1385 R__b << fMaxNofSamples;