23 #include "CLHEP/Geometry/Point3D.h"
24 #include "CLHEP/Random/RandomEngine.h"
25 #include "CLHEP/Random/RandGaussZiggurat.h"
36 const std::string&
name,
137 const SCT_ID* sct_id{
nullptr};
149 ATH_MSG_INFO(
"\tsurface drift still not on, wrong params");
154 ATH_MSG_FATAL(
"\tCannot set both FixedTime and SubtractTime options!");
155 ATH_MSG_INFO(
"\tMake sure the two flags are not set simultaneously in jo");
156 return StatusCode::FAILURE;
161 return StatusCode::SUCCESS;
169 return StatusCode::SUCCESS;
176 if (element==
nullptr) {
177 ATH_MSG_ERROR(
"SCT_SurfaceChargesGenerator::process element is nullptr");
181 if (design==
nullptr) {
182 ATH_MSG_ERROR(
"SCT_SurfaceChargesGenerator::process can not get " << design);
185 const double thickness{design->thickness()};
188 if ((zhit < 0.0) or (zhit > thickness)) {
193 float depletionVoltage{0.};
194 float biasVoltage{0.};
203 const float denominator{
static_cast<float>(depletionVoltage + biasVoltage - (2.0 * zhit * depletionVoltage / thickness))};
205 if (biasVoltage >= depletionVoltage) {
207 ATH_MSG_ERROR(
"driftTime: negative argument X for log(X) " << zhit);
217 t_drift *= thickness * thickness / (2.0 *
m_siPropertiesTool->getSiProperties(hashId, ctx).holeDriftMobility() * depletionVoltage);
225 if (element==
nullptr) {
226 ATH_MSG_ERROR(
"SCT_SurfaceChargesGenerator::diffusionSigma element is nullptr");
233 const float sigma{
static_cast<float>(std::sqrt(2. *
m_siPropertiesTool->getSiProperties(hashId, ctx).holeDiffusionConstant() *
t))};
245 const float sensorThickness{
static_cast<float>(element->
thickness())};
246 return driftTime(sensorThickness, element, ctx);
258 const float sensorThickness{
static_cast<float>(element->
thickness())};
273 float t_surfaceDrift{0.};
281 return t_surfaceDrift;
298 CLHEP::HepRandomEngine * rndmEngine,
299 const EventContext& ctx) {
312 unsigned short p_eventId,
313 CLHEP::HepRandomEngine* rndmEngine,
314 const EventContext& ctx) {
316 if (design==
nullptr) {
317 ATH_MSG_ERROR(
"SCT_SurfaceChargesGenerator::process can not get " << design);
321 const double thickness{design->thickness()};
329 float timeOfFlight{p_eventTime +
hitTime(phit)};
347 const float cEta{
static_cast<float>(endPos[
SiHit::xEta]) - xEta};
348 const float cPhi{
static_cast<float>(endPos[
SiHit::xPhi]) - xPhi};
349 const float cDep{
static_cast<float>(endPos[
SiHit::xDep]) - xDep};
351 const float LargeStep{std::sqrt(cEta*cEta + cPhi*cPhi + cDep*cDep)};
355 const float q1{
static_cast<float>(
e1 *
m_siPropertiesTool->getSiProperties(hashId, ctx).electronHolePairsPerEnergy())};
382 const float StepX{cEta / numberOfSteps};
383 const float StepY{cPhi / numberOfSteps};
384 const float StepZ{cDep / numberOfSteps};
401 for (
int istep{0}; istep < numberOfSteps; ++istep) {
403 float z1{zhit + StepZ * dstep};
407 float zReadout{
static_cast<float>(0.5 * thickness - design->readoutSide() * z1)};
408 const double spess{zReadout};
415 float t_drift{
driftTime(zReadout, element, ctx)};
416 if (t_drift>-2.0000002 and t_drift<-1.9999998) {
417 ATH_MSG_DEBUG(
"Checking for rounding errors in compression");
418 if ((std::abs(z1) - 0.5 * thickness) < 0.000010) {
419 ATH_MSG_DEBUG(
"Rounding error found attempting to correct it. z1 = " << std::fixed << std::setprecision(8) << z1);
421 z1 = 0.0000005 - 0.5 * thickness;
424 z1 = 0.5 * thickness - 0.0000005;
427 zReadout = 0.5 * thickness - design->readoutSide() * z1;
428 t_drift =
driftTime(zReadout, element, ctx);
429 if (t_drift>-2.0000002 and t_drift<-1.9999998) {
432 ATH_MSG_DEBUG(
"Correction Successful! z1 = " << std::fixed << std::setprecision(8) << z1 <<
", zReadout = " << zReadout <<
", t_drift = " << t_drift);
435 ATH_MSG_DEBUG(
"No rounding error found. Making no correction.");
439 const float x1{xhit + StepX * dstep};
440 float y1{yhit + StepY * dstep};
445 y1 += tanLorentz * zReadout;
449 const float rx{CLHEP::RandGaussZiggurat::shoot(rndmEngine)};
451 const float ry{CLHEP::RandGaussZiggurat::shoot(rndmEngine)};
452 const float yd{
y1 +
sigma * ry};
455 const double stripPitch{0.080};
456 double dstrip{
y1 / stripPitch};
458 dstrip = dstrip - std::trunc(dstrip);
460 dstrip = dstrip - std::trunc(dstrip) + 1;
464 double y0{dstrip * stripPitch};
465 double z0{thickness - zReadout};
472 double trap_pos{-999999.}, drift_time{-999999.};
477 double Q_all[5]={0.0,0.0,0.0,0.0,0.0};
479 dstrip =
y1 / stripPitch;
485 dstrip -=
static_cast<double>(
static_cast<int>(dstrip));
487 dstrip -=
static_cast<double>(
static_cast<int>(dstrip)) + 1;
491 double yfin{dstrip * stripPitch};
492 double zfin{thickness - trap_pos};
494 m_radDamageTool->holeTransport(y0,
z0, yfin, zfin, Q_all[0], Q_all[1], Q_all[2], Q_all[3], Q_all[4]);
496 const double ystrip{yd +
strip * stripPitch};
498 if (design->inActiveArea(position)) {
500 const double time{drift_time};
521 const double mm2cm = 0.1;
525 Q_m2, Q_m1, Q_00, Q_p1, Q_p2,
530 Q_m2, Q_m1, Q_00, Q_p1, Q_p2,
535 if (Q_00[
it] == 0.0)
continue;
536 double ICM_time{(
it+0.5)*0.5 + timeOfFlight};
538 Q_m2[
it], Q_m1[
it], Q_00[
it], Q_p1[
it], Q_p2[
it]
541 double ystrip{
y1 +
strip * stripPitch};
543 if (design->inActiveArea(position)) {
546 ICM_time, hitproc, trklink)));
552 if (design->inActiveArea(position)) {
553 const float sdist{
static_cast<float>(design->scaledDistanceToNearestDiode(position))};
556 const float totaltime{(
m_tfix > -998.) ?
m_tfix.value() : t_drift + timeOfFlight + t_surf};
559 ATH_MSG_VERBOSE(std::fixed << std::setprecision(8) <<
"Local position (phi, eta, depth): ("
560 << position.xPhi() <<
", " << position.xEta() <<
", " << position.xDepth()
561 <<
") of the element is out of active area, charge = " << q1);
573 double& drift_time) {
574 if (element==
nullptr) {
575 ATH_MSG_ERROR(
"SCT_SurfaceChargesGenerator::chargeIsTrapped element is nullptr");
578 bool isTrapped{
false};
581 const double electric_field{condData.getElectricField()};
584 const double mobChar{condData.getHoleDriftMobility()};
588 m_h_vel->Fill(electric_field, electric_field * mobChar);
590 const double t_electrode{condData.getTimeToElectrode()};
591 drift_time = condData.getTrappingTime();
592 const double z_trap{condData.getTrappingPositionZ()};
593 trap_pos = spess - z_trap;
602 if (drift_time < t_electrode) {
604 ATH_MSG_INFO(
"drift_time: " << drift_time <<
" t_electrode: " << t_electrode <<
" spess " << spess);
609 m_h_drift1->Fill(spess, drift_time / t_electrode);
610 m_h_gen->Fill(spess, drift_time);
612 m_h_gen2->Fill(spess, z_trap / drift_time * t_electrode);
620 const double z_trap{condData.getTrappingPositionZ()};