24 #include "CLHEP/Random/RandExpZiggurat.h"
25 #include "CLHEP/Random/RandFlat.h"
26 #include "TLorentzVector.h"
27 #include "CLHEP/Units/PhysicalConstants.h"
47 ATH_MSG_DEBUG(
"You are using RadDamageUtil for solid-state silicon detectors.");
48 return StatusCode::SUCCESS;
63 double sensorThickness =
module->thickness() * 1000.0;
68 double xmax = 2 * pitchX * 1000;
70 double ymax = 2 * pitchY * 1000;
74 ymax,
int(sensorThickness * 1000) / 10, 0., sensorThickness * 1000.);
79 for (
int k = 1;
k <= ramoPotentialMap->GetNbinsZ();
k++) {
81 double z = ramoPotentialMap->GetZaxis()->GetBinCenter(
k) - ramoPotentialMap->GetZaxis()->GetBinWidth(
k) / 2.;
86 for (
int i = 1;
i <= ramoPotentialMap->GetNbinsX();
i++) {
87 for (
int j = 1; j <= ramoPotentialMap->GetNbinsY(); j++) {
88 double x = ramoPotentialMap->GetXaxis()->GetBinCenter(
i) - ramoPotentialMap->GetXaxis()->GetBinWidth(
i) / 2.;
89 double y = ramoPotentialMap->GetYaxis()->GetBinCenter(j) - ramoPotentialMap->GetYaxis()->GetBinWidth(j) / 2.;
95 if (
x > (pitchX * 1000.0 * 0.5) ||
y > (pitchY * 1000.0 * 0.5)) {
96 ramoPotentialMap->SetBinContent(
i, j,
k, 0.01);
101 double par_a = 3 * sensorThickness / pitchY;
103 double val =
exp(-par_a *
z / (1000.0 * sensorThickness)) +
exp(-
z / (1000 * sensorThickness));
106 ramoPotentialMap->SetBinContent(
i, j,
k,
val);
115 double val =
exp(-par_a *
z / (1000 * sensorThickness)) +
exp(-
z / (1000 * sensorThickness));
120 sensorThickness) *
val /
122 sensorThickness) *
weighting2D(0,
z, pitchY, sensorThickness));
123 ramoPotentialMap->SetBinContent(
i, j,
k, productSolution);
129 double fullSolution =
weighting3D(
x / sensorThickness,
y / sensorThickness,
z / sensorThickness,
131 pitchY / sensorThickness);
133 ramoPotentialMap->SetBinContent(
i, j,
k, fullSolution);
138 return StatusCode::SUCCESS;
147 return((2 *
M_PI *
n) / (Nrep *
a));
158 double potential = 0.;
160 for (
int i = -
n;
i <=
n;
i++) {
161 for (
int j = -
m; j <=
m; j++) {
165 double factor_x = 0.;
166 double factor_y = 0.;
167 if (
i == 0 && j == 0) {
168 factor_x = 1. / Nrep;
184 potential +=
Z *
X *
Y;
196 if (
z == 0)
z = 0.00001;
199 sensorThickness *= 1000.;
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)));
208 else return TMath::ATan(
val) /
M_PI + 1;
216 double biasVoltage = 600.;
217 double sensorThickness =
module->thickness();
220 eFieldMap =
new TH1F(
"hefieldz",
"hefieldz", 200, 0, sensorThickness * 1
e3);
223 if (sensorThickness > 0.2) {
226 if (sensorThickness > 0.25) {
227 ATH_MSG_WARNING(
"Sensor thickness (" << sensorThickness <<
"mm) does not match geometry provided in samples");
228 return StatusCode::FAILURE;
234 return StatusCode::SUCCESS;
238 double biasVoltage,
int layer,
const std::string& TCAD_list,
bool interpolate) {
241 TString predirname =
"";
244 id =
"Interpolation";
258 return StatusCode::FAILURE;
272 eFieldMap->SaveAs(
dirname.Data(),
"");
273 return StatusCode::SUCCESS;
284 TH1F*& timeMap_h,
TH2F*& lorentzMap_e,
TH2F*& lorentzMap_h,
289 double temperature = 300;
294 double sensorThickness = 0.2;
297 if (eFieldMap->GetXaxis()->GetXmax() > 210) {
298 sensorThickness = 0.250;
301 sensorThickness =
module->thickness() * 1000.0;
307 distanceMap_e =
new TH2F(
"edistance",
"Electron Distance Map", 100, 0, sensorThickness, 1000, 0, 1000);
308 distanceMap_h =
new TH2F(
"hdistance",
"Holes Distance Map", 100, 0, sensorThickness, 1000, 0, 1000);
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);
313 distanceMap_e->SetBinContent(
i, j, 0.);
318 timeMap_e =
new TH1F(
"etimes",
"Electron Time Map", 100, 0, sensorThickness);
319 timeMap_h =
new TH1F(
"htimes",
"Hole Time Map", 100, 0, sensorThickness);
324 lorentzMap_e =
new TH2F(
"lorentz_map_e",
"Lorentz Map e", 100, 0, sensorThickness, 100, 0, sensorThickness);
325 lorentzMap_h =
new TH2F(
"lorentz_map_h",
"Lorentz Map h", 100, 0, sensorThickness, 100, 0, sensorThickness);
326 ATH_MSG_DEBUG(
"Did not find time and/or distance maps. Will compute them from the E-field map..");
328 for (
int i = 1;
i <= distanceMap_e->GetNbinsX();
i++) {
331 double distanceTravelled_e = 0;
332 double distanceTravelled_h = 0;
336 for (
int j =
i; j >= 1; j--) {
337 double dz = distanceMap_e->GetXaxis()->GetBinWidth(j);
338 double z_j = distanceMap_e->GetXaxis()->GetBinCenter(j);
342 double Ez = eFieldMap->GetBinContent(eFieldMap->GetXaxis()->FindBin(z_j * 1000)) / 1e7;
349 time_e += dz / (
mu.first * Ez);
352 distanceMap_e->SetBinContent(
i, distanceMap_e->GetYaxis()->FindBin(time_e), z_j);
354 drift_e += dz * tanLorentzAngle;
355 distanceTravelled_e += dz;
356 lorentzMap_e->SetBinContent(
i, j, drift_e / distanceTravelled_e);
358 timeMap_e->SetBinContent(
i, time_e);
362 for (
int j =
i; j <= distanceMap_e->GetNbinsX(); j++) {
363 double dz = distanceMap_e->GetXaxis()->GetBinWidth(j);
365 double z_j = distanceMap_e->GetXaxis()->GetBinCenter(j);
366 double Ez = eFieldMap->GetBinContent(eFieldMap->GetXaxis()->FindBin(z_j * 1000)) / 1e7;
373 time_h += dz / (
mu.second * Ez);
374 distanceMap_h->SetBinContent(
i, distanceMap_h->GetYaxis()->FindBin(time_h), z_j);
376 drift_h += dz * tanLorentzAngle;
377 distanceTravelled_h += dz;
378 lorentzMap_h->SetBinContent(
i, j, drift_h / distanceTravelled_h);
380 timeMap_h->SetBinContent(
i, time_h);
384 return StatusCode::SUCCESS;
398 double vsat_e = 15.3 *
pow(temperature, -0.87);
399 double ecrit_e = 1.01E-7 *
pow(temperature, 1.55);
400 double beta_e = 2.57E-2 *
pow(temperature, 0.66);
401 double r_e = 1.13 + 0.0008 * (temperature - 273.);
403 double vsat_h = 1.62 *
pow(temperature, -0.52);
404 double ecrit_h = 1.24E-7 *
pow(temperature, 1.68);
405 double beta_h = 0.46 *
pow(temperature, 0.17);
406 double r_h = 0.72 - 0.0005 * (temperature - 273.);
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;
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;
416 return std::make_pair(mobility_e, mobility_h);
425 double hallEffect = 1.;
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);
440 double trappingTimeElectrons(0.), trappingTimeHoles(0.);
442 if (fluence != 0.0) {
446 trappingTimeElectrons = 1000;
447 trappingTimeHoles = 1000;
450 return std::make_pair(trappingTimeElectrons, trappingTimeHoles);
462 return StatusCode::SUCCESS;