ATLAS Offline Software
RD53SimTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3  */
4 
5 #include "RD53SimTool.h"
6 
8 #include "PixelConditionsData/ChargeCalibParameters.h" //for Thresholds
11 
15 #include "CLHEP/Random/RandFlat.h"
16 #include "CLHEP/Random/RandGaussZiggurat.h"
17 #include "PixelNoiseFunctions.h"
18 #include <cmath>
19 
20 using namespace PixelDigitization;
21 
22 RD53SimTool::RD53SimTool(const std::string& type, const std::string& name, const IInterface* parent) :
24 }
25 
26 RD53SimTool::~RD53SimTool() = default;
27 
30  ATH_MSG_DEBUG("RD53SimTool::initialize()");
32  return StatusCode::SUCCESS;
33 }
34 
36  ATH_MSG_DEBUG("RD53SimTool::finalize()");
37  return StatusCode::SUCCESS;
38 }
39 
41  CLHEP::HepRandomEngine* rndmEngine) {
42  const InDetDD::PixelModuleDesign* p_design =
43  static_cast<const InDetDD::PixelModuleDesign*>(&(chargedDiodes.element())->design());
44 
46  return;
47  }
48 
49  const PixelID* pixelId = static_cast<const PixelID*>(chargedDiodes.element()->getIdHelper());
50  const IdentifierHash moduleHash = pixelId->wafer_hash(chargedDiodes.identify()); // wafer hash
51  Identifier moduleID = pixelId->wafer_id(chargedDiodes.element()->identify());
52 
53  int barrel_ec = pixelId->barrel_ec(chargedDiodes.element()->identify());
54  int layerIndex = pixelId->layer_disk(chargedDiodes.element()->identify());
55 
56  if (std::abs(barrel_ec) != m_BarrelEC) {
57  return;
58  }
59 
60  const EventContext& ctx{Gaudi::Hive::currentContext()};
62  const PixelModuleData *moduleData = *moduleDataHandle;
64  const PixelChargeCalibCondData *calibData = *calibDataHandle;
65 
66  int overflowToT = calibData->getFEI4OverflowToT();
67 
68  std::vector<Pixel1RawData*> p_rdo_small_fei4;
69  std::vector<int> row, col;
70 
71 
72  // Add cross-talk
73  crossTalk(moduleData->getCrossTalk(barrel_ec, layerIndex), chargedDiodes);
74 
75  if (m_doNoise) {
76  // Add thermal noise
77  thermalNoise(m_thermalNoise, chargedDiodes, rndmEngine);
78 
79  // Add random noise
80  randomNoise(chargedDiodes, moduleData, m_numberOfBcid, calibData, rndmEngine, m_pixelReadout.get());
81  }
82 
83  // Add random diabled pixels
84  randomDisable(chargedDiodes, moduleData, rndmEngine); // FIXME How should we handle disabling pixels in Overlay jobs?
85 
86  for (SiChargedDiodeIterator i_chargedDiode = chargedDiodes.begin(); i_chargedDiode != chargedDiodes.end();
87  ++i_chargedDiode) {
88  Identifier diodeID = chargedDiodes.getId((*i_chargedDiode).first);
89  double charge = (*i_chargedDiode).second.charge();
90 
91  unsigned int FE = m_pixelReadout->getFE(diodeID, moduleID);
92  InDetDD::PixelDiodeType type = m_pixelReadout->getDiodeType(diodeID);
93 
94  // Apply analogue threshold, timing simulation
95  const auto thresholds = calibData->getThresholds(type, moduleHash, FE);
96  const int th0 = thresholds.value;
97  const int sigma = thresholds.sigma;
98  const int noise = thresholds.noise;
99  double threshold = th0 +
100  sigma * CLHEP::RandGaussZiggurat::shoot(rndmEngine) +
101  noise * CLHEP::RandGaussZiggurat::shoot(rndmEngine); // This noise check is unaffected by digitizationFlags.doInDetNoise in 21.0 - see PixelCellDiscriminator.cxx in that branch
102 
103  if (charge > threshold) {
104  int bunchSim = 0;
105  if ((*i_chargedDiode).second.totalCharge().fromTrack()) {
106  bunchSim =
107  static_cast<int>(std::floor((getG4Time((*i_chargedDiode).second.totalCharge()) +
109 
110  //Timewalk implementation
111  if(m_doTimeWalk){
112  if(charge < (threshold + m_overDrive)){
113  const int timeWalk = 25; // Here it is assumed that the maximum value of timewalk is one bunch crossing (25ns)
114  bunchSim =
115  static_cast<int>(std::floor((getG4Time((*i_chargedDiode).second.totalCharge()) +
116  m_timeOffset+ timeWalk) / m_bunchSpace));
117  }
118  }
119  } else {
120  bunchSim = CLHEP::RandFlat::shootInt(rndmEngine, m_numberOfBcid);
121  }
122 
123  if (bunchSim < 0 || bunchSim > m_numberOfBcid) {
124  SiHelper::belowThreshold((*i_chargedDiode).second, true, true);
125  } else {
126  SiHelper::SetBunch((*i_chargedDiode).second, bunchSim);
127  }
128  } else {
129  SiHelper::belowThreshold((*i_chargedDiode).second, true, true);
130  }
131 
132  // charge to ToT conversion
133  double tot = calibData->getToT(type, moduleHash, FE, charge);
134  double totsig = calibData->getTotRes(moduleHash, FE, tot);
135  int nToT = static_cast<int>(CLHEP::RandGaussZiggurat::shoot(rndmEngine, tot, totsig));
136 
137  if (nToT < 1) {
138  nToT = 1;
139  }
140 
141  // RD53 HitDiscConfig
142  if (nToT >= overflowToT) {
143  nToT = overflowToT;
144  }
145 
146  if (nToT <= moduleData->getToTThreshold(barrel_ec, layerIndex)) {
147  SiHelper::belowThreshold((*i_chargedDiode).second, true, true);
148  }
149 
150  // Filter events
151  if (SiHelper::isMaskOut((*i_chargedDiode).second)) {
152  continue;
153  }
154  if (SiHelper::isDisabled((*i_chargedDiode).second)) {
155  continue;
156  }
157 
158  if (!m_pixelConditionsTool->isActive(moduleHash, diodeID, ctx)) {
159  SiHelper::disabled((*i_chargedDiode).second, true, true);
160  continue;
161  }
162 
163  int flag = (*i_chargedDiode).second.flag();
164  int bunch = (flag >> 8) & 0xff;
165 
166  InDetDD::SiReadoutCellId cellId = (*i_chargedDiode).second.getReadoutCell();
167  const Identifier id_readout = chargedDiodes.element()->identifierFromCellId(cellId);
168 
169  // Front-End simulation
170  if (bunch >= 0 && bunch < m_numberOfBcid) {
171  Pixel1RawData* p_rdo = new Pixel1RawData(id_readout, nToT, bunch, 0, bunch);
172  rdoCollection.push_back(p_rdo);
173  p_rdo = nullptr;
174  }
175  }
176 }
query_example.row
row
Definition: query_example.py:24
PixelChargeCalibCondData::getToT
float getToT(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE, float Q) const
Definition: PixelChargeCalibCondData.cxx:173
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
SiHelper.h
PixelNoiseFunctions.h
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
SiChargedDiodeCollection::element
const InDetDD::SolidStateDetectorElementBase * element() const
Definition: SiChargedDiodeCollection.h:218
InDetDD::PixelModuleDesign
Definition: PixelModuleDesign.h:48
SiHelper::isDisabled
static bool isDisabled(SiChargedDiode &chDiode)
Definition: SiHelper.h:179
PixelID::barrel_ec
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0)
Definition: PixelID.h:619
PixelModuleData::getCrossTalk
double getCrossTalk(int barrel_ec, int layer) const
Definition: PixelModuleData.cxx:129
PixelChargeCalibCondData::getThresholds
PixelChargeCalib::Thresholds getThresholds(InDetDD::PixelDiodeType type, unsigned int moduleHash, unsigned int FE) const
Definition: PixelChargeCalibCondData.cxx:99
PixelModuleData
Definition: PixelModuleData.h:22
FrontEndSimTool::m_thermalNoise
double m_thermalNoise
Definition: FrontEndSimTool.h:54
InDetDD::PixelDiodeType
PixelDiodeType
Definition: PixelReadoutDefinitions.h:20
ChargeCalibParameters.h
Structs for holding charge calibration parameterisation and data.
SiChargedDiodeCollection::end
SiChargedDiodeIterator end()
Definition: SiChargedDiodeCollection.h:253
RD53SimTool.h
PixelChargeCalibCondData::getTotRes
float getTotRes(unsigned int moduleHash, unsigned int FE, float Q) const
Definition: PixelChargeCalibCondData.cxx:162
PixelDigitization
Definition: PixelDigitizationUtilities.cxx:29
SiChargedDiodeCollection::begin
SiChargedDiodeIterator begin()
Definition: SiChargedDiodeCollection.h:248
SiHelper::disabled
static void disabled(SiChargedDiode &chDiode, bool flag, bool mask=false)
Definition: SiHelper.h:93
PixelID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition: PixelID.h:364
InDetDD::SolidStateDetectorElementBase::getIdHelper
const AtlasDetectorID * getIdHelper() const
Returns the id helper (inline)
PixelDigitization::getG4Time
double getG4Time(const SiTotalCharge &totalCharge)
Definition: PixelNoiseFunctions.cxx:168
SiChargedDiodeIterator
SiChargedDiodeMap::iterator SiChargedDiodeIterator
Definition: SiChargedDiodeCollection.h:70
InDetDD::PixelReadoutTechnology::RD53
@ RD53
FrontEndSimTool::initialize
virtual StatusCode initialize() override
Definition: FrontEndSimTool.cxx:13
InDetDD::SolidStateDetectorElementBase::identifierFromCellId
virtual Identifier identifierFromCellId(const SiCellId &cellId) const =0
Identifier <-> SiCellId (ie strip number or pixel eta_index,phi_index) Identifier from SiCellId (ie s...
FrontEndSimTool::m_doNoise
Gaudi::Property< bool > m_doNoise
Definition: FrontEndSimTool.h:72
SiChargedDiodeCollection::getId
Identifier getId(const InDetDD::SiCellId &id) const
Definition: SiChargedDiodeCollection.h:144
SiReadoutCellId.h
RD53SimTool::m_doTimeWalk
Gaudi::Property< bool > m_doTimeWalk
Definition: RD53SimTool.h:41
PixelID::wafer_hash
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
Definition: PixelID.h:387
RD53SimTool::m_moduleDataKey
SG::ReadCondHandleKey< PixelModuleData > m_moduleDataKey
Definition: RD53SimTool.h:36
FrontEndSimTool::m_bunchSpace
static constexpr double m_bunchSpace
Definition: FrontEndSimTool.h:50
SiChargedDiodeCollection
Definition: SiChargedDiodeCollection.h:109
PixelRDO_Collection.h
FrontEndSimTool
Definition: FrontEndSimTool.h:31
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
PixelChargeCalibCondData
Definition: PixelChargeCalibCondData.h:24
RD53SimTool::RD53SimTool
RD53SimTool()
SiHelper::belowThreshold
static void belowThreshold(SiChargedDiode &chDiode, bool flag, bool mask=false)
Definition: SiHelper.h:84
FrontEndSimTool::m_numberOfBcid
int m_numberOfBcid
Definition: FrontEndSimTool.h:51
master.flag
bool flag
Definition: master.py:29
Pixel1RawData.h
InDetRawDataCollection
Definition: InDetRawDataCollection.h:31
test_pyathena.parent
parent
Definition: test_pyathena.py:15
FrontEndSimTool::m_pixelReadout
ServiceHandle< InDetDD::IPixelReadoutManager > m_pixelReadout
Definition: FrontEndSimTool.h:59
RD53SimTool::initialize
virtual StatusCode initialize()
Definition: RD53SimTool.cxx:28
Pixel1RawData
Definition: Pixel1RawData.h:23
SiHelper::SetBunch
static void SetBunch(SiChargedDiode &chDiode, int bunch, MsgStream *log=nullptr)
Definition: SiHelper.h:129
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
PixelChargeCalib::Thresholds::value
int value
Definition: ChargeCalibParameters.h:74
RD53SimTool::m_overDrive
Gaudi::Property< int > m_overDrive
Definition: RD53SimTool.h:44
FrontEndSimTool::m_BarrelEC
Gaudi::Property< int > m_BarrelEC
Definition: FrontEndSimTool.h:68
RD53SimTool::process
virtual void process(SiChargedDiodeCollection &chargedDiodes, PixelRDO_Collection &rdoCollection, CLHEP::HepRandomEngine *rndmEngine)
Definition: RD53SimTool.cxx:40
LB_AnalMapSplitter.tot
tot
Definition: LB_AnalMapSplitter.py:46
PixelID::layer_disk
int layer_disk(const Identifier &id) const
Definition: PixelID.h:626
SiHelper::isMaskOut
static bool isMaskOut(SiChargedDiode &chDiode)
Definition: SiHelper.h:171
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
threshold
Definition: chainparser.cxx:74
charge
double charge(const T &p)
Definition: AtlasPID.h:494
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
InDetDD::PixelModuleDesign::getReadoutTechnology
PixelReadoutTechnology getReadoutTechnology() const
Definition: PixelModuleDesign.h:368
query_example.col
col
Definition: query_example.py:7
PixelDigitization::crossTalk
void crossTalk(double crossTalk, SiChargedDiodeCollection &chargedDiodes)
Definition: PixelNoiseFunctions.cxx:25
RD53SimTool::~RD53SimTool
virtual ~RD53SimTool()
PixelModuleDesign.h
FrontEndSimTool::m_timeOffset
double m_timeOffset
Definition: FrontEndSimTool.h:52
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
PixelChargeCalibCondData::getFEI4OverflowToT
constexpr int getFEI4OverflowToT() const
Definition: PixelChargeCalibCondData.h:106
RD53SimTool::finalize
virtual StatusCode finalize()
Definition: RD53SimTool.cxx:35
FrontEndSimTool::m_chargeDataKey
SG::ReadCondHandleKey< PixelChargeCalibCondData > m_chargeDataKey
Definition: FrontEndSimTool.h:64
InDetDD::SiReadoutCellId
Definition: SiReadoutCellId.h:42
PixelDigitization::randomNoise
void randomNoise(SiChargedDiodeCollection &chargedDiodes, const PixelModuleData *moduleData, int nBcid, const PixelChargeCalibCondData *chargeCalibData, CLHEP::HepRandomEngine *rndmEngine, InDetDD::IPixelReadoutManager *pixelReadout)
Definition: PixelNoiseFunctions.cxx:73
PixelID
Definition: PixelID.h:67
FrontEndSimTool::m_pixelConditionsTool
ToolHandle< IInDetConditionsTool > m_pixelConditionsTool
Definition: FrontEndSimTool.h:55
PixelDigitization::randomDisable
void randomDisable(SiChargedDiodeCollection &chargedDiodes, const PixelModuleData *moduleData, CLHEP::HepRandomEngine *rndmEngine)
Definition: PixelNoiseFunctions.cxx:146
InDetDD::SolidStateDetectorElementBase::identify
virtual Identifier identify() const override final
identifier of this detector element (inline)
PixelDigitization::thermalNoise
void thermalNoise(double thermalNoise, SiChargedDiodeCollection &chargedDiodes, CLHEP::HepRandomEngine *rndmEngine)
Definition: PixelNoiseFunctions.cxx:61
WriteCellNoiseToCool.noise
noise
Definition: WriteCellNoiseToCool.py:380
SiChargedDiodeCollection.h
SiChargedDiodeCollection::identify
virtual Identifier identify() const override final
Definition: SiChargedDiodeCollection.h:230