ATLAS Offline Software
Loading...
Searching...
No Matches
ITk::StripSurfaceChargesGenerator Class Reference

#include <StripSurfaceChargesGenerator.h>

Inheritance diagram for ITk::StripSurfaceChargesGenerator:
Collaboration diagram for ITk::StripSurfaceChargesGenerator:

Classes

struct  Hists

Public Member Functions

 StripSurfaceChargesGenerator (const std::string &type, const std::string &name, const IInterface *parent)
 constructor
virtual ~StripSurfaceChargesGenerator ()=default
 Destructor.
virtual StatusCode initialize () override
 AlgTool initialize.
virtual StatusCode finalize () override
 AlgTool finalize.

Private Member Functions

virtual void setFixedTime (float fixedTime) override
virtual void process (const InDetDD::SiDetectorElement *element, const TimedHitPtr< SiHit > &phit, ISiSurfaceChargesInserter &inserter, CLHEP::HepRandomEngine *rndmEngine, const EventContext &ctx) override
 create a list of surface charges from a hit
void processSiHit (const InDetDD::SiDetectorElement *element, const SiHit &phit, ISiSurfaceChargesInserter &inserter, float eventTime, unsigned short eventID, CLHEP::HepRandomEngine *rndmEngine, const EventContext &ctx) const
float driftTime (float zhit, const InDetDD::SiDetectorElement *element, const EventContext &ctx) const
 calculate drift time perpandicular to the surface for a charge at distance zhit from mid gap
float diffusionSigma (float zhit, const InDetDD::SiDetectorElement *element, const EventContext &ctx) const
 calculate diffusion sigma from a gaussian dist scattered charge
float surfaceDriftTime (float ysurf) const
 Calculate of the surface drift time.
float maxDriftTime (const InDetDD::SiDetectorElement *element, const EventContext &ctx) const
 max drift charge equivalent to the detector thickness
float maxDiffusionSigma (const InDetDD::SiDetectorElement *element, const EventContext &ctx) const
 max sigma diffusion
bool chargeIsTrapped (double spess, const InDetDD::SiDetectorElement *element, double &trap_pos, double &drift_time) const
HistsgetHists () const

Private Attributes

IntegerProperty m_numberOfCharges {this, "NumberOfCharges", 1, "number of charges"}
FloatProperty m_smallStepLength {this, "SmallStepLength", 5 * CLHEP::micrometer, "max internal step along the larger G4 step"}
FloatProperty m_tSurfaceDrift {this, "SurfaceDriftTime", 10 * CLHEP::ns, "max surface drift time"}
 related to the surface drift
FloatProperty m_tfix {this, "FixedTime", -999., "fixed time"}
FloatProperty m_tsubtract {this, "SubtractTime", -999., "subtract drift time from mid gap"}
BooleanProperty m_useSiCondDB {this, "UseSiCondDB", true, "Usage of SiConditions DB values can be disabled to use setable ones"}
FloatProperty m_vdepl {this, "DepletionVoltage", 70., "depletion voltage, default 70V"}
FloatProperty m_vbias {this, "BiasVoltage", 150., "bias voltage, default 150V"}
BooleanProperty m_doTrapping {this, "doTrapping", false, "Flag to set Charge Trapping"}
BooleanProperty m_doHistoTrap {this, "doHistoTrap", false, "Histogram the charge trapping effect"}
BooleanProperty m_doRamo {this, "doRamo", false, "Ramo Potential for charge trapping effect"}
BooleanProperty m_isOverlay {this, "isOverlay", false, "flag for overlay"}
BooleanProperty m_doInducedChargeModel {this, "doInducedChargeModel", false, "Flag for Induced Charge Model"}
ToolHandle< ISiPropertiesToolm_siPropertiesTool {this, "SiPropertiesTool", "StripSiPropertiesTool", "Tool to retrieve SCT silicon properties"}
ToolHandle< ISCT_RadDamageSummaryToolm_radDamageTool {this, "RadDamageSummaryTool", "StripRadDamageSummaryTool", "Tool to retrieve SCT radiation damages"}
ToolHandle< ISiliconConditionsToolm_siConditionsTool {this, "SiConditionsTool", "StripSiliconConditionsTool", "Tool to retrieve SCT silicon information"}
ToolHandle< ISiLorentzAngleToolm_lorentzAngleTool {this, "LorentzAngleTool", "SiLorentzAngleTool/ITkStripLorentzAngleTool", "Tool to retreive Lorentz angle"}
ServiceHandle< ITHistSvc > m_thistSvc {this, "THistSvc", "THistSvc"}
SG::ReadCondHandleKey< AtlasFieldCacheCondObjm_fieldCacheCondObjInputKey
float m_tHalfwayDrift {0.}
 Surface drift time.
float m_distInterStrip {1.0}
 Inter strip distance normalized to 1.
float m_distHalfInterStrip {0.}
 Half way distance inter strip.
bool m_SurfaceDriftFlag {false}
 surface drift ON/OFF
std::unique_ptr< Histsm_h
std::unique_ptr< InducedChargeModelm_InducedChargeModel

Detailed Description

Definition at line 62 of file StripSurfaceChargesGenerator.h.

Constructor & Destructor Documentation

◆ StripSurfaceChargesGenerator()

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

constructor

Definition at line 40 of file StripSurfaceChargesGenerator.cxx.

43 : base_class(type, name, parent) {
44}

◆ ~StripSurfaceChargesGenerator()

virtual ITk::StripSurfaceChargesGenerator::~StripSurfaceChargesGenerator ( )
virtualdefault

Destructor.

Member Function Documentation

