ATLAS Offline Software
Loading...
Searching...
No Matches
RD53SimTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3 */
4
5#include "RD53SimTool.h"
9#include "PixelConditionsData/ChargeCalibParameters.h" //for Thresholds
12
16#include "CLHEP/Random/RandFlat.h"
17#include "PixelNoiseFunctions.h"
18#include <cmath>
19
20using namespace PixelDigitization;
21
22RD53SimTool::RD53SimTool(const std::string& type, const std::string& name, const IInterface* parent) :
23 FrontEndSimTool(type, name, parent) {
24}
25
28 ATH_MSG_DEBUG("RD53SimTool::initialize()");
29 return StatusCode::SUCCESS;
30}
31
32void RD53SimTool::process(const EventContext& ctx,
33 SiChargedDiodeCollection& chargedDiodes, PixelRDO_Collection& rdoCollection,
34 CLHEP::HepRandomEngine* rndmEngine) const {
35 const PixelID* pixelId = static_cast<const PixelID*>(chargedDiodes.element()->getIdHelper());
36 const IdentifierHash moduleHash = pixelId->wafer_hash(chargedDiodes.identify()); // wafer hash
37 Identifier moduleID = pixelId->wafer_id(chargedDiodes.element()->identify());
38
39 int barrel_ec = pixelId->barrel_ec(chargedDiodes.element()->identify());
40 if (std::abs(barrel_ec) != m_BarrelEC) {
41 return;
42 }
43
45 const PixelChargeCalibCondData *calibData = *calibDataHandle;
46
47 int overflowToT = 14; //for RD53 (aka ITkPixV2) chip, not FEI4
48
49 // Add cross-talk
50 auto xtalk = m_chipSim.crossTalk();
51 crossTalk(xtalk, chargedDiodes);
52
53 if (m_doNoise) {
54 // Add thermal noise
55 thermalNoise(m_thermalNoise, chargedDiodes, rndmEngine);
56 // Add random noise
57 randomNoise(chargedDiodes, m_chipSim, m_numberOfBcid, calibData, rndmEngine, m_pixelReadout.get());
58 }
59
60 // Add random diabled pixels
61 randomDisable(chargedDiodes, m_chipSim, rndmEngine); // FIXME How should we handle disabling pixels in Overlay jobs?
62
63 for (auto &[mapId,mapDiode]:chargedDiodes) {//cannot be const ref, mapDiode will be altered
64 Identifier diodeID = chargedDiodes.getId(mapId);
65 double charge = mapDiode.charge();
66 unsigned int FE = m_pixelReadout->getFE(diodeID, moduleID);
67 InDetDD::PixelDiodeType type = m_pixelReadout->getDiodeType(diodeID);
69 SiHelper::disabled(mapDiode, true, true);
70 continue;//invalid frontend
71 }
72 // Apply analogue threshold, timing simulation
73 const auto &thresholds = calibData->getThresholds(type, moduleHash, FE);
74 double threshold = PixelDigitization::randomThreshold(thresholds, rndmEngine);
75
76 if (charge > threshold) {
77 int bunchSim = 0;
78 if (mapDiode.totalCharge().fromTrack()) {
79 bunchSim = static_cast<int>(std::floor((getG4Time(mapDiode.totalCharge()) + m_timeOffset) / m_bunchSpace));
80 //Timewalk implementation
81 if(m_doTimeWalk){
83 const int timeWalk = 25; // Here it is assumed that the maximum value of timewalk is one bunch crossing (25ns)
84 bunchSim = static_cast<int>(std::floor((getG4Time(mapDiode.totalCharge()) + m_timeOffset + timeWalk) / m_bunchSpace));
85 }
86 }
87 } else {
88 bunchSim = CLHEP::RandFlat::shootInt(rndmEngine, m_numberOfBcid);
89 }
90
91 if (bunchSim < 0 || bunchSim > m_numberOfBcid) {
92 SiHelper::belowThreshold(mapDiode, true, true);
93 } else {
94 SiHelper::SetBunch(mapDiode, bunchSim);
95 }
96 } else {
97 SiHelper::belowThreshold(mapDiode, true, true);
98 }
99
100 // charge to ToT conversion
101 double tot = calibData->getToT(type, moduleHash, FE, charge);
102 double totsig = calibData->getTotRes(moduleHash, FE, tot);
103 int nToT = generateToT(rndmEngine, tot,totsig, std::make_pair(0,overflowToT));
104 auto thresh = m_chipSim.totThreshold();
105
106 if (nToT <= thresh) {
107 SiHelper::belowThreshold(mapDiode, true, true);
108 }
109
110 // Filter events
111 if (SiHelper::isMaskOut(mapDiode)) {
112 continue;
113 }
114 if (SiHelper::isDisabled(mapDiode)) {
115 continue;
116 }
117
118 if (!m_pixelConditionsTool->isActive(moduleHash, diodeID, ctx)) {
119 SiHelper::disabled(mapDiode, true, true);
120 continue;
121 }
122
123 int flag = mapDiode.flag();
124 int bunch = (flag >> 8) & 0xff;
125
126 InDetDD::SiReadoutCellId cellId = mapDiode.getReadoutCell();
127 const Identifier id_readout = chargedDiodes.element()->identifierFromCellId(cellId);
128
129 // Front-End simulation
130 if (bunch >= 0 && bunch < m_numberOfBcid) {
131 Pixel1RawData* p_rdo = new Pixel1RawData(id_readout, nToT, bunch, 0, bunch);
132 rdoCollection.push_back(p_rdo);
133 p_rdo = nullptr;
134 }
135 }
136}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
Structs for holding charge calibration parameterisation and data.
This is an Identifier helper class for the Pixel subdetector.
InDetRawDataCollection< PixelRDORawData > PixelRDO_Collection
value_type push_back(value_type pElem)
SG::ReadCondHandleKey< PixelChargeCalibCondData > m_chargeDataKey
ServiceHandle< InDetDD::IPixelReadoutManager > m_pixelReadout
virtual StatusCode initialize() override
static constexpr double m_bunchSpace
ToolHandle< IInDetConditionsTool > m_pixelConditionsTool
Gaudi::Property< bool > m_doNoise
Gaudi::Property< int > m_BarrelEC
This is a "hash" representation of an Identifier.
Identifier for the strip or pixel readout cell.
virtual Identifier identify() const override final
identifier of this detector element (inline)
virtual Identifier identifierFromCellId(const SiCellId &cellId) const =0
Identifier <-> SiCellId (ie strip number or pixel eta_index,phi_index) Identifier from SiCellId (ie s...
PixelChargeCalib::Thresholds getThresholds(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
float getToT(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float Q) const
float getTotRes(unsigned int moduleHash, unsigned int FE, float Q) const
This is an Identifier helper class for the Pixel subdetector.
Definition PixelID.h:69
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition PixelID.h:355
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0).
Definition PixelID.h:595
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
Definition PixelID.h:378
Gaudi::Property< bool > m_doTimeWalk
Definition RD53SimTool.h:39
virtual StatusCode initialize() override
ITkPixSimulationParameters m_chipSim
Definition RD53SimTool.h:36
virtual void process(const EventContext &ctx, SiChargedDiodeCollection &chargedDiodes, PixelRDO_Collection &rdoCollection, CLHEP::HepRandomEngine *rndmEngine) const override
Gaudi::Property< int > m_overDrive
Definition RD53SimTool.h:42
virtual Identifier identify() const override final
Identifier getId(const InDetDD::SiCellId &id) const
const InDetDD::SolidStateDetectorElementBase * element() const
static bool isMaskOut(SiChargedDiode &chDiode)
Definition SiHelper.h:171
static void SetBunch(SiChargedDiode &chDiode, int bunch, MsgStream *log=nullptr)
Definition SiHelper.h:129
static void disabled(SiChargedDiode &chDiode, bool flag, bool mask=false)
Definition SiHelper.h:93
static void belowThreshold(SiChargedDiode &chDiode, bool flag, bool mask=false)
Definition SiHelper.h:84
static bool isDisabled(SiChargedDiode &chDiode)
Definition SiHelper.h:179
constexpr uint32_t invalidFrontEnd
void randomDisable(SiChargedDiodeCollection &chargedDiodes, const PixelModuleData *moduleData, CLHEP::HepRandomEngine *rndmEngine)
void crossTalk(double crossTalk, SiChargedDiodeCollection &chargedDiodes)
void thermalNoise(double thermalNoise, SiChargedDiodeCollection &chargedDiodes, CLHEP::HepRandomEngine *rndmEngine)
double randomThreshold(const PixelChargeCalib::Thresholds &t, CLHEP::HepRandomEngine *pEngine)
void randomNoise(SiChargedDiodeCollection &chargedDiodes, const PixelModuleData *moduleData, int nBcid, const PixelChargeCalibCondData *chargeCalibData, CLHEP::HepRandomEngine *rndmEngine, InDetDD::IPixelReadoutManager *pixelReadout)
int generateToT(CLHEP::HepRandomEngine *rndmEngine, double mean, double sd, const std::pair< int, int > &range)
double getG4Time(const SiTotalCharge &totalCharge)