#include <stdio.h>
#include <string.h>
+#include <TSystem.h>
+#include <TROOT.h>
+#include <TStopwatch.h>
+#include <TCanvas.h>
+#include <TF1.h>
+#include <TRandom.h>
+#include <TH1.h>
+#include <TFile.h>
+#include <TVector.h>
+#include <TArrayI.h>
+#include <TArrayF.h>
+
#include "AliRun.h"
#include "AliITS.h"
+#include "AliITShit.h"
+#include "AliITSdigit.h"
+#include "AliITSmodule.h"
#include "AliITSMapA1.h"
#include "AliITSMapA2.h"
-#include "AliITSsimulationSDD.h"
#include "AliITSetfSDD.h"
#include "AliITSRawData.h"
#include "AliITSHuffman.h"
+#include "AliITSsegmentation.h"
+#include "AliITSresponse.h"
+#include "AliITSsimulationSDD.h"
ClassImp(AliITSsimulationSDD)
////////////////////////////////////////////////////////////////////////
void FastFourierTransform(AliITSetfSDD *alisddetf,Double_t *real,
Double_t *imag,Int_t direction) {
// Do a Fast Fourier Transform
+ //printf("FFT: direction %d\n",direction);
Int_t samples = alisddetf->GetSamples();
Int_t l = (Int_t) ((log((Float_t) samples)/log(2.))+0.5);
fResponse = 0;
fSegmentation = 0;
fHis = 0;
+ fHitMap1 = 0;
+ fHitMap2 = 0;
+ fElectronics = 0;
+ fStream = 0;
fD.Set(0);
fT1.Set(0);
fT2.Set(0);
fTol.Set(0);
+ fNoise.Set(0);
+ fBaseline.Set(0);
SetScaleFourier();
SetPerpendTracksFlag();
+ SetDoFFT();
+ SetCheckNoise();
fInZR = 0;
fInZI = 0;
fOutZR = 0;
fOutZI = 0;
+ fNofMaps = 0;
+ fMaxNofSamples = 0;
+ fITS = 0;
+ fTreeB=0;
}
//_____________________________________________________________________________
AliITSsimulationSDD::AliITSsimulationSDD(AliITSsimulationSDD &source)
AliITSsimulationSDD::AliITSsimulationSDD(AliITSsegmentation *seg,AliITSresponse *resp)
{
// Standard Constructor
+
+ fHis=0;
+ fTreeB=0;
fResponse = resp;
fSegmentation = seg;
SetScaleFourier();
SetPerpendTracksFlag();
+ SetDoFFT();
+ SetCheckNoise();
fHitMap2 = new AliITSMapA2(fSegmentation,fScaleSize,1);
fHitMap1 = new AliITSMapA1(fSegmentation);
if(anodePitch*(fNofMaps/2) > sddWidth) {
Warning("AliITSsimulationSDD",
- "Too many anodes %d or too big pitch %f \n",fNofMaps/2,anodePitch);
+ "Too many anodes %d or too big pitch %f \n",fNofMaps/2,anodePitch);
}
if(timeStep*fMaxNofSamples < sddLength/driftSpeed) {
Error("AliITSsimulationSDD",
- "Time Interval > Allowed Time Interval: exit\n");
+ "Time Interval > Allowed Time Interval: exit\n");
return;
}
- fElectronics = new AliITSetfSDD(timeStep/fScaleSize);
+ fElectronics = new AliITSetfSDD(timeStep/fScaleSize,fResponse->Electronics());
char opt1[20], opt2[20];
fResponse->ParamOptions(opt1,opt2);
delete fHitMap1;
delete fHitMap2;
delete fStream;
+ delete fElectronics;
fD.Set(0);
fT1.Set(0);
fTol.Set(0);
fNoise.Set(0);
fBaseline.Set(0);
+ fITS = 0;
if (fHis) {
fHis->Delete();
delete fHis;
- }
+ }
+ if(fTreeB) delete fTreeB;
if(fInZR) delete [] fInZR;
if(fInZI) delete [] fInZI;
if(fOutZR) delete [] fOutZR;
void AliITSsimulationSDD::DigitiseModule(AliITSmodule *mod,Int_t md,Int_t ev){
// create maps to build the lists of tracks
// for each digit
-
+ cout << "Module: " << md << endl;
fModule=md;
fEvent=ev;
TObjArray *fHits = mod->GetHits();
Int_t nhits = fHits->GetEntriesFast();
- if (!nhits) return;
+ if (!nhits && fCheckNoise) {
+ ChargeToSignal();
+ GetNoise();
+ fHitMap2->ClearMap();
+ return;
+ } else if (!nhits) return;
+
+ //printf("simSDD: module nhits %d %d\n",md,nhits);
TObjArray *list=new TObjArray;
Int_t arg[6] = {0,0,0,0,0,0};
fHitMap1->SetArray(list);
+ // cout << "set Parameters" << endl;
Int_t nofAnodes=fNofMaps/2;
Float_t sddLength = fSegmentation->Dx();
Float_t sddWidth = fSegmentation->Dz();
-
+
Int_t dummy=0;
Float_t anodePitch = fSegmentation->Dpz(dummy);
Float_t timeStep = fSegmentation->Dpx(dummy);
Float_t driftSpeed=fResponse->DriftSpeed();
+ Float_t maxadc = fResponse->MaxAdc();
+ Float_t topValue = fResponse->DynamicRange();
+ Float_t CHloss = fResponse->ChargeLoss();
+ Float_t norm = maxadc/topValue;
+
// Piergiorgio's part (apart for few variables which I made float
// when i thought that can be done
// Fill detector maps with GEANT hits
// loop over hits in the module
+ // TStopwatch timer;
+ // timer.Start();
+
const Float_t kconv=1.0e+6; // GeV->KeV
Int_t ii;
+ Int_t idhit=-1;
+ Float_t xL[3];
+ Float_t xL1[3];
for(ii=0; ii<nhits; ii++) {
- AliITShit *hit = (AliITShit*) fHits->At(ii);
- Float_t xL[3];
- hit = (AliITShit*) fHits->At(ii);
+ // cout << "hit: " << ii+1 << " of " << nhits << endl;
+ AliITShit *hit = (AliITShit*) fHits->At(ii);
+ AliITShit *hit1 = 0;
+
+ // Take into account all hits when several GEANT steps are carried out
+ // inside the silicon
+ // Get and use the status of hit(track):
+ // 66 - for entering hit,
+ // 65 - for inside hit,
+ // 68 - for exiting hit,
+ // 33 - for stopping hit.
+
+ //Int_t status = hit->GetTrackStatus();
+ Int_t status1 = 0;
+ Int_t hitDetector = hit->GetDetector();
+ Float_t depEnergy = 0.;
+ if(hit->StatusEntering()) { // to be coupled to following hit
+ idhit=ii;
hit->GetPositionL(xL[0],xL[1],xL[2]);
- Int_t hitDetector = hit->GetDetector();
-
- // Deposited energy in keV
- Float_t avpath = 0.;
- Float_t avanod = 0.;
- Float_t depEnergy = kconv*hit->GetIonization();
- AliITShit *hit1 = 0;
- if(depEnergy != 0.) continue;
-
- ii++;
- Float_t xL1[3];
+ if(ii<nhits-1) ii++;
hit1 = (AliITShit*) fHits->At(ii);
hit1->GetPositionL(xL1[0],xL1[1],xL1[2]);
- avpath = xL1[0];
- avanod = xL1[2];
- depEnergy = kconv*hit1->GetIonization();
-
- // scale path to simulate a perpendicular track
- if (fFlag) {
- Float_t lC[3];
- hit->GetPositionL(lC[0],lC[1],lC[2]);
- Float_t lC1[3];
- hit1->GetPositionL(lC1[0],lC1[1],lC1[2]);
- Float_t pathInSDD = TMath::Sqrt((lC[0]-lC1[0])*(lC[0]-lC1[0])+(lC[1]-lC1[1])*(lC[1]-lC1[1])+(lC[2]-lC1[2])*(lC[2]-lC1[2]));
- depEnergy *= (0.03/pathInSDD);
- }
-
- Float_t avDrft = xL[0]+avpath;
- Float_t avAnode = xL[2]+avanod;
-
- if(avpath != 0.) avDrft /= 2.;
- if(avanod != 0.) avAnode /= 2.;
-
+ status1 = hit1->GetTrackStatus();
+ depEnergy = kconv*hit1->GetIonization();
+ } else {
+ depEnergy = kconv*hit->GetIonization(); // Deposited energy in keV
+ hit->GetPositionL(xL1[0],xL1[1],xL1[2]);
+ }
+ // cout << "status: " << status << ", status1: " << status1 << ", dE: " << depEnergy << endl;
+ if(fFlag && status1 == 33) continue;
+
+ Int_t nOfSplits = 1;
+
+ // hit->Print();
+
+// Int_t status1 = -1;
+// Int_t ctr = 0;
+ //Take now the entering and inside hits only
+// if(status == 66) {
+// do {
+// if(ii<nhits-1) ii++;
+// hit1 = (AliITShit*) fHits->At(ii);
+// hit1->GetPositionL(xL1[0],xL1[1],xL1[2]);
+// status1 = hit1->GetTrackStatus();
+// depEnergy += kconv*hit1->GetIonization();
+// if(fFlag && status1 == 65) ctr++;
+// } while(status1 != 68 && status1 != 33);
+// }
+
+
+ // scale path to simulate a perpendicular track
+ // continue if the particle did not lose energy
+ // passing through detector
+ if (!depEnergy) {
+ printf("This particle has passed without losing energy!\n");
+ continue;
+ }
+ 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]));
+
+ if (fFlag && pathInSDD) { depEnergy *= (0.03/pathInSDD); }
+ Float_t Drft = (xL1[0]+xL[0])*0.5;
+ Float_t drPath = 10000.*Drft;
+ if(drPath < 0) drPath = -drPath;
+ drPath = sddLength-drPath;
+ if(drPath < 0) {
+ cout << "Warning: negative drift path " << drPath << endl;
+ continue;
+ }
+
+ // Drift Time
+ Float_t drTime = drPath/driftSpeed;
+ // Signal 2d Shape
+ Float_t dfCoeff, s1;
+ fResponse->DiffCoeff(dfCoeff,s1);
+
+ // Squared Sigma along the anodes
+ Double_t sig2A = 2.*dfCoeff*drTime+s1*s1;
+ Double_t sigA = TMath::Sqrt(sig2A);
+ if(pathInSDD) {
+ nOfSplits = (Int_t) (1 + 10000.*pathInSDD/sigA);
+ //cout << "nOfSplits: " << nOfSplits << ", sigA: " << sigA << ", path: " << pathInSDD << endl;
+ }
+ if(fFlag) nOfSplits = 1;
+ depEnergy /= nOfSplits;
+
+ for(Int_t kk=0;kk<nOfSplits;kk++) {
+ Float_t avDrft =
+ xL[0]+(xL1[0]-xL[0])*((kk+0.5)/((Float_t) nOfSplits));
+ Float_t avAnode =
+ xL[2]+(xL1[2]-xL[2])*((kk+0.5)/((Float_t) nOfSplits));
Float_t driftPath = 10000.*avDrft;
+
Int_t iWing = 2;
if(driftPath < 0) {
- iWing = 1;
- driftPath = -driftPath;
+ iWing = 1;
+ driftPath = -driftPath;
}
driftPath = sddLength-driftPath;
Int_t detector = 2*(hitDetector-1) + iWing;
if(driftPath < 0) {
- cout << "Warning: negative drift path " << driftPath << endl;
- continue;
+ cout << "Warning: negative drift path " << driftPath << endl;
+ continue;
}
// Drift Time
Float_t driftTime = driftPath/driftSpeed;
Int_t timeSample = (Int_t) (fScaleSize*driftTime/timeStep + 1);
if(timeSample > fScaleSize*fMaxNofSamples) {
- cout << "Warning: Wrong Time Sample: " << timeSample << endl;
- continue;
+ cout << "Warning: Wrong Time Sample: " << timeSample << endl;
+ continue;
}
// Anode
Float_t xAnode = 10000.*(avAnode)/anodePitch + nofAnodes/2; // +1?
- if((xAnode+1)*anodePitch > sddWidth || xAnode*anodePitch < 0.)
- { cout << "Warning: Z = " << xAnode*anodePitch << endl; }
+ if(xAnode*anodePitch > sddWidth || xAnode*anodePitch < 0.)
+ { cout << "Warning: Z = " << xAnode*anodePitch << endl; }
Int_t iAnode = (Int_t) (1.+xAnode); // xAnode?
- if(iAnode < 0 || iAnode > nofAnodes) {
+ if(iAnode < 1 || iAnode > nofAnodes) {
cout << "Warning: Wrong iAnode: " << iAnode << endl;
continue;
}
-
// work with the idtrack=entry number in the TreeH for the moment
- Int_t idhit,idtrack;
- mod->GetHitTrackAndHitIndex(ii,idtrack,idhit);
+ //Int_t idhit,idtrack;
+ //mod->GetHitTrackAndHitIndex(ii,idtrack,idhit);
//Int_t idtrack=mod->GetHitTrackIndex(ii);
// or store straight away the particle position in the array
- // of particles :
- Int_t itrack = hit->GetTrack();
+ // of particles and take idhit=ii only when part is entering (this
+ // requires FillModules() in the macro for analysis) :
+ Int_t itrack = hit->GetTrack();
// Signal 2d Shape
Float_t diffCoeff, s0;
Double_t sigma2A = 2.*diffCoeff*driftTime+s0*s0;
Double_t sigmaA = TMath::Sqrt(sigma2A);
Double_t sigmaT = sigmaA/driftSpeed;
-
// Peak amplitude in nanoAmpere
Double_t eVpairs = 3.6;
Double_t amplitude = fScaleSize*160.*depEnergy/(timeStep*eVpairs*2.*acos(-1.)*sigmaT*sigmaA);
-
+ amplitude *= timeStep/25.; // WARNING!!!!! Amplitude scaling to account for clock variations (reference value: 40 MHz)
+ Double_t chargeloss = 1.-CHloss*driftPath/1000;
+ amplitude *= chargeloss;
Float_t nsigma=fResponse->NSigmaIntegration();
+ Int_t nlookups = fResponse->GausNLookUp();
+ Float_t width = 2.*nsigma/(nlookups-1);
// Spread the charge
// Pixel index
Int_t ja = iAnode;
Int_t jt = timeSample;
+ Int_t ndiv = 2;
+ Float_t nmul = 3.;
+ if(driftTime > 1200.) {
+ ndiv = 4;
+ nmul = 1.5;
+ }
// Sub-pixel index
Int_t nsplit = 4; // hard-wired
nsplit = (nsplit+1)/2*2;
// Define SDD window corresponding to the hit
Int_t anodeWindow = (Int_t) (fScaleSize*nsigma*sigmaA/anodePitch + 1);
Int_t timeWindow = (Int_t) (fScaleSize*nsigma*sigmaT/timeStep + 1);
- Int_t jamin = (ja - anodeWindow/2 - 1)*fScaleSize*nsplit + 1;
- Int_t jamax = (ja + anodeWindow/2)*fScaleSize*nsplit;
+ Int_t jamin = (ja - anodeWindow/ndiv - 1)*fScaleSize*nsplit + 1;
+ Int_t jamax = (ja + anodeWindow/ndiv)*fScaleSize*nsplit;
if(jamin <= 0) jamin = 1;
if(jamax > fScaleSize*nofAnodes*nsplit) jamax = fScaleSize*nofAnodes*nsplit;
- Int_t jtmin = (jt - timeWindow*3 - 1)*nsplit + 1; //hard-wired
- Int_t jtmax = (jt + timeWindow*3)*nsplit; //hard-wired
+ Int_t jtmin = (Int_t) (jt - timeWindow*nmul - 1)*nsplit + 1; //hard-wired
+ Int_t jtmax = (Int_t) (jt + timeWindow*nmul)*nsplit; //hard-wired
if(jtmin <= 0) jtmin = 1;
if(jtmax > fScaleSize*fMaxNofSamples*nsplit) jtmax = fScaleSize*fMaxNofSamples*nsplit;
- Double_t rlAnode = log(aStep*amplitude);
-
// Spread the charge in the anode-time window
Int_t ka;
+ //cout << "jamin: " << jamin << ", jamax: " << jamax << endl;
+ //cout << "jtmin: " << jtmin << ", jtmax: " << jtmax << endl;
for(ka=jamin; ka <=jamax; ka++) {
Int_t ia = (ka-1)/(fScaleSize*nsplit) + 1;
if(ia <= 0) { cout << "Warning: ia < 1: " << endl; continue; }
if(ia > nofAnodes) ia = nofAnodes;
Double_t aExpo = (aStep*(ka-0.5)-xAnode*anodePitch)/sigmaA;
- Double_t anodeAmplitude = rlAnode - 0.5*aExpo*aExpo;
- // Protect against overflows
- if(anodeAmplitude > -87.3)
- anodeAmplitude = exp(anodeAmplitude);
- else
- anodeAmplitude = 0;
- Int_t index = ((detector+1)%2)*nofAnodes+ia-1; // index starts from 0
+ Double_t anodeAmplitude = 0;
+ if(TMath::Abs(aExpo) > nsigma) {
+ anodeAmplitude = 0.;
+ //cout << "aExpo: " << aExpo << endl;
+ } else {
+ Int_t i = (Int_t) ((aExpo+nsigma)/width);
+ //cout << "eval ampl: " << i << ", " << amplitude << endl;
+ anodeAmplitude = amplitude*fResponse->GausLookUp(i);
+ //cout << "ampl: " << anodeAmplitude << endl;
+ }
+ Int_t index = ((detector+1)%2)*nofAnodes+ia-1; // index starts from 0
if(anodeAmplitude) {
- Double_t rlTime = log(tStep*anodeAmplitude);
+ //Double_t rlTime = log(tStep*anodeAmplitude);
Int_t kt;
for(kt=jtmin; kt<=jtmax; kt++) {
Int_t it = (kt-1)/nsplit+1; // it starts from 1
if(it<=0) { cout << "Warning: it < 1: " << endl; continue; }
if(it>fScaleSize*fMaxNofSamples) it = fScaleSize*fMaxNofSamples;
Double_t tExpo = (tStep*(kt-0.5)-driftTime)/sigmaT;
- Double_t timeAmplitude = rlTime - 0.5*tExpo*tExpo;
- // Protect against overflows
- if(timeAmplitude > -87.3){
- timeAmplitude = exp(timeAmplitude);
- } else
- timeAmplitude = 0;
+ Double_t timeAmplitude = 0.;
+ if(TMath::Abs(tExpo) > nsigma) {
+ timeAmplitude = 0.;
+ //cout << "tExpo: " << tExpo << endl;
+ } else {
+ Int_t i = (Int_t) ((tExpo+nsigma)/width);
+ //cout << "eval ampl: " << i << ", " << anodeAmplitude << endl;
+ timeAmplitude = anodeAmplitude*fResponse->GausLookUp(i);
+ }
// build the list of digits for this module
arg[0]=index;
arg[1]=it;
arg[2]=itrack;
arg[3]=idhit;
+ timeAmplitude *= norm;
+ timeAmplitude *= 10;
ListOfFiredCells(arg,timeAmplitude,list,padr);
- } // loop over time in window
- } // end if anodeAmplitude
- } // loop over anodes in window
- } // end loop over hits
-
+ //cout << "ampl: " << timeAmplitude << endl;
+ } // loop over time in window
+ } // end if anodeAmplitude
+ } // loop over anodes in window
+ } // end loop over "sub-hits"
+ for(Int_t ki=0; ki<3; ki++) xL[ki] = xL1[ki];
+ } // end loop over hits
+
+ // timer.Stop(); timer.Print();
+
// introduce the electronics effects and do zero-suppression if required
Int_t nentries=list->GetEntriesFast();
if (nentries) {
+
+ // TStopwatch timer1;
ChargeToSignal();
+ // timer1.Stop(); cout << "ele: "; timer1.Print();
const char *kopt=fResponse->ZeroSuppOption();
ZeroSuppression(kopt);
TVector *ptrkp=(TVector*)trlist->At(lastentry);
TVector &trinfo=*ptrkp;
Int_t lasttrack=Int_t(trinfo(0));
- Int_t lasthit=Int_t(trinfo(1));
+ //Int_t lasthit=Int_t(trinfo(1));
Float_t lastcharge=(trinfo(2));
if (lasttrack==idtrack ) {
lastcharge+=(Float_t)timeAmplitude;
trlist->RemoveAt(lastentry);
trinfo(0)=lasttrack;
- trinfo(1)=lasthit; // or idhit
+ //trinfo(1)=lasthit; // or idhit
+ trinfo(1)=idhit;
trinfo(2)=lastcharge;
trlist->AddAt(&trinfo,lastentry);
} else {
Int_t trk[20], htrk[20];
Float_t chtrk[20];
- signal=Convert8to10(signal); // set a flag in case non-ZS are 10-bit
+ Bool_t do10to8=fResponse->Do10to8();
+
+ if(do10to8) signal=Convert8to10(signal);
AliITSTransientDigit *obj = (AliITSTransientDigit*)fHitMap1->GetHit(i,j);
digits[0]=i;
digits[1]=j;
for (k=0;k<3;k++) {
tracks[k]=-2;
charges[k]=0;
- hits[k]=0;
+ hits[k]=-1;
}
fITS->AddSimDigit(1,phys,digits,tracks,hits,charges);
} else {
chtrk[tr]=(pp(2));
}
if (nptracks > 1) {
+ //printf("nptracks > 2 -- %d\n",nptracks);
SortTracks(trk,chtrk,htrk,nptracks);
}
Int_t i;
hits[i]=htrk[i];
}
for (i=nptracks; i<3; i++) {
- tracks[i]=0;
- hits[i]=0;
+ tracks[i]=-3;
+ hits[i]=-1;
charges[i]=0;
}
} else {
} else {
charges[i]=jch[i];
tracks[i]=jtr[i];
- hits[i]=jtr[i];
+ hits[i]=jhit[i];
}
}
void AliITSsimulationSDD::ChargeToSignal() {
// add baseline, noise, electronics and ADC saturation effects
-
- Float_t maxadc = fResponse->MaxAdc();
- Float_t topValue = fResponse->MagicValue();
- Float_t norm = maxadc/topValue;
-
-
char opt1[20], opt2[20];
fResponse->ParamOptions(opt1,opt2);
char *read = strstr(opt1,"file");
} else fResponse->GetNoiseParam(noise,baseline);
Float_t contrib=0;
- Bool_t first=kTRUE;
- TRandom *random = new TRandom();
+ TRandom random;
Int_t i,k,kk;
- for (i=0;i<=fNofMaps;i++) {
- if (read && i<fNofMaps) GetAnodeBaseline(i,baseline,noise);
- if (!first) FastFourierTransform(fElectronics,&fInZR[0],&fInZI[0],1);
- for (k=0;k<fScaleSize*fMaxNofSamples;k++) {
- if (!first) {
- Float_t newcont = 0.;
- Float_t maxcont = 0.;
- Int_t it=(Int_t)(k/fScaleSize);
- if (k%fScaleSize == 0) {
- for(kk=0;kk<fScaleSize;kk++) {
- newcont = fOutZR[fScaleSize*it+kk];
- if(newcont > maxcont) maxcont = newcont;
- }
- newcont = maxcont;
- // analog to digital ?
- Double_t signal = newcont*norm;
- if (signal >= maxadc) signal = maxadc -1;
- // back to analog: ?
- signal /=norm;
- fHitMap2->SetHit(i-1,it,signal);
- }
- Double_t rw = fElectronics->GetTraFunReal(k);
- Double_t iw = fElectronics->GetTraFunImag(k);
- fOutZR[k] = fInZR[k]*rw - fInZI[k]*iw;
- fOutZI[k] = fInZR[k]*iw + fInZI[k]*rw;
- if(i+1 < fNofMaps) fInZR[k] = fHitMap2->GetSignal(i+1,k);
- }
-
- if (first) {
- fInZR[k] = fHitMap2->GetSignal(i,k);
+
+ Float_t maxadc = fResponse->MaxAdc();
+ if(!fDoFFT) {
+ for (i=0;i<fNofMaps;i++) {
+ if (read && i<fNofMaps) GetAnodeBaseline(i,baseline,noise);
+ for(k=0; k<fScaleSize*fMaxNofSamples; k++) {
+ fInZR[k] = fHitMap2->GetSignal(i,k);
+ contrib = (baseline + noise*random.Gaus());
+ fInZR[k] += contrib;
}
- fInZI[k] = 0.;
- // add baseline and noise
- contrib = baseline + noise*random->Gaus();
- fInZR[k] += contrib;
-
- } // loop over time
-
- if (first) {
+ for(k=0; k<fMaxNofSamples; k++) {
+ Double_t newcont = 0.;
+ Double_t maxcont = 0.;
+ for(kk=0;kk<fScaleSize;kk++) {
+
+ newcont = fInZR[fScaleSize*k+kk];
+ if(newcont > maxcont) maxcont = newcont;
+
+ //newcont += (fInZR[fScaleSize*k+kk]/fScaleSize);
+ }
+ newcont = maxcont;
+ if (newcont >= maxadc) newcont = maxadc -1;
+ if(newcont >= baseline) cout << "newcont: " << newcont << endl;
+ // back to analog: ?
+ fHitMap2->SetHit(i,k,newcont);
+ }
+ } // loop over anodes
+ return;
+ } // end if DoFFT
+
+ for (i=0;i<fNofMaps;i++) {
+ if (read && i<fNofMaps) GetAnodeBaseline(i,baseline,noise);
+ for(k=0; k<fScaleSize*fMaxNofSamples; k++) {
+ fInZR[k] = fHitMap2->GetSignal(i,k);
+ contrib = (baseline + noise*random.Gaus());
+ fInZR[k] += contrib;
+ fInZI[k] = 0.;
+ }
FastFourierTransform(fElectronics,&fInZR[0],&fInZI[0],1);
- for (k=0; k<fScaleSize*fMaxNofSamples; k++) {
- Double_t rw = fElectronics->GetTraFunReal(k);
+ for(k=0; k<fScaleSize*fMaxNofSamples; k++) {
+ Double_t rw = fElectronics->GetTraFunReal(k);
Double_t iw = fElectronics->GetTraFunImag(k);
- fOutZR[k] = fInZR[k]*rw - fInZI[k]*iw;
- fOutZI[k] = fInZR[k]*iw + fInZI[k]*rw;
- fInZR[k] = fHitMap2->GetSignal(i+1,k);
- fInZI[k] = 0.;
- // add baseline and noise
- contrib = baseline + noise*random->Gaus();
- fInZR[k] += contrib;
+ fOutZR[k] = fInZR[k]*rw - fInZI[k]*iw;
+ fOutZI[k] = fInZR[k]*iw + fInZI[k]*rw;
}
- }
- if(i<fNofMaps) FastFourierTransform(fElectronics,&fOutZR[0],&fOutZI[0],-1);
- first = kFALSE;
+ FastFourierTransform(fElectronics,&fOutZR[0],&fOutZI[0],-1);
+ for(k=0; k<fMaxNofSamples; k++) {
+ Double_t newcont1 = 0.;
+ Double_t maxcont1 = 0.;
+ for(kk=0;kk<fScaleSize;kk++) {
+
+ newcont1 = fOutZR[fScaleSize*k+kk];
+ if(newcont1 > maxcont1) maxcont1 = newcont1;
+
+ //newcont1 += (fInZR[fScaleSize*k+kk]/fScaleSize);
+ }
+ newcont1 = maxcont1;
+ //cout << "newcont1: " << newcont1 << endl;
+ if (newcont1 >= maxadc) newcont1 = maxadc -1;
+ fHitMap2->SetHit(i,k,newcont1);
+ }
} // loop over anodes
-
+ return;
+
}
//____________________________________________
Int_t db,tl,th;
Int_t minval = fResponse->MinVal();
Bool_t write=fResponse->OutputOption();
+ Bool_t do10to8=fResponse->Do10to8();
Int_t nz, nl, nh, low, i, j;
nh++;
Bool_t cond=kTRUE;
FindCluster(i,j,signal,minval,cond);
+ if (cond && j && ((TMath::Abs(fHitMap2->GetSignal(i,j-1))-th)>=minval)) {
+ if(do10to8) signal = Convert10to8(signal);
+ AddDigit(i,j,signal);
+ }
} else if ((signal - tl) >= minval) nl++;
} // loop time samples
if (write) TreeB()->Fill(nz,nl,nh,low,i+1);
//_____________________________________________________________________________
void AliITSsimulationSDD::FindCluster(Int_t i,Int_t j,Int_t signal,
- Int_t minval,Bool_t cond){
+ Int_t minval,Bool_t &cond){
//
// Find clusters according to the online 2D zero-suppression algorithm
//
+ Bool_t do10to8=fResponse->Do10to8();
+
Bool_t high=kFALSE;
fHitMap2->FlagHit(i,j);
Int_t dbx,tlx,thx;
Int_t xList[maxNeighbours], yList[maxNeighbours];
fSegmentation->Neighbours(i,j,&nn,xList,yList);
- Int_t in,ix,iy;
+ Int_t in,ix,iy,qns;
for (in=0; in<nn; in++) {
ix=xList[in];
iy=yList[in];
} else {
if ((qn - thx) >= minval) high=kTRUE;
if (cond) {
- signal = Convert10to8(signal);
+ if(do10to8) signal = Convert10to8(signal);
AddDigit(i,j,signal);
}
- Int_t qns = Convert10to8(qn);
+ if(do10to8) qns = Convert10to8(qn);
+ else qns=qn;
if (!high) AddDigit(ix,iy,qns);
cond=kFALSE;
if(!high) fHitMap2->FlagHit(ix,iy);
UChar_t *str=fStream->Stream();
Int_t counter=0;
+ Bool_t do10to8=fResponse->Do10to8();
+
Int_t last=0;
Int_t k,i,j;
- for (k=1; k<=2; k++) {
- tol = Tolerance(k-1);
- dis = Disable(k-1);
+ for (k=0; k<2; k++) {
+ tol = Tolerance(k);
+ dis = Disable(k);
for (i=0; i<fNofMaps/2; i++) {
Bool_t firstSignal=kTRUE;
- CompressionParam(k*i,decr,thres);
+ Int_t idx=i+k*fNofMaps/2;
+ CompressionParam(idx,decr,thres);
for (j=0; j<fMaxNofSamples; j++) {
- Int_t signal=(Int_t)(fHitMap2->GetSignal(k*i,j));
+ Int_t signal=(Int_t)(fHitMap2->GetSignal(idx,j));
signal -= decr; // if baseline eq.
- signal = Convert10to8(signal);
- if (signal < thres) {
+ if(do10to8) signal = Convert10to8(signal);
+ if (signal <= thres) {
signal=0;
diff=128;
last=0;
if (diff < -128) diff=-128;
if (signal < dis) {
+ // tol has changed to 8 possible cases ? - one can write
+ // this if(TMath::Abs(diff)<tol) ... else ...
+ if(TMath::Abs(diff)<tol) diff=0;
+ // or keep it as it was before
+ /*
if (tol==1 && (diff >= -2 && diff <= 1)) diff=0;
if (tol==2 && (diff >= -4 && diff <= 3)) diff=0;
if (tol==3 && (diff >= -16 && diff <= 15)) diff=0;
- AddDigit(k*i,j,last+diff);
+ */
+ AddDigit(idx,j,last+diff);
} else {
- AddDigit(k*i,j,signal);
+ AddDigit(idx,j,signal);
}
diff += 128;
}
//____________________________________________
void AliITSsimulationSDD::StoreAllDigits(){
- // if non-zero-suppressed data
+ // if non-zero-suppressed data
- Int_t i, j, digits[3];
+ Bool_t do10to8=fResponse->Do10to8();
+ Int_t i, j, digits[3];
for (i=0; i<fNofMaps; i++) {
for (j=0; j<fMaxNofSamples; j++) {
Int_t signal=(Int_t)(fHitMap2->GetSignal(i,j));
- signal = Convert10to8(signal);
- signal = Convert8to10(signal); // ?
+ if(do10to8) signal = Convert10to8(signal);
+ if(do10to8) signal = Convert8to10(signal);
digits[0]=i;
digits[1]=j;
digits[2]=signal;
- fITS->AddRealDigit(1,digits);
+ fITS->AddRealDigit(1,digits);
}
}
}
//____________________________________________
-void AliITSsimulationSDD::CreateHistograms(){
+void AliITSsimulationSDD::CreateHistograms(Int_t scale){
// Creates histograms of maps for debugging
Int_t i;
+
+ fHis=new TObjArray(fNofMaps);
for (i=0;i<fNofMaps;i++) {
- TString *sddName = new TString("sdd_");
+ TString sddName("sdd_");
Char_t candNum[4];
sprintf(candNum,"%d",i+1);
- sddName->Append(candNum);
- (*fHis)[i] = new TH1F(sddName->Data(),"SDD maps",
- fMaxNofSamples,(Axis_t)0.,(Axis_t) fMaxNofSamples);
- delete sddName;
+ sddName.Append(candNum);
+ (*fHis)[i] = new TH1F(sddName.Data(),"SDD maps",
+ scale*fMaxNofSamples,0.,(Float_t) scale*fMaxNofSamples);
}
}
+//____________________________________________
+void AliITSsimulationSDD::FillHistograms(){
+ // fill 1D histograms from map
+ if (!fHis) return;
+
+ for( Int_t i=0; i<fNofMaps; i++) {
+ TH1F *hist =(TH1F *)fHis->UncheckedAt(i);
+ Int_t nsamples = hist->GetNbinsX();
+ for( Int_t j=0; j<nsamples; j++) {
+ Double_t signal=fHitMap2->GetSignal(i,j);
+ hist->Fill((Float_t)j,signal);
+ }
+ }
+}
+
//____________________________________________
void AliITSsimulationSDD::ResetHistograms(){
return;
}
//____________________________________________
-Float_t AliITSsimulationSDD::GetNoise(Float_t threshold) {
+Float_t AliITSsimulationSDD::GetNoise() {
// Returns the noise value
- if (!fHis) return 0.;
- TH1F *noisehist = new TH1F("noisehist","noise",100,(Axis_t)0.,(Axis_t)threshold);
+ //Bool_t do10to8=fResponse->Do10to8();
+ //noise will always be in the liniar part of the signal
+
+ Int_t decr;
+ Int_t threshold=fT1[0];
+
+ char opt1[20], opt2[20];
+ fResponse->ParamOptions(opt1,opt2);
+ fParam=opt2;
+ char *same = strstr(opt1,"same");
+ Float_t noise,baseline;
+ if (same) {
+ fResponse->GetNoiseParam(noise,baseline);
+ } else {
+ static Bool_t readfile=kTRUE;
+ //read baseline and noise from file
+ if (readfile) ReadBaseline();
+ readfile=kFALSE;
+ }
+
+ TCanvas *c2 = (TCanvas*)gROOT->GetListOfCanvases()->FindObject("c2");
+ if(c2) delete c2->GetPrimitive("noisehist");
+ if(c2) delete c2->GetPrimitive("anode");
+ else c2=new TCanvas("c2");
+ c2->cd();
+ c2->SetFillColor(0);
+
+ TH1F *noisehist = new TH1F("noisehist","noise",100,0.,(float)2*threshold);
+ TH1F *anode = new TH1F("anode","Anode Projection",fMaxNofSamples,0.,(float)fMaxNofSamples);
Int_t i,k;
for (i=0;i<fNofMaps;i++) {
- Int_t nOfBinsA = ((TH1F*)(*fHis)[i])->GetNbinsX();
- for (k=0;k<nOfBinsA;k++) {
- Float_t content = ((TH1F*)(*fHis)[i])->GetBinContent(k+1);
- if (content < threshold) noisehist->Fill(content);
+ CompressionParam(i,decr,threshold);
+ if (!same) GetAnodeBaseline(i,baseline,noise);
+ anode->Reset();
+ for (k=0;k<fMaxNofSamples;k++) {
+ Float_t signal=(Float_t)fHitMap2->GetSignal(i,k);
+ //if (signal <= (float)threshold) noisehist->Fill(signal-baseline);
+ if (signal <= (float)threshold) noisehist->Fill(signal);
+ anode->Fill((float)k,signal);
}
+ anode->Draw();
+ c2->Update();
}
- TF1 *gnoise = new TF1("gnoise","gaus",(Double_t)0.,(Double_t)threshold);
+ TF1 *gnoise = new TF1("gnoise","gaus",0.,threshold);
noisehist->Fit("gnoise","RQ");
noisehist->Draw();
+ c2->Update();
Float_t mnoise = gnoise->GetParameter(1);
cout << "mnoise : " << mnoise << endl;
Float_t rnoise = gnoise->GetParameter(2);
delete noisehist;
return rnoise;
}
+
+//____________________________________________
+
+void AliITSsimulationSDD::Print() {
+
+ // Print SDD simulation Parameters
+
+ cout << "**************************************************" << endl;
+ cout << " Silicon Drift Detector Simulation Parameters " << endl;
+ cout << "**************************************************" << endl;
+ cout << "Flag for Perpendicular tracks: " << (Int_t) fFlag << endl;
+ cout << "Flag for noise checking: " << (Int_t) fCheckNoise << endl;
+ cout << "Flag to switch off electronics: " << (Int_t) fDoFFT << endl;
+ cout << "Number pf Anodes used: " << fNofMaps << endl;
+ cout << "Number of Time Samples: " << fMaxNofSamples << endl;
+ cout << "Scale size factor: " << fScaleSize << endl;
+ cout << "**************************************************" << endl;
+}