ATLAS Offline Software
Loading...
Searching...
No Matches
InducedChargeModel Class Reference

#include <InducedChargeModel.h>

Inheritance diagram for InducedChargeModel:
Collaboration diagram for InducedChargeModel:

Classes

struct  SCT_InducedChargeModelData

Public Types

enum  EFieldModel { FlatDiodeModel =0 , FEMsolutions =1 , UniformE =2 }
enum  TransportStep { NTransportSteps =100 }
enum  FEMNums { NRamoPoints =81 , NEFieldPoints =17 , NDepthPoints =115 }
enum  InducedStrips { StartStrip =-2 , EndStrip =+2 , Offset =-StartStrip , NStrips =EndStrip+Offset+1 }

Public Member Functions

 InducedChargeModel (size_t maxHash, EFieldModel model=FEMsolutions)
SCT_InducedChargeModelDatasetWaferData (const float vdepl, const float vbias, const InDetDD::SolidStateDetectorElementBase *element, const AtlasFieldCacheCondObj *fieldCondObj, const ToolHandle< ISiliconConditionsTool > &siConditionsTool, CLHEP::HepRandomEngine *rndmEngine, const EventContext &ctx) const
void setEField (SCT_InducedChargeModelData &data) const
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 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 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
bool msgLvl (const MSG::Level lvl) const
 Test the output level.
MsgStream & msg () const
 The standard message stream.
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream.
void setLevel (MSG::Level lvl)
 Change the current logging level.

Private Member Functions

void loadICMParameters ()
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
double induced (const SCT_InducedChargeModelData &data, const int istrip, const double x, const double y) const
void getEField (const SCT_InducedChargeModelData &data, const double x, const double y, double &Ex, double &Ey) const
void initMessaging () const
 Initialize our message level and MessageSvc.

Static Private Member Functions

static size_t getFEMIndex (SCT_InducedChargeModelData &data)

Private Attributes

EFieldModel m_EFieldModel
double m_transportTimeStep = 0.50
double m_transportTimeMax = m_transportTimeStep*NTransportSteps
double m_bulk_depth = 0.0285
double m_strip_pitch = 0.0080
double m_y_origin_min = 0.
std::vector< std::array< std::array< double, NDepthPoints >, NRamoPoints > > m_PotentialValue
std::vector< std::array< std::array< double, NDepthPoints >, NEFieldPoints > > m_ExValue
std::vector< std::array< std::array< double, NDepthPoints >, NEFieldPoints > > m_EyValue
std::vector< std::unique_ptr< SCT_InducedChargeModelData > > m_data ATLAS_THREAD_SAFE
std::mutex m_mutex
std::string m_nm
 Message source name.
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels)
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer.
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level.

Static Private Attributes

static const double s_kB = Gaudi::Units::k_Boltzmann / Gaudi::Units::joule
static const double s_e = Gaudi::Units::e_SI
static const std::vector< float > s_VFD0
static const std::vector< std::string > s_VFD0str

Detailed Description

Definition at line 43 of file InducedChargeModel.h.

Member Enumeration Documentation

◆ EFieldModel

Enumerator
FlatDiodeModel 
FEMsolutions 
UniformE 

Definition at line 46 of file InducedChargeModel.h.

◆ FEMNums

Enumerator
NRamoPoints 
NEFieldPoints 
NDepthPoints 

Definition at line 48 of file InducedChargeModel.h.

◆ InducedStrips

◆ TransportStep

Enumerator
NTransportSteps 

Definition at line 47 of file InducedChargeModel.h.

Constructor & Destructor Documentation

◆ InducedChargeModel()

InducedChargeModel::InducedChargeModel ( size_t maxHash,
EFieldModel model = FEMsolutions )

Definition at line 31 of file InducedChargeModel.cxx.

31 :
32 AthMessaging("InducedChargeModel"),
33 m_EFieldModel(model)
34{
36 m_data.resize(maxHash);
37}
AthMessaging()
Default constructor:

