ATLAS Offline Software
Loading...
Searching...
No Matches
LisNtuple.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 <TSystem.h>
6#include <TFile.h>
10#include <ZdcNtuple/LisNtuple.h>
11
12
13LisNtuple::LisNtuple(const std::string &name, ISvcLocator *pSvcLocator)
14 : EL::AnaAlgorithm(name, pSvcLocator)
15{
16 declareProperty("enableOutputTree", m_enableOutputTree = true, "Enable output tree");
17 declareProperty("auxSuffix", m_auxSuffix = "", "Suffix for aux data names");
18 declareProperty("lisInj", m_lisInj = false, "LIS injected-pulse run");
19 declareProperty("lisLED", m_lisLED = false, "LIS LED run");
20
22}
23
25{
26 ANA_MSG_DEBUG("Initializing LisNtuple");
27
29 ANA_CHECK(m_zdcSumContainerName.initialize());
30
32 {
33 ANA_CHECK(book(TTree("lisTree", "LIS Tree")));
34 m_outputTree = tree("lisTree");
35
36 // Event info branches
37 m_outputTree->Branch("bcid", &t_bcid, "bcid/i");
38 m_outputTree->Branch("runNumber", &t_runNumber, "runNumber/i");
39 m_outputTree->Branch("eventNumber", &t_eventNumber, "eventNumber/i");
40 m_outputTree->Branch("lumiBlock", &t_lumiBlock, "lumiBlock/i");
41 m_outputTree->Branch("bunchGroup", &t_bunchGroup, "bunchGroup/b");
42 m_outputTree->Branch("extendedLevel1ID", &t_extendedLevel1ID, "extendedLevel1ID/i");
43 m_outputTree->Branch("timeStamp", &t_timeStamp, "timeStamp/i");
44 m_outputTree->Branch("timeStampNSOffset", &t_timeStampNSOffset, "timeStampNSOffset/i");
45
46 m_outputTree->Branch("avgIntPerCrossing", &t_avgIntPerCrossing, "avgIntPerCrossing/F");
47 m_outputTree->Branch("actIntPerCrossing", &t_actIntPerCrossing, "actIntPerCrossing/F");
48
49 if (m_lisLED)
50 {m_outputTree->Branch("LEDType", &t_LEDType, "LEDType/i");}
51 if (m_lisInj)
52 {m_outputTree->Branch("vInj",&t_vInj,"vInj/F");}
53
54 // LIS processed data branches
55 m_outputTree->Branch("LISPresample", &t_LISPresample, Form("LISPresample[%d]/F", nLISChannels));
56 m_outputTree->Branch("LISADCSum", &t_LISADCSum, Form("LISADCSum[%d]/I", nLISChannels));
57 m_outputTree->Branch("LISMaxADC", &t_LISMaxADC, Form("LISMaxADC[%d]/I", nLISChannels));
58 m_outputTree->Branch("LISMaxSample", &t_LISMaxSample, Form("LISMaxSample[%d]/i", nLISChannels));
59 m_outputTree->Branch("LISAvgTime", &t_LISAvgTime, Form("LISAvgTime[%d]/F", nLISChannels));
60 // LIS raw waveform data
61 m_outputTree->Branch("LISRawdata", &t_LISRawdata, Form("LISRawdata[%d][%d]/s", nLISChannels, nSamples));
62
63
64 if (m_lisInj)
65 {
66 m_zdcInjPulserAmpMap = std::make_unique<ZdcInjPulserAmpMap>();
67 ATH_MSG_INFO( "Using JSON file for injector-pulse voltage at path " << m_zdcInjPulserAmpMap->getFilePath() );
68 }
69
70 }
71
72 return StatusCode::SUCCESS;
73}
74
76{
77 if (!evtStore())
78 {
79 ANA_MSG_INFO("*** No event found! ***");
80 return StatusCode::SUCCESS;
81 }
82
83 ANA_CHECK(evtStore()->retrieve(m_eventInfo, "EventInfo"));
85
86 if (m_lisInj){
88 }
89
91
93 {
94 tree("lisTree")->Fill();
95 }
96
97 return StatusCode::SUCCESS;
98}
99
101{
102 // iside 0 is side C, iside 1 is side A
105
106 ANA_MSG_DEBUG("Processing LIS modules");
107
108 // Initialize arrays to zero
109
110 for (int ichan = 0; ichan < nLISChannels; ichan++)
111 {
112 t_LISPresample[ichan] = 0;
113 t_LISADCSum[ichan] = 0;
114 t_LISMaxADC[ichan] = 0;
115 t_LISMaxSample[ichan] = 0;
116 t_LISAvgTime[ichan] = 0;
117
118 for (int isam = 0; isam < nSamples; isam++)
119 {
120 t_LISRawdata[ichan][isam] = 0;
121 }
122 }
123
124
125 // Default LED type
126 t_LEDType = 999;
127
128 ANA_MSG_DEBUG("Accessing ZdcModules for LIS data");
129
130 static const SG::ConstAccessor<unsigned int> ZdcLEDTypeAccessor("ZdcLEDType" + m_auxSuffix);
131 static const SG::ConstAccessor<unsigned int> LEDTypeAccessor("LEDType" + m_auxSuffix);
132 static const SG::ConstAccessor<float> LISPresampleAccessor("LISPresample" + m_auxSuffix);
133 static const SG::ConstAccessor<int> LISADCSumAccessor("LISADCSum" + m_auxSuffix);
134 static const SG::ConstAccessor<int> LISMaxADCAccessor("LISMaxADC" + m_auxSuffix);
135 static const SG::ConstAccessor<unsigned int> LISMaxSampleAccessor("LISMaxSample" + m_auxSuffix);
136 static const SG::ConstAccessor<float> LISAvgTimeAccessor("LISAvgTime" + m_auxSuffix);
137 static const SG::ConstAccessor<std::vector<uint16_t>> g0dataAccessor("g0data" + m_auxSuffix);
138 static const SG::ConstAccessor<std::vector<uint16_t>> g1dataAccessor("g1data" + m_auxSuffix);
139
140 if (zdcModules.ptr())
141 {
142 for (const auto zdcMod : *zdcModules)
143 {
144 // Get LED type from sum container
145 if (zdcSums.ptr())
146 {
147 for (const auto zdcSum : *zdcSums)
148 {
149 if (zdcSum->zdcSide() == infoSumInd)
150 {
151 if (ZdcLEDTypeAccessor.isAvailable(*zdcSum))
152 {
153 t_LEDType = ZdcLEDTypeAccessor(*zdcSum);
154 break;
155 }
156 // Fallback to LEDType if ZdcLEDType not available
157 else if (LEDTypeAccessor.isAvailable(*zdcSum))
158 {
159 t_LEDType = LEDTypeAccessor(*zdcSum);
160 break;
161 }
162 }
163 }
164 }
165
166 // Skip side 0 (info container)
167 if (zdcMod->zdcSide() == 0)
168 continue;
169
170 // Check if this is a LIS module (type=2, module=5)
171 if (zdcMod->zdcType() == LISTypeInd && zdcMod->zdcModule() == LISModuleInd)
172 {
173
174 if(zdcMod->zdcSide() > 0){
175 ANA_MSG_WARNING("No LIS on side A, whats that?");
176 }
177
178 int ichan = zdcMod->zdcChannel();
179
180 // Bounds check
181 if (ichan < 0 || ichan >= nLISChannels)
182 {
183 ANA_MSG_WARNING("LIS channel " << ichan << " out of range");
184 continue;
185 }
186
187 ANA_MSG_VERBOSE("LIS Module side " << zdcMod->zdcSide() << " channel " << ichan);
188
189 // Check for LIS aux data availability
190 if (!LISPresampleAccessor.isAvailable(*zdcMod))
191 {
192 ANA_MSG_WARNING("Missing LIS aux data for side " << zdcMod->zdcSide() << " channel " << ichan);
193 continue;
194 }
195
196 // Read processed LIS data
197 t_LISPresample[ichan] = LISPresampleAccessor(*zdcMod);
198 t_LISADCSum[ichan] = LISADCSumAccessor(*zdcMod);
199 t_LISMaxADC[ichan] = LISMaxADCAccessor(*zdcMod);
200 t_LISMaxSample[ichan] = LISMaxSampleAccessor(*zdcMod);
201 t_LISAvgTime[ichan] = LISAvgTimeAccessor(*zdcMod);
202
203 // Read raw waveform data
204 if(ichan > 3){
205 if (g1dataAccessor.isAvailable(*zdcMod))
206 {
207 const std::vector<uint16_t> &g1dataVec = g1dataAccessor(*zdcMod);
208 for (int isam = 0; isam < nSamples && isam < static_cast<int>(g1dataVec.size()); isam++)
209 {
210 t_LISRawdata[ichan][isam] = g1dataVec.at(isam);
211 }
212 }
213 }
214 else{
215 if (g0dataAccessor.isAvailable(*zdcMod))
216 {
217 const std::vector<uint16_t> &g0dataVec = g0dataAccessor(*zdcMod);
218 for (int isam = 0; isam < nSamples && isam < static_cast<int>(g0dataVec.size()); isam++)
219 {
220 t_LISRawdata[ichan][isam] = g0dataVec.at(isam);
221 }
222 }
223 }
224
225 }
226 }
227 }
228}
229
231{
232 ANA_MSG_DEBUG("Processing event info");
233
234 // Get BCID from ZdcSums rodBCID decoration (from LUCROD)
235 static const SG::Accessor<std::vector<uint16_t>> rodBCIDAcc("rodBCID");
237
238 t_bcid = m_eventInfo->bcid(); // Default from EventInfo
239
240 if (zdcSums.ptr()) {
241 for (const auto zdcSum : *zdcSums) {
242 if (zdcSum->zdcSide() == infoSumInd) {
243 if (rodBCIDAcc.isAvailable(*zdcSum)) {
244 const std::vector<uint16_t>& rodBCID = rodBCIDAcc(*zdcSum);
245 if (!rodBCID.empty()) {
246 t_bcid = rodBCID[0]; // Use BCID from LUCROD
247 ANA_MSG_DEBUG("Using BCID from rodBCID: " << t_bcid);
248 }
249 }
250 break;
251 }
252 }
253 }
254
255 t_runNumber = m_eventInfo->runNumber();
256 t_eventNumber = m_eventInfo->eventNumber();
257 t_lumiBlock = m_eventInfo->lumiBlock();
258 t_bunchGroup = -1;
259 t_extendedLevel1ID = m_eventInfo->extendedLevel1ID();
260 t_timeStamp = m_eventInfo->timeStamp();
261 t_timeStampNSOffset = m_eventInfo->timeStampNSOffset();
262 t_avgIntPerCrossing = m_eventInfo->averageInteractionsPerCrossing();
263 t_actIntPerCrossing = m_eventInfo->actualInteractionsPerCrossing();
264
265 if (!(m_eventCounter++ % 1000))
266 {
267 ANA_MSG_INFO("Event# " << m_eventCounter << " Run " << m_eventInfo->runNumber()
268 << " Event " << m_eventInfo->eventNumber() << " LB " << m_eventInfo->lumiBlock());
269 }
270}
271
273{
274 return StatusCode::SUCCESS;
275}
276
278 // Check for new run number
279 //
281 //
282 // Get access to the injector pulse steps for this run
283 //
285 if (!m_injMapRunToken.isValid()) {
286 ANA_MSG_ERROR("Unable to obtain injector pulse steps for run " << t_runNumber);
287 }
288 else {
289 unsigned int startLB = m_zdcInjPulserAmpMap->getFirstLumiBlock(m_injMapRunToken);
290 unsigned int nsteps = m_zdcInjPulserAmpMap->getNumSteps(m_injMapRunToken);
291 ANA_MSG_DEBUG("Successfully obtained injector pulse steps for run " << t_runNumber
292 << ", first LB = " << startLB << ", number of steps = " << nsteps);
293 }
294
295 // update the last run number to be the current run number
297 }
298
300}
#define ATH_MSG_INFO(x)
Helper class to provide constant type-safe access to aux data.
#define ANA_MSG_INFO(xmsg)
Macro printing info messages.
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
#define ANA_MSG_WARNING(xmsg)
Macro printing warning messages.
#define ANA_MSG_VERBOSE(xmsg)
Macro printing verbose messages.
#define ANA_MSG_DEBUG(xmsg)
Macro printing debug messages.
#define ANA_CHECK(EXP)
check whether the given expression was successful
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
StatusCode book(const TH1 &hist, const std::string &tDir="", const std::string &stream="")
Simplify the booking and registering (into THistSvc) of histograms.
AnaAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
constructor with parameters
std::string m_auxSuffix
Definition LisNtuple.h:32
uint32_t t_timeStampNSOffset
Definition LisNtuple.h:49
uint8_t t_bunchGroup
Definition LisNtuple.h:46
float t_LISPresample[nLISChannels]
Definition LisNtuple.h:65
uint32_t t_runNumber
Definition LisNtuple.h:42
int t_LISADCSum[nLISChannels]
Definition LisNtuple.h:66
uint32_t t_eventNumber
Definition LisNtuple.h:43
void processLisNtupleFromModules()
static constexpr int LISTypeInd
Definition LisNtuple.h:60
unsigned int t_LISMaxSample[nLISChannels]
Definition LisNtuple.h:68
float t_actIntPerCrossing
Definition LisNtuple.h:51
float t_vInj
Definition LisNtuple.h:41
const xAOD::EventInfo * m_eventInfo
Definition LisNtuple.h:25
virtual StatusCode execute() override
Definition LisNtuple.cxx:75
static constexpr int infoSumInd
Definition LisNtuple.h:62
static constexpr int LISModuleInd
Definition LisNtuple.h:61
virtual StatusCode initialize() override
Definition LisNtuple.cxx:24
uint32_t t_extendedLevel1ID
Definition LisNtuple.h:47
int m_eventCounter
Definition LisNtuple.h:26
static constexpr int nSamples
Definition LisNtuple.h:58
void processVInjInfo()
float t_avgIntPerCrossing
Definition LisNtuple.h:50
bool m_enableOutputTree
Definition LisNtuple.h:29
uint32_t t_bcid
Definition LisNtuple.h:45
uint16_t t_LISRawdata[nLISChannels][nSamples]
Definition LisNtuple.h:72
SG::ReadHandleKey< xAOD::ZdcModuleContainer > m_zdcSumContainerName
Definition LisNtuple.h:24
virtual StatusCode finalize() override
uint32_t t_lumiBlock
Definition LisNtuple.h:44
ZdcInjPulserAmpMap::Token m_injMapRunToken
Definition LisNtuple.h:20
unsigned int m_lastRunNumber
Definition LisNtuple.h:19
SG::ReadHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleContainerName
Definition LisNtuple.h:23
uint32_t t_timeStamp
Definition LisNtuple.h:48
void processEventInfo()
bool m_lisLED
Definition LisNtuple.h:31
float t_LISAvgTime[nLISChannels]
Definition LisNtuple.h:69
bool m_lisInj
Definition LisNtuple.h:30
unsigned int t_LEDType
Definition LisNtuple.h:54
TTree * m_outputTree
Definition LisNtuple.h:35
LisNtuple(const std::string &name, ISvcLocator *pSvcLocator)
Definition LisNtuple.cxx:13
int t_LISMaxADC[nLISChannels]
Definition LisNtuple.h:67
static constexpr int nLISChannels
Definition LisNtuple.h:57
std::unique_ptr< ZdcInjPulserAmpMap > m_zdcInjPulserAmpMap
Definition LisNtuple.h:38
Helper class to provide type-safe access to aux data.
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.
const_pointer_type ptr()
Dereference the pointer.
This module defines the arguments passed from the BATCH driver to the BATCH worker.
TChain * tree