◆ chargeIsTrapped()

bool ITk::StripSurfaceChargesGenerator::chargeIsTrapped ( double spess,
const InDetDD::SiDetectorElement * element,
double & trap_pos,
double & drift_time ) const
private

Definition at line 622 of file StripSurfaceChargesGenerator.cxx.

625 {
626 if (element==nullptr) {
627 ATH_MSG_ERROR("StripSurfaceChargesGenerator::chargeIsTrapped element is nullptr");
628 return false;
629 }
630 bool isTrapped{false};
631 const IdentifierHash hashId{element->identifyHash()};
632 const SCT_ChargeTrappingCondData condData{m_radDamageTool->getCondData(hashId, spess)};
633 const double electric_field{condData.getElectricField()};
634
635 if (m_doHistoTrap) {
636 Hists& h = getHists();
637 const double mobChar{condData.getHoleDriftMobility()};
638 h.m_h_efieldz->Fill(spess, electric_field);
639 h.m_h_efield->Fill(electric_field);
640 h.m_h_mob_Char->Fill(electric_field, mobChar);
641 h.m_h_vel->Fill(electric_field, electric_field * mobChar);
642 }
643 const double t_electrode{condData.getTimeToElectrode()};
644 drift_time = condData.getTrappingTime();
645 const double z_trap{condData.getTrappingPositionZ()};
646 trap_pos = spess - z_trap;
647 if (m_doHistoTrap) {
648 Hists& h = getHists();
649 h.m_h_drift_time->Fill(drift_time);
650 h.m_h_t_electrode->Fill(t_electrode);
651 h.m_h_drift_electrode->Fill(drift_time, t_electrode);
652 h.m_h_ztrap_tot->Fill(z_trap);
653 }
654 // -- Calculate if the charge is trapped, and at which distance
655 // -- Charge gets trapped before arriving to the electrode
656 if (drift_time < t_electrode) {
657 isTrapped = true;
658 ATH_MSG_INFO("drift_time: " << drift_time << " t_electrode: " << t_electrode << " spess " << spess);
659 ATH_MSG_INFO("z_trap: " << z_trap);
660 if (m_doHistoTrap) {
661 Hists& h = getHists();
662 h.m_h_ztrap->Fill(z_trap);
663 h.m_h_trap_drift_t->Fill(drift_time);
664 h.m_h_drift1->Fill(spess, drift_time / t_electrode);
665 h.m_h_gen->Fill(spess, drift_time);
666 h.m_h_gen1->Fill(spess, z_trap);
667 h.m_h_gen2->Fill(spess, z_trap / drift_time * t_electrode);
668 h.m_h_velocity_trap->Fill(electric_field, z_trap / drift_time);
669 h.m_h_mobility_trap->Fill(electric_field, z_trap / drift_time / electric_field);
670 h.m_h_trap_pos->Fill(trap_pos);
671 }
672 } else {
673 isTrapped = false;
674 if (m_doHistoTrap) {
675 const double z_trap{condData.getTrappingPositionZ()};
676 Hists& h = getHists();
677 h.m_h_no_ztrap->Fill(z_trap);
678 h.m_h_notrap_drift_t->Fill(drift_time);
679 }
680 }
681 return isTrapped;
682}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
ToolHandle< ISCT_RadDamageSummaryTool > m_radDamageTool
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)

◆ diffusionSigma()

float ITk::StripSurfaceChargesGenerator::diffusionSigma ( float zhit,
const InDetDD::SiDetectorElement * element,
const EventContext & ctx ) const
private

calculate diffusion sigma from a gaussian dist scattered charge

Definition at line 242 of file StripSurfaceChargesGenerator.cxx.

242 {
243 if (element==nullptr) {
244 ATH_MSG_ERROR("StripSurfaceChargesGenerator::diffusionSigma element is nullptr");
245 return 0.0;
246 }
247 const IdentifierHash hashId{element->identifyHash()};
248 const float t{driftTime(zhit, element, ctx)}; // in ns
249
250 if (t > 0.0) {
251 const float sigma{static_cast<float>(std::sqrt(2. * m_siPropertiesTool->getSiProperties(hashId, ctx).holeDiffusionConstant() * t))}; // in mm
252 return sigma;
253 } else {
254 return 0.0;
255 }
256}
float driftTime(float zhit, const InDetDD::SiDetectorElement *element, const EventContext &ctx) const
calculate drift time perpandicular to the surface for a charge at distance zhit from mid gap
ToolHandle< ISiPropertiesTool > m_siPropertiesTool

◆ driftTime()

float ITk::StripSurfaceChargesGenerator::driftTime ( float zhit,
const InDetDD::SiDetectorElement * element,
const EventContext & ctx ) const
private

calculate drift time perpandicular to the surface for a charge at distance zhit from mid gap

Definition at line 193 of file StripSurfaceChargesGenerator.cxx.