Member Function Documentation

◆ electronTransport()

void InducedChargeModel::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

Definition at line 211 of file InducedChargeModel.cxx.

216 {
217 // Q_m2[100],Q_m1[100],Q_00[100],Q_p1[100],Q_p2[100] NTransportSteps=100
218 const bool isElectron = true;
221 x0, y0,
222 Q_m2, Q_m1, Q_00, Q_p1, Q_p2,
223 hashId,
224 siPropertiesTool,
225 ctx);
226}
bool isElectron(const T &p)
Definition AtlasPID.h:202
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
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

◆ getEField()

void InducedChargeModel::getEField ( const SCT_InducedChargeModelData & data,
const double x,
const double y,
double & Ex,
double & Ey ) const
private

Definition at line 308 of file InducedChargeModel.cxx.

309 {
310 // m_EFieldModel == FlatDiodeModel 0; flat diode model
311 // m_EFieldModel == FEMsolutions 1; FEM solusions
312 // m_EFieldModel == UniformE 2; uniform E-field model
313 // x == 0.0040 [cm] : at the center of strip
314 // x must be within 0 and 0.008 [cm]
315
316 // Electric field : 16 divisions (17 points) with 2.5 um intervals from 0-40 um.
317 // In sensor depth directions 114 divisions (115 points) with 2.5 nm intervals for 285 um.
318 const double deltay=0.00025, deltax=0.00025; // [cm]
319
320 Ex = 0.;
321 Ey = 0.;
322 if (y < 0. || y > m_bulk_depth) return;
323 //---------- case for FEM analysis solution -------------------------
324 if (data.m_EFieldModel==FEMsolutions) {
325 int iy = static_cast<int>(y/deltay);
326 double fy = (y-iy*deltay) / deltay;
327 double xhalfpitch = m_strip_pitch/2.;
328 double x999 = 999.*m_strip_pitch;
329 double xx = fmod(x+x999, m_strip_pitch);
330 double xxx = xx;
331 if (xx > xhalfpitch) xxx = m_strip_pitch - xx;
332 int ix = static_cast<int>(xxx/deltax);
333 double fx = (xxx - ix*deltax) / deltax;
334
335 int ix1 = ix+1;
336 int iy1 = iy+1;
337 double Ex00 = 0., Ex10 = 0., Ex01 = 0., Ex11 = 0.;
338 double Ey00 = 0., Ey10 = 0., Ey01 = 0., Ey11 = 0.;
339 //-------- pick up appropriate data file for m_VD-----------------------
340
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];
345
346 //---------------- end of data bank search---
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;
352 }
353 //---------- case for uniform electric field ------------------------
354 else if (data.m_EFieldModel==UniformE) {
356 Ey = data.m_VB / data.m_depletion_depth;
357 } else {
358 Ey = 0.;
359 }
360 }
361 //---------- case for flat diode model ------------------------------
362 else if (data.m_EFieldModel==FlatDiodeModel) {
363 if (data.m_VB > std::abs(data.m_VD)) {
364 Ey = (data.m_VB+data.m_VD)/m_bulk_depth - 2.*data.m_VD*(m_bulk_depth-y)/(m_bulk_depth*m_bulk_depth);
365 } else {
367 double Emax = 2.* data.m_depletion_depth * std::abs(data.m_VD) / (m_bulk_depth*m_bulk_depth);
368 Ey = Emax*(1.-(m_bulk_depth-y)/data.m_depletion_depth);
369 } else {
370 Ey = 0.;
371 }
372 }
373 }
374}
#define y
#define x

◆ getFEMIndex()

size_t InducedChargeModel::getFEMIndex ( SCT_InducedChargeModelData & data)
staticprivate

Definition at line 377 of file InducedChargeModel.cxx.

