-void AliITSsimulationSPD::ChargeSharing(Float_t x1l,Float_t z1l,Float_t x2l,
- Float_t z2l,Int_t c1,Int_t r1,Int_t c2,
- Int_t r2,Float_t etot,
- Int_t &npixel,Int_t *frowpixel,
- Int_t *fcolpixel,Double_t *fenepixel){
- // Take into account the geometrical charge sharing when the track
- // crosses more than one pixel.
- //
- //Begin_Html
- /*
- <img src="picts/ITS/barimodel_2.gif">
- </pre>
- <br clear=left>
- <font size=+2 color=red>
- <a href="mailto:Rocco.Caliandro@ba.infn.it"></a>.
- </font>
- <pre>
- */
- //End_Html
- Float_t xa,za,xb,zb,dx,dz,dtot,dm,refr,refm,refc;
- Float_t refn=0.;
- Float_t arefm, arefr, arefn, arefc, azb, az2l, axb, ax2l;
- Int_t dirx,dirz,rb,cb;
- Int_t flag,flagrow,flagcol;
- Double_t epar;
-
- npixel = 0;
- xa = x1l;
- za = z1l;
- dx = TMath::Abs(x1l-x2l);
- dz = TMath::Abs(z1l-z2l);
- dtot = TMath::Sqrt((dx*dx)+(dz*dz));
- dm = (x2l - x1l) / (z2l - z1l);
- dirx = (Int_t) ((x2l - x1l) / dx);
- dirz = (Int_t) ((z2l - z1l) / dz);
-
- // calculate the x coordinate of the pixel in the next column
- // and the z coordinate of the pixel in the next row
- Float_t xpos, zpos;
-
- fSegmentation->GetPadCxz(c1, r1-1, xpos, zpos);
-
- Float_t xsize = fSegmentation->Dpx(0);
- Float_t zsize = fSegmentation->Dpz(r1-1);
-
- if (dirx == 1) refr = xpos+xsize/2.;
- else refr = xpos-xsize/2.;
-
- if (dirz == 1) refn = zpos+zsize/2.;
- else refn = zpos-zsize/2.;
-
- flag = 0;
- flagrow = 0;
- flagcol = 0;
- do{
- // calculate the x coordinate of the intersection with the pixel
- // in the next cell in row direction
- refm = (refn - z1l)*dm + x1l;
-
- // calculate the z coordinate of the intersection with the pixel
- // in the next cell in column direction
- refc = (refr - x1l)/dm + z1l;
-
- arefm = refm * dirx;
- arefr = refr * dirx;
- arefn = refn * dirz;
- arefc = refc * dirz;
-
- if ((arefm < arefr) && (arefn < arefc)){
- // the track goes in the pixel in the next cell in row direction
- xb = refm;
- zb = refn;
- cb = c1;
- rb = r1 + dirz;
- azb = zb * dirz;
- az2l = z2l * dirz;
- if (rb == r2) flagrow=1;
- if (azb > az2l) {
- zb = z2l;
- xb = x2l;
- } // end if
- // shift to the pixel in the next cell in row direction
- Float_t zsizeNext = fSegmentation->Dpz(rb-1);
- //to account for cell at the borders of the detector
- if(zsizeNext==0) zsizeNext = zsize;
- refn += zsizeNext*dirz;
- }else {
- // the track goes in the pixel in the next cell in column direction
- xb = refr;
- zb = refc;
- cb = c1 + dirx;
- rb = r1;
- axb = xb * dirx;
- ax2l = x2l * dirx;
- if (cb == c2) flagcol=1;
- if (axb > ax2l) {
- zb = z2l;
- xb = x2l;
- } // end ifaxb > ax2l
-
- // shift to the pixel in the next cell in column direction
- Float_t xsizeNext = fSegmentation->Dpx(cb-1);
- //to account for cell at the borders of the detector
- if(xsizeNext==0) xsizeNext = xsize;
- refr += xsizeNext*dirx;
- } // end if (arefm < arefr) && (arefn < arefc)
-
- //calculate the energy lost in the crossed pixel
- epar = TMath::Sqrt((xb-xa)*(xb-xa)+(zb-za)*(zb-za));
- epar = etot*(epar/dtot);
-
- //store row, column and energy lost in the crossed pixel
- frowpixel[npixel] = r1;
- fcolpixel[npixel] = c1;
- fenepixel[npixel] = epar;
- npixel++;
-
- // the exit point of the track is reached
- if (epar == 0) flag = 1;
- if ((r1 == r2) && (c1 == c2)) flag = 1;
- if (flag!=1) {
- r1 = rb;
- c1 = cb;
- xa = xb;
- za = zb;
- } // end if flag!=1
- } while (flag==0);
+void AliITSsimulationSPD::SpreadCharge(Double_t x0,Double_t z0,
+ Int_t ix0,Int_t iz0,
+ Double_t el,Double_t sig,Int_t t,
+ Int_t hi){
+ // Spreads the charge over neighboring cells. Assume charge is distributed
+ // as charge(x,z) = (el/2*pi*sig*sig)*exp(-arg)
+ // arg=((x-x0)*(x-x0)/2*sig*sig)+((z-z0*z-z0)/2*sig*sig)
+ // Defined this way, the integral over all x and z is el.
+ // Inputs:
+ // Double_t x0 x position of point where charge is liberated
+ // Double_t y0 y position of point where charge is liberated
+ // Double_t z0 z position of point where charge is liberated
+ // Int_t ix0 row of cell corresponding to point x0
+ // Int_t iz0 columb of cell corresponding to point z0
+ // Double_t el number of electrons liberated in this step
+ // Double_t sig Sigma difusion for this step (y0 dependent)
+ // Int_t t track number
+ // Int_t ti hit track index number
+ // Int_t hi hit "hit" index number
+ // Outputs:
+ // none.
+ // Return:
+ // none.
+ const Int_t knx = 3,knz = 2;
+ const Double_t kRoot2 = 1.414213562; // Sqrt(2).
+ const Double_t kmictocm = 1.0e-4; // convert microns to cm.
+ Int_t ix,iz,ixs,ixe,izs,ize;
+ Float_t x,z;
+ Double_t x1,x2,z1,z2,s,sp;
+ AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
+
+
+ if(GetDebug(4)) Info("SpreadCharge","(x0=%e,z0=%e,ix0=%d,iz0=%d,el=%e,"
+ "sig=%e,t=%d,i=%d)",x0,z0,ix0,iz0,el,sig,t,hi);
+ if(sig<=0.0) { // if sig<=0 No diffusion to simulate.
+ GetMap()->AddSignal(iz0,ix0,t,hi,GetModuleNumber(),el);
+ if(GetDebug(2)){
+ cout << "sig<=0.0=" << sig << endl;
+ } // end if GetDebug
+ return;
+ } // end if
+ sp = 1.0/(sig*kRoot2);
+ if(GetDebug(2)){
+ cout << "sig=" << sig << " sp=" << sp << endl;
+ } // end if GetDebug
+ ixs = TMath::Max(-knx+ix0,0);
+ ixe = TMath::Min(knx+ix0,seg->Npx()-1);
+ izs = TMath::Max(-knz+iz0,0);
+ ize = TMath::Min(knz+iz0,seg->Npz()-1);
+ for(ix=ixs;ix<=ixe;ix++) for(iz=izs;iz<=ize;iz++){
+ seg->DetToLocal(ix,iz,x,z); // pixel center
+ x1 = x;
+ z1 = z;
+ x2 = x1 + 0.5*kmictocm*seg->Dpx(ix); // Upper
+ x1 -= 0.5*kmictocm*seg->Dpx(ix); // Lower
+ z2 = z1 + 0.5*kmictocm*seg->Dpz(iz); // Upper
+ z1 -= 0.5*kmictocm*seg->Dpz(iz); // Lower
+ x1 -= x0; // Distance from where track traveled
+ x2 -= x0; // Distance from where track traveled
+ z1 -= z0; // Distance from where track traveled
+ z2 -= z0; // Distance from where track traveled
+ s = 0.25; // Correction based on definision of Erfc
+ s *= TMath::Erfc(sp*x1) - TMath::Erfc(sp*x2);
+ if(GetDebug(3)){
+ cout <<"el="<<el<<" ix0="<<ix0<<" ix="<<ix<<" x0="<<x<<
+ " iz0="<<iz0<<" iz="<<iz<<" z0="<<z<<
+ " sp*x1="<<sp*x1<<" sp*x2="<<sp*x2<<" s="<<s;
+ } // end if GetDebug
+ s *= TMath::Erfc(sp*z1) - TMath::Erfc(sp*z2);
+ if(GetDebug(3)){
+ cout<<" sp*z1="<<sp*z1<<" sp*z2="<<sp*z2<<" s="<<s<< endl;
+ } // end if GetDebug
+ GetMap()->AddSignal(iz,ix,t,hi,GetModuleNumber(),s*el);
+ } // end for ix, iz
+}
+//______________________________________________________________________
+void AliITSsimulationSPD::SpreadChargeAsym(Double_t x0,Double_t z0,
+ Int_t ix0,Int_t iz0,
+ Double_t el,Double_t sigx,Double_t sigz,
+ Int_t t,Int_t hi){
+ // Spreads the charge over neighboring cells. Assume charge is distributed
+ // as charge(x,z) = (el/2*pi*sigx*sigz)*exp(-arg)
+ // arg=((x-x0)*(x-x0)/2*sigx*sigx)+((z-z0*z-z0)/2*sigz*sigz)
+ // Defined this way, the integral over all x and z is el.
+ // Inputs:
+ // Double_t x0 x position of point where charge is liberated
+ // Double_t y0 y position of point where charge is liberated
+ // Double_t z0 z position of point where charge is liberated
+ // Int_t ix0 row of cell corresponding to point x0
+ // Int_t iz0 columb of cell corresponding to point z0
+ // Double_t el number of electrons liberated in this step
+ // Double_t sigx Sigma difusion along x for this step (y0 dependent)
+ // Double_t sigz Sigma difusion along z for this step (y0 dependent)
+ // Int_t t track number
+ // Int_t ti hit track index number
+ // Int_t hi hit "hit" index number
+ // Outputs:
+ // none.
+ // Return:
+ // none.
+ const Int_t knx = 3,knz = 2;
+ const Double_t kRoot2 = 1.414213562; // Sqrt(2).
+ const Double_t kmictocm = 1.0e-4; // convert microns to cm.
+ Int_t ix,iz,ixs,ixe,izs,ize;
+ Float_t x,z;
+ Double_t x1,x2,z1,z2,s,spx,spz;
+ AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
+
+
+ if(GetDebug(4)) Info("SpreadCharge","(x0=%e,z0=%e,ix0=%d,iz0=%d,el=%e,"
+ "sig=%e,t=%d,i=%d)",x0,z0,ix0,iz0,el,sigx,sigz,t,hi);
+ if(sigx<=0.0 || sigz<=0.0) { // if sig<=0 No diffusion to simulate.
+ GetMap()->AddSignal(iz0,ix0,t,hi,GetModuleNumber(),el);
+ if(GetDebug(2)){
+ cout << "sigx<=0.0=" << sigx << endl;
+ cout << "sigz<=0.0=" << sigz << endl;
+ } // end if GetDebug
+ return;
+ } // end if
+ spx = 1.0/(sigx*kRoot2); spz = 1.0/(sigz*kRoot2);
+ if(GetDebug(2)){
+ cout << "sigx=" << sigx << " spx=" << spx << endl;
+ cout << "sigz=" << sigz << " spz=" << spz << endl;
+ } // end if GetDebug
+ ixs = TMath::Max(-knx+ix0,0);
+ ixe = TMath::Min(knx+ix0,seg->Npx()-1);
+ izs = TMath::Max(-knz+iz0,0);
+ ize = TMath::Min(knz+iz0,seg->Npz()-1);
+ for(ix=ixs;ix<=ixe;ix++) for(iz=izs;iz<=ize;iz++){
+ seg->DetToLocal(ix,iz,x,z); // pixel center
+ x1 = x;
+ z1 = z;
+ x2 = x1 + 0.5*kmictocm*seg->Dpx(ix); // Upper
+ x1 -= 0.5*kmictocm*seg->Dpx(ix); // Lower
+ z2 = z1 + 0.5*kmictocm*seg->Dpz(iz); // Upper
+ z1 -= 0.5*kmictocm*seg->Dpz(iz); // Lower
+ x1 -= x0; // Distance from where track traveled
+ x2 -= x0; // Distance from where track traveled
+ z1 -= z0; // Distance from where track traveled
+ z2 -= z0; // Distance from where track traveled
+ s = 0.25; // Correction based on definision of Erfc
+ s *= TMath::Erfc(spx*x1) - TMath::Erfc(spx*x2);
+ if(GetDebug(3)){
+ cout <<"el="<<el<<" ix0="<<ix0<<" ix="<<ix<<" x0="<<x<<
+ " iz0="<<iz0<<" iz="<<iz<<" z0="<<z<<
+ " spx*x1="<<spx*x1<<" spx*x2="<<spx*x2<<" s="<<s;
+ } // end if GetDebug
+ s *= TMath::Erfc(spz*z1) - TMath::Erfc(spz*z2);
+ if(GetDebug(3)){
+ cout<<" spz*z1="<<spz*z1<<" spz*z2="<<spz*z2<<" s="<<s<< endl;
+ } // end if GetDebug
+ GetMap()->AddSignal(iz,ix,t,hi,GetModuleNumber(),s*el);
+ } // end for ix, iz
+}
+//______________________________________________________________________
+void AliITSsimulationSPD::RemoveDeadPixels(AliITSmodule *mod){
+ // Removes dead pixels on each module (ladder)
+ // Inputs:
+ // Module Index (0,239)
+ // Outputs:
+ // none.
+ // Return:
+ // none.
+
+ Int_t moduleNr = mod->GetIndex();
+ Int_t nrDead = fCalObj[moduleNr]->GetNrDead();
+ for (Int_t i=0; i<nrDead; i++) {
+ GetMap()->DeleteHit(fCalObj[moduleNr]->GetDeadColAt(i),fCalObj[moduleNr]->GetDeadRowAt(i));
+ }
+}
+//______________________________________________________________________
+void AliITSsimulationSPD::FrompListToDigits(){
+ // add noise and electronics, perform the zero suppression and add the
+ // digit to the list
+ // Inputs:
+ // none.
+ // Outputs:
+ // none.
+ // Return:
+ // none.
+ static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
+ Int_t j,ix,iz;
+ Double_t electronics;
+ Double_t sig;
+ const Int_t knmaxtrk=AliITSdigitSPD::GetNTracks();
+ static AliITSdigitSPD dig;
+ AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
+ if(GetDebug(1)) Info("FrompListToDigits","()");
+ for(iz=0; iz<GetNPixelsZ(); iz++) for(ix=0; ix<GetNPixelsX(); ix++){
+// NEW (for the moment plugged by hand, in the future possibly read from Data Base)
+// here parametrize the efficiency of the pixel along the row for the test columns (1,9,17,25)
+// if(iz==1 || iz == 9 || iz == 17 || iz == 25) {
+// Double_t eff,p1=0.,p2=0.;
+// Double_t x=ix;
+// switch (iz) {
+// case 1: p1=0.63460;p2=0.42438E-01;break;
+// case 9: p1=0.41090;p2=0.75914E-01;break;
+// case 17: p1=0.31883;p2=0.91502E-01;break;
+// case 25: p1=0.48828;p2=0.57975E-01;break;
+// } // end switch
+// eff=1.-p1*exp(-p2*x);
+// if (gRandom->Rndm() >= eff) continue;
+// } // end if
+ // END parametrize the efficiency
+ //
+ electronics = res->ApplyBaselineAndNoise();
+ UpdateMapNoise(ix,iz,electronics);
+ //
+ // Apply Threshold and write Digits.
+ sig = GetMap()->GetSignalOnly(iz,ix);
+ FillHistograms(ix,iz,sig+electronics);
+ if(GetDebug(3)){
+ cout<<sig<<"+"<<electronics<<">threshold("<<ix<<","<<iz
+ <<")="<<GetThreshold() <<endl;
+ } // end if GetDebug
+ if (sig+electronics <= GetThreshold()) continue;
+ dig.SetCoord1(iz);
+ dig.SetCoord2(ix);
+ dig.SetSignal(1);
+
+// dig.SetSignalSPD((Int_t) GetMap()->GetSignal(iz,ix));
+ Double_t aSignal = GetMap()->GetSignal(iz,ix);
+ if (TMath::Abs(aSignal)>2147483647.0) {
+ //PH 2147483647 is the max. integer
+ //PH This apparently is a problem which needs investigation
+ AliWarning(Form("Too big or too small signal value %f",aSignal));
+ aSignal = TMath::Sign((Double_t)2147483647,aSignal);
+ }
+ dig.SetSignalSPD((Int_t)aSignal);
+
+ for(j=0;j<knmaxtrk;j++){
+ if (j<GetMap()->GetNEntries()) {
+ dig.SetTrack(j,GetMap()->GetTrack(iz,ix,j));
+ dig.SetHit(j,GetMap()->GetHit(iz,ix,j));
+ }else { // Default values
+ dig.SetTrack(j,-3);
+ dig.SetHit(j,-1);
+ } // end if GetMap()
+ } // end for j
+ if(GetDebug(3)){
+ cout<<iz<<","<<ix<<","<<*(GetMap()->GetpListItem(iz,ix))<<endl;
+ } // end if GetDebug
+ aliITS->AddSimDigit(0,&dig);
+ } // for ix/iz