//#include "AthenaKernel/IAtRndmGenSvc.h" #include "CLHEP/Random/RandFlat.h" #include "CLHEP/Random/RandGauss.h" #include "SCT1/MySCTcharge.h" #include ///////////////////////////////////////---------------- MySCTcharge::MySCTcharge(const std::string& name, ISvcLocator* pSvcLocator) : AthAlgorithm(name, pSvcLocator), m_rndmSvc("AtRndmGenSvc",name), m_rndmEngineName("MySCTcharge") // Algorithm(name, pSvcLocator),m_analysisTools( "AnalysisTools", this ) // , m_rndmEngineName(0) { //---------------setting basic parameters--------------------------- declareProperty("EfieldModel", m_model = 2); // model=2 for FEM field model declareProperty("IsSCTDigiModel", m_isSCTDigiModel = false); declareProperty("DepletionVoltage_VD", m_VD = 70.); // [Volt] declareProperty("BiasVoltage_VB", m_VB = 150.); // [Volt] declareProperty("MagneticField_B", m_B = -2.0); // [Tesla] declareProperty("Temperature_T", m_T = 273.15); declareProperty("TransportTimeStep", m_transportTimeStep = 0.25 ); declareProperty("TransportTimeMax", m_transportTimeMax = 25.0 ); declareProperty("X0", m_x0 = 5.0) ; // [micron] declareProperty("Y0", m_y0 = 20.0) ; // [micron] declareProperty("CoutLevel", m_coutLevel = 0); // specify printout level //------------------usually fixed------------------------------------- declareProperty("BulkDepth", m_bulk_depth = 0.0285); // in [cm] declareProperty("StripPitch", m_strip_pitch = 0.0080); // in [cm] } /////////////////////////////////////////////////////////////////////////////// MySCTcharge::~MySCTcharge() {} ////////////////////////////////////////////////////////////////////////////// StatusCode MySCTcharge::initialize() { StatusCode sc=StatusCode::SUCCESS; m_eventNumber = 0; initTransport(); //+++ Get the random generator engine m_sc = initRandomEngine(); if(m_sc.isFailure()) return StatusCode::FAILURE ; //////////////////////////////////////////////////////////// std::cout<<"EfieldModel\t"<< m_model <<"\t(default = 2)"<(" <(" <xfinal,istrip,dx=" <"<t_current="< 0.) { double REx = -Ex; // because electron has negative charge double REy = -Ey; // because electron has negative charge E = sqrt(Ex*Ex+Ey*Ey); mu_e = mud_e(E); v_e = mu_e * E; r_e = 1.13+0.0008*(m_T-273.15); tanLA_e = r_e * mu_e * (-m_B) * 1.E-4; // because e has negative charge secLA = sqrt(1.+tanLA_e*tanLA_e); cosLA=1./secLA; sinLA = tanLA_e / secLA; vy_e = v_e * (REy*cosLA - REx*sinLA)/E; vx_e = v_e * (REx*cosLA + REy*sinLA)/E; D_e = kB * m_T * mu_e/ e; return true; } else return false; } //--------------------------------------------------------------- // parameters for hole transport //--------------------------------------------------------------- bool MySCTcharge::hole(double x_h, double y_h, double &vx_h, double &vy_h, double &D_h) { double kB= 1.38E-23; // [m^2*kg/s^2/K] double e= 1.602E-19; // [Coulomb] double E, Ex, Ey, mu_h, v_h, r_h, tanLA_h, secLA, cosLA, sinLA; EField( x_h, y_h, Ex, Ey); // [V/cm] if( Ey > 0.) { E = sqrt(Ex*Ex+Ey*Ey); mu_h = mud_h(E); v_h = mu_h * E; r_h = 0.72 - 0.0005*(m_T-273.15); tanLA_h = r_h * mu_h * m_B * 1.E-4; secLA = sqrt(1.+tanLA_h*tanLA_h); cosLA=1./secLA; sinLA = tanLA_h / secLA; vy_h = v_h * (Ey*cosLA - Ex*sinLA)/E; vx_h = v_h * (Ex*cosLA + Ey*sinLA)/E; D_h = kB * m_T * mu_h/ e; return true; } else return false; } //------------------------------------------------------------------- // calculation od induced charge using Weighting (Ramo) function //------------------------------------------------------------------- double MySCTcharge::induced (int istrip, double x, double y) { // x and y are the coorlocation of charge (e or hole) // induced chardege on the strip "istrip" situated at the height y = d // the center of the strip (istrip=0) is x = 0.004 [cm] double deltax = 0.0005, deltay = 0.00025; if ( y < 0. || y > m_bulk_depth) return 0; double xc = m_strip_pitch * (istrip + 0.5); double dx = fabs( x-xc ); int ix = int( dx / deltax ); if ( ix > 80 ) return 0.; int iy = int( y / deltay ); double fx = (dx - ix*deltax) / deltax; double fy = ( y - iy*deltay) / deltay; int ix1 = ix + 1; int iy1 = iy + 1; double P = m_PotentialValue[ix][iy] *(1.-fx)*(1.-fy) + m_PotentialValue[ix1][iy] *fx*(1.-fy) + m_PotentialValue[ix][iy1] *(1.-fx)*fy + m_PotentialValue[ix1][iy1] *fx*fy ; // cout <<"x,y,iy="< xhalfpitch ) Ex = -Ex; Ey = Ey00*(1.-fx)*(1.-fy) + Ey10*fx*(1.-fy) + Ey01*(1.-fx)*fy + Ey11*fx*fy ; return; } //---------- case for uniform electriv field ------------------------ if( m_model ==0 ) { Ey = m_VB / m_depletion_depth ; return; } //---------- case for flat diode model ------------------------------ if(m_model==1) { if(m_VB > m_VD) Ey = (m_VB+m_VD)/m_depletion_depth - 2.*m_VD*(m_bulk_depth-y)/(m_bulk_depth*m_bulk_depth); else { double Emax = 2.* m_depletion_depth * m_VD / (m_bulk_depth*m_bulk_depth); Ey = Emax*(1-(m_bulk_depth-y)/m_depletion_depth); } return; } return; } //---------------------------------------------------------------------- // perpandicular Drift time calculation //---------------------------------------------------------------------- double MySCTcharge::Drift_Time( double zhit) { double denominator = m_VD + m_VB - (2.0*zhit*m_VD/m_bulk_depth); double driftTime = log((m_VD + m_VB)/denominator) ; driftTime *= m_bulk_depth * m_bulk_depth / (2.0 * m_driftMobility * m_VD); return driftTime ; } //---------------------------------------------------------------------- // Surface Drift time calculation //---------------------------------------------------------------------- double MySCTcharge::Drift_SurfaceTime(double ysurf) { double surfaceDriftTime ; if(ysurf<0.5) { double y = ysurf/ 0.5; surfaceDriftTime = 5.0e-9 * y * y; } else { double y = (1.0 - ysurf)/ 0.5 ; surfaceDriftTime = 1.e-8 + ( 5.e-9 - 1.e-8) * y * y; } return surfaceDriftTime ; } ///////////////////////////////////////////////////////////////////// //------------------------------------------------------------ // initialization of e/h transport programme //----------------------------------------------------------- void MySCTcharge::initTransport() { //------------------------ initialize subfunctions ------------ init_mud_h(m_T) ; init_mud_e(m_T) ; initExEyArray(); initPotentialValue(); //---------------------------------------------------------------- m_kB = 1.38E-23; // [m^2*kg/s^2/K] m_e = 1.602E-19; // [Coulomb] //------------ find delepletion deph for model=0 and 1 ------------- std::cout<<" model= "<< m_model<<" VB= "<< m_VB <<" B= "<< m_B << std::endl; m_depletion_depth = m_bulk_depth; if (m_VB < m_VD) m_depletion_depth = sqrt(m_VB/m_VD) * m_bulk_depth; // ----------- find for the case of model = 2---------------- if (m_model == 2) { double Ex, Ey; for ( double y = 0.; y < 0.0285 ; y += 0.00025 ) { EField(0., y, Ex, Ey); if ( Ey > 0.1 ) continue; m_depletion_depth = m_bulk_depth - y; } } m_y_origin_min = m_bulk_depth - m_depletion_depth; std::cout<<"------ initialization of e-h transport ------"<" ) ; return StatusCode::SUCCESS; }