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

#include <RadDamageUtil.h>

Inheritance diagram for RadDamageUtil:
Collaboration diagram for RadDamageUtil:

Public Member Functions

 RadDamageUtil (const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode initialize () override
virtual StatusCode finalize () override
virtual ~RadDamageUtil ()
StatusCode initTools ()
const StatusCode generateRamoMap (TH3F *ramPotentialMap, InDetDD::PixelModuleDesign *module)
const StatusCode generateEfieldMap (TH1F *&eFieldMap, InDetDD::PixelModuleDesign *module)
StatusCode generateEfieldMap (TH1F *&eFieldMap, InDetDD::PixelModuleDesign *module, double fluence, double biasVoltage, int layer, const std::string &TCAD_list, bool interpolate)
const StatusCode generateDistanceTimeMap (TH2F *&distanceMap_e, TH2F *&distanceMap_h, TH1F *&timeMap_e, TH1F *&timeMap_h, TH2F *&lorentzMap_e, TH2F *&lorentzMap_h, TH1F *&eFieldMap, InDetDD::PixelModuleDesign *module)
const std::pair< double, double > getTrappingTimes (double fluence) const
bool saveDebugMaps ()
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysInitialize () override
 Perform system initialization for an algorithm.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const

Static Public Member Functions

static const std::pair< double, double > getMobility (double electricField, double temperature)
static double getTanLorentzAngle (double electricField, double temperature, double bField, bool isHole)

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed.

Private Types

typedef ServiceHandle< StoreGateSvcStoreGateSvc_t

Private Member Functions

 RadDamageUtil ()
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Static Private Member Functions

static double alpha (int n, int Nrep, double a)
static double weighting3D (double x, double y, double z, int n, int m, int Nrep, double a, double b)
static double weighting2D (double x, double z, double Lx, double sensorThickness)

Private Attributes

Gaudi::Property< int > m_defaultRamo
Gaudi::Property< double > m_betaElectrons
Gaudi::Property< double > m_betaHoles
Gaudi::Property< bool > m_saveDebugMaps
Gaudi::Property< double > m_fieldScale {this, "fieldScale", 1.}
ToolHandle< EfieldInterpolatorm_EfieldInterpolator
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default)
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default)
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared

Detailed Description

Definition at line 32 of file RadDamageUtil.h.

Member Typedef Documentation

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ RadDamageUtil() [1/2]

RadDamageUtil::RadDamageUtil ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 36 of file RadDamageUtil.cxx.

36 :
37 AthAlgTool(type, name, parent) {}
AthAlgTool()
Default constructor:

◆ ~RadDamageUtil()

RadDamageUtil::~RadDamageUtil ( )
virtualdefault

◆ RadDamageUtil() [2/2]

RadDamageUtil::RadDamageUtil ( )
private

Member Function Documentation

◆ alpha()

double RadDamageUtil::alpha ( int n,
int Nrep,
double a )
staticprivate

Definition at line 146 of file RadDamageUtil.cxx.

146 {
147 return((2 * M_PI * n) / (Nrep * a));
148}
#define M_PI
static Double_t a

◆ declareGaudiProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > & hndl,
const SG::VarHandleKeyType &  )
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158 {
160 hndl.value(),
161 hndl.documentation());
162
163 }
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)

