ATLAS Offline Software
Loading...
Searching...
No Matches
ITkStripFrontEnd.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 "ITkStripFrontEnd.h"
6
10
11
12// Random number
13#include "CLHEP/Random/RandFlat.h"
14#include "CLHEP/Random/RandGaussZiggurat.h" // for RandGaussZiggurat
15#include "CLHEP/Random/RandPoisson.h"
16
17#include "CLHEP/Random/RandomEngine.h"
18
19using namespace InDetDD;
20
21// constructor
22ITkStripFrontEnd::ITkStripFrontEnd(const std::string& type, const std::string& name, const IInterface* parent)
23 : base_class(type, name, parent) {
24}
25
26// ----------------------------------------------------------------------
27// Initialize
28// ----------------------------------------------------------------------
30 if (m_NoiseOn and (not m_analogueNoiseOn)) {
31 ATH_MSG_FATAL("AnalogueNoiseOn/m_analogueNoiseOn should be true if NoiseOn/m_NoiseOn is true.");
32 return StatusCode::FAILURE;
33 }
34
35 ATH_MSG_DEBUG("ITkStripFrontEnd::initialize()");
36 // Get SCT helper
37 ATH_CHECK(detStore()->retrieve(m_ITkStripId, "SCT_ID"));
38 // Get SCT detector manager
39 ATH_CHECK(detStore()->retrieve(m_ITkStripMgr,m_detMgrName));
40
41 ATH_CHECK(m_strip_amplifier.retrieve());
42
43 constexpr float fC = 6242.2;
45
46 // Check configuration. If it is invalid, abort this job.
50 ATH_MSG_FATAL("m_data_compression_mode = " << m_data_compression_mode
51 << " is invalid. Abort this job!!!");
52 return StatusCode::FAILURE;
53 }
55 ATH_MSG_FATAL("m_data_readout_mode = " << m_data_readout_mode
56 << " is invalid. Abort this job!!!");
57 return StatusCode::FAILURE;
58 }
61 ATH_MSG_FATAL("m_data_compression_mode = " << m_data_compression_mode
62 << (m_data_compression_mode==Level_X1X ? " (Level_X1X)" : " (AnyHit_1XX_X1X_XX1)")
63 << " requires timing information."
64 << " However, m_data_readout_mode = " << m_data_readout_mode
65 << " (Condensed) does not keep timing information. Abort this job!!!");
66 return StatusCode::FAILURE;
67 }
68
69 return StatusCode::SUCCESS;
70}
71
72// ----------------------------------------------------------------------
73// Init the class variable vectors
74// ----------------------------------------------------------------------
76 data.m_GainFactor.resize(strips);
77
78 data.m_Analogue[0].resize(strips);
79 data.m_Analogue[1].resize(strips);
80 data.m_Analogue[2].resize(strips);
81
82}
83
84
85// ----------------------------------------------------------------------
86// process the collection of pre digits this will need to go through
87// all single-strip pre-digits calculate the amplifier response add noise
88// (this could be moved elsewhere later) apply threshold do clustering
89// ----------------------------------------------------------------------
90void
91ITkStripFrontEnd::process(SiChargedDiodeCollection& collection, CLHEP::HepRandomEngine* /*rndmEngine*/) const {
92 // get ITk module side design
93 [[maybe_unused]] const SCT_ModuleSideDesign *p_design = static_cast<const SCT_ModuleSideDesign*>(&(collection.design()));
94
96
97 // Check number of strips in design and from manager(max number of strips on any module)
98 // The design value should always be equal or lower than the manager one
99 // However, no resising is now done in case of a lower value
100 const int strip_max = p_design->cells();
101
102 // Init vectors
103 initVectors(strip_max, data);
104
105 // Contains strip hit info, reset to 0 for each wafer processed
106 data.m_StripHitsOnWafer.assign(strip_max, 0);
107
108 // data.m_Analogue were cleared in initVectors().
109
110 // Check if collection empty
111 if (not collection.empty()) {
112 //Commented parts are future Tools to be added
113 // Setup gain/offset/noise to the hit and neighbouring strips// Use JO values
114 // if (StatusCode::SUCCESS != prepareGainAndOffset(collection, moduleId, rndmEngine, data, strip_max)) {
115 // ATH_MSG_ERROR("\tCan't prepare Gain and Offset");
116 // }
117
118 doSignalChargeForHits(collection, data, strip_max);
119
120 doThresholdCheckForRealHits(collection, data, strip_max);
121
122 // if (StatusCode::SUCCESS != doThresholdCheckForCrosstalkHits(collection, data, strip_max)) {
123 // ATH_MSG_ERROR("\tCan't doThresholdCheckForCrosstalkHits");
124 // }
125 }
126
127 // if (m_NoiseOn) {
128 // if (StatusCode::SUCCESS != randomNoise(collection, moduleId, rndmEngine, data,strip_max)) {
129 // ATH_MSG_ERROR("\tCan't do random noise on wafer?!");
130 // }
131 // }
132
133 // // Check for strips above threshold and do clustering
134 // if (StatusCode::SUCCESS != doClustering(collection, data,strip_max)) {
135 // ATH_MSG_ERROR("\tCan't cluster the hits?!");
136 // }
137
138}
139
140
142 using list_t = SiTotalCharge::list_t;
143
144 // *****************************************************************************
145 // Loop over the diodes (strips ) and for each of them define the total signal
146 // *****************************************************************************
147
148 // set up number of needed bins depending on the compression mode
149 short bin_max = 0;
151 bin_max = m_data_compression_mode;
152 } else {
153 bin_max = 3;
154 }
155
156 std::vector<float> response(bin_max);
157
158 for (auto& [blub, diode]: collection) {
159 // should be const as we aren't trying to change it here - but getReadoutCell() is not a const method...
160 unsigned int flagmask = diode.flag() & 0xFE;
161 // Get the flag for this diode ( if flagmask = 1 If diode is disconnected/disabled skip it)
162 if (!flagmask) { // If the diode is OK (not flagged)
163 const SiReadoutCellId &roCell = diode.getReadoutCell();
164
165 if (roCell.isValid()) {
166 int strip = roCell.strip();
167
168 [[maybe_unused]] const list_t &ChargesOnStrip = diode.totalCharge().chargeComposition();
169
171 // Amplifier response
172 // m_sct_amplifier->response(ChargesOnStrip, m_timeOfThreshold, response);
173 for (short bin = 0; bin < bin_max; ++bin) {
174 data.m_Analogue[bin][strip] += data.m_GainFactor[strip] * response[bin];
175 }
176 // Add Crosstalk signal for neighboring strip
177 // m_sct_amplifier->crosstalk(ChargesOnStrip, m_timeOfThreshold, response);
178 for (short bin = 0; bin < bin_max; ++bin) {
179 if (strip + 1 < strip_max) {
180 data.m_Analogue[bin][strip + 1] += data.m_GainFactor[strip + 1] * response[bin];
181 }
182 if (strip > 0) {
183 data.m_Analogue[bin][strip - 1] += data.m_GainFactor[strip - 1] * response[bin];
184 }
185 }
186 } else { // Expanded
187 // Amplifier response
188 // m_sct_amplifier->response(ChargesOnStrip, m_timeOfThreshold, response);
189 for (short bin = 0; bin < bin_max; ++bin) {
190 data.m_Analogue[bin][strip] += data.m_GainFactor[strip] * response[bin];
191 }
192 // Add Crosstalk signal for neighboring strip
193 // m_sct_amplifier->crosstalk(ChargesOnStrip, m_timeOfThreshold, response);
194 for (short bin = 0; bin < bin_max; ++bin) {
195 if (strip + 1 < strip_max) {
196 data.m_Analogue[bin][strip + 1] += data.m_GainFactor[strip + 1] * response[bin];
197 }
198 if (strip > 0) {
199 data.m_Analogue[bin][strip - 1] += data.m_GainFactor[strip - 1] * response[bin];
200 }
201 }
202 }
203 } else { // if roCell not valid
204 ATH_MSG_WARNING("\t Cannot get the cell ");
205 }
206 } else {// If diode is disconnected/disabled skip it
207 ATH_MSG_WARNING("\tDisabled or disconnected diode (strip)");
208 }
209 }
210}
211
212
214 // **********************************************************************************
215 // Flag strips below threshold and flag the threshold check into data.m_StripHitsOnWafer
216 // **********************************************************************************
217
218 for (auto& [blub, diode]: collection) {
219 const SiReadoutCellId & roCell = diode.getReadoutCell();
220 if (roCell.isValid()) {
221 int strip = roCell.strip();
222 if (strip > -1 and strip < strip_max) {
224 if ((data.m_Analogue[0][strip] >= m_Threshold or data.m_Analogue[1][strip] < m_Threshold)) {
225 SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
226 data.m_StripHitsOnWafer[strip] = -1;
227 } else if (((0x10 & diode.flag()) == 0x10) or ((0x4 & diode.flag()) == 0x4)) {
228 // previously a crazy strip number could have screwed things up here.
229 data.m_StripHitsOnWafer[strip] = -1;
230 } else {
231 data.m_StripHitsOnWafer[strip] = 1;
232 SiHelper::SetTimeBin(diode, 2, &msg()); // set timebin info
233 }
234 } else { // Expanded
235 int have_hit_bin = 0;
236 if (data.m_Analogue[0][strip] >= m_Threshold) {
237 have_hit_bin = 4;
238 }
239 if (data.m_Analogue[1][strip] >= m_Threshold) {
240 have_hit_bin += 2;
241 }
242 if (data.m_Analogue[2][strip] >= m_Threshold) {
243 have_hit_bin += 1;
244 }
245 if (((0x10 & diode.flag()) == 0x10) || ((0x4 & diode.flag()) == 0x4)) {
246 // previously a crazy strip number could have screwed things up here.
247 data.m_StripHitsOnWafer[strip] = -1;
248 } else if (m_data_compression_mode == Level_X1X) { // !< level and expanded mode
249 if (have_hit_bin == 2 or have_hit_bin == 3 or have_hit_bin == 6 or have_hit_bin == 7) {
250 data.m_StripHitsOnWafer[strip] = 1;
251 SiHelper::SetTimeBin(diode, have_hit_bin, &msg());
252 } else {
253 SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
254 data.m_StripHitsOnWafer[strip] = -1;
255 }
256 } else if (m_data_compression_mode == Edge_01X) { // !< edge and expanded mode
257 if (have_hit_bin == 2 or have_hit_bin == 3) {
258 data.m_StripHitsOnWafer[strip] = 1;
259 SiHelper::SetTimeBin(diode, have_hit_bin, &msg());
260 } else {
261 SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
262 data.m_StripHitsOnWafer[strip] = -1;
263 }
264 } else if (m_data_compression_mode == AnyHit_1XX_X1X_XX1) { // !< any hit mode
265 if (have_hit_bin == 0) {
266 SiHelper::belowThreshold(diode, true); // Below strip diode signal threshold
267 data.m_StripHitsOnWafer[strip] = -1;
268 } else {
269 data.m_StripHitsOnWafer[strip] = 1;
270 if (m_data_readout_mode == Expanded) { // !< check for exp mode or not
271 SiHelper::SetTimeBin(diode, have_hit_bin, &msg());
272 } else {
273 SiHelper::SetTimeBin(diode, 2, &msg());
274 }
275 }
276 }
277 }
278 }
279 }
280 }
281}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
MDT_Response response
This is an Identifier helper class for the SCT subdetector.
StringProperty m_detMgrName
const InDetDD::SCT_DetectorManager * m_ITkStripMgr
Handle to SCT detector manager, also valid for ITkStrips.
void initVectors(int strips, ITkStripFrontEndData &data) const
void doSignalChargeForHits(SiChargedDiodeCollection &collectione, ITkStripFrontEndData &data, const int &stripMax) const
void doThresholdCheckForRealHits(SiChargedDiodeCollection &collectione, ITkStripFrontEndData &data, const int &stripMax) const
BooleanProperty m_NoiseOn
ITkStripFrontEnd(const std::string &type, const std::string &name, const IInterface *parent)
constructor
virtual void process(SiChargedDiodeCollection &collection, CLHEP::HepRandomEngine *rndmEngine) const override
use the baseclass default finalize
BooleanProperty m_analogueNoiseOn
ShortProperty m_data_compression_mode
const SCT_ID * m_ITkStripId
Handle to SCT ID helper also valid for ITkStrips.
FloatProperty m_Threshold
ShortProperty m_data_readout_mode
ToolHandle< IAmplifier > m_strip_amplifier
Handle the Amplifier tool.
virtual StatusCode initialize() override
AlgTool initialize.
Base class for the SCT module side design, extended by the Forward and Barrel module design.
int cells() const
number of readout stips within module side:
int strip() const
Get strip number. Equivalent to phiIndex().
Definition SiCellId.h:131
bool isValid() const
Test if its in a valid state.
Definition SiCellId.h:136
Identifier for the strip or pixel readout cell.
const InDetDD::DetectorDesign & design() const
static void SetTimeBin(SiChargedDiode &chDiode, int time, MsgStream *log=nullptr)
Definition SiHelper.h:149
static void belowThreshold(SiChargedDiode &chDiode, bool flag, bool mask=false)
Definition SiHelper.h:84
std::vector< SiCharge > list_t
Message Stream Member.
simulation of the ITk Strips front-end electronics working as a SiPreDigitsProcessor models response ...
MsgStream & msg
Definition testRead.cxx:32