377 {
378 // Return index for s_VFD0 and EFieldModel.
379 // If vdepl is out of range of s_VFD0, EFieldModel of FlatDiodeModel is returned.
380 size_t iVFD = 0;
381 if (data.m_VD<s_VFD0[0] || data.m_VD>s_VFD0[s_VFD0.size()-1]) { // Out of range
382 data.m_EFieldModel = FlatDiodeModel;
383 } else {
384 float dVFD2 = 0.;
385 for (iVFD=0; iVFD<s_VFD0.size()-1; iVFD++) {
386 dVFD2 = s_VFD0[iVFD+1] - data.m_VD;
387 if (dVFD2 >= 0.) break;
388 }
389 }
390 return iVFD;
391}
static const std::vector< float > s_VFD0

◆ getVxVyD()

bool InducedChargeModel::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
private

Definition at line 231 of file InducedChargeModel.cxx.

236 {
237 double Ex, Ey;
238 getEField(data, x, y, Ex, Ey); // [V/cm]
239 if (Ey > 0.) {
240 if (isElectron) {
241 // because electron has negative charge
242 Ex *= -1.;
243 Ey *= -1.;
244 }
245 const double E = std::sqrt(Ex*Ex+Ey*Ey);
246 const double mu = (isElectron ?
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;
251 const double r = (isElectron ?
252 siPropertiesTool->getSiProperties(hashId, ctx).calcElectronHallFactor(data.m_T) :
253 siPropertiesTool->getSiProperties(hashId, ctx).calcHoleHallFactor(data.m_T));
254
255 const double tanLA = data.m_element->design().readoutSide()
256 * r * mu * (isElectron ? -1. : +1.) // because e has negative charge.
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.; // 1000. is to convert kTesla to Tesla.
261
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;
267 D = s_kB * data.m_T * mu/ s_e;
268 return true;
269 }
270 return false;
271}
void getEField(const SCT_InducedChargeModelData &data, const double x, const double y, double &Ex, double &Ey) const
static const double s_e
static const double s_kB
int r
Definition globals.cxx:22

◆ holeTransport()

void InducedChargeModel::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

Definition at line 191 of file InducedChargeModel.cxx.

196 {
197 // Q_m2[100],Q_m1[100],Q_00[100],Q_p1[100],Q_p2[100] NTransportSteps=100
198 const bool isElectron = false;
201 x0, y0,
202 Q_m2, Q_m1, Q_00, Q_p1, Q_p2,
203 hashId,
204 siPropertiesTool,
205 ctx);
206}

◆ induced()

double InducedChargeModel::induced ( const SCT_InducedChargeModelData & data,
const int istrip,
const double x,
const double y ) const
private

Definition at line 276 of file InducedChargeModel.cxx.

278{
279 // x and y are the location of charge (e or hole)
280 // induced charge on the strip "istrip" situated at the height y = d
281 // the center of the strip (istrip=0) is x = 0.004 [cm]
282
283 // Ramo potential : 80 divisions (81 points) with 5 um intervals from 40-440 um.
284 // In sensor depth directions 114 divisions (115 points) with 2.5 nm intervals for 285 um.
285 const double deltax = 0.0005, deltay = 0.00025;
286
287 if (y < 0. || y > m_bulk_depth) return 0.;
288 double xc = m_strip_pitch * (istrip + 0.5);
289 double dx = std::abs(x-xc);
290 int ix = static_cast<int>(dx / deltax);
291 if (ix >= NRamoPoints) return 0.;
292 int iy = static_cast<int>(y / deltay);
293 double fx = (dx - ix*deltax) / deltax;
294 double fy = ( y - iy*deltay) / deltay;
295 int ix1 = ix + 1;
296 int iy1 = iy + 1;
297 double P = m_PotentialValue[data.m_EFieldModel][ix ][iy ] *(1.-fx)*(1.-fy)
298 + m_PotentialValue[data.m_EFieldModel][ix1][iy ] * fx *(1.-fy)
299 + m_PotentialValue[data.m_EFieldModel][ix ][iy1] *(1.-fx)* fy
300 + m_PotentialValue[data.m_EFieldModel][ix1][iy1] * fx* fy;
301
302 return P;
303}
static Double_t P(Double_t *tt, Double_t *par)
std::vector< std::array< std::array< double, NDepthPoints >, NRamoPoints > > m_PotentialValue

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40{
42 // If user did not set an explicit level, set a default
43 if (m_lvl == MSG::NIL) {
44 m_lvl = m_imsg ?
45 static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
46 MSG::INFO;
47 }
48}
std::string m_nm
Message source name.
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
std::atomic< MSG::Level > m_lvl
Current logging level.
IMessageSvc * getMessageSvc(bool quiet=false)