◆ declareProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > & t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145 {
146 typedef typename SG::HandleClassifier<T>::type htype;
148 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

◆ detStore()

const ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

◆ evtStore()

ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase & ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ finalize()

StatusCode RadDamageUtil::finalize ( )
overridevirtual

Definition at line 460 of file RadDamageUtil.cxx.

460 {
461 ATH_MSG_DEBUG("RadDamageUtil::finalize()");
462 return StatusCode::SUCCESS;
463}
#define ATH_MSG_DEBUG(x)

◆ generateDistanceTimeMap()

const StatusCode RadDamageUtil::generateDistanceTimeMap ( TH2F *& distanceMap_e,
TH2F *& distanceMap_h,
TH1F *& timeMap_e,
TH1F *& timeMap_h,
TH2F *& lorentzMap_e,
TH2F *& lorentzMap_h,
TH1F *& eFieldMap,
InDetDD::PixelModuleDesign * module )

Definition at line 283 of file RadDamageUtil.cxx.

285 {
286 // Implementation for precomputed maps
287 //https://gitlab.cern.ch/radiationDamageDigitization/radDamage_athena_rel22/blob/rel22_radDamageDev_master/scripts/SaveMapsForAthena.C
288 //TODO: From DB call each time
289 double temperature = 300;
290 double bField = 2*m_fieldScale;//Tesla
291 //From PixelModuleDesign: TODO
292 //FIXME workaround, if PixelModuleDesign not available: retrieve sensor thickness from E field
293 //double sensorThickness = module->thickness() * 1000.0;//default is 200;
294 double sensorThickness = 0.2; //mm
295
296 //Check if x axis (sensor depth) of E field larger than IBL sensors
297 if (eFieldMap->GetXaxis()->GetXmax() > 210) { //Efield in um
298 sensorThickness = 0.250;
299 }
300 if (module) {
301 sensorThickness = module->thickness() * 1000.0;//default is 200;
302 }
303
304 //Y-axis is time charge carrier travelled for,
305 //X-axis is initial position of charge carrier,
306 //Z-axis is final position of charge carrier
307 distanceMap_e = new TH2F("edistance", "Electron Distance Map", 100, 0, sensorThickness, 1000, 0, 1000); //mm by ns
308 distanceMap_h = new TH2F("hdistance", "Holes Distance Map", 100, 0, sensorThickness, 1000, 0, 1000);
309 //Initalize distance maps
310 for (int i = 1; i <= distanceMap_e->GetNbinsX(); i++) {
311 for (int j = 1; j <= distanceMap_e->GetNbinsY(); j++) {
312 distanceMap_h->SetBinContent(i, j, sensorThickness); //if you travel long enough, you will reach the electrode.
313 distanceMap_e->SetBinContent(i, j, 0.); //if you travel long enough, you will reach the electrode.
314 }
315 }
316
317 //From a given place in the sensor bulk, show time-to-electrode
318 timeMap_e = new TH1F("etimes", "Electron Time Map", 100, 0, sensorThickness); //mm
319 timeMap_h = new TH1F("htimes", "Hole Time Map", 100, 0, sensorThickness); //mm
320
321 //X axis is initial position of charge carrier (in z)
322 //Y axis is distance travelled in z by charge carrier
323 //Z axis is tan( lorentz_angle )
324 lorentzMap_e = new TH2F("lorentz_map_e", "Lorentz Map e", 100, 0, sensorThickness, 100, 0, sensorThickness); //mm by mm
325 lorentzMap_h = new TH2F("lorentz_map_h", "Lorentz Map h", 100, 0, sensorThickness, 100, 0, sensorThickness); //mm by mm
326 ATH_MSG_DEBUG("Did not find time and/or distance maps. Will compute them from the E-field map..");
327
328 for (int i = 1; i <= distanceMap_e->GetNbinsX(); i++) { //Loop over initial position of charge carrier (in z)
329 double time_e = 0.; //ns
330 double time_h = 0.; //ns
331 double distanceTravelled_e = 0; //mm
332 double distanceTravelled_h = 0; //mm
333 double drift_e = 0.; //mm
334 double drift_h = 0.; //mm
335
336 for (int j = i; j >= 1; j--) { //Lower triangle
337 double dz = distanceMap_e->GetXaxis()->GetBinWidth(j); //mm
338 double z_j = distanceMap_e->GetXaxis()->GetBinCenter(j); //mm
339 //printf("\n \n distance map bin center i/j: %f/%f width %f (mm) \n sensor thickness: %f \n E field value: %f in
340 // bin %f \n ", z_i, z_j, dz, sensorThickness, Ez, z_i*1000);
341 //
342 double Ez = eFieldMap->GetBinContent(eFieldMap->GetXaxis()->FindBin(z_j * 1000)) / 1e7; // in MV/mm;
343 std::pair<double, double> mu = getMobility(Ez, temperature); //mm^2/MV*ns
344 if (Ez > 0) {
345 //Electrons
346 //double tanLorentzAngle = mu.first*bField*(1.0E-3); //rad, unit conversion; pixelPitch_eta-Field is in T =
347 // V*s/m^2
348 double tanLorentzAngle = getTanLorentzAngle(Ez, temperature, bField, false);
349 time_e += dz / (mu.first * Ez); //mm * 1/(mm/ns) = ns
350
351 //Fill: time charge carrier travelled for, given staring position (i) and final position (z_j)
352 distanceMap_e->SetBinContent(i, distanceMap_e->GetYaxis()->FindBin(time_e), z_j);
353
354 drift_e += dz * tanLorentzAngle; //Increment the total drift parallel to plane of sensor
355 distanceTravelled_e += dz; //mm (travelled in z)
356 lorentzMap_e->SetBinContent(i, j, drift_e / distanceTravelled_e);
357 }
358 timeMap_e->SetBinContent(i, time_e);
359 }
360 //Mainly copied from l416 ff changed naming k=>j
361 //https://gitlab.cern.ch/radiationDamageDigitization/radDamage_athena_rel22/blob/rel22_radDamageDev_master/scripts/SaveMapsForAthena.C
362 for (int j = i; j <= distanceMap_e->GetNbinsX(); j++) { //holes go the opposite direction as electrons.
363 double dz = distanceMap_e->GetXaxis()->GetBinWidth(j); //similar to _h
364 //double Ez = eFieldMap->GetBinContent(eFieldMap->GetXaxis()->FindBin(z_i*1000))/1e7; // in MV/mm;
365 double z_j = distanceMap_e->GetXaxis()->GetBinCenter(j); //mm //similar to _h
366 double Ez = eFieldMap->GetBinContent(eFieldMap->GetXaxis()->FindBin(z_j * 1000)) / 1e7; // in MV/mm;
367 std::pair<double, double> mu = getMobility(Ez, temperature); //mm^2/MV*ns
368 if (Ez > 0) {
369 //Holes
370 //std::pair<double, double> mu = getMobility(Ez, temperature); //mm^2/MV*ns
371 //double tanLorentzAngle = mu.second*bField*(1.0E-3); //rad
372 double tanLorentzAngle = getTanLorentzAngle(Ez, temperature, bField, true);
373 time_h += dz / (mu.second * Ez); //mm * 1/(mm/ns) = ns
374 distanceMap_h->SetBinContent(i, distanceMap_h->GetYaxis()->FindBin(time_h), z_j);
375
376 drift_h += dz * tanLorentzAngle;
377 distanceTravelled_h += dz; //mm
378 lorentzMap_h->SetBinContent(i, j, drift_h / distanceTravelled_h);
379 }
380 timeMap_h->SetBinContent(i, time_h);
381 }
382 }
383
384 return StatusCode::SUCCESS;
385 //Finally, we make maps of the average collected charge, in order to make charge chunking corrections later.
386 //TODO: talk to Ben about the above comment. Where is code?
387}
static double getTanLorentzAngle(double electricField, double temperature, double bField, bool isHole)
Gaudi::Property< double > m_fieldScale
static const std::pair< double, double > getMobility(double electricField, double temperature)
TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)
TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)

