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()};