-void AliITSsimulationSDD::DigitiseModule(AliITSmodule *mod,Int_t md,Int_t ev){
- // create maps to build the lists of tracks for each digit
-
- TObjArray *fHits = mod->GetHits();
- Int_t nhits = fHits->GetEntriesFast();
- fModule = md;
- fEvent = ev;
-
- if (!nhits && fCheckNoise) {
- ChargeToSignal();
- GetNoise();
- fHitMap2->ClearMap();
- return;
- } else if (!nhits) return;
-
- // inputs to ListOfFiredCells.
- TObjArray *alist = new TObjArray;
- fHitMap1->SetArray(alist);
- static TClonesArray *padr = 0;
- if(!padr) padr = new TClonesArray("TVector",1000);
- Int_t arg[6] = {0,0,0,0,0,0};
-
- Int_t dummy = 0;
- Int_t nofAnodes = fNofMaps/2;
- Float_t sddLength = fSegmentation->Dx();
- Float_t sddWidth = fSegmentation->Dz();
- 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;
- Float_t dfCoeff, s1; fResponse->DiffCoeff(dfCoeff,s1); // Signal 2d Shape
- Double_t eVpairs = 3.6; // electron pair energy eV.
- Float_t nsigma = fResponse->NSigmaIntegration(); //
- Int_t nlookups = fResponse->GausNLookUp(); //
-
- // 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
-
- const Float_t kconv = 1.0e+6; // GeV->KeV
- Int_t itrack = 0;
- Int_t hitDetector; // detector number (lay,lad,hitDetector)
- Int_t iWing; // which detector wing/side.
- Int_t detector; // 2*(detector-1)+iWing
- Int_t ii,kk,ka,kt; // loop indexs
- Int_t ia,it,index; // sub-pixel integration indexies
- Int_t iAnode; // anode number.
- Int_t timeSample; // time buckett.
- Int_t anodeWindow; // anode direction charge integration width
- Int_t timeWindow; // time direction charge integration width
- Int_t jamin,jamax; // anode charge integration window
- Int_t jtmin,jtmax; // time charge integration window
- Int_t ndiv; // Anode window division factor.
- Int_t nsplit; // the number of splits in anode and time windows==1.
- Int_t nOfSplits; // number of times track length is split into
- Float_t nOfSplitsF; // Floating point version of nOfSplits.
- Float_t kkF; // Floating point version of loop index kk.
- Float_t pathInSDD; // Track length in SDD.
- Float_t drPath; // average position of track in detector. in microns
- Float_t drTime; // Drift time
- Float_t nmul; // drift time window multiplication factor.
- Float_t avDrft; // x position of path length segment in cm.
- Float_t avAnode; // Anode for path length segment in Anode number (float)
- Float_t xAnode; // Floating point anode number.
- Float_t driftPath; // avDrft in microns.
- Float_t width; // width of signal at anodes.
- Double_t depEnergy; // Energy deposited in this GEANT step.
- Double_t xL[3],dxL[3]; // local hit coordinates and diff.
- Double_t sigA; // sigma of signal at anode.
- Double_t sigT; // sigma in time/drift direction for track segment
- Double_t aStep,aConst; // sub-pixel size and offset anode
- Double_t tStep,tConst; // sub-pixel size and offset time
- Double_t amplitude; // signal amplitude for track segment in nanoAmpere
- Double_t chargeloss; // charge loss for track segment.
- Double_t anodeAmplitude; // signal amplitude in anode direction
- Double_t aExpo; // exponent of Gaussian anode direction
- Double_t timeAmplitude; // signal amplitude in time direction
- Double_t tExpo; // exponent of Gaussian time direction
-// Double_t tof; // Time of flight in ns of this step.
-
- for(ii=0; ii<nhits; ii++) {
- if(!mod->LineSegmentL(ii,xL[0],dxL[0],xL[1],dxL[1],xL[2],dxL[2],
- depEnergy,itrack)) continue;
- depEnergy *= kconv;
- hitDetector = mod->GetDet();
- //tof = 1.E+09*(mod->GetHit(ii)->GetTOF()); // tof in ns.
- //if(tof>sddLength/driftSpeed) continue; // hit happed too late.
-
- // scale path to simulate a perpendicular track
- // continue if the particle did not lose energy
- // passing through detector
- if (!depEnergy) {
- cout << "This particle has passed without losing energy!" << endl;
- continue;
- } // end if !depEnergy
-
- pathInSDD = TMath::Sqrt(dxL[0]*dxL[0]+dxL[1]*dxL[1]+dxL[2]*dxL[2]);
-
- if (fFlag && pathInSDD) { depEnergy *= (0.03/pathInSDD); }
- drPath = 10000.*(dxL[0]+2.*xL[0])*0.5;
- if(drPath < 0) drPath = -drPath;
- drPath = sddLength-drPath;
- if(drPath < 0) {
- cout << "Warning: negative drift path " << drPath << endl;
- continue;
- } // end if drPath < 0
-
- // Compute number of segments to brake step path into
- drTime = drPath/driftSpeed; // Drift Time
- sigA = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1);// Sigma along the anodes
- // calcuate the number of time the path length should be split into.
- nOfSplits = (Int_t) (1. + 10000.*pathInSDD/sigA);
- if(fFlag) nOfSplits = 1;
-
- // loop over path segments, init. some variables.
- depEnergy /= nOfSplits;
- nOfSplitsF = (Float_t) nOfSplits;
- for(kk=0;kk<nOfSplits;kk++) { // loop over path segments
- kkF = (Float_t) kk + 0.5;
- avDrft = xL[0]+dxL[0]*kkF/nOfSplitsF;
- avAnode = xL[2]+dxL[2]*kkF/nOfSplitsF;
- driftPath = 10000.*avDrft;
-
- iWing = 2; // Assume wing is 2
- if(driftPath < 0) { // if wing is not 2 it is 1.
- iWing = 1;
- driftPath = -driftPath;
- } // end if driftPath < 0
- driftPath = sddLength-driftPath;
- detector = 2*(hitDetector-1) + iWing;
- if(driftPath < 0) {
- cout << "Warning: negative drift path " << driftPath << endl;
- continue;
- } // end if driftPath < 0
-
- // Drift Time
- drTime = driftPath/driftSpeed; // drift time for segment.
- timeSample = (Int_t) (fScaleSize*drTime/timeStep + 1);
- // compute time Sample including tof information. The tof only
- // effects the time of the signal is recoreded and not the
- // the defusion.
- // timeSample = (Int_t) (fScaleSize*(drTime+tof)/timeStep + 1);
- if(timeSample > fScaleSize*fMaxNofSamples) {
- cout << "Warning: Wrong Time Sample: " << timeSample << endl;
- continue;
- } // end if timeSample > fScaleSize*fMaxNoofSamples
-
- // Anode
- xAnode = 10000.*(avAnode)/anodePitch + nofAnodes/2; // +1?
- if(xAnode*anodePitch > sddWidth || xAnode*anodePitch < 0.)
- cout << "Warning: Z = " << xAnode*anodePitch << endl;
- iAnode = (Int_t) (1.+xAnode); // xAnode?
- if(iAnode < 1 || iAnode > nofAnodes) {
- cout << "Warning: Wrong iAnode: " << iAnode << endl;
- continue;
- } // end if iAnode < 1 || iAnode > nofAnodes
-
- // store straight away the particle position in the array
- // of particles and take idhit=ii only when part is entering (this
- // requires FillModules() in the macro for analysis) :
-
- // Sigma along the anodes for track segment.
- sigA = TMath::Sqrt(2.*dfCoeff*drTime+s1*s1);
- sigT = sigA/driftSpeed;
- // Peak amplitude in nanoAmpere
- amplitude = fScaleSize*160.*depEnergy/
- (timeStep*eVpairs*2.*acos(-1.)*sigT*sigA);
- amplitude *= timeStep/25.; // WARNING!!!!! Amplitude scaling to
- // account for clock variations
- // (reference value: 40 MHz)
- chargeloss = 1.-cHloss*driftPath/1000;
- amplitude *= chargeloss;
- width = 2.*nsigma/(nlookups-1);
- // Spread the charge
- // Pixel index
- ndiv = 2;
- nmul = 3.;
- if(drTime > 1200.) {
- ndiv = 4;
- nmul = 1.5;
- } // end if drTime > 1200.
- // Sub-pixel index
- nsplit = 4; // hard-wired //nsplit=4;nsplit = (nsplit+1)/2*2;
- // Sub-pixel size see computation of aExpo and tExpo.
- aStep = anodePitch/(nsplit*fScaleSize*sigA);
- aConst = xAnode*anodePitch/sigA;
- tStep = timeStep/(nsplit*fScaleSize*sigT);
- tConst = drTime/sigT;
- // Define SDD window corresponding to the hit
- anodeWindow = (Int_t)(fScaleSize*nsigma*sigA/anodePitch+1);
- timeWindow = (Int_t) (fScaleSize*nsigma*sigT/timeStep+1.);
- jamin = (iAnode - anodeWindow/ndiv - 1)*fScaleSize*nsplit +1;
- jamax = (iAnode + anodeWindow/ndiv)*fScaleSize*nsplit;
- if(jamin <= 0) jamin = 1;
- if(jamax > fScaleSize*nofAnodes*nsplit)
- jamax = fScaleSize*nofAnodes*nsplit;
- // jtmin and jtmax are Hard-wired
- jtmin = (Int_t)(timeSample-timeWindow*nmul-1)*nsplit+1;
- jtmax = (Int_t)(timeSample+timeWindow*nmul)*nsplit;
- if(jtmin <= 0) jtmin = 1;
- if(jtmax > fScaleSize*fMaxNofSamples*nsplit)
- jtmax = fScaleSize*fMaxNofSamples*nsplit;
- // Spread the charge in the anode-time window
- for(ka=jamin; ka <=jamax; ka++) {
- ia = (ka-1)/(fScaleSize*nsplit) + 1;
- if(ia <= 0) { cout << "Warning: ia < 1: " << endl; continue; }
- if(ia > nofAnodes) ia = nofAnodes;
- aExpo = (aStep*(ka-0.5)-aConst);
- if(TMath::Abs(aExpo) > nsigma) anodeAmplitude = 0.;
- else {
- dummy = (Int_t) ((aExpo+nsigma)/width);
- anodeAmplitude = amplitude*fResponse->GausLookUp(dummy);
- } // end if TMath::Abs(aEspo) > nsigma
- // index starts from 0
- index = ((detector+1)%2)*nofAnodes+ia-1;
- if(anodeAmplitude) for(kt=jtmin; kt<=jtmax; kt++) {
- 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;
- tExpo = (tStep*(kt-0.5)-tConst);
- if(TMath::Abs(tExpo) > nsigma) timeAmplitude = 0.;
- else {
- dummy = (Int_t) ((tExpo+nsigma)/width);
- timeAmplitude = anodeAmplitude*
- fResponse->GausLookUp(dummy);
- } // end if TMath::Abs(tExpo) > nsigma
- // build the list of digits for this module
- arg[0] = index;
- arg[1] = it;
- arg[2] = itrack; // track number
- arg[3] = ii-1; // hit number.
- timeAmplitude *= norm;
- timeAmplitude *= 10;
- ListOfFiredCells(arg,timeAmplitude,alist,padr);
- } // end if anodeAmplitude and loop over time in window
- } // loop over anodes in window
- } // end loop over "sub-hits"
- } // end loop over hits
-
- // introduce the electronics effects and do zero-suppression if required
- Int_t nentries=alist->GetEntriesFast();
- if (nentries) {
- ChargeToSignal();
- const char *kopt=fResponse->ZeroSuppOption();
- ZeroSuppression(kopt);
- } // end if netries
-
- // clean memory
- alist->Delete();
- delete alist;
- padr->Delete();
- fHitMap1->ClearMap();
- fHitMap2->ClearMap();