◆ generateEfieldMap() [1/2]

const StatusCode RadDamageUtil::generateEfieldMap ( TH1F *& eFieldMap,
InDetDD::PixelModuleDesign * module )

Definition at line 214 of file RadDamageUtil.cxx.

214 {
215 //TODO: from DB
216 double biasVoltage = 600.;
217 double sensorThickness = module->thickness(); //default should be 0.2?
218 double fluence = 8.;//*e14 neq/cm^2
219
220 eFieldMap = new TH1F("hefieldz", "hefieldz", 200, 0, sensorThickness * 1e3);
221
222 std::string TCAD_list = PathResolver::find_file("ibl_TCAD_EfieldProfiles.txt", "DATAPATH"); //IBL layer
223 if (sensorThickness > 0.2) {
224 //is blayer
225 TCAD_list = PathResolver::find_file("blayer_TCAD_EfieldProfiles.txt", "DATAPATH"); //B layer
226 if (sensorThickness > 0.25) {
227 ATH_MSG_WARNING("Sensor thickness (" << sensorThickness << "mm) does not match geometry provided in samples");
228 return StatusCode::FAILURE;
229 }
230 }
231
232 CHECK(m_EfieldInterpolator->loadTCADlist(TCAD_list));
233 eFieldMap = (TH1F*) m_EfieldInterpolator->getEfield(fluence, biasVoltage);
234 return StatusCode::SUCCESS;
235}
#define ATH_MSG_WARNING(x)
#define CHECK(...)
Evaluate an expression and check for errors.
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
ToolHandle< EfieldInterpolator > m_EfieldInterpolator

