27 { -180., -150., -120., -90., -60., -30., 0., 30., 70.};
29 {
"M180",
"M150",
"M120",
"M90",
"M60",
"M30",
"0",
"30",
"70"};
36 m_data.resize(maxHash);
44 const ToolHandle<ISiliconConditionsTool>& siConditionsTool,
45 CLHEP::HepRandomEngine* rndmEngine,
46 const EventContext& ctx)
const {
47 std::lock_guard<std::mutex> lock(
m_mutex);
51 if (p_data)
return p_data;
53 ATH_MSG_DEBUG(
"--- Induced Charged Model Paramter (Begin) --------");
55 HepGeom::Point3D<double> localpos(0., 0., 0.);
57 double point[3] = {globalpos.x(), globalpos.y(), globalpos.z()};
58 double field[3] = {0., 0., 0.};
62 const Amg::Vector3D magneticField(field[0], field[1], field[2]);
65 std::unique_ptr<SCT_InducedChargeModelData>
data =
66 std::make_unique<SCT_InducedChargeModelData>(vdepl,
81 ATH_MSG_DEBUG(
" EFieldModel 0 (Flat Diode Model), 1 (FEM solusions) 2 (uniform E)\t"<<
data->m_EFieldModel);
94 ATH_MSG_DEBUG(
"--- Induced Charged Model Paramter (End) ---------");
106 const double x0,
const double y0,
107 double* Q_m2,
double* Q_m1,
double* Q_00,
double* Q_p1,
double* Q_p2,
109 const ToolHandle<ISiPropertiesTool>& siPropertiesTool,
110 const EventContext& ctx)
const {
123 bool isInBulk =
true;
124 double t_current = 0.;
131 if (!isInBulk)
break;
150 x += vx * dt / Gaudi::Units::second;
151 double diffusion = std::sqrt(2.* D * dt / Gaudi::Units::second);
152 y += diffusion * CLHEP::RandGaussZiggurat::shoot(
data.m_rndmEngine, 0.0, 1.0);
153 x += diffusion * CLHEP::RandGaussZiggurat::shoot(
data.m_rndmEngine, 0.0, 1.0);
170 double dq = qnew - qstrip[jj];
176 case -2: Q_m2[jt] += dq;
break;
177 case -1: Q_m1[jt] += dq;
break;
178 case 0: Q_00[jt] += dq;
break;
179 case +1: Q_p1[jt] += dq;
break;
180 case +2: Q_p2[jt] += dq;
break;
192 const double x0,
const double y0,
193 double* Q_m2,
double* Q_m1,
double* Q_00,
double* Q_p1,
double* Q_p2,
195 const ToolHandle<ISiPropertiesTool>& siPropertiesTool,
196 const EventContext& ctx)
const {
202 Q_m2, Q_m1, Q_00, Q_p1, Q_p2,
212 const double x0,
const double y0,
213 double* Q_m2,
double* Q_m1,
double* Q_00,
double* Q_p1,
double* Q_p2,
215 const ToolHandle<ISiPropertiesTool>& siPropertiesTool,
216 const EventContext& ctx)
const {
222 Q_m2, Q_m1, Q_00, Q_p1, Q_p2,
233 const double x,
const double y,
double& vx,
double& vy,
double& D,
235 const ToolHandle<ISiPropertiesTool>& siPropertiesTool,
236 const EventContext& ctx)
const {
245 const double E = std::sqrt(Ex*Ex+Ey*Ey);
247 siPropertiesTool->getSiProperties(hashId, ctx).calcElectronDriftMobility(
data.m_T, E*CLHEP::volt/CLHEP::cm) :
248 siPropertiesTool->getSiProperties(hashId, ctx).calcHoleDriftMobility (
data.m_T, E*CLHEP::volt/CLHEP::cm))
249 * (CLHEP::volt/CLHEP::cm)/(CLHEP::cm/CLHEP::s);
250 const double v = mu * E;
252 siPropertiesTool->getSiProperties(hashId, ctx).calcElectronHallFactor(
data.m_T) :
253 siPropertiesTool->getSiProperties(hashId, ctx).calcHoleHallFactor(
data.m_T));
255 const double tanLA =
data.m_element->design().readoutSide()
257 *
data.m_element->hitDepthDirection()
258 *
data.m_element->hitPhiDirection()
259 * (
data.m_element->normal().cross(
data.m_magneticField)).dot(
data.m_element->phiAxis())
260 / Gaudi::Units::tesla * Gaudi::Units::gauss * 1000.;
262 const double secLA = std::sqrt(1.+tanLA*tanLA);
263 const double cosLA = 1./secLA;
264 const double sinLA = tanLA/secLA;
265 vy = v * (Ey*cosLA - Ex*sinLA)/E;
266 vx = v * (Ex*cosLA + Ey*sinLA)/E;
277 const int istrip,
const double x,
const double y)
const
285 const double deltax = 0.0005, deltay = 0.00025;
289 double dx = std::abs(
x-xc);
290 int ix =
static_cast<int>(dx / deltax);
292 int iy =
static_cast<int>(
y / deltay);
293 double fx = (dx - ix*deltax) / deltax;
294 double fy = (
y - iy*deltay) / deltay;
309 const double x,
const double y,
double& Ex,
double& Ey)
const {
318 const double deltay=0.00025, deltax=0.00025;
325 int iy =
static_cast<int>(
y/deltay);
326 double fy = (
y-iy*deltay) / deltay;
332 int ix =
static_cast<int>(xxx/deltax);
333 double fx = (xxx - ix*deltax) / deltax;
337 double Ex00 = 0., Ex10 = 0., Ex01 = 0., Ex11 = 0.;
338 double Ey00 = 0., Ey10 = 0., Ey01 = 0., Ey11 = 0.;
341 Ex00 =
data.m_ExValue[ix][iy]; Ex10 =
data.m_ExValue[ix1][iy];
342 Ex01 =
data.m_ExValue[ix][iy1]; Ex11 =
data.m_ExValue[ix1][iy1];
343 Ey00 =
data.m_EyValue[ix][iy]; Ey10 =
data.m_EyValue[ix1][iy];
344 Ey01 =
data.m_EyValue[ix][iy1]; Ey11 =
data.m_EyValue[ix1][iy1];
347 Ex = Ex00*(1.-fx)*(1.-fy) + Ex10*fx*(1.-fy)
348 + Ex01*(1.-fx)* fy + Ex11*fx* fy;
349 if (xx > xhalfpitch) Ex = -Ex;
350 Ey = Ey00*(1.-fx)*(1.-fy) + Ey10*fx*(1.-fy)
351 + Ey01*(1.-fx)* fy + Ey11*fx* fy;
356 Ey =
data.m_VB /
data.m_depletion_depth;
363 if (
data.m_VB > std::abs(
data.m_VD)) {
385 for (iVFD=0; iVFD<
s_VFD0.size()-1; iVFD++) {
387 if (dVFD2 >= 0.)
break;
406 TH2F* h_Potential_FDM =
static_cast<TH2F*
>(hfile->Get(
"Potential_FDM"));
407 TH2F* h_Potential_FEM =
static_cast<TH2F*
>(hfile->Get(
"Potential_FEM"));
422 h_Potential_FDM->Delete();
423 h_Potential_FEM->Delete();
430 TH2F* h_Ex =
static_cast<TH2F*
>(hfile->Get((
"Ex_FEM_"+
str+
"_0").c_str()));
431 TH2F* h_Ey =
static_cast<TH2F*
>(hfile->Get((
"Ey_FEM_"+
str+
"_0").c_str()));
434 m_ExValue[i][ix][iy] = h_Ex->GetBinContent(ix+1, iy+1);
435 m_EyValue[i][ix][iy] = h_Ey->GetBinContent(ix+1, iy+1);
443 TH2F* h_ExHV =
static_cast<TH2F*
>(hfile->Get(
"Ex_FEM_0_100"));
444 TH2F* h_EyHV =
static_cast<TH2F*
>(hfile->Get(
"Ey_FEM_0_100"));
447 m_ExValue[i][ix][iy] = h_ExHV->GetBinContent(ix+1, iy+1);
448 m_EyValue[i][ix][iy] = h_EyHV->GetBinContent(ix+1, iy+1);
463 ATH_MSG_INFO(
"Changed to Flat Diode Model since deplettion volage is out of range. ("
469 const float dVFD2 =
s_VFD0[iVFD+1] -
data.m_VD;
471 const float scalingFactor =
data.m_VB / 100.;
473 const size_t iHV =
s_VFD0.size();
481 data.m_ExValue[ix][iy] = (Ex1*dVFD2+Ex2*dVFD1)/(dVFD1+dVFD2);
482 data.m_ExValue[ix][iy] += ExHV*scalingFactor;
487 data.m_EyValue[ix][iy] = (Ey1*dVFD2+Ey2*dVFD1)/(dVFD1+dVFD2);
488 data.m_EyValue[ix][iy] += EyHV*scalingFactor;
bool isElectron(const T &p)
char data[hepevt_bytes_allocation_ATLAS]
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
This is a "hash" representation of an Identifier.
Class to hold geometrical description of a solid state detector element.
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
HepGeom::Point3D< double > globalPositionHit(const HepGeom::Point3D< double > &simulationLocalPos) const
transform a hit local position into a global position (inline):
std::vector< std::array< std::array< double, NDepthPoints >, NEFieldPoints > > m_EyValue
double induced(const SCT_InducedChargeModelData &data, const int istrip, const double x, const double y) const
bool getVxVyD(const SCT_InducedChargeModelData &data, const bool isElectron, const double x, const double y, double &vx, double &vy, double &D, const IdentifierHash hashId, const ToolHandle< ISiPropertiesTool > &siPropertiesTool, const EventContext &ctx) const
static const std::vector< std::string > s_VFD0str
static size_t getFEMIndex(SCT_InducedChargeModelData &data)
void holeTransport(const SCT_InducedChargeModelData &data, const double x0, const double y0, double *Q_m2, double *Q_m1, double *Q_00, double *Q_p1, double *Q_p2, const IdentifierHash hashId, const ToolHandle< ISiPropertiesTool > &siPropertiesTool, const EventContext &ctx) const
void getEField(const SCT_InducedChargeModelData &data, const double x, const double y, double &Ex, double &Ey) const
static const std::vector< float > s_VFD0
void electronTransport(const SCT_InducedChargeModelData &data, const double x0, const double y0, double *Q_m2, double *Q_m1, double *Q_00, double *Q_p1, double *Q_p2, const IdentifierHash hashId, const ToolHandle< ISiPropertiesTool > &siPropertiesTool, const EventContext &ctx) const
EFieldModel m_EFieldModel
void transport(const SCT_InducedChargeModelData &data, const bool isElectron, const double x0, const double y0, double *Q_m2, double *Q_m1, double *Q_00, double *Q_p1, double *Q_p2, const IdentifierHash hashId, const ToolHandle< ISiPropertiesTool > &siPropertiesTool, const EventContext &ctx) const
void setEField(SCT_InducedChargeModelData &data) const
std::vector< std::array< std::array< double, NDepthPoints >, NRamoPoints > > m_PotentialValue
double m_transportTimeStep
SCT_InducedChargeModelData * setWaferData(const float vdepl, const float vbias, const InDetDD::SolidStateDetectorElementBase *element, const AtlasFieldCacheCondObj *fieldCondObj, const ToolHandle< ISiliconConditionsTool > &siConditionsTool, CLHEP::HepRandomEngine *rndmEngine, const EventContext &ctx) const
std::vector< std::array< std::array< double, NDepthPoints >, NEFieldPoints > > m_ExValue
double m_transportTimeMax
InducedChargeModel(size_t maxHash, EFieldModel model=FEMsolutions)
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
Eigen::Matrix< double, 3, 1 > Vector3D