193 {
194 if (element==nullptr) {
195 ATH_MSG_ERROR("StripSurfaceChargesGenerator::process element is nullptr");
196 return -2.0;
197 }
198 const SCT_ModuleSideDesign* design{dynamic_cast<const SCT_ModuleSideDesign*>(&(element->design()))};
199 if (design==nullptr) {
200 ATH_MSG_ERROR("StripSurfaceChargesGenerator::process can not get " << design);
201 return -2.0;
202 }
203 const double thickness{design->thickness()};
204 const IdentifierHash hashId{element->identifyHash()};
205
206 if ((zhit < 0.0) or (zhit > thickness)) {
207 ATH_MSG_DEBUG("driftTime: hit coordinate zhit=" << zhit / CLHEP::micrometer << " out of range");
208 return -2.0;
209 }
210
211 float depletionVoltage{0.};
212 float biasVoltage{0.};
213 if (m_useSiCondDB) {
214 depletionVoltage = m_siConditionsTool->depletionVoltage(hashId, ctx) * CLHEP::volt;
215 biasVoltage = m_siConditionsTool->biasVoltage(hashId, ctx) * CLHEP::volt;
216 } else {
217 depletionVoltage = m_vdepl * CLHEP::volt;
218 biasVoltage = m_vbias * CLHEP::volt;
219 }
220
221 const float denominator{static_cast<float>(depletionVoltage + biasVoltage - (2.0 * zhit * depletionVoltage / thickness))};
222 if (denominator <= 0.0) {
223 if (biasVoltage >= depletionVoltage) { // Should not happen
224 if(not m_isOverlay) {
225 ATH_MSG_ERROR("driftTime: negative argument X for log(X) " << zhit);
226 }
227 return -1.0;
228 } else {
229 // (m_biasVoltage<m_depletionVoltage) can happen with underdepleted sensors, lose charges in that volume
230 return -10.0;
231 }
232 }
233
234 float t_drift{std::log((depletionVoltage + biasVoltage) / denominator)};
235 t_drift *= thickness * thickness / (2.0 * m_siPropertiesTool->getSiProperties(hashId, ctx).holeDriftMobility() * depletionVoltage);
236 return t_drift;
237}
#define ATH_MSG_DEBUG(x)
ToolHandle< ISiliconConditionsTool > m_siConditionsTool
double thickness() const
Method which returns thickness of the silicon wafer.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):

◆ finalize()

StatusCode ITk::StripSurfaceChargesGenerator::finalize ( )
overridevirtual

AlgTool finalize.

Definition at line 185 of file StripSurfaceChargesGenerator.cxx.

185 {
186 ATH_MSG_DEBUG("StripSurfaceChargesGenerator::finalize()");
187 return StatusCode::SUCCESS;
188}

◆ getHists()

StripSurfaceChargesGenerator::Hists & ITk::StripSurfaceChargesGenerator::getHists ( ) const
private

Definition at line 686 of file StripSurfaceChargesGenerator.cxx.

687{
688 // We earlier checked that no more than one thread is being used.
689 Hists* h ATLAS_THREAD_SAFE = m_h.get();
690 return *h;
691}
#define ATLAS_THREAD_SAFE

◆ initialize()

StatusCode ITk::StripSurfaceChargesGenerator::initialize ( )
overridevirtual

AlgTool initialize.

Definition at line 49 of file StripSurfaceChargesGenerator.cxx.

49 {
50 ATH_MSG_DEBUG("StripSurfaceChargesGenerator::initialize()");
51
52 // Get ISiPropertiesTool
53 ATH_CHECK(m_siPropertiesTool.retrieve());
54
55 // Get ISiliconConditionsSvc
56 ATH_CHECK(m_siConditionsTool.retrieve());
57
59
60 if (m_doTrapping) {
61 // -- Get Radiation Damage Tool
62 ATH_CHECK(m_radDamageTool.retrieve());
63 } else {
64 m_radDamageTool.disable();
65 }
66
67 if (m_doHistoTrap) {
68 if (Gaudi::Concurrency::ConcurrencyFlags::numThreads() > 1) {
69 ATH_MSG_FATAL("Filling histograms not supported in MT jobs.");
70 return StatusCode::FAILURE;
71 }
72
73 // -- Get Histogram Service
74 ATH_CHECK(m_thistSvc.retrieve());
75 m_h = std::make_unique<Hists>();
76 ATH_CHECK(m_h->book(*m_thistSvc));
77 }
79
80 // Induced Charge Module.
82 const SCT_ID* sct_id{nullptr};
83 ATH_CHECK(detStore()->retrieve(sct_id, "SCT_ID"));
84 m_InducedChargeModel = std::make_unique<InducedChargeModel>(sct_id->wafer_hash_max());
85 }
86
87 // Surface drift time calculation Stuff
90 if ((m_tSurfaceDrift > m_tHalfwayDrift) and (m_tHalfwayDrift >= 0.0) and
92 m_SurfaceDriftFlag = true;
93 } else {
94 ATH_MSG_INFO("\tsurface drift still not on, wrong params");
95 }
96
97 // Make sure these two flags are not set simultaneously
98 if (m_tfix>-998. and m_tsubtract>-998.) {
99 ATH_MSG_FATAL("\tCannot set both FixedTime and SubtractTime options!");
100 ATH_MSG_INFO("\tMake sure the two flags are not set simultaneously in jo");
101 return StatusCode::FAILURE;
102 }
103
104 ATH_CHECK(m_lorentzAngleTool.retrieve());
105
106 return StatusCode::SUCCESS;
107}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
FloatProperty m_tSurfaceDrift
related to the surface drift
ToolHandle< ISiLorentzAngleTool > m_lorentzAngleTool
float m_distInterStrip
Inter strip distance normalized to 1.
std::unique_ptr< InducedChargeModel > m_InducedChargeModel
float m_distHalfInterStrip
Half way distance inter strip.
size_type wafer_hash_max() const
Definition SCT_ID.cxx:621
retrieve(aClass, aKey=None)
Definition PyKernel.py:110

◆ maxDiffusionSigma()

float ITk::StripSurfaceChargesGenerator::maxDiffusionSigma ( const InDetDD::SiDetectorElement * element,
const EventContext & ctx ) const
private

max sigma diffusion

Definition at line 274 of file StripSurfaceChargesGenerator.cxx.