◆ generateEfieldMap() [2/2]

StatusCode RadDamageUtil::generateEfieldMap ( TH1F *& eFieldMap,
InDetDD::PixelModuleDesign * module,
double fluence,
double biasVoltage,
int layer,
const std::string & TCAD_list,
bool interpolate )

Definition at line 237 of file RadDamageUtil.cxx.

238 {
239 TString id;
240 //TODO adapt saving location for documentation of E field interpolation
241 TString predirname = "";
242
243 if (interpolate) {
244 id = "Interpolation";
245 } else {
246 id = "TCAD";
247 }
248 if (interpolate) {
249 CHECK(m_EfieldInterpolator->loadTCADlist(TCAD_list));
250 eFieldMap = (TH1F*) m_EfieldInterpolator->getEfield(fluence, biasVoltage);
251 } else {
252 //retrieve E field directly from file (needs to be .dat file with table)
253 CHECK(m_EfieldInterpolator->loadTCADlist(TCAD_list));
254 ATH_MSG_INFO("Load Efield map from " << TCAD_list);
255 }
256 if (!eFieldMap) {
257 ATH_MSG_ERROR("E field has not been created!");
258 return StatusCode::FAILURE;
259 }
260 //For debugging save map
261 //TCAD_list.ReplaceAll(".txt","_map.root");
262 TString dirname = "layer";
263 dirname += layer;
264 dirname += "_fl";
265 dirname += TString::Format("%.1f", fluence / (float) (1e14));
266 dirname += "e14_U";
267 dirname += TString::Format("%.0f", biasVoltage);
268 dirname += id;
269 dirname.ReplaceAll(".", "-");
270 dirname = predirname + dirname;
271 dirname += (".root");
272 eFieldMap->SaveAs(dirname.Data(), "");
273 return StatusCode::SUCCESS;
274}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
@ layer
Definition HitInfo.h:79
std::string dirname(std::string name)
Definition utils.cxx:200

◆ generateRamoMap()

const StatusCode RadDamageUtil::generateRamoMap ( TH3F * ramPotentialMap,
InDetDD::PixelModuleDesign * module )

Definition at line 58 of file RadDamageUtil.cxx.

