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
12LisNtuple::LisNtuple(const std::string &name, ISvcLocator *pSvcLocator)
13 : EL::AnaAlgorithm(name, pSvcLocator)
14{
15 declareProperty("enableOutputTree", m_enableOutputTree = true, "Enable output tree");
16 declareProperty("auxSuffix", m_auxSuffix = "", "Suffix for aux data names");
17 declareProperty("lisInj", m_lisInj = false, "LIS injected-pulse run");
18 declareProperty("lisLED", m_lisLED = false, "LIS LED run");
19 declareProperty("enableTrigger", enableTrigger = true, "use trigger info");
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 m_outputTree->Branch("tbp", &t_tbp, "tbp[16]/i");
49 m_outputTree->Branch("tav", &t_tav, "tav[16]/i");
50
51 if (m_lisLED)
52 {m_outputTree->Branch("LEDType", &t_LEDType, "LEDType/i");}
53 if (m_lisInj)
54 {m_outputTree->Branch("vInj",&t_vInj,"vInj/F");}
55
56 // LIS processed data branches
57 m_outputTree->Branch("LISPresample", &t_LISPresample, Form("LISPresample[%d]/F", nLISChannels));
58 m_outputTree->Branch("LISADCSum", &t_LISADCSum, Form("LISADCSum[%d]/I", nLISChannels));
59 m_outputTree->Branch("LISMaxADC", &t_LISMaxADC, Form("LISMaxADC[%d]/I", nLISChannels));
60 m_outputTree->Branch("LISMaxSample", &t_LISMaxSample, Form("LISMaxSample[%d]/i", nLISChannels));
61 m_outputTree->Branch("LISAvgTime", &t_LISAvgTime, Form("LISAvgTime[%d]/F", nLISChannels));
62 m_outputTree->Branch("LISModuleStatus", &t_LISModuleStatus, Form("LISModuleStatus[%d]/i", nLISChannels));
63 // LIS raw waveform data
64 m_outputTree->Branch("LISRawdata", &t_LISRawdata, Form("LISRawdata[%d][%d]/s", nLISChannels, nSamples));
65
66 if (m_lisInj)
67 {
68 m_zdcInjPulserAmpMap = std::make_unique<ZdcInjPulserAmpMap>();
69 ATH_MSG_INFO( "Using JSON file for injector-pulse voltage at path " << m_zdcInjPulserAmpMap->getFilePath() );
70 }
71
72 }
73
74 return StatusCode::SUCCESS;
75}
76
78{
79 if (!evtStore())
80 {
81 ANA_MSG_INFO("*** No event found! ***");
82 return StatusCode::SUCCESS;
83 }
84
85 ANA_CHECK(evtStore()->retrieve(m_eventInfo, "EventInfo"));
87
88 if (m_lisInj){
90 }
91
92 bool passTrigger = true;
94 if (enableTrigger)
95 {
96 ANA_CHECK(evtStore()->retrieve( m_trigDecision, "xTrigDecision"));
97 passTrigger = processTriggerDecision();
98 }
99
100 if(!passTrigger){
101 // The trigger chains will be implemented in the future, for now just fill the tree with all events
102 //return StatusCode::FAILURE;
103 }
104
106
108 {
109 tree("lisTree")->Fill();
110 }
111
112 return StatusCode::SUCCESS;
113}
114
116{
117 // iside 0 is side C, iside 1 is side A
120
121 ANA_MSG_DEBUG("Processing LIS modules");
122
123 // Initialize arrays to zero
124
125 for (int ichan = 0; ichan < nLISChannels; ichan++)
126 {
127 t_LISPresample[ichan] = 0;
128 t_LISADCSum[ichan] = 0;
129 t_LISMaxADC[ichan] = 0;
130 t_LISMaxSample[ichan] = 0;
131 t_LISAvgTime[ichan] = 0;
132 t_LISModuleStatus[ichan] = 0;
133
134 for (int isam = 0; isam < nSamples; isam++)
135 {
136 t_LISRawdata[ichan][isam] = 0;
137 }
138 }
139
140
141 // Default LED type
142 t_LEDType = 999;
143
144 ANA_MSG_DEBUG("Accessing ZdcModules for LIS data");
145
146 static const SG::ConstAccessor<unsigned int> ZdcLEDTypeAccessor("ZdcLEDType" + m_auxSuffix);
147 static const SG::ConstAccessor<unsigned int> LEDTypeAccessor("LEDType" + m_auxSuffix);
148 static const SG::ConstAccessor<float> LISPresampleAccessor("LISPresample" + m_auxSuffix);
149 static const SG::ConstAccessor<int> LISADCSumAccessor("LISADCSum" + m_auxSuffix);
150 static const SG::ConstAccessor<int> LISMaxADCAccessor("LISMaxADC" + m_auxSuffix);
151 static const SG::ConstAccessor<unsigned int> LISMaxSampleAccessor("LISMaxSample" + m_auxSuffix);
152 static const SG::ConstAccessor<float> LISAvgTimeAccessor("LISAvgTime" + m_auxSuffix);
153 static const SG::ConstAccessor<unsigned int> LISModuleStatusAccessor("LISModuleStatus" + m_auxSuffix);
154 static const SG::ConstAccessor<std::vector<uint16_t>> g0dataAccessor("g0data" + m_auxSuffix);
155 static const SG::ConstAccessor<std::vector<uint16_t>> g1dataAccessor("g1data" + m_auxSuffix);
156
157 if (zdcModules.ptr())
158 {
159 for (const auto zdcMod : *zdcModules)
160 {
161 // Get LED type from sum container
162 if (zdcSums.ptr())
163 {
164 for (const auto zdcSum : *zdcSums)
165 {
166 if (zdcSum->zdcSide() == infoSumInd)
167 {
168 if (ZdcLEDTypeAccessor.isAvailable(*zdcSum))
169 {
170 t_LEDType = ZdcLEDTypeAccessor(*zdcSum);
171 break;
172 }
173 // Fallback to LEDType if ZdcLEDType not available
174 else if (LEDTypeAccessor.isAvailable(*zdcSum))
175 {
176 t_LEDType = LEDTypeAccessor(*zdcSum);
177 break;
178 }
179 }
180 }
181 }
182
183 // Skip side 0 (info container)
184 if (zdcMod->zdcSide() == 0)
185 continue;
186
187 // Check if this is a LIS module (type=2, module=5)
188 if (zdcMod->zdcType() == LISTypeInd && zdcMod->zdcModule() == LISModuleInd)
189 {
190
191 if(zdcMod->zdcSide() > 0){
192 ANA_MSG_WARNING("No LIS on side A, whats that?");
193 }
194
195 int ichan = zdcMod->zdcChannel();
196
197 // Bounds check
198 if (ichan < 0 || ichan >= nLISChannels)
199 {
200 ANA_MSG_WARNING("LIS channel " << ichan << " out of range");
201 continue;
202 }
203
204 ANA_MSG_VERBOSE("LIS Module side " << zdcMod->zdcSide() << " channel " << ichan);
205
206 // Check for LIS aux data availability
207 if (!LISPresampleAccessor.isAvailable(*zdcMod))
208 {
209 ANA_MSG_WARNING("Missing LIS aux data for side " << zdcMod->zdcSide() << " channel " << ichan);
210 continue;
211 }
212
213 // Read processed LIS data
214 t_LISPresample[ichan] = LISPresampleAccessor(*zdcMod);
215 t_LISADCSum[ichan] = LISADCSumAccessor(*zdcMod);
216 t_LISMaxADC[ichan] = LISMaxADCAccessor(*zdcMod);
217 t_LISMaxSample[ichan] = LISMaxSampleAccessor(*zdcMod);
218 t_LISAvgTime[ichan] = LISAvgTimeAccessor(*zdcMod);
219 t_LISModuleStatus[ichan] = LISModuleStatusAccessor(*zdcMod);
220 // Read raw waveform data
221 if(ichan > 3){
222 if (g1dataAccessor.isAvailable(*zdcMod))
223 {
224 const std::vector<uint16_t> &g1dataVec = g1dataAccessor(*zdcMod);
225 for (int isam = 0; isam < nSamples && isam < static_cast<int>(g1dataVec.size()); isam++)
226 {
227 t_LISRawdata[ichan][isam] = g1dataVec.at(isam);
228 }
229 }
230 }
231 else{
232 if (g0dataAccessor.isAvailable(*zdcMod))
233 {
234 const std::vector<uint16_t> &g0dataVec = g0dataAccessor(*zdcMod);
235 for (int isam = 0; isam < nSamples && isam < static_cast<int>(g0dataVec.size()); isam++)
236 {
237 t_LISRawdata[ichan][isam] = g0dataVec.at(isam);
238 }
239 }
240 }
241
242 }
243 }
244 }
245}
246
248{
249 ANA_MSG_DEBUG("Processing event info");
250
251 // Get BCID from ZdcSums rodBCID decoration (from LUCROD)
252 static const SG::Accessor<std::vector<uint16_t>> rodBCIDAcc("rodBCID");
254
255 t_bcid = m_eventInfo->bcid(); // Default from EventInfo
256
257 if (zdcSums.ptr()) {
258 for (const auto zdcSum : *zdcSums) {
259 if (zdcSum->zdcSide() == infoSumInd) {
260 if (rodBCIDAcc.isAvailable(*zdcSum)) {
261 const std::vector<uint16_t>& rodBCID = rodBCIDAcc(*zdcSum);
262 if (!rodBCID.empty()) {
263 t_bcid = rodBCID[0]; // Use BCID from LUCROD
264 ANA_MSG_DEBUG("Using BCID from rodBCID: " << t_bcid);
265 }
266 }
267 break;
268 }
269 }
270 }
271
272 t_runNumber = m_eventInfo->runNumber();
273 t_eventNumber = m_eventInfo->eventNumber();
274 t_lumiBlock = m_eventInfo->lumiBlock();
275 t_bunchGroup = -1;
276 t_extendedLevel1ID = m_eventInfo->extendedLevel1ID();
277 t_timeStamp = m_eventInfo->timeStamp();
278 t_timeStampNSOffset = m_eventInfo->timeStampNSOffset();
279 t_avgIntPerCrossing = m_eventInfo->averageInteractionsPerCrossing();
280 t_actIntPerCrossing = m_eventInfo->actualInteractionsPerCrossing();
281
282 if (!(m_eventCounter++ % 1000))
283 {
284 ANA_MSG_INFO("Event# " << m_eventCounter << " Run " << m_eventInfo->runNumber()
285 << " Event " << m_eventInfo->eventNumber() << " LB " << m_eventInfo->lumiBlock());
286 }
287}
288
290{
291 return StatusCode::SUCCESS;
292}
293
294bool LisNtuple::processTriggerDecision() // reimpleneted from ZdcNtuple.cxx
295{
296 ANA_MSG_DEBUG ("Processing trigger");
297
298 bool passTrigger = false;
299
300 t_trigger = 0;
301 t_trigger_TBP = 0;
302
303 for (int i = 0; i < 16; i++)
304 {
305 t_tav[i] = 0;
306 t_tbp[i] = 0;
307 }
308
309 if (m_trigDecision)
310 {
311 for (int i = 0; i < 16; i++)
312 {
313 t_tbp[i] = m_trigDecision->tbp().at(i);
314 t_tav[i] = m_trigDecision->tav().at(i);
315 ANA_MSG_DEBUG( "TD: " << i << " tbp: " << std::hex << t_tbp[i] << "\t" << t_tav[i] );
316 }
317 t_bunchGroup = m_trigDecision->bgCode();
318 }
319
320 return passTrigger;
321}
322
324 // Check for new run number
325 //
327 //
328 // Get access to the injector pulse steps for this run
329 //
331 if (!m_injMapRunToken.isValid()) {
332 ANA_MSG_ERROR("Unable to obtain injector pulse steps for run " << t_runNumber);
333 }
334 else {
335 unsigned int startLB = m_zdcInjPulserAmpMap->getFirstLumiBlock(m_injMapRunToken);
336 unsigned int nsteps = m_zdcInjPulserAmpMap->getNumSteps(m_injMapRunToken);
337 ANA_MSG_DEBUG("Successfully obtained injector pulse steps for run " << t_runNumber
338 << ", first LB = " << startLB << ", number of steps = " << nsteps);
339 }
340
341 // update the last run number to be the current run number
343 }
344
346}
#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:39
uint32_t t_timeStampNSOffset
Definition LisNtuple.h:58
const xAOD::TrigDecision * m_trigDecision
Definition LisNtuple.h:32
uint8_t t_bunchGroup
Definition LisNtuple.h:55
float t_LISPresample[nLISChannels]
Definition LisNtuple.h:84
uint32_t t_runNumber
Definition LisNtuple.h:51
int t_LISADCSum[nLISChannels]
Definition LisNtuple.h:85
uint32_t t_eventNumber
Definition LisNtuple.h:52
void processLisNtupleFromModules()
static constexpr int LISTypeInd
Definition LisNtuple.h:79
bool enableTrigger
Definition LisNtuple.h:36
unsigned int t_LISMaxSample[nLISChannels]
Definition LisNtuple.h:87
uint32_t t_tbp[nTriggerWords]
Definition LisNtuple.h:64
float t_actIntPerCrossing
Definition LisNtuple.h:60
float t_vInj
Definition LisNtuple.h:50
const xAOD::EventInfo * m_eventInfo
Definition LisNtuple.h:30
virtual StatusCode execute() override
Definition LisNtuple.cxx:77
static constexpr int infoSumInd
Definition LisNtuple.h:81
static constexpr int LISModuleInd
Definition LisNtuple.h:80
virtual StatusCode initialize() override
Definition LisNtuple.cxx:24
uint32_t t_extendedLevel1ID
Definition LisNtuple.h:56
int m_eventCounter
Definition LisNtuple.h:31
bool processTriggerDecision()
unsigned int t_LISModuleStatus[nLISChannels]
Definition LisNtuple.h:89
static constexpr int nSamples
Definition LisNtuple.h:77
void processVInjInfo()
float t_avgIntPerCrossing
Definition LisNtuple.h:59
bool m_enableOutputTree
Definition LisNtuple.h:35
uint32_t t_bcid
Definition LisNtuple.h:54
uint16_t t_LISRawdata[nLISChannels][nSamples]
Definition LisNtuple.h:92
uint32_t t_tav[nTriggerWords]
Definition LisNtuple.h:62
SG::ReadHandleKey< xAOD::ZdcModuleContainer > m_zdcSumContainerName
Definition LisNtuple.h:29
virtual StatusCode finalize() override
uint32_t t_lumiBlock
Definition LisNtuple.h:53
ZdcInjPulserAmpMap::Token m_injMapRunToken
Definition LisNtuple.h:25
unsigned int m_lastRunNumber
Definition LisNtuple.h:24
SG::ReadHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleContainerName
Definition LisNtuple.h:28
uint32_t t_timeStamp
Definition LisNtuple.h:57
void processEventInfo()
bool m_lisLED
Definition LisNtuple.h:38
float t_LISAvgTime[nLISChannels]
Definition LisNtuple.h:88
bool m_lisInj
Definition LisNtuple.h:37
uint32_t t_trigger_TBP
Definition LisNtuple.h:67
unsigned int t_LEDType
Definition LisNtuple.h:73
TTree * m_outputTree
Definition LisNtuple.h:44
LisNtuple(const std::string &name, ISvcLocator *pSvcLocator)
Definition LisNtuple.cxx:12
int t_LISMaxADC[nLISChannels]
Definition LisNtuple.h:86
static constexpr int nLISChannels
Definition LisNtuple.h:76
uint64_t t_trigger
Definition LisNtuple.h:66
std::unique_ptr< ZdcInjPulserAmpMap > m_zdcInjPulserAmpMap
Definition LisNtuple.h:47
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