ATLAS Offline Software
Loading...
Searching...
No Matches
RD53SimTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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
27
30 ATH_MSG_DEBUG("RD53SimTool::initialize()");
31 return StatusCode::SUCCESS;
32}
33
35 ATH_MSG_DEBUG("RD53SimTool::finalize()");
36 return StatusCode::SUCCESS;
37}
38
40 CLHEP::HepRandomEngine* rndmEngine) const {
41 const PixelID* pixelId = static_cast<const PixelID*>(chargedDiodes.element()->getIdHelper());
42 const IdentifierHash moduleHash = pixelId->wafer_hash(chargedDiodes.identify()); // wafer hash
43 Identifier moduleID = pixelId->wafer_id(chargedDiodes.element()->identify());
44
45 int barrel_ec = pixelId->barrel_ec(chargedDiodes.element()->identify());
46 if (std::abs(barrel_ec) != m_BarrelEC) {
47 return;
48 }
49
50 const EventContext& ctx{Gaudi::Hive::currentContext()};
52 const PixelChargeCalibCondData *calibData = *calibDataHandle;
53
54 int overflowToT = 14; //for RD53 (aka ITkPixV2) chip, not FEI4
55
56 // Add cross-talk
57 auto xtalk = m_chipSim.crossTalk();
58 crossTalk(xtalk, chargedDiodes);
59
60 if (m_doNoise) {
61 // Add thermal noise
62 thermalNoise(m_thermalNoise, chargedDiodes, rndmEngine);
63 // Add random noise
64 randomNoise(chargedDiodes, m_chipSim, m_numberOfBcid, calibData, rndmEngine, m_pixelReadout.get());
65 }
66
67 // Add random diabled pixels
68 randomDisable(chargedDiodes, m_chipSim, rndmEngine); // FIXME How should we handle disabling pixels in Overlay jobs?
69
70 for (auto &[mapId,mapDiode]:chargedDiodes) {//cannot be const ref, mapDiode will be altered
71 Identifier diodeID = chargedDiodes.getId(mapId);
72 double charge = mapDiode.charge();
73 unsigned int FE = m_pixelReadout->getFE(diodeID, moduleID);
74 InDetDD::PixelDiodeType type = m_pixelReadout->getDiodeType(diodeID);
76 SiHelper::disabled(mapDiode, true, true);
77 continue;//invalid frontend
78 }
79 // Apply analogue threshold, timing simulation
80 const auto &thresholds = calibData->getThresholds(type, moduleHash, FE);
81 double threshold = PixelDigitization::randomThreshold(thresholds, rndmEngine);
82
83 if (charge > threshold) {
84 int bunchSim = 0;
85 if (mapDiode.totalCharge().fromTrack()) {
86 bunchSim = static_cast<int>(std::floor((getG4Time(mapDiode.totalCharge()) + m_timeOffset) / m_bunchSpace));
87 //Timewalk implementation
88 if(m_doTimeWalk){
90 const int timeWalk = 25; // Here it is assumed that the maximum value of timewalk is one bunch crossing (25ns)
91 bunchSim = static_cast<int>(std::floor((getG4Time(mapDiode.totalCharge()) + m_timeOffset + timeWalk) / m_bunchSpace));
92 }
93 }
94 } else {
95 bunchSim = CLHEP::RandFlat::shootInt(rndmEngine, m_numberOfBcid);
96 }
97
98 if (bunchSim < 0 || bunchSim > m_numberOfBcid) {
99 SiHelper::belowThreshold(mapDiode, true, true);
100 } else {
101 SiHelper::SetBunch(mapDiode, bunchSim);
102 }
103 } else {
104 SiHelper::belowThreshold(mapDiode, true, true);
105 }
106
107 // charge to ToT conversion
108 double tot = calibData->getToT(type, moduleHash, FE, charge);
109 double totsig = calibData->getTotRes(moduleHash, FE, tot);
110 int nToT = generateToT(rndmEngine, tot,totsig, std::make_pair(0,overflowToT));
111 auto thresh = m_chipSim.totThreshold();
112
113 if (nToT <= thresh) {
114 SiHelper::belowThreshold(mapDiode, true, true);
115 }
116
117 // Filter events
118 if (SiHelper::isMaskOut(mapDiode)) {
119 continue;
120 }
121 if (SiHelper::isDisabled(mapDiode)) {
122 continue;
123 }
124
125 if (!m_pixelConditionsTool->isActive(moduleHash, diodeID, ctx)) {
126 SiHelper::disabled(mapDiode, true, true);
127 continue;
128 }
129
130 int flag = mapDiode.flag();
131 int bunch = (flag >> 8) & 0xff;
132
133 InDetDD::SiReadoutCellId cellId = mapDiode.getReadoutCell();
134 const Identifier id_readout = chargedDiodes.element()->identifierFromCellId(cellId);
135
136 // Front-End simulation
137 if (bunch >= 0 && bunch < m_numberOfBcid) {
138 Pixel1RawData* p_rdo = new Pixel1RawData(id_readout, nToT, bunch, 0, bunch);
139 rdoCollection.push_back(p_rdo);
140 p_rdo = nullptr;
141 }
142 }
143}
#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
FrontEndSimTool(const std::string &type, const std::string &name, const IInterface *parent)
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:67
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition PixelID.h:360
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0)
Definition PixelID.h:600
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
Definition PixelID.h:383
virtual ~RD53SimTool()
virtual void process(SiChargedDiodeCollection &chargedDiodes, PixelRDO_Collection &rdoCollection, CLHEP::HepRandomEngine *rndmEngine) const
Gaudi::Property< bool > m_doTimeWalk
Definition RD53SimTool.h:40
ITkPixSimulationParameters m_chipSim
Definition RD53SimTool.h:37
virtual StatusCode finalize()
virtual StatusCode initialize()
Gaudi::Property< int > m_overDrive
Definition RD53SimTool.h:43
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)