58 {
59 //TODO: this needs to come from DB
60 double pitchX = 0.05;
61 double pitchY = 0.25;
62 //TODO: from PixelModuleDesign
63 double sensorThickness = module->thickness() * 1000.0;//default 200;
64
65 //Ramo potential evaluated up to 2x pitch away
66 //from the center of the primary pixel.
67 double xmin = 0.;
68 double xmax = 2 * pitchX * 1000;
69 double ymin = 0.;
70 double ymax = 2 * pitchY * 1000;
71
72 //One bin per 10 microns.
73 ramoPotentialMap = new TH3F("hramomap1", "hramomap1", ((xmax - xmin) / 10.), xmin, xmax, ((ymax - ymin) / 10.), ymin,
74 ymax, int(sensorThickness * 1000) / 10, 0., sensorThickness * 1000.);
75
76 //******************
77 //*** Loop in z ***
78 //******************
79 for (int k = 1; k <= ramoPotentialMap->GetNbinsZ(); k++) {
80 //use the lower bin edge.
81 double z = ramoPotentialMap->GetZaxis()->GetBinCenter(k) - ramoPotentialMap->GetZaxis()->GetBinWidth(k) / 2.;
82
83 //******************
84 //*** Loop in x,y ***
85 //******************
86 for (int i = 1; i <= ramoPotentialMap->GetNbinsX(); i++) { //Loop over x
87 for (int j = 1; j <= ramoPotentialMap->GetNbinsY(); j++) { //loop over y
88 double x = ramoPotentialMap->GetXaxis()->GetBinCenter(i) - ramoPotentialMap->GetXaxis()->GetBinWidth(i) / 2.;
89 double y = ramoPotentialMap->GetYaxis()->GetBinCenter(j) - ramoPotentialMap->GetYaxis()->GetBinWidth(j) / 2.;
90
91 //*******************************
92 //*** Option A: 1D approx. in z
93 //*******************************
94 if (m_defaultRamo == -1) {
95 if (x > (pitchX * 1000.0 * 0.5) || y > (pitchY * 1000.0 * 0.5)) {
96 ramoPotentialMap->SetBinContent(i, j, k, 0.01); //outside of the primary pixel.
97 //TODO what is the last bin value? Is 0.01 the min?
98 } else {
99 //TODO make sure all of these eta/phi values make sense for non-barrel modules too
100 //The formula below parameterises the 1D Ramo potential. See ATL-COM-INDET-2018-011 for details.
101 double par_a = 3 * sensorThickness / pitchY;
102 double norm = exp(-par_a) + exp(-1.0);
103 double val = exp(-par_a * z / (1000.0 * sensorThickness)) + exp(-z / (1000 * sensorThickness));
104 val -= norm;
105 val /= (2.0 - norm);
106 ramoPotentialMap->SetBinContent(i, j, k, val);
107 }
108 }
109 //*******************************
110 //*** Option B: 2D approx. in xy
111 //*******************************
112 else if (m_defaultRamo == 0) {
113 double par_a = 10.0;
114 double norm = exp(-par_a) + exp(-1.);
115 double val = exp(-par_a * z / (1000 * sensorThickness)) + exp(-z / (1000 * sensorThickness));
116 val -= norm;
117 val /= (2. - norm);
118 //From equation 16 in the RadDamageDefaults support note, using solution for weighting potential in 2D
119 double productSolution = weighting2D(x, z, pitchX, sensorThickness) * weighting2D(y, z, pitchY,
120 sensorThickness) * val /
121 (weighting2D(0, z, pitchX,
122 sensorThickness) * weighting2D(0, z, pitchY, sensorThickness));
123 ramoPotentialMap->SetBinContent(i, j, k, productSolution);
124 }
125 //************************************************
126 //*** Option C: Poisson's eqn. w/ simple geometry
127 //************************************************
128 else if (m_defaultRamo > 0) {
129 double fullSolution = weighting3D(x / sensorThickness, y / sensorThickness, z / sensorThickness,
130 m_defaultRamo, m_defaultRamo, 4, pitchX / sensorThickness,
131 pitchY / sensorThickness); //N = 4 is arbitrary; just need something bigger
132 // than ~1
133 ramoPotentialMap->SetBinContent(i, j, k, fullSolution);
134 }//Ramo option > 0.
135 }//loop over y.
136 }//loop over x.
137 }//loop over z.
138 return StatusCode::SUCCESS;
139} //TODO: What about debugging the ramo potential? I vaguely remember running into issues with this.
#define y
#define x
#define z
static double weighting2D(double x, double z, double Lx, double sensorThickness)
static double weighting3D(double x, double y, double z, int n, int m, int Nrep, double a, double b)
Gaudi::Property< int > m_defaultRamo
double xmax
Definition listroot.cxx:61
double ymin
Definition listroot.cxx:63
double xmin
Definition listroot.cxx:60
double ymax
Definition listroot.cxx:64

◆ getMobility()

const std::pair< double, double > RadDamageUtil::getMobility ( double electricField,
double temperature )
static

Definition at line 392 of file RadDamageUtil.cxx.

392 {
393 //Returns the electron/hole mobility *in the z direction*
394 //Note, this already includes the Hall scattering factor!
395 //These parameterizations come from C. Jacoboni et al., Solid-State Electronics 20 89. (1977) 77. (see also
396 // https://cds.cern.ch/record/684187/files/indet-2001-004.pdf).
397 //electrons
398 double vsat_e = 15.3 * pow(temperature, -0.87);// mm/ns
399 double ecrit_e = 1.01E-7 * pow(temperature, 1.55);// MV/mm
400 double beta_e = 2.57E-2 * pow(temperature, 0.66);//dimensionless
401 double r_e = 1.13 + 0.0008 * (temperature - 273.);//Hall scaling factor
402 //holes
403 double vsat_h = 1.62 * pow(temperature, -0.52);// mm/ns
404 double ecrit_h = 1.24E-7 * pow(temperature, 1.68);// MV/mm
405 double beta_h = 0.46 * pow(temperature, 0.17);
406 double r_h = 0.72 - 0.0005 * (temperature - 273.);
407
408 double num_e = vsat_e / ecrit_e;
409 double den_e = pow(1 + pow((electricField / ecrit_e), beta_e), (1 / beta_e));
410 double mobility_e = r_e * num_e / den_e;
411
412 double num_h = vsat_h / ecrit_h;
413 double den_h = pow(1 + pow((electricField / ecrit_h), beta_h), (1 / beta_h));
414 double mobility_h = r_h * num_h / den_h;
415
416 return std::make_pair(mobility_e, mobility_h);
417}
const std::string r_e
constexpr int pow(int base, int exp) noexcept