◆ loadICMParameters()

void InducedChargeModel::loadICMParameters ( )
private

Definition at line 395 of file InducedChargeModel.cxx.

395 {
396 // Loading Ramo potential and Electric field.
397 // In strip pitch directions :
398 // Ramo potential : 80 divisions (81 points) with 5 um intervals from 40-440 um.
399 // Electric field : 16 divisions (17 points) with 2.5 um intervals from 0-40 um.
400 // In sensor depth directions (for both potential and Electric field):
401 // 114 divisions (115 points) with 2.5 nm intervals for 285 um.
402
403 TFile *hfile = new TFile(PathResolverFindCalibFile("SCT_Digitization/SCT_InducedChargedModel.root").c_str());
404
405 // For Ramo Potential
406 TH2F* h_Potential_FDM = static_cast<TH2F*>(hfile->Get("Potential_FDM"));
407 TH2F* h_Potential_FEM = static_cast<TH2F*>(hfile->Get("Potential_FEM"));
408 // FDM case keeps only FDM potential.
409 // FEM case keeps both FDM and FEM potentials.
412 else m_PotentialValue.resize(FEMsolutions+1);
413 for (int ix=0; ix<NRamoPoints; ix++) {
414 for (int iy=0; iy<NDepthPoints; iy++) {
415 m_PotentialValue[FlatDiodeModel][ix][iy] = h_Potential_FDM->GetBinContent(ix+1, iy+1);
417 m_PotentialValue[FEMsolutions][ix][iy] = h_Potential_FEM->GetBinContent(ix+1, iy+1);
418 }
419 }
420 }
421 }
422 h_Potential_FDM->Delete();
423 h_Potential_FEM->Delete();
424
426 size_t i=0;
427 m_ExValue.resize(s_VFD0str.size()+1);
428 m_EyValue.resize(s_VFD0str.size()+1);
429 for (const std::string& str : s_VFD0str) {
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()));
432 for (int ix=0; ix <NEFieldPoints; ix++){
433 for (int iy=0; iy<NDepthPoints; iy++) {
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);
436 }
437 }
438 h_Ex->Delete();
439 h_Ey->Delete();
440 i++;
441 }
442
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"));
445 for (int ix=0; ix <NEFieldPoints; ix++){
446 for (int iy=0; iy<NDepthPoints; iy++) {
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);
449 }
450 }
451 h_ExHV->Delete();
452 h_EyHV->Delete();
453 }
454
455 hfile->Close();
456}
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
std::vector< std::array< std::array< double, NDepthPoints >, NEFieldPoints > > m_EyValue
static const std::vector< std::string > s_VFD0str
std::vector< std::array< std::array< double, NDepthPoints >, NEFieldPoints > > m_ExValue
TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 163 of file AthMessaging.h.

164{
165 MsgStream* ms = m_msg_tls.get();
166 if (!ms) {
167 if (!m_initialized.test_and_set()) initMessaging();
168 ms = new MsgStream(m_imsg,m_nm);
169 m_msg_tls.reset( ms );
170 }
171
172 ms->setLevel (m_lvl);
173 return *ms;
174}
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels)
void initMessaging() const
Initialize our message level and MessageSvc.

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 178 of file AthMessaging.h.

