From a4005be718bdbeb92609b2d3234337f2f028f848 Mon Sep 17 00:00:00 2001 From: masera Date: Tue, 19 Feb 2008 11:40:07 +0000 Subject: [PATCH] Possibility of switching on Lorentz drift in SPD (G. Bruno) --- ITS/AliITSCalibration.cxx | 52 +++++++++++++++++++- ITS/AliITSCalibration.h | 5 ++ ITS/AliITSsimulationSPD.cxx | 95 +++++++++++++++++++++++++++---------- ITS/AliITSsimulationSPD.h | 20 ++++++-- 4 files changed, 140 insertions(+), 32 deletions(-) diff --git a/ITS/AliITSCalibration.cxx b/ITS/AliITSCalibration.cxx index 269ef51ab67..f8a159f378b 100644 --- a/ITS/AliITSCalibration.cxx +++ b/ITS/AliITSCalibration.cxx @@ -13,7 +13,7 @@ * provided "as is" without express or implied warranty. * **************************************************************************/ -/* $Id$ */ +/* $Id:$ */ ////////////////////////////////////////////////////// // Calibration class for set:ITS // @@ -198,6 +198,56 @@ Double_t AliITSCalibration::DiffusionCoefficientHole() const { 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]. diff --git a/ITS/AliITSCalibration.h b/ITS/AliITSCalibration.h index 499f111e869..4acd23ea66d 100644 --- a/ITS/AliITSCalibration.h +++ b/ITS/AliITSCalibration.h @@ -3,6 +3,8 @@ /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ +/* $Id:$ */ + ////////////////////////////////////////////// // Base ITS calibration class // ////////////////////////////////////////////// @@ -122,6 +124,9 @@ class AliITSCalibration : public TObject { // voltage v [volt] through a distance d [cm] in any material at a // temperature T [degree K]. virtual Double_t SigmaDiffusion1D(Double_t l) const; + // Computes the Lorentz angle for Electron and Hole, under the Magnetic field bz (in kGauss) + virtual Double_t LorentzAngleElectron(Double_t bz) const; + virtual Double_t LorentzAngleHole(Double_t bz) const; // Compute the thickness of the depleted region in a Si detector, version A virtual Double_t DepletedRegionThicknessA(Double_t dopCons, Double_t voltage, diff --git a/ITS/AliITSsimulationSPD.cxx b/ITS/AliITSsimulationSPD.cxx index 4381468afea..5561132c9d8 100644 --- a/ITS/AliITSsimulationSPD.cxx +++ b/ITS/AliITSsimulationSPD.cxx @@ -14,7 +14,7 @@ **************************************************************************/ /* -$Id$ +$Id:$ */ #include @@ -30,6 +30,7 @@ $Id$ #include "AliITSsimulationSPD.h" #include "AliLog.h" #include "AliRun.h" +#include "AliMagF.h" //#define DEBUG @@ -55,7 +56,9 @@ AliITSsimulationSPD::AliITSsimulationSPD(): AliITSsimulation(), fHis(0), fSPDname(), -fCoupling(){ +fCoupling(), +fLorentz(kFALSE), +fTanLorAng(0){ // Default constructor. // Inputs: // none. @@ -72,7 +75,9 @@ AliITSsimulationSPD::AliITSsimulationSPD(AliITSDetTypeSim *dettyp): AliITSsimulation(dettyp), fHis(0), fSPDname(), -fCoupling(){ +fCoupling(), +fLorentz(kFALSE), +fTanLorAng(0){ // standard constructor // Inputs: // AliITSsegmentation *seg A pointer to the segmentation class @@ -118,7 +123,40 @@ void AliITSsimulationSPD::Init(){ } 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(){ @@ -141,7 +179,9 @@ AliITSsimulationSPD::AliITSsimulationSPD(const &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 @@ -166,6 +206,8 @@ AliITSsimulationSPD& AliITSsimulationSPD::operator=(const this->fHis = s.fHis; fCoupling = s.fCoupling; fSPDname = s.fSPDname; + fLorentz = s.fLorentz; + fTanLorAng = s.fTanLorAng; return *this; } //______________________________________________________________________ @@ -313,7 +355,7 @@ void AliITSsimulationSPD::HitToSDigit(AliITSmodule *mod){ 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()); @@ -345,11 +387,10 @@ void AliITSsimulationSPD::HitToSDigit(AliITSmodule *mod){ <<" de="<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; @@ -358,10 +399,10 @@ void AliITSsimulationSPD::HitToSDigit(AliITSmodule *mod){ 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 @@ -411,7 +452,7 @@ void AliITSsimulationSPD::HitToSDigitFast(AliITSmodule *mod){ 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()); @@ -445,8 +486,8 @@ void AliITSsimulationSPD::HitToSDigitFast(AliITSmodule *mod){ 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 @@ -456,10 +497,10 @@ void AliITSsimulationSPD::HitToSDigitFast(AliITSmodule *mod){ 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 @@ -490,20 +531,21 @@ void AliITSsimulationSPD::HitToSDigitFast(AliITSmodule *mod){ //______________________________________________________________________ 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 @@ -545,8 +587,8 @@ void AliITSsimulationSPD::SpreadCharge(Double_t x0,Double_t z0, 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 @@ -567,20 +609,21 @@ void AliITSsimulationSPD::SpreadCharge(Double_t x0,Double_t z0, 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 @@ -597,7 +640,7 @@ void AliITSsimulationSPD::SpreadChargeAsym(Double_t x0,Double_t z0, 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); @@ -624,8 +667,8 @@ void AliITSsimulationSPD::SpreadChargeAsym(Double_t x0,Double_t z0, 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 diff --git a/ITS/AliITSsimulationSPD.h b/ITS/AliITSsimulationSPD.h index 36a8a9b9fed..bf1e549202a 100644 --- a/ITS/AliITSsimulationSPD.h +++ b/ITS/AliITSsimulationSPD.h @@ -4,7 +4,7 @@ /* Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ -/* $Id$ */ +/* $Id:$ */ //////////////////////////////////////////////////////////// // Simulation class for SPD // @@ -54,8 +54,15 @@ class AliITSsimulationSPD : public AliITSsimulation { 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); @@ -73,9 +80,9 @@ class AliITSsimulationSPD : public AliITSsimulation { 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 @@ -111,6 +118,9 @@ class AliITSsimulationSPD : public AliITSsimulation { 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 + -- 2.43.5