X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=ITS%2FAliITSsimulationSSD.cxx;h=074a18e44aa95c03dc4498b31b955f3a241eda57;hb=7fe075c8aadca29e837989cc0acd2d65ada119c9;hp=345dd7a1a03236a64a90c988200eb4f9e566ee25;hpb=bba587ca06599962894edc348a928caa7888db12;p=u%2Fmrichter%2FAliRoot.git diff --git a/ITS/AliITSsimulationSSD.cxx b/ITS/AliITSsimulationSSD.cxx index 345dd7a1a03..074a18e44aa 100644 --- a/ITS/AliITSsimulationSSD.cxx +++ b/ITS/AliITSsimulationSSD.cxx @@ -1,435 +1,526 @@ -/************************************************************************** - * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * * - * Author: The ALICE Off-line Project. * - * Contributors are mentioned in the code where appropriate. * - * * - * Permission to use, copy, modify and distribute this software and its * - * documentation strictly for non-commercial purposes is hereby granted * - * without fee, provided that the above copyright notice appears in all * - * copies and that both the copyright notice and this permission notice * - * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * - * provided "as is" without express or implied warranty. * - **************************************************************************/ - #include +#include +#include #include +#include +#include +#include "AliITSmodule.h" +#include "AliITSMapA2.h" #include "AliITSsegmentationSSD.h" #include "AliITSresponseSSD.h" #include "AliITSsimulationSSD.h" -#include "AliITSdictSSD.h" +//#include "AliITSdictSSD.h" #include "AliITSdcsSSD.h" #include "AliITS.h" #include "AliRun.h" - +#include "AliITSgeom.h" ClassImp(AliITSsimulationSSD); -//------------------------------------------------------------ +//////////////////////////////////////////////////////////////////////// +// Version: 0 +// Written by Enrico Fragiacomo +// July 2000 +// +// AliITSsimulationSSD is the simulation of SSDs. + +//---------------------------------------------------------------------- AliITSsimulationSSD::AliITSsimulationSSD(AliITSsegmentation *seg, AliITSresponse *resp){ - // Constructor + // Constructor fSegmentation = seg; fResponse = resp; + Float_t noise[2] = {0.,0.}; + fResponse->GetNoiseParam(noise[0],noise[1]); // retrieves noise parameters fDCS = new AliITSdcsSSD(seg,resp); fNstrips = fSegmentation->Npx(); fPitch = fSegmentation->Dpx(0); - - fP = new TArrayF(fNstrips); - fN = new TArrayF(fNstrips); + fMapA2 = new AliITSMapA2(fSegmentation); - fTracksP = new AliITSdictSSD[fNstrips]; - fTracksN = new AliITSdictSSD[fNstrips]; - - fSteps = 10; // still hard-wired - set in SetDetParam and get it via + fSteps = 100; // still hard-wired - set in SetDetParam and get it via // fDCS together with the others eventually - - - //printf("SSD ctor: fNstrips fPitch %d %f\n",fNstrips, fPitch); } -//___________________________________________________________________________ +//______________________________________________________________________ AliITSsimulationSSD& AliITSsimulationSSD::operator=(AliITSsimulationSSD &source){ -// Operator = + // Operator = + if(this==&source) return *this; - this->fDCS = new AliITSdcsSSD(*(source.fDCS)); - this->fN = new TArrayF(*(source.fN)); - this->fP = new TArrayF(*(source.fP)); - this->fTracksP = new AliITSdictSSD(*(source.fTracksP)); - this->fTracksN = new AliITSdictSSD(*(source.fTracksN)); + this->fDCS = new AliITSdcsSSD(*(source.fDCS)); + this->fMapA2 = source.fMapA2; this->fNstrips = source.fNstrips; this->fPitch = source.fPitch; this->fSteps = source.fSteps; return *this; } -//_____________________________________________________________ +//_____________________________________________________________--------- AliITSsimulationSSD::AliITSsimulationSSD(AliITSsimulationSSD &source){ - // copy constructor - *this = source; + // copy constructor + + *this = source; } -//____________________________________________________________________________ +//______________________________________________________________________ AliITSsimulationSSD::~AliITSsimulationSSD() { - // anihilator - - if(fP) delete fP; - if(fN) delete fN; - - if(fTracksP) delete fTracksP; - if(fTracksN) delete fTracksN; - + // destructor + delete fMapA2; delete fDCS; -} -//_______________________________________________________________ -// -// Hit to digit -//_______________________________________________________________ -// +} +//_______________________________________________________________------- void AliITSsimulationSSD::DigitiseModule(AliITSmodule *mod,Int_t module, Int_t dummy) { - // Digitizes one SSD module of hits. - + // Digitizes hits for one SSD module + + Int_t lay, lad, detect; + AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS"); + AliITSgeom *geom = aliITS->GetITSgeom(); + geom->GetModuleId(module,lay, lad, detect); + if ( lay == 6 )((AliITSsegmentationSSD*)fSegmentation)->SetLayer(6); + if ( lay == 5 )((AliITSsegmentationSSD*)fSegmentation)->SetLayer(5); + TObjArray *hits = mod->GetHits(); Int_t nhits = hits->GetEntriesFast(); - //printf("SSD: nhits %d\n",nhits); if (!nhits) return; - - Int_t i; - for(i=0; iGetHitTrackIndex(i); - HitToDigit(i,idtrack,nhits,hits); - } - - - ApplyNoise(); - ApplyCoupling(); - ApplyThreshold(); - ApplyDAQ(); - - -} - -//--------------------------------------------------------------- - -void AliITSsimulationSSD::HitToDigit(Int_t & hitNo,Int_t idtrack, - Int_t nhits,TObjArray *hits) { - // Turns one or more hits in an SSD module into one or more digits. - - Int_t stripP, stripN, i; - Float_t dsP, dsN; - Float_t sP, sN; - Float_t eP, eN; - Float_t arrayEP[10]; - Float_t arrayEN[10]; - Int_t track = 0; - - Float_t ionization = 0; - Float_t signal; - - AliITSdictSSD *dict; + //cout<<"!! module, nhits ="<At(hitNo++); - AliITShit *hitE = (AliITShit*)hits->At(hitNo); + for(Int_t i=0; iStatusExiting()) || - (hitE->StatusDisappeared()) || - (hitE->StatusStop()))) { - - if (++hitNoGetIonization(); - hitE = (AliITShit*)hits->At(hitNo); - } - } - - - if (hitI->GetTrack() == hitE->GetTrack()) - //track = idtrack; - track = hitI->GetTrack(); - else - printf("!!! Emergency !!!\n"); - - - ionization += hitE->GetIonization(); + if (mod->LineSegmentL(i, x0, x1, y0, y1, z0, z1, de, idtrack)) { + HitToDigit(module, x0, y0, z0, x1, y1, z1, de, indexRange, first); - const Float_t kconvm=10000.; // cm -> microns - - Float_t xI, yI, zI; - hitI->GetPositionL(xI, yI, zI); - - //Float_t zI = hitI->GetZL(); - - xI *= kconvm; - yI *= kconvm; - zI *= kconvm; - - Float_t xE, yE, zE; - hitE->GetPositionL(xE, yE, zE); - - //Float_t zE = hitE->GetZL(); + if (lasttrack != idtrack || i==(nhits-1)) { + GetList(idtrack,pList,indexRange); + first=kTRUE; + } // end if + lasttrack=idtrack; + } // end if + } // end loop over hits - xE *= kconvm; - yE *= kconvm; - zE *= kconvm; - - Float_t dx = (xE - xI); - Float_t dz = (zE - zI); - - - // Debuging - /* - fSegmentation->GetCellIxz(xI,zI,stripP,stripN); - - printf("%5d %8.3f %8.3f %8.3f %8.3f %d %d %d\n", - hitNo, xI, zI, dx, dz, - stripP, stripN, track); - printf("%10.5f %10d \n", ionization, hitI->fTrack); - */ - - // end of debuging - - - eP=0; - eN=0; - //fNparticles++; - - for(i=0; iLandau(ionization/fSteps, ionization/(4*fSteps)); - // arrayEN[i] = gRandom->Landau(ionization/fSteps, ionization/(4*fSteps)); - arrayEP[i] = ionization/fSteps; - arrayEN[i] = ionization/fSteps; - - eP += arrayEP[i]; - eN += arrayEN[i]; - } - - const Float_t kconv = 1.0e9 / 3.6; // GeV -> e-hole pairs - - for(i=0; iSigmaSpread(sigmaP,sigmaN); - - //printf("SigmaP SigmaN %f %f\n",sigmaP, sigmaN); - - Float_t noiseP, noiseN; - fResponse->GetNoiseParam(noiseP,noiseN); + ApplyNoise(); + ApplyCoupling(); - //printf("NoiseP NoiseN %f %f\n",noiseP, noiseN); + ChargeToSignal(pList); - for(i=0; iGetCellIxz(xI,zI,stripP,stripN); - //printf("i xI zI stripP stripN %d %f %f %d %d\n",i,xI, zI, stripP, stripN); - dsP = Get2Strip(1,stripP,xI, zI); // Between 0-1 - dsN = Get2Strip(0,stripN,xI, zI); // Between 0-1 - - sP = sigmaP * sqrt(300. * i / (fSteps)); - sN = sigmaN * sqrt(300. * i /(fSteps-i)); - - - sP = (i<2 && dsP>0.3 && dsP<0.7)? 20. : sP; // square of (microns) - sN = (i>fSteps-2 && dsN>0.3 && dsN<0.7)? 20. : sN; // square of (microns) - - sP = (i==2 && dsP>0.4 && dsP<0.6)? 15. : sP; // square of (microns) - sN = (i==8 && dsN>0.4 && dsN<0.6)? 15. : sN; // square of (microns) - - - //printf("i=%d SigmaP SigmaN sP sN %f %f %e %e\n",i,sigmaP, sigmaN,sP,sN); - - for(j=-1; j<2; j++) { - - if (stripP+j<0 || stripP+j>fNstrips) continue; - - signal = arrayEP[i] * TMath::Abs( (F(j+0.5-dsP,sP)-F(j-0.5-dsP,sP)) ); - //printf("SimSSD::HitsToDigits:%d arrayEP[%d]=%e signal=%e\n",j,i,arrayEP[i],signal); - if (signal > noiseP/fSteps) { - (*fP)[stripP+j] += signal; - dict = (fTracksP+stripP+j); - (*dict).AddTrack(track); - } - } // end for j loop over neighboring strips - for(j=-1; j<2; j++) { - - if (stripN+j<0 || stripN+j>fNstrips) continue; - - signal = arrayEN[i] * TMath::Abs( (F(j+0.5-dsN,sN)-F(j-0.5-dsN,sN)) ); - //printf("SimSSD::HitsToDigits:%d arrayEN[%d]=%e signal=%e\n",j,i,arrayEN[i],signal); - if (signal > noiseN/fSteps) { - (*fN)[stripN+j] += signal; - dict = (fTracksN+stripN+j); //co to jest - (*dict).AddTrack(track); - } - } // end for j loop over neighboring strips - - xI += dx; - zI += dz; - } - + fMapA2->ClearMap(); +} +//---------------------------------------------------------------------- +void AliITSsimulationSSD::HitToDigit(Int_t module, Double_t x0, Double_t y0, + Double_t z0, Double_t x1, Double_t y1, + Double_t z1, Double_t de, + Int_t *indexRange, Bool_t first) { + // Turns hits in SSD module into one or more digits. + + Float_t tang[2] = {0.0,0.0}; + fSegmentation->Angles(tang[0], tang[1]);// stereo<< -> tan(stereo)~=stereo + Double_t x, y, z; + Double_t dex=0.0, dey=0.0, dez=0.0; + Double_t pairs; + Double_t ionE = 3.62E-9; // ionization energy of Si (GeV) + Double_t sigma[2] = {0.,0.};// standard deviation of the diffusion gaussian + + Double_t D[2] = {11.,30.}; // diffusion constant {h,e} (cm**2/sec) + Double_t tdrift[2] = {0.,0.}; // time of drift + Double_t vdrift[2] = {0.86E6,2.28E6}; // drift velocity (cm/sec) + Double_t w; + Double_t inf[2], sup[2], par0[2]; + // Steps in the module are determined "manually" (i.e. No Geant) + // NumOfSteps divide path between entering and exiting hits in steps + Int_t numOfSteps = NumOfSteps(x1, y1, z1, dex, dey, dez); + + // Enery loss is equally distributed among steps + de = de/numOfSteps; + pairs = de/ionE; // e-h pairs generated + + for(Int_t j=0; jDy()*1.0E-4)/2) / vdrift[0]; + tdrift[1] = ((fSegmentation->Dy()*1.0E-4)/2-y) / vdrift[1]; + + for(Int_t k=0; k<2; k++) { // both sides remember: 0=Pside 1=Nside + + tang[k]=TMath::Tan(tang[k]); + + // w is the coord. perpendicular to the strips + if(k==0) { + //w=(x+(seg->Dx()*1.0E-4)/2)-(z+(seg->Dz()*1.0E-4)/2)*tang[k]; + w = (x+(fSegmentation->Dx()*1.0E-4)/2) - + (z+(fSegmentation->Dz()*1.0E-4)/2)*tang[k]; + }else{ + //w =(x+(seg->Dx()*1.0E-4)/2)+(z-(seg->Dz()*1.0E-4)/2)*tang[k]; + w = (x+(fSegmentation->Dx()*1.0E-4)/2) + + (z-(fSegmentation->Dz()*1.0E-4)/2)*tang[k]; + //cout<<"k,x,z,w ="<(fNstrips-0.5))) { + // this check rejects hits in regions not covered by strips + // 0.5 takes into account boundaries + if(k==0) cout<<"AliITSsimulationSSD::HitToDigit: " + "Warning: no strip in this region of P side" + <GetNoiseParam(noise[0],noise[1]); // retrieves noise parameters + for(Int_t k=0;k<2;k++){ // both sides (0=Pside, 1=Nside) + for(Int_t ix=0;ixGetSignal(k,ix);// retrieves signal + // from map -//____________________________________________________________________ -// -// Private Methods for Simulation -//______________________________________________________________________ -// + signal += gRandom->Gaus(0,noise[k]);// add noise to signal + if(signal<0.) signal=0.0; // in case noise is negative... -void AliITSsimulationSSD::ApplyNoise() { - // Apply Noise. - Float_t noiseP, noiseN; - fResponse->GetNoiseParam(noiseP,noiseN); - - Int_t i; - for(i = 0; iGaus(0,noiseP); - (*fN)[i] += gRandom->Gaus(0,noiseN); - } + fMapA2->SetHit(k,ix,(Double_t)signal); // give back signal to map + } // loop over strip + } // loop over k (P or N side) } - -//_________________________________________________________________________ - +//______________________________________________________________________ void AliITSsimulationSSD::ApplyCoupling() { - // Apply the effecto of electronic coupling between channels - - Int_t i; - for(i = 1; iGetCouplingPL() + (*fP)[i+1]*fDCS->GetCouplingPR(); - (*fN)[i] += (*fN)[i-1]*fDCS->GetCouplingNL() + (*fN)[i+1]*fDCS->GetCouplingNR(); - } + // Apply the effect of electronic coupling between channels + Float_t signal, signalLeft=0, signalRight=0; + + for(Int_t ix=0;ix0.) signalLeft = (Float_t) fMapA2->GetSignal(0,ix-1)* + fDCS->GetCouplingPL(); + else signalLeft = 0.0; + if(ix<(fNstrips-1)) signalRight = (Float_t) fMapA2->GetSignal(0,ix+1)* + fDCS->GetCouplingPR(); + else signalRight = 0.0; + signal = (Float_t) fMapA2->GetSignal(0,ix); + signal += signalLeft + signalRight; + fMapA2->SetHit(0,ix,(Double_t)signal); + + if(ix>0.) signalLeft = (Float_t) fMapA2->GetSignal(1,ix-1)* + fDCS->GetCouplingNL(); + else signalLeft = 0.0; + if(ix<(fNstrips-1)) signalRight = (Float_t) fMapA2->GetSignal(1,ix+1)* + fDCS->GetCouplingNR(); + else signalRight = 0.0; + signal = (Float_t) fMapA2->GetSignal(1,ix); + signal += signalLeft + signalRight; + fMapA2->SetHit(1,ix,(Double_t)signal); + } // loop over strips } - -//__________________________________________________________________________ - -void AliITSsimulationSSD::ApplyThreshold() { - // Applies the effect of a threshold on the signals for digitization. - Float_t noiseP, noiseN; - fResponse->GetNoiseParam(noiseP,noiseN); - - // or introduce the SetThresholds in fResponse - - Int_t i; - for(i=0; i noiseP*4) ? (*fP)[i] : 0; - (*fN)[i] = ((*fN)[i] > noiseN*4) ? (*fN)[i] : 0; - //printf("SSD:(*fP)[i] (*fN)[i] %f %f \n",(*fP)[i], (*fN)[i]); - } - +//______________________________________________________________________ +Float_t AliITSsimulationSSD::F(Float_t av, Float_t x, Float_t s) { + // Computes the integral of a gaussian using Error Function + Float_t sqrt2 = TMath::Sqrt(2.0); + Float_t sigm2 = sqrt2*s; + Float_t integral; + + integral = 0.5 * TMath::Erf( (x - av) / sigm2); + return integral; } - -//__________________________________________________________________________ - -void AliITSsimulationSSD::ApplyDAQ() { - // Converts simulated signals to simulated ADC counts - AliITS *its=(AliITS*)gAlice->GetModule("ITS"); - - Float_t noiseP, noiseN; - fResponse->GetNoiseParam(noiseP,noiseN); - - // Set signal = 0 if invalid strip - Int_t i,j; - for(i=0; iIsValidP(i))) (*fP)[i] = 0; - if (!(fDCS->IsValidN(i))) (*fN)[i] = 0; - } - - Int_t digits[3], tracks[3]; - Float_t charges[3]; - Float_t phys=0; - for(i=0; iGetNTracks(); j++) { - if(j>2) continue; - tracks[j] = (fTracksP+i)->GetTrack(j); - charges[j] = 0; - } - its->AddDigit(2,phys,digits,tracks,charges); - - //cout << (fTracksP+i)->GetNTracks(); - // - //if ((fTracksP+i)->GetNTracks() == 0) { - // cout << d.fCoord2 << " " << d.fSignal << "\n"; - //} - } +//______________________________________________________________________ +void AliITSsimulationSSD::IntegrateGaussian(Int_t k,Double_t par, Double_t w, + Double_t sigma, + Double_t inf, Double_t sup, + Int_t *indexRange, Bool_t first) { + // integrate the diffusion gaussian + // remind: inf and sup are w-3sigma and w+3sigma + // we could define them here instead of passing them + // this way we are free to introduce asimmetry + + Double_t a=0.0, b=0.0; + Double_t signal = 0.0, dXCharge1 = 0.0, dXCharge2 = 0.0; + // dXCharge1 and 2 are the charge to two neighbouring strips + // Watch that we only involve at least two strips + // Numbers greater than 2 of strips in a cluster depend on + // geometry of the track and delta rays, not charge diffusion! + + Double_t strip = TMath::Floor(w); // clostest strip on the left + + if ( TMath::Abs((strip - w)) < 0.5) { + // gaussian mean is closer to strip on the left + a = inf; // integration starting point + if((strip+0.5)<=sup) { + // this means that the tail of the gaussian goes beyond + // the middle point between strips ---> part of the signal + // is given to the strip on the right + b = strip + 0.5; // integration stopping point + dXCharge1 = F( w, b, sigma) - F(w, a, sigma); + dXCharge2 = F( w, sup, sigma) - F(w ,b, sigma); + }else { + // this means that all the charge is given to the strip on the left + b = sup; + dXCharge1 = 0.9973; // gaussian integral at 3 sigmas + dXCharge2 = 0.0; + } // end if + + dXCharge1 = par * dXCharge1;// normalize by mean of number of carriers + dXCharge2 = par * dXCharge2; + + // for the time being, signal is the charge + // in ChargeToSignal signal is converted in ADC channel + signal = fMapA2->GetSignal(k,strip); + signal += dXCharge1; + + fMapA2->SetHit(k,strip,(Double_t)signal); + if(((Int_t) strip) < (fNstrips-1)) { + // strip doesn't have to be the last (remind: last=fNstrips-1) + // otherwise part of the charge is lost + signal = fMapA2->GetSignal(k,(strip+1)); + signal += dXCharge2; + fMapA2->SetHit(k,(strip+1),(Double_t)signal); + } // end if + if(dXCharge1 > 1.) { + if (first) { + indexRange[k*2+0]=indexRange[k*2+1]=(Int_t) strip; + first=kFALSE; + } // end if first + + indexRange[k*2+0]=TMath::Min(indexRange[k*2+0],(Int_t) strip); + indexRange[k*2+1]=TMath::Max(indexRange[k*2+1],(Int_t) strip); + } // dXCharge > 1 e- + + }else{ + // gaussian mean is closer to strip on the right + strip++; // move to strip on the rigth + b = sup; // now you know where to stop integrating + if((strip-0.5)>=inf) { + // tail of diffusion gaussian on the left goes left of + // middle point between strips + a = strip - 0.5; // integration starting point + dXCharge1 = F(w, b, sigma) - F(w, a, sigma); + dXCharge2 = F(w, a, sigma) - F(w, inf, sigma); + }else { + a = inf; + dXCharge1 = 0.9973; // gaussian integral at 3 sigmas + dXCharge2 = 0.0; + } // end if - for(i=0; iGetNTracks(); j++) { - if(j>2) continue; - tracks[j] = (fTracksN+i)->GetTrack(j); - charges[j] = 0; - } - its->AddDigit(2,phys,digits,tracks,charges); - - //cout << (fTracksN+i)->GetNTracks(); - //if ((fTracksN+i)->GetNTracks() == 0) { - // cout << d.fCoord2 << " " << d.fSignal << "\n"; - //} - } + dXCharge1 = par * dXCharge1; // normalize by means of carriers + dXCharge2 = par * dXCharge2; + + // for the time being, signal is the charge + // in ChargeToSignal signal is converted in ADC channel + signal = fMapA2->GetSignal(k,strip); + signal += dXCharge1; + fMapA2->SetHit(k,strip,(Double_t)signal); + if(((Int_t) strip) > 0) { + // strip doesn't have to be the first + // otherwise part of the charge is lost + signal = fMapA2->GetSignal(k,(strip-1)); + signal += dXCharge2; + fMapA2->SetHit(k,(strip-1),(Double_t)signal); + } // end if + if(dXCharge1 > 1.) { + if (first) { + indexRange[k*2+0]=indexRange[k*2+1]=(Int_t) strip; + first=kFALSE; + } // end if first + + indexRange[k*2+0]=TMath::Min(indexRange[k*2+0],(Int_t) strip); + indexRange[k*2+1]=TMath::Max(indexRange[k*2+1],(Int_t) strip); + } // dXCharge > 1 e- + } // end if } - - -//____________________________________________________________________________ - -Float_t AliITSsimulationSSD::F(Float_t x, Float_t s) { - // Computes the integral of a gaussian at the mean valuse x with sigma s. - //printf("SDD:F(%e,%e)\n",x,s); - return 0.5*TMath::Erf(x * fPitch / s) ; -} - //______________________________________________________________________ +Int_t AliITSsimulationSSD::NumOfSteps(Double_t x, Double_t y, Double_t z, + Double_t & dex,Double_t & dey,Double_t & dez){ + // number of steps + // it also returns steps for each coord + //AliITSsegmentationSSD *seg = new AliITSsegmentationSSD(); -Float_t AliITSsimulationSSD::Get2Strip(Int_t flag, Int_t iStrip, Float_t x, Float_t z){ - // Returns the relative space between two strips. + Double_t step = 25E-4; + //step = (Double_t) seg->GetStepSize(); // step size (cm) + Int_t numOfSteps = (Int_t) (TMath::Sqrt(x*x+y*y+z*z)/step); - // flag==1 for Pside, 0 for Nside + if (numOfSteps < 1) numOfSteps = 1; // one step, at least - Float_t stereoP, stereoN; - fSegmentation->Angles(stereoP,stereoN); - - Float_t tanP=TMath::Tan(stereoP); - Float_t tanN=TMath::Tan(stereoN); - - Float_t dx = fSegmentation->Dx(); - Float_t dz = fSegmentation->Dz(); + // we could condition the stepping depending on the incident angle + // of the track + dex = x/numOfSteps; + dey = y/numOfSteps; + dez = z/numOfSteps; + return numOfSteps; +} +//---------------------------------------------------------------------- +void AliITSsimulationSSD::GetList(Int_t label,Float_t **pList, + Int_t *indexRange) { + // loop over nonzero digits + Int_t ix,globalIndex; + Float_t signal=0.; + Float_t highest,middle,lowest; + // printf("SPD-GetList: indexRange[0] indexRange[1] indexRange[2] indexRange[3] %d %d %d %d\n",indexRange[0], indexRange[1], indexRange[2], indexRange[3]); + + for(Int_t k=0; k<2; k++) { + for(ix=indexRange[k*2+0];ixGetSignal(k,ix); + + globalIndex = k*fNstrips+ix; // globalIndex starts from 0! + if(!pList[globalIndex]){ + // + //Create new list (6 elements-3 signals and 3 tracks+total sig) + // + pList[globalIndex] = new Float_t [6]; + // set list to -1 + *pList[globalIndex] = -2.; + *(pList[globalIndex]+1) = -2.; + *(pList[globalIndex]+2) = -2.; + *(pList[globalIndex]+3) = 0.; + *(pList[globalIndex]+4) = 0.; + *(pList[globalIndex]+5) = 0.; + *pList[globalIndex] = (float)label; + *(pList[globalIndex]+3) = signal; + }else{ + // check the signal magnitude + highest = *(pList[globalIndex]+3); + middle = *(pList[globalIndex]+4); + lowest = *(pList[globalIndex]+5); + signal -= (highest+middle+lowest); + // + // compare the new signal with already existing list + // + if(signalhighest){ + *(pList[globalIndex]+5) = middle; + *(pList[globalIndex]+4) = highest; + *(pList[globalIndex]+3) = signal; + *(pList[globalIndex]+2) = *(pList[globalIndex]+1); + *(pList[globalIndex]+1) = *pList[globalIndex]; + *pList[globalIndex] = label; + }else if (signal>middle){ + *(pList[globalIndex]+5) = middle; + *(pList[globalIndex]+4) = signal; + *(pList[globalIndex]+2) = *(pList[globalIndex]+1); + *(pList[globalIndex]+1) = label; + }else{ + *(pList[globalIndex]+5) = signal; + *(pList[globalIndex]+2) = label; + } // end if + } // end if + } // end of loop pixels in x + } // end of loop over pixels in z +} +//---------------------------------------------------------------------- +void AliITSsimulationSSD::ChargeToSignal(Float_t **pList) { + // charge to signal + AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS"); + Float_t threshold = 0.; + Int_t digits[3], tracks[3],hits[3],gi,j1; + Float_t charges[3]; + Float_t signal,phys; + Float_t noise[2] = {0.,0.}; - x += dx/2; - z += dz/2; - - if (flag) return (x - z*tanP) / fPitch - iStrip; // from 0 to 1 - else return (x - tanN*(dz - z)) / fPitch - iStrip; + fResponse->GetNoiseParam(noise[0],noise[1]); + + for(Int_t k=0;k<2;k++){ // both sides (0=Pside, 1=Nside) + + // Threshold for zero-suppression + // It can be defined in AliITSresponseSSD + // threshold = (Float_t)fResponse->MinVal(k); + // I prefer to think adjusting the threshold "manually", looking + // at the scope, and considering noise standard deviation + threshold = 4.0*noise[k]; // 4 times noise is a choice + for(Int_t ix=0;ixGetSignal(k,ix); + + gi =k*fNstrips+ix; // global index + if (signal > threshold) { + digits[0]=k; + digits[1]=ix; + + // convert to ADC signal + // conversion factor are rather arbitrary (need tuning) + // minimum ionizing particle--> ~30000 pairs--> ADC channel 50 + signal = signal*50.0/30000.0; + if(signal>1000.) signal = 1000.0;//if exceeding, accumulate + // last one + digits[2]=(Int_t) signal; + + //gi =k*fNstrips+ix; // global index + for(j1=0;j1<3;j1++){ + if (pList[gi]) { + tracks[j1] = (Int_t)(*(pList[gi]+j1)); + } else { + tracks[j1]=-2; //noise + } // end if pList + charges[j1] = 0; + } // end for j1 + + phys=0; + + hits[0]=0; + hits[1]=0; + hits[2]=0; + // finally add digit + aliITS->AddSimDigit(2,phys,digits,tracks,hits,charges); + + //if(pList[gi]) delete [] pList[gi]; + } // end if signal > threshold + if(pList[gi]) delete [] pList[gi]; + } // end for ix + } // end for k + delete [] pList; } -//____________________________________________________________________________