179{ return msg() << lvl; }
MsgStream & msg() const
The standard message stream.

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152{
153 if (m_lvl <= lvl) {
154 msg() << lvl;
155 return true;
156 } else {
157 return false;
158 }
159}

◆ setEField()

void InducedChargeModel::setEField ( SCT_InducedChargeModelData & data) const

Definition at line 458 of file InducedChargeModel.cxx.

458 {
459 if (data.m_EFieldModel!=FEMsolutions) return;
460
461 size_t iVFD = getFEMIndex(data);
462 if (data.m_EFieldModel==FlatDiodeModel) {
463 ATH_MSG_INFO("Changed to Flat Diode Model since deplettion volage is out of range. ("
464 << s_VFD0[0] << " < m_VD < " << s_VFD0[s_VFD0.size()-1] << " is allowed.)");
465 return;
466 }
467
468 const float dVFD1 = data.m_VD - s_VFD0[iVFD];
469 const float dVFD2 = s_VFD0[iVFD+1] - data.m_VD;
470
471 const float scalingFactor = data.m_VB / 100.; // Reference voltage is 100 V
472
473 const size_t iHV = s_VFD0.size();
474
475 // For Electric field
476 for (int ix=0; ix <NEFieldPoints; ix++){
477 for (int iy=0; iy<NDepthPoints; iy++) {
478 float Ex1 = m_ExValue[iVFD ][ix][iy];
479 float Ex2 = m_ExValue[iVFD+1][ix][iy];
480 float ExHV = m_ExValue[iHV ][ix][iy];
481 data.m_ExValue[ix][iy] = (Ex1*dVFD2+Ex2*dVFD1)/(dVFD1+dVFD2);
482 data.m_ExValue[ix][iy] += ExHV*scalingFactor;
483
484 float Ey1 = m_EyValue[iVFD ][ix][iy];
485 float Ey2 = m_EyValue[iVFD+1][ix][iy];
486 float EyHV = m_EyValue[iHV ][ix][iy];
487 data.m_EyValue[ix][iy] = (Ey1*dVFD2+Ey2*dVFD1)/(dVFD1+dVFD2);
488 data.m_EyValue[ix][iy] += EyHV*scalingFactor;
489 }
490 }
491}
#define ATH_MSG_INFO(x)
static size_t getFEMIndex(SCT_InducedChargeModelData &data)

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29{
30 m_lvl = lvl;
31}

◆ setWaferData()

InducedChargeModel::SCT_InducedChargeModelData * InducedChargeModel::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

Definition at line 40 of file InducedChargeModel.cxx.