◆ getTanLorentzAngle()

double RadDamageUtil::getTanLorentzAngle ( double electricField,
double temperature,
double bField,
bool isHole )
static

Definition at line 424 of file RadDamageUtil.cxx.

424 {
425 double hallEffect = 1.;//already in mobility//= 1.13 + 0.0008*(temperature - 273.0); //Hall Scattering Factor - taken
426 // from https://cds.cern.ch/record/684187/files/indet-2001-004.pdf
427
428 if (isHole) hallEffect = 0.72 - 0.0005 * (temperature - 273.0);
429 std::pair<double, double> mobility = getMobility(electricField, temperature);
430 double mobility_object = mobility.first;
431 if (isHole) mobility_object = mobility.second;
432 double tanLorentz = hallEffect * mobility_object * bField * (1.0E-3); //unit conversion
433 return tanLorentz;
434}

◆ getTrappingTimes()

const std::pair< double, double > RadDamageUtil::getTrappingTimes ( double fluence) const

Definition at line 439 of file RadDamageUtil.cxx.

439 {
440 double trappingTimeElectrons(0.), trappingTimeHoles(0.);
441
442 if (fluence != 0.0) {
443 trappingTimeElectrons = 1.0 / (m_betaElectrons * fluence); //Make memberVar
444 trappingTimeHoles = 1.0 / (m_betaHoles * fluence); //ns
445 } else {//fluence = 0 so do not trap!
446 trappingTimeElectrons = 1000; //~infinity
447 trappingTimeHoles = 1000;
448 }
449
450 return std::make_pair(trappingTimeElectrons, trappingTimeHoles);
451}
Gaudi::Property< double > m_betaElectrons
Gaudi::Property< double > m_betaHoles

◆ initialize()

StatusCode RadDamageUtil::initialize ( )
overridevirtual

Definition at line 44 of file RadDamageUtil.cxx.

44 {
45 ATH_CHECK(AthAlgTool::initialize());
47 ATH_MSG_DEBUG("You are using RadDamageUtil for solid-state silicon detectors.");
48 return StatusCode::SUCCESS;
49}
#define ATH_CHECK
Evaluate an expression and check for errors.

◆ initTools()

StatusCode RadDamageUtil::initTools ( )

◆ inputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ msg()

MsgStream & AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ outputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ renounce()

std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T & h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381 {
382 h.renounce();
384 }
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray & handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364 {
366 }

◆ saveDebugMaps()

bool RadDamageUtil::saveDebugMaps ( )

Definition at line 453 of file RadDamageUtil.cxx.

453 {
454 return m_saveDebugMaps;
455}
Gaudi::Property< bool > m_saveDebugMaps

◆ sysInitialize()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for an algorithm.

We override this to declare all the elements of handle key arrays at the end of initialization. See comments on updateVHKA.

Reimplemented in asg::AsgMetadataTool, AthCheckedComponent< AthAlgTool >, AthCheckedComponent<::AthAlgTool >, and DerivationFramework::CfAthAlgTool.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase & )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308 {
309 // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310 // << " size: " << m_vhka.size() << endmsg;
311 for (auto &a : m_vhka) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }
std::vector< SG::VarHandleKeyArray * > m_vhka

◆ weighting2D()

double RadDamageUtil::weighting2D ( double x,
double z,
double Lx,
double sensorThickness )
staticprivate

Definition at line 195 of file RadDamageUtil.cxx.

195 {
196 if (z == 0) z = 0.00001; //a pathology in the definition.M_PI
197
198 //scale to binsize (inputs assumed to be in mm)
199 sensorThickness *= 1000.;
200 Lx *= 1000;
201
202 //val is set according to equation 3 in the radDamageDefaults support note
203 double val =
204 (TMath::Sin(M_PI * z / sensorThickness) * TMath::SinH(0.5 * M_PI * Lx / sensorThickness) /
205 (TMath::CosH(M_PI * x / sensorThickness) - TMath::Cos(M_PI * z / sensorThickness) *
206 TMath::CosH(0.5 * M_PI * Lx / sensorThickness)));
207 if (val > 0) return TMath::ATan(val) / M_PI;
208 else return TMath::ATan(val) / M_PI + 1;
209}

