ATLAS Offline Software
Loading...
Searching...
No Matches
LISAnalysisTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
13
14namespace ZDC {
15
16LISAnalysisTool::LISAnalysisTool(std::string const& name) :
17 asg::AsgTool(name),
18 m_name(name)
19{
20#ifndef XAOD_STANDALONE
21 declareInterface<IZdcAnalysisTool>(this);
22#endif
23}
24
26 ATH_MSG_INFO("Initializing LISAnalysisTool with configuration: " << m_configuration);
27 ATH_MSG_INFO("Initializing LISAnalysisTool with BaselineStart: " << m_nBaselineStart << ", BaselineEnd: " << m_nBaselineEnd);
28
30
31 ATH_MSG_INFO("LIS Configuration:");
32 ATH_MSG_INFO(" NumSamples: " << m_numSamples);
33 ATH_MSG_INFO(" Presample: " << m_preSample);
34 ATH_MSG_INFO(" DeltaTSample: " << m_deltaTSample << " ns");
35 ATH_MSG_INFO(" SampleAnaStart: " << m_sampleAnaStart);
36 ATH_MSG_INFO(" SampleAnaEnd: " << m_sampleAnaEnd);
37
38 // If an aux suffix is provided, prepend it with "_"
39 std::string auxSuffix = m_auxSuffix;
40 if (auxSuffix != "") auxSuffix = "_" + auxSuffix;
41
42 // Initialize eventInfo access
43 ATH_CHECK(m_eventInfoKey.initialize());
44
45 // Initialize keys for reading ZDC event-level aux decor information
47 ATH_CHECK(m_eventTypeKey.initialize());
48
50 ATH_CHECK(m_DAQModeKey.initialize());
51
53 ATH_CHECK(m_robBCIDKey.initialize());
54
55 // Initialize WriteDecor handles
56 if (m_writeAux) {
57 m_ZdcLEDType = m_zdcSumContainerName + ".ZdcLEDType" + auxSuffix;
58 ATH_CHECK(m_ZdcLEDType.initialize());
59
60 m_LISPresampleADC = m_zdcModuleContainerName + ".LISPresample" + auxSuffix;
61 ATH_CHECK(m_LISPresampleADC.initialize());
62
63 m_LISADCSum = m_zdcModuleContainerName + ".LISADCSum" + auxSuffix;
64 ATH_CHECK(m_LISADCSum.initialize());
65
66 m_LISMaxADC = m_zdcModuleContainerName + ".LISMaxADC" + auxSuffix;
67 ATH_CHECK(m_LISMaxADC.initialize());
68
69 m_LISMaxSample = m_zdcModuleContainerName + ".LISMaxSample" + auxSuffix;
70 ATH_CHECK(m_LISMaxSample.initialize());
71
72 m_LISAvgTime = m_zdcModuleContainerName + ".LISAvgTime" + auxSuffix;
73 ATH_CHECK(m_LISAvgTime.initialize());
74
75 }
76
77 m_init = true;
78 ATH_MSG_INFO("LISAnalysisTool initialization complete");
79
80 return StatusCode::SUCCESS;
81}
82
84 // PbPb 2025 configuration
85 m_numSamples = 24;
86 m_preSample = 0;
87 m_deltaTSample = 3.125;
89 m_sampleAnaEnd = 23;
91
92 m_LEDBCID = {3476, 3479, 3482};
93 m_LEDCalreqIdx = {0 ,1 ,2};}
94
96 int side, int channel,
97 const std::vector<unsigned short>& data,
98 unsigned int startSample, unsigned int endSample)
99{
100 ATH_MSG_DEBUG("Processing LIS data for side " << side << ", channel " << channel);
101
102 int ADCSum = 0;
103 int maxADCsub = -999;
104 unsigned int maxSample = 0;
105 float avgTime = 0.f;
106
107 if (data.empty()) {
108 ATH_MSG_DEBUG("Empty waveform data");
109 return LISModuleResults();
110 }
111
112 if (startSample >= data.size() || endSample >= data.size()) {
113 ATH_MSG_WARNING("Start or end sample number greater than number of samples");
114 return LISModuleResults();
115 }
116
117 // Calculate presample (baseline) from first few samples
118 float preFADC = 0;
119 unsigned int nBaseline = std::min(m_nBaselineSamples, static_cast<unsigned int>(data.size()));
120 for (unsigned int i = m_nBaselineStart; i < m_nBaselineEnd; ++i) {
121 preFADC += data[i];
122 }
123 preFADC /= nBaseline;
124
125 // Process samples in analysis window
126 for (unsigned int sample = startSample; sample <= endSample; sample++) {
127 int FADCsub = static_cast<int>(data[sample]) - static_cast<int>(std::round(preFADC));
128
129 float time = (sample + 0.5f) * m_deltaTSample;
130 ADCSum += FADCsub;
131
132 if (FADCsub > maxADCsub) {
133 maxADCsub = FADCsub;
134 maxSample = sample;
135 }
136
137 avgTime += time * FADCsub;
138 }
139
140 // Calculate average time
141 if (ADCSum != 0) {
142 avgTime /= ADCSum;
143 } else {
144 avgTime = 0.f;
145 }
146
147 ATH_MSG_DEBUG(" Presample: " << preFADC << ", ADCSum: " << ADCSum
148 << ", MaxADC: " << maxADCsub << ", MaxSample: " << maxSample
149 << ", AvgTime: " << avgTime);
150
151 return LISModuleResults(preFADC, ADCSum, maxADCsub, maxSample, avgTime);
152}
153
155 ATH_MSG_DEBUG("Processing LIS module: side=" << module.zdcSide()
156 << ", module=" << module.zdcModule()
157 << ", channel=" << module.zdcChannel());
158
159 int LISModuleGain = 0;
160
161 if(module.zdcChannel() > 3){
162 LISModuleGain = 1; // gain 1 for channels 4-7
163 }
164 else{
165 LISModuleGain = 0; // gain 0 for channels 0-3
166 }
167
168 ATH_MSG_DEBUG("LIS module gain: " << LISModuleGain);
169
170 // Determine which gain data to use
171 static SG::ConstAccessor<std::vector<uint16_t>> g0dataAccessor("g0data");
172 static SG::ConstAccessor<std::vector<uint16_t>> g1dataAccessor("g1data");
173 const SG::ConstAccessor<std::vector<uint16_t>> &gainDataAccessor = (LISModuleGain == 0) ? g0dataAccessor : g1dataAccessor;
174
175 // Get waveform data
176 if (!gainDataAccessor.isAvailable(module)) {
177 ATH_MSG_DEBUG("No gain data available for this module");
178 return LISModuleResults();
179 }
180
181 const std::vector<uint16_t> &waveform = gainDataAccessor(module);
182 if (waveform.empty()) {
183 ATH_MSG_DEBUG("Empty waveform");
184 return LISModuleResults();
185 }
186
187 return processModuleData(module.zdcSide(), module.zdcChannel(),
189}
190
192 xAOD::ZdcModuleContainer const& moduleContainer,
193 xAOD::ZdcModuleContainer const& moduleSumContainer) {
194
195 ATH_MSG_DEBUG("LISAnalysisTool::recoZdcModules processing event");
196
197 if (!m_init) {
198 ATH_MSG_WARNING("Tool not initialized!");
199 return StatusCode::FAILURE;
200 }
201
202 if (moduleContainer.empty()) {
203 return StatusCode::SUCCESS;
204 }
205 // Check for decoding errors
207 if (!eventInfo.isValid()) {
208 ATH_MSG_WARNING("EventInfo not valid");
209 return StatusCode::FAILURE;
210 }
211
212 bool lisErr = eventInfo->isEventFlagBitSet(xAOD::EventInfo::ForwardDet, ZdcEventInfo::LISDECODINGERROR);
213 if (lisErr) {
214 ATH_MSG_WARNING("LIS decoding error found - abandoning LISAnalysisTool!");
215 return StatusCode::SUCCESS;
216 }
217
220
221 // Loop over the sum container to find event-level info (side == 0)
222 //
223 bool haveZdcEventInfo = false;
224 unsigned int eventType = ZdcEventInfo::ZdcEventUnknown;
225 unsigned int bcid = 0;
226
227 const xAOD::ZdcModule* moduleSumEventInfo_ptr = 0;
228
229 for (auto modSum : moduleSumContainer) {
230 //
231 // Module sum object with side == 0 contains event-level information
232 //
233 if (modSum->zdcSide() == 0) {
234 //
235 // Add the event type and bcid as aux decors
236 //
237 ATH_MSG_DEBUG("Found global sum");
238 eventType = eventTypeHandle(*modSum);
239 haveZdcEventInfo = true;
240 moduleSumEventInfo_ptr = modSum;
241 }
242 }
243
244 if (!haveZdcEventInfo) {
245 ATH_MSG_ERROR("Zdc event data not available (moduleSum with side = 0)");
246 return StatusCode::FAILURE;
247 }
248
249 // Get the BCID from the rodBCID vector
250 const std::vector<uint16_t>& rodBCID = rodBCIDHandle(*moduleSumEventInfo_ptr);
251 if (!rodBCID.empty()) {
252 bcid = rodBCID[0]; // Use first BCID from LUCROD
253 ATH_MSG_DEBUG("Retrieved BCID from rodBCID: " << bcid);
254 } else {
255 ATH_MSG_WARNING("rodBCID vector is empty, using EventInfo BCID");
256 bcid = eventInfo->bcid();
257 }
258
259 // Determine the LED type
260 //
261 unsigned int evtLEDType = ZdcEventInfo::LEDNone;
262
263 for (unsigned int idxLED = 0; idxLED < ZdcEventInfo::NumLEDs; idxLED++) {
264 //
265 // Does the BCID match one of those associated with the LEDs?
266 //
267 if (m_LEDBCID[idxLED] == bcid) {
268
269 evtLEDType = idxLED;
270 break;
271 }
272 }
273
274 if (evtLEDType == ZdcEventInfo::LEDNone && eventType == ZdcEventInfo::ZdcEventLED) {
275 //
276 // Thie BCID does not appear to be associated with one of the LEDs, print warning and quit processing
277 //
278 ATH_MSG_WARNING("LED event: Unexpected BCID found in data: bcid = " << bcid << m_configuration);
279 return StatusCode::SUCCESS;
280 }
281 else {
282 ATH_MSG_DEBUG("Event with BCID = " << bcid << " has LED type " << evtLEDType);
283 }
284
285
286 // Create write decoration handles
293
294 ATH_MSG_DEBUG("Processing " << moduleContainer.size() << " modules");
295
296 // Loop over modules and process LIS channels (module=5, type=2)
297 for (const auto* zdcModule : moduleContainer) {
298
299 LISModuleResults results = processLISModule(*zdcModule);
300
301
302
303 ATH_MSG_DEBUG("Writing aux decors to LIS module: side=" << zdcModule->zdcSide()
304 << ", channel=" << zdcModule->zdcChannel());
305
306 // Write decorations
307 presampleHandle(*zdcModule) = results.getPresampleADC();
308 adcSumHandle(*zdcModule) = results.getADCSum();
309 maxADCHandle(*zdcModule) = results.getMaxADC();
310 maxSampleHandle(*zdcModule) = results.getMaxSample();
311 avgTimeHandle(*zdcModule) = results.getAvgTime();
312
313 }
314
315
316 if(eventType == ZdcEventInfo::ZdcEventLED){
317 // Write the LED type to the moduleSum container keep event-level data
318 //
319 LEDTypeHandle(*moduleSumEventInfo_ptr) = evtLEDType;
320 }
321
322 ATH_MSG_DEBUG("Finished event processing");
323
324 return StatusCode::SUCCESS;
325}
326
328 if (!m_init) {
329 ATH_MSG_WARNING("Tool not initialized!");
330 return StatusCode::FAILURE;
331 }
332
333 ATH_MSG_DEBUG("Trying to retrieve " << m_zdcModuleContainerName);
334
335 m_zdcModules = nullptr;
337
338 m_zdcSums = nullptr;
340
342
343 return StatusCode::SUCCESS;
344}
345
346} // namespace ZDC
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
Handle class for recording to StoreGate.
Helper class to provide constant type-safe access to aux data.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Define enumerations for event-level ZDC data.
ServiceHandle< StoreGateSvc > & evtStore()
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Handle class for reading a decoration on an object.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Handle class for adding a decoration to an object.
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_LISMaxADC
Gaudi::Property< bool > m_writeAux
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_LISMaxSample
Gaudi::Property< unsigned int > m_nBaselineEnd
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_LISADCSum
LISAnalysisTool(std::string const &name)
Gaudi::Property< std::string > m_auxSuffix
SG::ReadDecorHandleKey< xAOD::ZdcModuleContainer > m_robBCIDKey
unsigned int m_sampleAnaStart
LISModuleResults processModuleData(int side, int channel, const std::vector< unsigned short > &data, unsigned int startSample, unsigned int endSample)
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_LISPresampleADC
SG::ReadDecorHandleKey< xAOD::ZdcModuleContainer > m_eventTypeKey
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_ZdcLEDType
Gaudi::Property< unsigned int > m_nBaselineStart
LISModuleResults processLISModule(const xAOD::ZdcModule &module)
std::vector< unsigned int > m_LEDCalreqIdx
StatusCode reprocessZdc() override
std::vector< unsigned int > m_LEDBCID
Gaudi::Property< std::string > m_configuration
unsigned int m_nBaselineSamples
SG::ReadDecorHandleKey< xAOD::ZdcModuleContainer > m_DAQModeKey
StatusCode initialize() override
Dummy implementation of the initialisation function.
const xAOD::ZdcModuleContainer * m_zdcSums
Gaudi::Property< std::string > m_zdcModuleContainerName
const xAOD::ZdcModuleContainer * m_zdcModules
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_LISAvgTime
unsigned int m_numSamples
Gaudi::Property< std::string > m_zdcSumContainerName
unsigned int m_sampleAnaEnd
StatusCode recoZdcModules(xAOD::ZdcModuleContainer const &moduleContainer, xAOD::ZdcModuleContainer const &moduleSumContainer) override
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
@ ForwardDet
The forward detectors.
ZdcModuleContainer_v1 ZdcModuleContainer
ZdcModule_v1 ZdcModule
Definition ZdcModule.h:15