46 {
47 std::lock_guard<std::mutex> lock(m_mutex);
48
49 // If cache exists, cache is used.
50 SCT_InducedChargeModelData* p_data = m_data[element->identifyHash()].get();
51 if (p_data) return p_data;
52
53 ATH_MSG_DEBUG("--- Induced Charged Model Paramter (Begin) --------");
54
55 HepGeom::Point3D<double> localpos(0., 0., 0.); // The center of wafer
56 HepGeom::Point3D<double> globalpos = element->globalPositionHit(localpos);
57 double point[3] = {globalpos.x(), globalpos.y(), globalpos.z()};
58 double field[3] = {0., 0., 0.};
59 MagField::AtlasFieldCache fieldCache;
60 fieldCondObj->getInitializedCache(fieldCache);
61 fieldCache.getField(point, field);
62 const Amg::Vector3D magneticField(field[0], field[1], field[2]); // in kTesla
63
64 //---------------setting basic parameters---------------------------
65 std::unique_ptr<SCT_InducedChargeModelData> data =
66 std::make_unique<SCT_InducedChargeModelData>(vdepl,
67 vbias,
68 element,
69 magneticField,
72 siConditionsTool,
73 rndmEngine,
74 ctx);
75
76 //--- set electric fields ---
78
79 //--------------------------------------------------------
80
81 ATH_MSG_DEBUG(" EFieldModel 0 (Flat Diode Model), 1 (FEM solusions) 2 (uniform E)\t"<< data->m_EFieldModel);
82 ATH_MSG_DEBUG(" DepletionVoltage_VD\t"<< data->m_VD <<" V");
83 ATH_MSG_DEBUG(" BiasVoltage_VB \t"<< data->m_VB <<" V");
84 ATH_MSG_DEBUG(" MagneticField_B \t"
85 << data->m_magneticField[Amg::x] << " "
86 << data->m_magneticField[Amg::y] << " "
87 << data->m_magneticField[Amg::z] <<" kTesla");
88 ATH_MSG_DEBUG(" Temperature_T \t"<< data->m_T <<" K");
89 ATH_MSG_DEBUG(" TransportTimeStep \t"<< m_transportTimeStep <<" ns");
90 ATH_MSG_DEBUG(" TransportTimeMax\t"<< m_transportTimeMax <<" ns");
91 ATH_MSG_DEBUG(" BulkDepth\t\t"<< m_bulk_depth << " cm");
92 ATH_MSG_DEBUG(" DepletionDepth\t\t"<< data->m_depletion_depth << " cm");
93 ATH_MSG_DEBUG(" StripPitch\t\t"<< m_strip_pitch << " cm");
94 ATH_MSG_DEBUG("--- Induced Charged Model Paramter (End) ---------");
95
96 m_data[element->identifyHash()] = std::move(data);
97
98 return m_data[element->identifyHash()].get();
99}
#define ATH_MSG_DEBUG(x)
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
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):
void setEField(SCT_InducedChargeModelData &data) const
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

◆ transport()

void InducedChargeModel::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

Definition at line 104 of file InducedChargeModel.cxx.

110 {
111 // transport electrons and holes in the bulk
112 // T. Kondo, 2010.9.9, 2017.7.20
113 // External parameters to be specified
114 // m_transportTimeMax [nsec]
115 // m_transportTimeStep [nsec]
116 // m_bulk_depth [cm]
117 // Induced currents are added to every m_transportTimeStep (defailt is 0.5 ns):
118 // Q_m2[100],Q_m1[100],Q_00[100],Q_p1[100],Q_p2[100] NTransportSteps=100
119 // means 50 ns storages of charges in each strips.
120
121 double x = x0; // original electron/hole position [cm]
122 double y = y0; // original electron/hole position [cm]
123 bool isInBulk = true;
124 double t_current = 0.;
125 double qstrip[NStrips]; // induced charges on strips due to an electron or a hole
126 double vx, vy, D;
127 for (int istrip=StartStrip; istrip<=EndStrip; istrip++) {
128 qstrip[istrip+Offset] = (isElectron ? -1. : +1.) * induced(data, istrip, x, y); // original induced charge by electron or hole
129 }
130 while (t_current < m_transportTimeMax) {
131 if (!isInBulk) break;
132 if (!getVxVyD(data, isElectron, x, y, vx, vy, D, hashId, siPropertiesTool, ctx)) break;
133 double delta_y = vy * m_transportTimeStep / Gaudi::Units::second; // ns -> s
134 y += delta_y;
135 double dt = m_transportTimeStep; // [nsec]
136 if (isElectron) {
137 if (y < m_y_origin_min) {
138 isInBulk = false;
139 dt = (m_y_origin_min - (y-delta_y))/delta_y * m_transportTimeStep;
141 }
142 } else {
143 if (y > m_bulk_depth) {
144 isInBulk = false; // outside bulk region
145 dt = (m_bulk_depth - (y-delta_y))/delta_y * m_transportTimeStep;
146 y = m_bulk_depth;
147 }
148 }
149 t_current += dt;
150 x += vx * dt / Gaudi::Units::second; // ns -> s
151 double diffusion = std::sqrt(2.* D * dt / Gaudi::Units::second); // ns -> s
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);
154 if (isElectron) {
155 if (y < m_y_origin_min) {
157 isInBulk = false;
158 }
159 } else {
160 if (y > m_bulk_depth) {
161 y = m_bulk_depth;
162 isInBulk = false; // outside bulk region
163 }
164 }
165
166 // get induced current by subtracting induced charges
167 for (int istrip=StartStrip; istrip<=EndStrip; istrip++) {
168 double qnew = (isElectron ? -1. : +1.) * induced(data, istrip, x, y);
169 int jj = istrip + Offset;
170 double dq = qnew - qstrip[jj];
171 qstrip[jj] = qnew;
172
173 int jt = static_cast<int>((t_current+0.001) / m_transportTimeStep);
174 if (jt < NTransportSteps) {
175 switch (istrip) {
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;
181 }
182 }
183
184 }
185 } // end of electron or hole tracing
186}
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

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::vector<std::unique_ptr<SCT_InducedChargeModelData> > m_data InducedChargeModel::ATLAS_THREAD_SAFE
mutableprivate