274 {
275 if (element) {
276 const float sensorThickness{static_cast<float>(element->thickness())};
277 return diffusionSigma(sensorThickness, element, ctx);
278 } else {
279 ATH_MSG_INFO("Error: SiDetectorElement not set!");
280 return 0.;
281 }
282}
float diffusionSigma(float zhit, const InDetDD::SiDetectorElement *element, const EventContext &ctx) const
calculate diffusion sigma from a gaussian dist scattered charge

◆ maxDriftTime()

float ITk::StripSurfaceChargesGenerator::maxDriftTime ( const InDetDD::SiDetectorElement * element,
const EventContext & ctx ) const
private

max drift charge equivalent to the detector thickness

Definition at line 261 of file StripSurfaceChargesGenerator.cxx.

261 {
262 if (element) {
263 const float sensorThickness{static_cast<float>(element->thickness())};
264 return driftTime(sensorThickness, element, ctx);
265 } else {
266 ATH_MSG_INFO("Error: SiDetectorElement not set!");
267 return 0.;
268 }
269}

◆ process()

void ITk::StripSurfaceChargesGenerator::process ( const InDetDD::SiDetectorElement * element,
const TimedHitPtr< SiHit > & phit,
ISiSurfaceChargesInserter & inserter,
CLHEP::HepRandomEngine * rndmEngine,
const EventContext & ctx )
overrideprivatevirtual

create a list of surface charges from a hit

Definition at line 313 of file StripSurfaceChargesGenerator.cxx.

317 {
318 ATH_MSG_VERBOSE("StripSurfaceChargesGenerator::process starts");
319 processSiHit(element, *phit, inserter, phit.eventTime(), phit.eventId(), rndmEngine, ctx);
320}
#define ATH_MSG_VERBOSE(x)
void processSiHit(const InDetDD::SiDetectorElement *element, const SiHit &phit, ISiSurfaceChargesInserter &inserter, float eventTime, unsigned short eventID, CLHEP::HepRandomEngine *rndmEngine, const EventContext &ctx) const
unsigned short eventId() const
the index of the component event in PileUpEventInfo.
Definition TimedHitPtr.h:47
float eventTime() const
t0 offset of the bunch xing containing the hit in ns.
Definition TimedHitPtr.h:55

◆ processSiHit()

void ITk::StripSurfaceChargesGenerator::processSiHit ( const InDetDD::SiDetectorElement * element,
const SiHit & phit,
ISiSurfaceChargesInserter & inserter,
float eventTime,
unsigned short eventID,
CLHEP::HepRandomEngine * rndmEngine,
const EventContext & ctx ) const
private

Definition at line 326 of file StripSurfaceChargesGenerator.cxx.