◆ weighting3D()

double RadDamageUtil::weighting3D ( double x,
double y,
double z,
int n,
int m,
int Nrep,
double a,
double b )
staticprivate

Definition at line 155 of file RadDamageUtil.cxx.

155 {
156 //TODO: talk to ben about this comment:
157 //be warned that there is numerical instability if n and m are too large! Suggest n ~ m ~ 10.
158 double potential = 0.;
159
160 for (int i = -n; i <= n; i++) {
161 for (int j = -m; j <= m; j++) {
162 double X = 0.;
163 double Y = 0.;
164 double Z = 0.;
165 double factor_x = 0.;
166 double factor_y = 0.;
167 if (i == 0 && j == 0) {
168 factor_x = 1. / Nrep;
169 factor_y = factor_x;
170 Z = 1 - z;
171 } else {
172 //Equation 18 & 19 in support note
173 factor_x = std::sin(i * M_PI / Nrep) / (M_PI * i);
174 factor_y = std::sin(j * M_PI / Nrep) / (M_PI * j);
175 //Equation 17 in support note
176 double norm = std::sqrt(std::pow(alpha(i, Nrep, a), 2) + std::pow(alpha(j, Nrep, b), 2));
177 Z = std::sinh(norm * (1 - z)) / sinh(norm);
178 }
179 //Equation 18 & 19 in support note
180 X = factor_x * std::cos(alpha(i, Nrep, a) * x);
181 Y = factor_y * std::cos(alpha(j, Nrep, b) * y);
182
183 //Equation 20 in support note
184 potential += Z * X * Y;
185 }
186 }
187 return potential;
188}
static double alpha(int n, int Nrep, double a)

Member Data Documentation

◆ m_betaElectrons

Gaudi::Property<double> RadDamageUtil::m_betaElectrons
private
Initial value:
{
this, "betaElectrons", 4.5e-16, "Used in trapping time calculation"
}

Definition at line 62 of file RadDamageUtil.h.

63 {
64 this, "betaElectrons", 4.5e-16, "Used in trapping time calculation"
65 };

◆ m_betaHoles

Gaudi::Property<double> RadDamageUtil::m_betaHoles
private
Initial value:
{
this, "betaHoles", 6.0e-16, "Used in trapping time calculation"
}

Definition at line 67 of file RadDamageUtil.h.

68 {
69 this, "betaHoles", 6.0e-16, "Used in trapping time calculation"
70 };

◆ m_defaultRamo

Gaudi::Property<int> RadDamageUtil::m_defaultRamo
private
Initial value:
{
this, "defaultRamo", 1, "Mapping strategy of Ramo potential"
}

Definition at line 57 of file RadDamageUtil.h.

58 {
59 this, "defaultRamo", 1, "Mapping strategy of Ramo potential"
60 };

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default)

Definition at line 393 of file AthCommonDataStore.h.

◆ m_EfieldInterpolator

ToolHandle<EfieldInterpolator> RadDamageUtil::m_EfieldInterpolator
private
Initial value:
{
this, "EfieldInterpolator", "EfieldInterpolator",
"Create an Efield for fluence and bias volatge of interest based on TCAD samples"
}

Definition at line 83 of file RadDamageUtil.h.

84 {
85 this, "EfieldInterpolator", "EfieldInterpolator",
86 "Create an Efield for fluence and bias volatge of interest based on TCAD samples"
87 };

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default)

Definition at line 390 of file AthCommonDataStore.h.

◆ m_fieldScale

Gaudi::Property<double> RadDamageUtil::m_fieldScale {this, "fieldScale", 1.}
private

Definition at line 77 of file RadDamageUtil.h.

77{this, "fieldScale", 1.};

◆ m_saveDebugMaps

Gaudi::Property<bool> RadDamageUtil::m_saveDebugMaps
private
Initial value:
{
this, "saveDebugMaps", false, "Flag to save map"
}

Definition at line 72 of file RadDamageUtil.h.

73 {
74 this, "saveDebugMaps", false, "Flag to save map"
75 };

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.


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