* provided "as is" without express or implied warranty. *
**************************************************************************/
-/* $Id$ */
+/* $Id:$ */
//////////////////////////////////////////////////////
// Calibration class for set:ITS //
return m*kbqe*tT; // [cm^2/sec]
}
//______________________________________________________________________
+Double_t AliITSCalibration::LorentzAngleHole(Double_t B) const {
+ // Computes the Lorentz angle for electrons in Si
+ // Input: magnetic Field in KGauss
+ // Output: Lorentz angle in radians (positive if Bz is positive)
+ // Main Reference: NIM A 497 (2003) 389–396.
+ // "An algorithm for calculating the Lorentz angle in silicon detectors", V. Bartsch et al.
+ //
+ const Double_t krH=0.70; // Hall scattering factor for Hole
+ const Double_t kT0 = 300.; // reference Temperature (degree K).
+ const Double_t kmulow0 = 470.5; // cm^2/Volt-sec
+ const Double_t keT0 = -2.5; // Power of Temp.
+ const Double_t beta0 = 1.213; // beta coeff. at T0=300K
+ const Double_t keT1 = 0.17; // Power of Temp. for beta
+ const Double_t kvsat0 = 8.37E+06; // saturated velocity at T0=300K (cm/sec)
+ const Double_t keT2 = 0.52; // Power of Temp. for vsat
+ Double_t tT = fT;
+ Double_t eE= 1./fdv;
+ Double_t muLow=kmulow0*TMath::Power(tT/kT0,keT0);
+ Double_t beta=beta0*TMath::Power(tT/kT0,keT1);
+ Double_t vsat=kvsat0*TMath::Power(tT/kT0,keT2);
+ Double_t mu=muLow/TMath::Power(1+TMath::Power(muLow*eE/vsat,beta),1/beta);
+ Double_t angle=TMath::ATan(krH*mu*B*1.E-05); // Conversion Factor
+ return angle;
+}
+//______________________________________________________________________
+Double_t AliITSCalibration::LorentzAngleElectron(Double_t B) const {
+ // Computes the Lorentz angle for electrons in Si
+ // Input: magnetic Field in KGauss
+ // Output: Lorentz angle in radians (positive if Bz is positive)
+ // Main Reference: NIM A 497 (2003) 389–396.
+ // "An algorithm for calculating the Lorentz angle in silicon detectors", V. Bartsch et al.
+ //
+ const Double_t krH=1.15; // Hall scattering factor for Electron
+ const Double_t kT0 = 300.; // reference Temperature (degree K).
+ const Double_t kmulow0 = 1417.0; // cm^2/Volt-sec
+ const Double_t keT0 = -2.2; // Power of Temp.
+ const Double_t beta0 = 1.109; // beta coeff. at T0=300K
+ const Double_t keT1 = 0.66; // Power of Temp. for beta
+ const Double_t kvsat0 = 1.07E+07; // saturated velocity at T0=300K (cm/sec)
+ const Double_t keT2 = 0.87; // Power of Temp. for vsat
+ Double_t tT = fT;
+ Double_t eE= 1./fdv;
+ Double_t muLow=kmulow0*TMath::Power(tT/kT0,keT0);
+ Double_t beta=beta0*TMath::Power(tT/kT0,keT1);
+ Double_t vsat=kvsat0*TMath::Power(tT/kT0,keT2);
+ Double_t mu=muLow/TMath::Power(1+TMath::Power(muLow*eE/vsat,beta),1/beta);
+ Double_t angle=TMath::ATan(krH*mu*B*1.E-05);
+ return angle;
+}
+//______________________________________________________________________
Double_t AliITSCalibration::SpeedElectron() const {
// Computes the average speed for electrons in Si under the low-field
// approximation. [cm/sec].
**************************************************************************/
/*
-$Id$
+$Id:$
*/
#include <Riostream.h>
#include "AliITSsimulationSPD.h"
#include "AliLog.h"
#include "AliRun.h"
+#include "AliMagF.h"
//#define DEBUG
AliITSsimulation(),
fHis(0),
fSPDname(),
-fCoupling(){
+fCoupling(),
+fLorentz(kFALSE),
+fTanLorAng(0){
// Default constructor.
// Inputs:
// none.
AliITSsimulation(dettyp),
fHis(0),
fSPDname(),
-fCoupling(){
+fCoupling(),
+fLorentz(kFALSE),
+fTanLorAng(0){
// standard constructor
// Inputs:
// AliITSsegmentation *seg A pointer to the segmentation class
} else {
fCoupling=1;
} // end if
-
+ //SetLorentzDrift(kTRUE);
+ if (fLorentz) SetTanLorAngle();
+}
+//______________________________________________________________________
+Bool_t AliITSsimulationSPD::SetTanLorAngle(Double_t WeightHole) {
+ // This function set the Tangent of the Lorentz angle.
+ // A weighted average is used for electrons and holes
+ // Input: Double_t WeightHole: wheight for hole: it should be in the range [0,1]
+ // output: Bool_t : kTRUE in case of success
+ //
+ if(!fDetType) {
+ AliError("AliITSsimulationSPD::SetTanLorAngle: AliITSDetTypeSim* fDetType not set ");
+ return kFALSE;}
+ if(WeightHole<0) {
+ WeightHole=0.;
+ AliWarning("AliITSsimulationSPD::SetTanLorAngle: You have asked for negative Hole weight");
+ AliWarning("AliITSsimulationSPD::SetTanLorAngle: I'm going to use only electrons");
+ }
+ if(WeightHole>1) {
+ WeightHole=1.;
+ AliWarning("AliITSsimulationSPD::SetTanLorAngle: You have asked for weight > 1");
+ AliWarning("AliITSsimulationSPD::SetTanLorAngle: I'm going to use only holes");
+ }
+ Double_t WeightEle=1.-WeightHole;
+ AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
+ AliMagF *mf = gAlice->Field();
+ Float_t pos[3]={0.,0.,0.};
+ Float_t B[3]={0.,0.,0.};
+ mf->Field(pos,B);
+ fTanLorAng = TMath::Tan(WeightHole*res->LorentzAngleHole(B[2]) +
+ WeightEle*res->LorentzAngleElectron(B[2]));
+ fTanLorAng*=-1.; // this only for the old geometry
+ // comment the upper line for the new geometry
+ return kTRUE;
}
//______________________________________________________________________
AliITSsimulationSPD::~AliITSsimulationSPD(){
&s) : AliITSsimulation(s),
fHis(s.fHis),
fSPDname(s.fSPDname),
-fCoupling(s.fCoupling){
+fCoupling(s.fCoupling),
+fLorentz(s.fLorentz),
+fTanLorAng(s.fTanLorAng){
// Copy Constructor
// Inputs:
// AliITSsimulationSPD &s The original class for which
this->fHis = s.fHis;
fCoupling = s.fCoupling;
fSPDname = s.fSPDname;
+ fLorentz = s.fLorentz;
+ fTanLorAng = s.fTanLorAng;
return *this;
}
//______________________________________________________________________
Int_t nhits = hits->GetEntriesFast();
Int_t h,ix,iz,i;
Int_t idtrack;
- Double_t x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0,de=0.0;
+ Double_t x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0,de=0.0,ld=0.0;
Double_t x,y,z,t,tp,st,dt=0.2,el,sig,sigx,sigz,fda;
AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
<<" de="<<de<<endl;
} // end if GetDebug
sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
- // SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
sigx=sig;
sigz=sig*fda;
- SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
- cout << "sigx, sigz, y "<< sigx << " " << sigz<< " " << TMath::Abs(thick + y) << endl;// ciccio
+ if (fLorentz) ld=(y+thick)*fTanLorAng;
+ SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,ld,idtrack,h);
} // end for t
} else { // st == 0.0 deposit it at this point
x = x0;
if(!(seg->LocalToDet(x,z,ix,iz))) continue; // outside
el = res->GeVToCharge((Double_t)de);
sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
- // SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
sigx=sig;
sigz=sig*fda;
- SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
+ if (fLorentz) ld=(y+thick)*fTanLorAng;
+ SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,ld,idtrack,h);
} // end if st>0.0
} // Loop over all hits h
Int_t nhits = hits->GetEntriesFast();
Int_t h,ix,iz,i;
Int_t idtrack;
- Double_t x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0,de=0.0;
+ Double_t x0=0.0,x1=0.0,y0=0.0,y1=0.0,z0=0.0,z1=0.0,de=0.0,ld=0.0;
Double_t x,y,z,t,st,el,sig,sigx,sigz,fda;
AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
AliITSCalibrationSPD* res = (AliITSCalibrationSPD*)GetCalibrationModel(fDetType->GetITSgeom()->GetStartSPD());
sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
sigx=sig;
sigz=sig*fda;
- //SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
- SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
+ if (fLorentz) ld=(y+thick)*fTanLorAng;
+ SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,ld,idtrack,h);
// cout << "sigx sigz " << sigx << " " << sigz << endl; // dom
} // end for i // End Integrate over t
else { // st == 0.0 deposit it at this point
if(!(seg->LocalToDet(x,z,ix,iz))) continue; // outside
el = res->GeVToCharge((Double_t)de);
sig = res->SigmaDiffusion1D(TMath::Abs(thick + y));
- //SpreadCharge(x,z,ix,iz,el,sig,idtrack,h);
sigx=sig;
sigz=sig*fda;
- SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,idtrack,h);
+ if (fLorentz) ld=(y+thick)*fTanLorAng;
+ SpreadChargeAsym(x,z,ix,iz,el,sigx,sigz,ld,idtrack,h);
} // end if st>0.0
} // Loop over all hits h
//______________________________________________________________________
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){
+ Double_t el,Double_t sig,Double_t ld,
+ 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)
+ // if fLorentz=kTRUE, then x0=x0+ld (Lorentz drift taken into account)
// 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)
+ // Double_t ld lorentz drift in x for this step (y0 dependent)
// Int_t t track number
// Int_t ti hit track index number
// Int_t hi hit "hit" index number
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
+ x1 -= x0+ld; // Distance from where track traveled (taking into account the Lorentz drift)
+ x2 -= x0+ld; // Distance from where track traveled (taking into account the Lorentz drift)
z1 -= z0; // Distance from where track traveled
z2 -= z0; // Distance from where track traveled
s = 0.25; // Correction based on definision of Erfc
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){
+ Double_t ld,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)
+ // if fLorentz=kTRUE, then x0=x0+ld (Lorentz drift taken into account)
// 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)
+ // Double_t ld lorentz drift in x for this stip (y0 dependent)
// Int_t t track number
// Int_t ti hit track index number
// Int_t hi hit "hit" index number
AliITSsegmentationSPD* seg = (AliITSsegmentationSPD*)GetSegmentationModel(0);
- if(GetDebug(4)) Info("SpreadCharge","(x0=%e,z0=%e,ix0=%d,iz0=%d,el=%e,"
+ if(GetDebug(4)) Info("SpreadChargeAsym","(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);
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
+ x1 -= x0+ld; // Distance from where track traveled (taking into account the Lorentz drift)
+ x2 -= x0+ld; // Distance from where track traveled (taking into account the Lorentz drift)
z1 -= z0; // Distance from where track traveled
z2 -= z0; // Distance from where track traveled
s = 0.25; // Correction based on definision of Erfc
/* Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
* See cxx source for full Copyright notice */
-/* $Id$ */
+/* $Id:$ */
////////////////////////////////////////////////////////////
// Simulation class for SPD //
void HitToSDigitFast(AliITSmodule *mod);
// Removes dead pixels from pList
void RemoveDeadPixels(AliITSmodule *mod);
- // Take pList of signals and apply noise... create Digis
+ // Take pList of signals and apply noise... create Digits
void FrompListToDigits();
+ // This set the Lorentz drift of Electrons and Holes: by deafult equal weights to Electrons and Holes
+ void SetLorentzDrift(Bool_t b=kFALSE)
+ {fLorentz=b; if(fLorentz) SetTanLorAngle();};
+ // This function set the relative contribution between holes and electrons: use 0<=WeightHole<=1
+ Bool_t SetTanLorAngle(Double_t WeightHole=0.5);
+ // Getter for the Lorentz angle
+ Double_t GetTanLorAngle(){return fTanLorAng;};
//
void CreateHistograms();
void FillHistograms(Int_t ix,Int_t iz,Double_t v=1.0);
private:
void 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);
+ Double_t el,Double_t sig,Double_t ld,Int_t t,Int_t hi);
void 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);
+ Double_t el,Double_t sigx,Double_t sigz,Double_t ld,Int_t t,Int_t hi);
void UpdateMapSignal(Int_t ix,Int_t iz,Int_t trk,Int_t ht,Double_t signal){
// This function adds a signal to the pList from the pList class
// Inputs: iz column number ix row number trk track number ht hit number signal signal strength
TString fSPDname; //! Histogram name
Int_t fCoupling; // Sets the coupling to be used.
// ==1 use SetCoupling, ==2 use SetCouplingOld
- ClassDef(AliITSsimulationSPD,2) // Simulation of SPD clusters
+ Bool_t fLorentz; // kTRUE if Lorentz drift has been allowed
+ Double_t fTanLorAng; //! Tangent of the Lorentz Angle (weighted average for hole and electrons)
+ ClassDef(AliITSsimulationSPD,3) // Simulation of SPD clusters
};
#endif
+