332 {
333 const SCT_ModuleSideDesign* design;
334 const SCT_ModuleSideDesign* initialDesign{dynamic_cast<const SCT_ModuleSideDesign*>(&(element->design()))};
335 if (initialDesign==nullptr) {
336 ATH_MSG_ERROR("StripSurfaceChargesGenerator::process can not get " << initialDesign);
337 return;
338 }
339
340 //If this proves costly, we can pass a (potentially null) motherDesign
341 //in the interface instead, but this will require a new interface class
342 //(see comment in SiDigitization/ISurfaceChargesGenerator.h)
343
344 const SCT_ModuleSideDesign* motherDesign = initialDesign->getMother();
345
346 if(motherDesign!=nullptr){
347 ATH_MSG_DEBUG("Found a Mother Design - Using it!");
348 design = motherDesign;
349 }
350 else {
351 ATH_MSG_DEBUG("No Mother Design - Using Design from DetElement directly!");
352 design = initialDesign;
353 }
354
355 const double thickness{design->thickness()};
356 const IdentifierHash hashId{element->identifyHash()};
357 const double tanLorentz{m_lorentzAngleTool->getTanLorentzAngle(hashId, ctx)};
358
359 // ---**************************************
360 // Time of Flight Calculation - separate method?
361 // ---**************************************
362 // --- Original calculation of Time of Flight of the particle Time needed by the particle to reach the sensor
363 float timeOfFlight{p_eventTime + hitTime(phit)};
364
365 // Kondo 19/09/2007: Use the coordinate of the center of the module to calculate the time of flight
366 timeOfFlight -= (element->center().mag()) / CLHEP::c_light;
367 // !< extract the distance to the origin of the module to Time of flight
368
369 // !< timing set from jo to adjust (subtract) the timing
370 if (m_tsubtract > -998.) {
371 timeOfFlight -= m_tsubtract;
372 }
373 // ---**************************************
374
375 const CLHEP::Hep3Vector pos{phit.localStartPosition()};
376 const float xEta{static_cast<float>(pos[SiHit::xEta])};
377 const float xPhi{static_cast<float>(pos[SiHit::xPhi])};
378 const float xDep{static_cast<float>(pos[SiHit::xDep])};
379
380 const CLHEP::Hep3Vector endPos{phit.localEndPosition()};
381 const float cEta{static_cast<float>(endPos[SiHit::xEta]) - xEta};
382 const float cPhi{static_cast<float>(endPos[SiHit::xPhi]) - xPhi};
383 const float cDep{static_cast<float>(endPos[SiHit::xDep]) - xDep};
384
385
386
387 const float largeStep{std::sqrt(cEta*cEta + cPhi*cPhi + cDep*cDep)};
388 const int numberOfSteps{static_cast<int>(largeStep / m_smallStepLength) + 1};
389 const float steps{static_cast<float>(m_numberOfCharges * numberOfSteps)};
390 const float e1{static_cast<float>(phit.energyLoss() / steps)};
391 const float q1{static_cast<float>(e1 * m_siPropertiesTool->getSiProperties(hashId, ctx).electronHolePairsPerEnergy())};
392
393 // NB this is different to the SCT, where this would be
394 //float xhit{xEta};
395 //float yhit{xPhi};
396 //float zhit{xDep};
397 //float cX{cEta};
398 //float cY{cPhi};
399 //float cZ{cDep};
400
401 float xhit{xDep};
402 float yhit{xPhi};
403 float zhit{xEta};
404 float cX{cDep};
405 float cY{cPhi};
406 float cZ{cEta};
407
408 InducedChargeModel::SCT_InducedChargeModelData* data{nullptr};
409 if (m_doInducedChargeModel) { // Setting magnetic field for the ICM.
410 SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCacheCondObjInputKey, ctx};
411 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
412 float vdepl{m_vdepl};
413 float vbias{m_vbias};
414 if (m_useSiCondDB) {
415 vdepl = m_siConditionsTool->depletionVoltage(hashId, ctx);
416 vbias = m_siConditionsTool->biasVoltage(hashId, ctx);
417 }
418 data = m_InducedChargeModel->setWaferData(vdepl,
419 vbias,
420 element,
421 fieldCondObj,
423 rndmEngine,
424 ctx);
425 }
426
427 const float stepX{cX / numberOfSteps};
428 const float stepY{cY / numberOfSteps};
429 const float stepZ{cZ / numberOfSteps};
430
431 // check the status of truth information for this SiHit
432 // some Truth information is cut for pile up events
433 const HepMcParticleLink trklink = HepMcParticleLink::getRedirectedLink(phit.particleLink(), p_eventId, ctx); // This link should now correctly resolve to the TruthEvent McEventCollection in the main StoreGateSvc.
435 if (phit.truthID() != 0 || phit.truthBarcode() != 0) { // if the hit was not caused by a delta-ray then one of these must be true
436 if (not trklink.isValid()) {
437 // TODO consider extending this check to reject links to
438 // GenEvents other than the first one in the McEventCollection,
439 // so that the digitization output doesn't change if pile-up
440 // truth is saved.
441 hitproc = SiCharge::cut_track;
442 }
443 }
444
445 float dstep{-0.5};
446 for (int istep{0}; istep < numberOfSteps; ++istep) {
447 dstep += 1.0;
448 float z1{zhit + stepZ * dstep};
449
450 // Distance between charge and readout side.
451 // design->readoutSide() is +1 if readout side is in +ve depth axis direction and visa-versa.
452 float zReadout{static_cast<float>(0.5 * thickness - design->readoutSide() * z1)};
453 const double spess{zReadout};
454
455 if (m_doHistoTrap) {
456 Hists& h = getHists();
457 h.m_h_depD->Fill(z1);
458 h.m_h_spess->Fill(spess);
459 }
460
461 float t_drift{driftTime(zReadout, element, ctx)}; // !< t_drift: perpandicular drift time
462 if (t_drift>-2.0000002 and t_drift<-1.9999998) {
463 ATH_MSG_DEBUG("Checking for rounding errors in compression");
464 if ((std::abs(z1) - 0.5 * thickness) < 0.000010) {
465 ATH_MSG_DEBUG("Rounding error found attempting to correct it. z1 = " << std::fixed << std::setprecision(8) << z1);
466 if (z1 < 0.0) {
467 z1 = 0.0000005 - 0.5 * thickness;
468 // set new coordinate to be 0.5nm inside wafer volume.
469 } else {
470 z1 = 0.5 * thickness - 0.0000005;
471 // set new coordinate to be 0.5nm inside wafer volume.
472 }
473 zReadout = 0.5 * thickness - design->readoutSide() * z1;
474 t_drift = driftTime(zReadout, element, ctx);
475 if (t_drift>-2.0000002 and t_drift<-1.9999998) {
476 ATH_MSG_WARNING("Attempt failed. Making no correction.");
477 } else {
478 ATH_MSG_DEBUG("Correction Successful! z1 = " << std::fixed << std::setprecision(8) << z1 << ", zReadout = " << zReadout << ", t_drift = " << t_drift);
479 }
480 } else {
481 ATH_MSG_DEBUG("No rounding error found. Making no correction.");
482 }
483 }
484 if (t_drift > 0.0) {
485 const float x1{xhit + stepX * dstep};
486 float y1{yhit + stepY * dstep};
487
488 float sigma{0.};
489 if (not m_doInducedChargeModel) {
490 sigma = diffusionSigma(zReadout, element, ctx);
491 y1 += tanLorentz * zReadout; // !< Taking into account the magnetic field
492 } // These are treated in Induced Charge Model.
493
494 for (int i{0}; i < m_numberOfCharges; ++i) {
495 const float rx{CLHEP::RandGaussZiggurat::shoot(rndmEngine)};
496 const float xd{x1 + sigma * rx};
497 const float ry{CLHEP::RandGaussZiggurat::shoot(rndmEngine)};
498 const float yd{y1 + sigma * ry};
499
500 // For charge trapping with Ramo potential
501 const double stripPitch{0.080}; // mm
502 double dstrip{y1 / stripPitch}; // mm
503 if (dstrip > 0.) {
504 dstrip = dstrip - std::trunc(dstrip);
505 } else {
506 dstrip = dstrip - std::trunc(dstrip) + 1;
507 }
508
509 // now y will be x and z will be y ....just to make sure to confuse everebody
510 double y0{dstrip * stripPitch}; // mm
511 double z0{thickness - zReadout}; // mm
512
513 // -- Charge Trapping
514 if (m_doTrapping) {
515 if (m_doHistoTrap) {
516 Hists& h = getHists();
517 h.m_h_zhit->Fill(zhit);
518 }
519 double trap_pos{-999999.}, drift_time{-999999.}; // FIXME need better default values
520 if (chargeIsTrapped(spess, element, trap_pos, drift_time)) {
521 if (not m_doRamo) {
522 break;
523 } else { // if we want to take into account also Ramo Potential
524 double Q_m2{0.}, Q_m1{0.}, Q_00{0.}, Q_p1{0.}, Q_p2{0.}; // Charges
525
526 dstrip = y1 / stripPitch; // mm
527 // need the distance from the nearest strips
528 // edge not centre, xtaka = 1/2*stripPitch
529 // centre of detector, y1=0, is in the middle of
530 // an interstrip gap
531 if (dstrip > 0.) {
532 dstrip -= static_cast<double>(static_cast<int>(dstrip));
533 } else {
534 dstrip -= static_cast<double>(static_cast<int>(dstrip)) + 1;
535 }
536
537 // now y will be x and z will be y ....just to make sure to confuse everebody
538 double yfin{dstrip * stripPitch}; // mm
539 double zfin{thickness - trap_pos}; // mm
540
541 m_radDamageTool->holeTransport(y0, z0, yfin, zfin, Q_m2, Q_m1, Q_00, Q_p1, Q_p2);
542 for (int strip{-2}; strip<=2; strip++) {
543 const double ystrip{yd + strip * stripPitch}; // mm
544 const SiLocalPosition position(element->hitLocalToLocal(xd, ystrip));
545 if (design->inActiveArea(position)) {
546 double charge{0.};
547 if (strip == -2) charge = Q_m2;
548 else if (strip == -1) charge = Q_m1;
549 else if (strip == 0) charge = Q_00;
550 else if (strip == 1) charge = Q_p1;
551 else if (strip == 2) charge = Q_p2;
552 const double time{drift_time};
553 if (charge != 0.) {
554 inserter(SiSurfaceCharge(position, SiCharge(q1*charge, time, hitproc, trklink)));
555 continue;
556 }
557 }
558 }
559 ATH_MSG_INFO("strip zero charge = " << Q_00); // debug
560 } // m_doRamo==true
561 } // chargeIsTrapped()
562 } // m_doTrapping==true
563
564 if (not m_doRamo) {
565 if (m_doInducedChargeModel) { // Induced Charge Model
566 // Charges storages for 50 ns. 0.5 ns steps.
572
573 const double mm2cm = 0.1; // For mm -> cm conversion
574 // Unit for y and z : mm -> cm in InducedChargeModel
575 m_InducedChargeModel->holeTransport(*data,
576 y0*mm2cm, z0*mm2cm,
577 Q_m2, Q_m1, Q_00, Q_p1, Q_p2,
578 hashId, m_siPropertiesTool,
579 ctx);
580 m_InducedChargeModel->electronTransport(*data,
581 y0*mm2cm, z0*mm2cm,
582 Q_m2, Q_m1, Q_00, Q_p1, Q_p2,
583 hashId, m_siPropertiesTool,
584 ctx);
585
586 for (int it{0}; it<InducedChargeModel::NTransportSteps; it++) {
587 if (Q_00[it] == 0.0) continue;
588 double ICM_time{(it+0.5)*0.5 + timeOfFlight};
589 double Q_new[InducedChargeModel::NStrips]{
590 Q_m2[it], Q_m1[it], Q_00[it], Q_p1[it], Q_p2[it]
591 };
593 double ystrip{y1 + strip * stripPitch};
594 SiLocalPosition position{element->hitLocalToLocal(x1, ystrip)};
595 if (design->inActiveArea(position)) {
596 inserter(SiSurfaceCharge(position,
597 SiCharge(q1 * Q_new[strip+InducedChargeModel::Offset],
598 ICM_time, hitproc, trklink)));
599 }
600 }
601 }
602 } else { // not m_doInducedChargeModel
603 const SiLocalPosition position{element->hitLocalToLocal(xd, yd)};
604 if (design->inActiveArea(position)) {
605 const float sdist{static_cast<float>(design->scaledDistanceToNearestDiode(position))};
606 // !< dist on the surface from the hit point to the nearest strip (diode)
607 const float t_surf{surfaceDriftTime(2.0 * sdist)}; // !< Surface drift time
608 const float totaltime{(m_tfix > -998.) ? m_tfix.value() : t_drift + timeOfFlight + t_surf}; // !< Total drift time
609 inserter(SiSurfaceCharge(position, SiCharge(q1, totaltime, hitproc, trklink)));
610 } else {
611 ATH_MSG_VERBOSE(std::fixed << std::setprecision(8) << "Local position (phi, eta, depth): ("
612 << position.xPhi() << ", " << position.xEta() << ", " << position.xDepth()
613 << ") of the element is out of active area, charge = " << q1);
614 }
615 }
616 }
617 } // end of loop on charges
618 }
619 }
620 }
float hitTime(const AFP_SIDSimHit &hit)
Scalar mag() const
mag method
#define ATH_MSG_WARNING(x)
double charge(const T &p)
Definition AtlasPID.h:997
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
bool chargeIsTrapped(double spess, const InDetDD::SiDetectorElement *element, double &trap_pos, double &drift_time) const
float surfaceDriftTime(float ysurf) const
Calculate of the surface drift time.
int readoutSide() const
ReadoutSide.
virtual double scaledDistanceToNearestDiode(const SiLocalPosition &chargePos) const =0
give distance to the nearest diode in units of pitch, from 0.0 to 0.5, this method should be fast as ...
const SCT_ModuleSideDesign * getMother() const
virtual bool inActiveArea(const SiLocalPosition &chargePos, bool checkBondGap=true) const =0
check if the position is in active area
double xDepth() const
position along depth direction:
double xPhi() const
position along phi direction:
double xEta() const
position along eta direction:
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
Amg::Vector2D hitLocalToLocal(double xEta, double xPhi) const
Simulation/Hit local frame to reconstruction local frame.
@ cut_track
Definition SiCharge.h:28
double energyLoss() const
Definition SiHit.h:175
int truthID() const
Definition SiHit.cxx:208
HepGeom::Point3D< double > localStartPosition() const
Definition SiHit.cxx:146
@ xPhi
Definition SiHit.h:162
@ xEta
Definition SiHit.h:162
@ xDep
Definition SiHit.h:162
int truthBarcode() const
Definition SiHit.cxx:202
const HepMcParticleLink & particleLink() const
Definition SiHit.h:190
HepGeom::Point3D< double > localEndPosition() const
Definition SiHit.cxx:153
time(flags, cells_name, *args, **kw)
double e1(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 1st sampling

◆ setFixedTime()

virtual void ITk::StripSurfaceChargesGenerator::setFixedTime ( float fixedTime)
inlineoverrideprivatevirtual

Definition at line 79 of file StripSurfaceChargesGenerator.h.

79{m_tfix = fixedTime;}

◆ surfaceDriftTime()

float ITk::StripSurfaceChargesGenerator::surfaceDriftTime ( float ysurf) const
private

Calculate of the surface drift time.

Definition at line 288 of file StripSurfaceChargesGenerator.cxx.

288 {
289 if (m_SurfaceDriftFlag) {
290 if ((ysurf >= 0.0) and (ysurf <= m_distInterStrip)) {
291 float t_surfaceDrift{0.};
292 if (ysurf < m_distHalfInterStrip) {
293 const float y{ysurf / m_distHalfInterStrip};
294 t_surfaceDrift= m_tHalfwayDrift * y * y;
295 } else {
296 const float y{(m_distInterStrip - ysurf) / (m_distInterStrip - m_distHalfInterStrip)};
297 t_surfaceDrift = m_tSurfaceDrift + (m_tHalfwayDrift - m_tSurfaceDrift) * y * y;
298 }
299 return t_surfaceDrift;
300 } else {
301 ATH_MSG_INFO(" ysurf out of range " << ysurf);
302 return -1.0;
303 }
304 } else {
305 return 0.0;
306 }
307}
#define y

Member Data Documentation

◆ m_distHalfInterStrip

float ITk::StripSurfaceChargesGenerator::m_distHalfInterStrip {0.}
private

Half way distance inter strip.

Definition at line 135 of file StripSurfaceChargesGenerator.h.

135{0.};

◆ m_distInterStrip

float ITk::StripSurfaceChargesGenerator::m_distInterStrip {1.0}
private

Inter strip distance normalized to 1.

Definition at line 134 of file StripSurfaceChargesGenerator.h.

134{1.0};

◆ m_doHistoTrap

BooleanProperty ITk::StripSurfaceChargesGenerator::m_doHistoTrap {this, "doHistoTrap", false, "Histogram the charge trapping effect"}
private

Definition at line 117 of file StripSurfaceChargesGenerator.h.

117{this, "doHistoTrap", false, "Histogram the charge trapping effect"};

◆ m_doInducedChargeModel

BooleanProperty ITk::StripSurfaceChargesGenerator::m_doInducedChargeModel {this, "doInducedChargeModel", false, "Flag for Induced Charge Model"}
private

Definition at line 120 of file StripSurfaceChargesGenerator.h.

120{this, "doInducedChargeModel", false, "Flag for Induced Charge Model"};

◆ m_doRamo

BooleanProperty ITk::StripSurfaceChargesGenerator::m_doRamo {this, "doRamo", false, "Ramo Potential for charge trapping effect"}
private

Definition at line 118 of file StripSurfaceChargesGenerator.h.

118{this, "doRamo", false, "Ramo Potential for charge trapping effect"};

◆ m_doTrapping

BooleanProperty ITk::StripSurfaceChargesGenerator::m_doTrapping {this, "doTrapping", false, "Flag to set Charge Trapping"}
private

Definition at line 116 of file StripSurfaceChargesGenerator.h.

116{this, "doTrapping", false, "Flag to set Charge Trapping"};

◆ m_fieldCacheCondObjInputKey

SG::ReadCondHandleKey<AtlasFieldCacheCondObj> ITk::StripSurfaceChargesGenerator::m_fieldCacheCondObjInputKey
private
Initial value:
{
this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"}

Definition at line 130 of file StripSurfaceChargesGenerator.h.

130 {
131 this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};

◆ m_h

std::unique_ptr<Hists> ITk::StripSurfaceChargesGenerator::m_h
private

Definition at line 165 of file StripSurfaceChargesGenerator.h.

◆ m_InducedChargeModel

std::unique_ptr<InducedChargeModel> ITk::StripSurfaceChargesGenerator::m_InducedChargeModel
private

Definition at line 168 of file StripSurfaceChargesGenerator.h.

◆ m_isOverlay

BooleanProperty ITk::StripSurfaceChargesGenerator::m_isOverlay {this, "isOverlay", false, "flag for overlay"}
private

Definition at line 119 of file StripSurfaceChargesGenerator.h.

119{this, "isOverlay", false, "flag for overlay"};

◆ m_lorentzAngleTool

ToolHandle<ISiLorentzAngleTool> ITk::StripSurfaceChargesGenerator::m_lorentzAngleTool {this, "LorentzAngleTool", "SiLorentzAngleTool/ITkStripLorentzAngleTool", "Tool to retreive Lorentz angle"}
private

Definition at line 126 of file StripSurfaceChargesGenerator.h.

126{this, "LorentzAngleTool", "SiLorentzAngleTool/ITkStripLorentzAngleTool", "Tool to retreive Lorentz angle"};

◆ m_numberOfCharges

IntegerProperty ITk::StripSurfaceChargesGenerator::m_numberOfCharges {this, "NumberOfCharges", 1, "number of charges"}
private

Definition at line 104 of file StripSurfaceChargesGenerator.h.

104{this, "NumberOfCharges", 1, "number of charges"};

◆ m_radDamageTool

ToolHandle<ISCT_RadDamageSummaryTool> ITk::StripSurfaceChargesGenerator::m_radDamageTool {this, "RadDamageSummaryTool", "StripRadDamageSummaryTool", "Tool to retrieve SCT radiation damages"}
private

Definition at line 124 of file StripSurfaceChargesGenerator.h.

124{this, "RadDamageSummaryTool", "StripRadDamageSummaryTool", "Tool to retrieve SCT radiation damages"};

◆ m_siConditionsTool

ToolHandle<ISiliconConditionsTool> ITk::StripSurfaceChargesGenerator::m_siConditionsTool {this, "SiConditionsTool", "StripSiliconConditionsTool", "Tool to retrieve SCT silicon information"}
private

Definition at line 125 of file StripSurfaceChargesGenerator.h.

125{this, "SiConditionsTool", "StripSiliconConditionsTool", "Tool to retrieve SCT silicon information"};

◆ m_siPropertiesTool

ToolHandle<ISiPropertiesTool> ITk::StripSurfaceChargesGenerator::m_siPropertiesTool {this, "SiPropertiesTool", "StripSiPropertiesTool", "Tool to retrieve SCT silicon properties"}
private

Definition at line 123 of file StripSurfaceChargesGenerator.h.

123{this, "SiPropertiesTool", "StripSiPropertiesTool", "Tool to retrieve SCT silicon properties"};

◆ m_smallStepLength

FloatProperty ITk::StripSurfaceChargesGenerator::m_smallStepLength {this, "SmallStepLength", 5 * CLHEP::micrometer, "max internal step along the larger G4 step"}
private

Definition at line 105 of file StripSurfaceChargesGenerator.h.

105{this, "SmallStepLength", 5 * CLHEP::micrometer, "max internal step along the larger G4 step"};

◆ m_SurfaceDriftFlag

bool ITk::StripSurfaceChargesGenerator::m_SurfaceDriftFlag {false}
private

surface drift ON/OFF

Definition at line 137 of file StripSurfaceChargesGenerator.h.

137{false};

◆ m_tfix

FloatProperty ITk::StripSurfaceChargesGenerator::m_tfix {this, "FixedTime", -999., "fixed time"}
private

Definition at line 110 of file StripSurfaceChargesGenerator.h.

110{this, "FixedTime", -999., "fixed time"};

◆ m_tHalfwayDrift

float ITk::StripSurfaceChargesGenerator::m_tHalfwayDrift {0.}
private

Surface drift time.

Definition at line 133 of file StripSurfaceChargesGenerator.h.

133{0.};

◆ m_thistSvc

ServiceHandle<ITHistSvc> ITk::StripSurfaceChargesGenerator::m_thistSvc {this, "THistSvc", "THistSvc"}
private

Definition at line 128 of file StripSurfaceChargesGenerator.h.

128{this, "THistSvc", "THistSvc"};

◆ m_tsubtract

FloatProperty ITk::StripSurfaceChargesGenerator::m_tsubtract {this, "SubtractTime", -999., "subtract drift time from mid gap"}
private

Definition at line 111 of file StripSurfaceChargesGenerator.h.

111{this, "SubtractTime", -999., "subtract drift time from mid gap"};

◆ m_tSurfaceDrift

FloatProperty ITk::StripSurfaceChargesGenerator::m_tSurfaceDrift {this, "SurfaceDriftTime", 10 * CLHEP::ns, "max surface drift time"}
private

related to the surface drift

Definition at line 108 of file StripSurfaceChargesGenerator.h.

108{this, "SurfaceDriftTime", 10 * CLHEP::ns, "max surface drift time"};

◆ m_useSiCondDB

BooleanProperty ITk::StripSurfaceChargesGenerator::m_useSiCondDB {this, "UseSiCondDB", true, "Usage of SiConditions DB values can be disabled to use setable ones"}
private

Definition at line 113 of file StripSurfaceChargesGenerator.h.

113{this, "UseSiCondDB", true, "Usage of SiConditions DB values can be disabled to use setable ones"};

◆ m_vbias

FloatProperty ITk::StripSurfaceChargesGenerator::m_vbias {this, "BiasVoltage", 150., "bias voltage, default 150V"}
private

Definition at line 115 of file StripSurfaceChargesGenerator.h.

115{this, "BiasVoltage", 150., "bias voltage, default 150V"};

◆ m_vdepl

FloatProperty ITk::StripSurfaceChargesGenerator::m_vdepl {this, "DepletionVoltage", 70., "depletion voltage, default 70V"}
private

Definition at line 114 of file StripSurfaceChargesGenerator.h.

114{this, "DepletionVoltage", 70., "depletion voltage, default 70V"};

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