Definition at line 172 of file InducedChargeModel.h.

◆ m_bulk_depth

double InducedChargeModel::m_bulk_depth = 0.0285
private

Definition at line 153 of file InducedChargeModel.h.

◆ m_EFieldModel

EFieldModel InducedChargeModel::m_EFieldModel
private

Definition at line 148 of file InducedChargeModel.h.

◆ m_ExValue

std::vector<std::array<std::array<double, NDepthPoints>, NEFieldPoints> > InducedChargeModel::m_ExValue
private

Definition at line 166 of file InducedChargeModel.h.

◆ m_EyValue

std::vector<std::array<std::array<double, NDepthPoints>, NEFieldPoints> > InducedChargeModel::m_EyValue
private

Definition at line 167 of file InducedChargeModel.h.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

138{ MSG::NIL };

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels)

Definition at line 132 of file AthMessaging.h.

◆ m_mutex

std::mutex InducedChargeModel::m_mutex
mutableprivate

Definition at line 174 of file InducedChargeModel.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_PotentialValue

std::vector<std::array<std::array<double, NDepthPoints>, NRamoPoints> > InducedChargeModel::m_PotentialValue
private

Definition at line 165 of file InducedChargeModel.h.

◆ m_strip_pitch

double InducedChargeModel::m_strip_pitch = 0.0080
private

Definition at line 154 of file InducedChargeModel.h.

◆ m_transportTimeMax

double InducedChargeModel::m_transportTimeMax = m_transportTimeStep*NTransportSteps
private

Definition at line 150 of file InducedChargeModel.h.

◆ m_transportTimeStep

double InducedChargeModel::m_transportTimeStep = 0.50
private

Definition at line 149 of file InducedChargeModel.h.

◆ m_y_origin_min

double InducedChargeModel::m_y_origin_min = 0.
private

Definition at line 155 of file InducedChargeModel.h.

◆ s_e

const double InducedChargeModel::s_e = Gaudi::Units::e_SI
staticprivate

Definition at line 145 of file InducedChargeModel.h.

◆ s_kB

const double InducedChargeModel::s_kB = Gaudi::Units::k_Boltzmann / Gaudi::Units::joule
staticprivate

Definition at line 144 of file InducedChargeModel.h.

◆ s_VFD0

const std::vector< float > InducedChargeModel::s_VFD0
staticprivate
Initial value:
=
{ -180., -150., -120., -90., -60., -30., 0., 30., 70.}

Definition at line 26 of file InducedChargeModel.h.

◆ s_VFD0str

const std::vector< std::string > InducedChargeModel::s_VFD0str
staticprivate
Initial value:
=
{"M180", "M150", "M120", "M90", "M60", "M30", "0", "30", "70"}

Definition at line 28 of file InducedChargeModel.h.


The documentation for this class was generated from the following files: