ATLAS Offline Software
TrigCOOLUpdateHelper.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
11 #include "TrigCOOLUpdateHelper.h"
12 
14 #include "AthenaKernel/IOVTime.h"
15 #include "AthenaKernel/IOVRange.h"
17 #include "CoralBase/AttributeListException.h"
18 #include "StoreGate/DataHandle.h"
19 
20 // TDAQ includes
21 #include "CTPfragment/CTPfragment.h"
22 #include "CTPfragment/CTPExtraWordsFormat.h"
23 #include "CTPfragment/Issue.h"
24 
25 #include <algorithm>
26 #include <sstream>
27 
28 //=========================================================================
29 // Standard methods
30 //=========================================================================
32  const std::string &name,
33  const IInterface *parent)
35  m_robDataProviderSvc("ROBDataProviderSvc", name)
36 {}
37 
38 
40 {
41  // Do not create these services if they are not available already
42  m_iovSvc = service("IOVSvc", /*createIf=*/false);
43  m_iovDbSvc = service("IOVDbSvc", /*createIf=*/false);
44 
45  if (!m_monTool.empty()) ATH_CHECK(m_monTool.retrieve());
46 
47  return StatusCode::SUCCESS;
48 }
49 
50 
52 {
53  m_folderUpdates.clear();
54  return StatusCode::SUCCESS;
55 }
56 
58 {
59  std::ostringstream pending;
60  // Loop over folder updates
61  for (auto f : m_folderUpdates) {
62  if (f.second.needsUpdate) pending << "[" << f.second.lumiBlock << "," << f.second.folderIndex << "]";
63  }
64 
65  if (pending.str().empty()) pending << "NONE";
66  ATH_MSG_INFO("[LB,Folder] with pending COOL updates: " << pending.str());
67 
68  return StatusCode::SUCCESS;
69 }
70 
71 //=========================================================================
72 // Read COOL folder info
73 // Loop over all registered keys and get folder name and CLID
74 //=========================================================================
75 StatusCode TrigCOOLUpdateHelper::readFolderInfo()
76 {
77  if (!m_iovDbSvc) return StatusCode::SUCCESS;
78 
79  m_folderInfo.clear();
80  // Loop over all keys registered with IOVDbSvc
81  for (const std::string& key : m_iovDbSvc->getKeyList()) {
82 
83  // Get folder name and CLID for each key
85  if ( !m_iovDbSvc->getKeyInfo(key, info) ||
86  m_folderInfo.find(info.folderName)!=m_folderInfo.end() )
87  continue;
88 
89  CLID clid = detStore()->clid(key);
90  if (clid!=CLID_NULL)
91  m_folderInfo.insert({info.folderName, FolderInfo{clid, key}});
92  else
93  ATH_MSG_ERROR("Cannot find CLID for " << key);
94 
95  // If the folder is in the allowed list, make sure it is marked "extensible"
96  if (std::find(m_folders.begin(), m_folders.end(), info.folderName)!=m_folders.end() &&
97  not info.extensible) {
98  ATH_MSG_ERROR("IOVDBSvc folder " << info.folderName << " is not marked as </extensible>. "
99  "Remove it from the allowed 'Folders' property or mark it as extensible.");
100  return StatusCode::FAILURE;
101  }
102  }
103 
104  if (!m_coolFolderName.empty()) {
105  // Read COOL folder map
106  const DataHandle<CondAttrListCollection> folderMapHandle;
107  ATH_CHECK( detStore()->regHandle(folderMapHandle, m_coolFolderName) );
108 
109  ATH_MSG_INFO("COOL folder map in " << m_coolFolderName << ":");
110  for (auto const& [idx, attr] : *folderMapHandle) {
111  m_folderNames[idx] = attr["FolderName"].data<std::string>();
112  ATH_MSG_INFO(" (" << idx << ") " << m_folderNames[idx]);
113  }
114  }
115  return StatusCode::SUCCESS;
116 }
117 
118 StatusCode TrigCOOLUpdateHelper::resetFolders(const std::vector<std::string>& folders)
119 {
120  if (folders.empty()) return StatusCode::SUCCESS;
121 
122  StatusCode sc(StatusCode::SUCCESS);
123  for (const std::string& f : folders) {
124  if ( resetFolder(f).isFailure() ) {
125  sc = StatusCode::FAILURE;
126  }
127  }
128  return sc;
129 }
130 
132 {
133  // Force a reset of folders by setting an IOVRange in the past
134 
135  if (!m_iovSvc || !m_iovDbSvc) return StatusCode::SUCCESS;
136 
137  const auto& f = m_folderInfo.find(folder);
138  if ( f==m_folderInfo.end() ) {
139  ATH_MSG_DEBUG("Folder " << folder << " not registered with IOVDbSvc");
140  return StatusCode::SUCCESS;
141  }
142 
143  const CLID& clid = f->second.clid;
144  const std::string& key = f->second.key;
145 
146  // Make sure we are not trying to reset a time-based folder
147  IOVRange iov;
148  if ( m_iovSvc->getRange(clid, key, iov).isSuccess() ) {
149  if ( iov.start().isTimestamp() || iov.start().isBoth() ) {
150  ATH_MSG_ERROR(folder << " is not a Run/LB based folder. Cannot perform COOL update.");
151  return StatusCode::FAILURE;
152  }
153  }
154 
155  if ( m_iovSvc->dropObjectFromDB(clid, key, "StoreGateSvc").isFailure() ) {
156  ATH_MSG_WARNING("Could not invalidate folder " << folder);
157  return StatusCode::FAILURE;
158  }
159 
160  // All OK
161  ATH_MSG_INFO("Invalidated IOV and dropped payload of folder " <<
162  folder << (key!=folder ? " (key="+key+")" : "") );
163 
164  return StatusCode::SUCCESS;
165 }
166 
167 
168 //=========================================================================
169 // Folder update during the run
170 //=========================================================================
172 {
173  // Extract COOL folder updates from CTP fragment
174  if ( extractFolderUpdates(ctx).isFailure() ) {
175  ATH_MSG_ERROR("Failure reading CTP extra payload");
176  return StatusCode::FAILURE;
177  }
178 
179  // Loop over folders to be updated
180  for (auto& [idx, f] : m_folderUpdates) {
181 
182  if (f.needsUpdate) {
183 
184  if ( !m_iovSvc || m_coolFolderName.empty() ) {
185  ATH_MSG_DEBUG("Request to reload COOL folder ID " << idx << " for IOV change in lumiblock "
186  << f.lumiBlock << " but running without IOVSvc. Current event: " << ctx.eventID());
187  f.needsUpdate = false;
188  continue;
189  }
190 
191  std::string folderName;
192  if (getFolderName(f.folderIndex, folderName).isFailure()) {
193  continue; // On purpose not a failure
194  }
195 
196  ATH_MSG_INFO("Reload of COOL folder " << folderName << " for IOV change in lumiblock "
197  << f.lumiBlock << ". Current event: " << ctx.eventID());
198 
199  if ( hltCoolUpdate(folderName).isFailure() ) {
200  ATH_MSG_ERROR("COOL update failed for " << folderName << ". Aborting.");
201  return StatusCode::FAILURE;
202  }
203  // All OK
204  f.needsUpdate = false;
205  }
206  }
207 
208  return StatusCode::SUCCESS;
209 }
210 
212 {
213  if (std::find(m_folders.begin(), m_folders.end(), folderName)==m_folders.end()) {
214  ATH_MSG_ERROR("Received request to update COOL folder '" << folderName
215  << "' but this folder is not in the allowed list:" << m_folders);
216  return StatusCode::FAILURE;
217  }
218 
219  auto mon_t = Monitored::Timer("TIME_CoolFolderUpdate");
221 
222  // Reset folder and make IOVDbSvc drop objects
223  if (resetFolder(folderName).isFailure()) {
224  ATH_MSG_ERROR("Reset of " << folderName << " failed");
225  return StatusCode::FAILURE;
226  }
227 
228  return StatusCode::SUCCESS;
229 }
230 
231 StatusCode TrigCOOLUpdateHelper::getFolderName(CTPfragment::FolderIndex idx, std::string& folderName) const
232 {
233  const auto& itr = m_folderNames.find(idx);
234  if (itr==m_folderNames.end()) {
235  ATH_MSG_ERROR(m_coolFolderName << " does not contain a folder for index/channel " << idx
236  << ". Existing folders are:");
237  for (auto const& [idx, name] : m_folderNames) {
238  ATH_MSG_INFO(" (" << idx << ") " << name);
239  }
240  return StatusCode::FAILURE;
241  }
242 
243  folderName = itr->second;
244  return StatusCode::SUCCESS;
245 }
246 
247 
248 //=========================================================================
249 // Extract COOL folder updates from CTP fragment
250 //=========================================================================
252 {
253  using CTPfragment::FolderIndex;
255 
256  // Fetch CTP fragment ROB
257  const std::vector<uint32_t> robs{m_ctpRobId};
259  try {
260  m_robDataProviderSvc->addROBData(ctx, robs, name());
261  m_robDataProviderSvc->getROBData(ctx, robs, ctpRobs, name());
262  }
263  catch (const std::exception& ex) {
264  ATH_MSG_ERROR("Cannot retrieve CTP ROB 0x" << MSG::hex << m_ctpRobId.value() << MSG::dec << " due to exception: " << ex.what());
265  return StatusCode::FAILURE;
266  }
267 
268  if ( ctpRobs.empty() ) {
269  ATH_MSG_ERROR("Cannot retrieve CTP ROB 0x" << MSG::hex << m_ctpRobId.value() << MSG::dec);
270  return StatusCode::FAILURE;
271  }
272 
273  // Decode CTP extra payload words
274  std::vector<uint32_t> l1_extraPayload = CTPfragment::extraPayloadWords( ctpRobs[0] );
275  CTPfragment::ExtraPayload ctp_payload;
276  try {
277  ctp_payload = CTPfragment::ExtraPayload(l1_extraPayload);
278  }
279  catch (CTPfragment::ExtraPayloadTooLong& ex) {
280  ATH_MSG_ERROR("Invalid CTP fragment. Exception = " << ex.what());
281  return StatusCode::FAILURE;
282  }
283 
284  if ( msgLevel(MSG::DEBUG) ) {
285  msg() << MSG::DEBUG << "CTP extra payload (" << l1_extraPayload.size() << " words): ";
286  for (std::size_t i=0; i<l1_extraPayload.size(); ++i) {
287  msg() << " " << l1_extraPayload[i];
288  }
289  std::ostringstream out;
290  out << ctp_payload;
291  msg() << out.str() << endmsg;
292  }
293 
294  // Loop over potential new folder updates
295  for (const std::pair<const FolderIndex, FolderEntry>& kv : ctp_payload.getFolderUpdates()) {
296 
297  // Check if we already have an update for this folder
298  std::map<FolderIndex, FolderUpdate>::const_iterator f = m_folderUpdates.find(kv.first);
299 
300  // No updates yet or this update supersedes the previous one
301  if (f==m_folderUpdates.end() || (f->second.lumiBlock != kv.second.lumiBlock)) {
302  m_folderUpdates[kv.first] = FolderUpdate(kv.second); // new folder update
303 
304  ATH_MSG_DEBUG("Conditions update for folder " << kv.second.folderIndex
305  << " on lumiblock " << kv.second.lumiBlock);
306  }
307  }
308  return StatusCode::SUCCESS;
309 }
grepfile.info
info
Definition: grepfile.py:38
TrigCOOLUpdateHelper::m_folderNames
std::map< CTPfragment::FolderIndex, std::string > m_folderNames
Map to store the folder update index -> name mapping.
Definition: TrigCOOLUpdateHelper.h:116
TrigCOOLUpdateHelper::resetFolders
StatusCode resetFolders(const std::vector< std::string > &folders)
Reset list of COOL folders.
Definition: TrigCOOLUpdateHelper.cxx:118
dqt_zlumi_alleff_HIST.iov
iov
Definition: dqt_zlumi_alleff_HIST.py:119
IOVRange
Validity Range object. Holds two IOVTimes (start and stop)
Definition: IOVRange.h:30
CondAttrListCollection.h
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
IOVRange.h
Validity Range object. Holds two IOVTime instances (start and stop)
TrigCOOLUpdateHelper::m_folders
Gaudi::Property< std::vector< std::string > > m_folders
Definition: TrigCOOLUpdateHelper.h:129
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
Monitored::Group
Group of local monitoring quantities and retain correlation when filling histograms
Definition: MonitoredGroup.h:54
TrigCOOLUpdateHelper::m_folderInfo
std::map< std::string, FolderInfo > m_folderInfo
CLID/name mapping of COOL folders.
Definition: TrigCOOLUpdateHelper.h:110
DataHandle.h
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
IOVTime.h
Basic time unit for IOVSvc. Hold time as a combination of run and event numbers.
TrigCOOLUpdateHelper::initialize
virtual StatusCode initialize() override
Definition: TrigCOOLUpdateHelper.cxx:39
TrigCOOLUpdateHelper::m_monTool
ToolHandle< GenericMonitoringTool > m_monTool
Definition: TrigCOOLUpdateHelper.h:124
TrigCOOLUpdateHelper::m_iovSvc
SmartIF< IIOVSvc > m_iovSvc
Definition: TrigCOOLUpdateHelper.h:119
TrigCOOLUpdateHelper::extractFolderUpdates
StatusCode extractFolderUpdates(const EventContext &ctx)
Decode COOL folder updates according to extra payload in CTP fragment.
Definition: TrigCOOLUpdateHelper.cxx:251
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
TrigCOOLUpdateHelper::m_iovDbSvc
SmartIF< IIOVDbSvc > m_iovDbSvc
Definition: TrigCOOLUpdateHelper.h:120
TrigCOOLUpdateHelper::m_folderUpdates
std::map< CTPfragment::FolderIndex, FolderUpdate > m_folderUpdates
Map to store scheduled/done COOL folder updates.
Definition: TrigCOOLUpdateHelper.h:113
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
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
python.HLT.CommonSequences.EventBuildingSequences.robs
robs
Definition: EventBuildingSequences.py:401
TrigCOOLUpdateHelper::getFolderName
StatusCode getFolderName(CTPfragment::FolderIndex idx, std::string &folderName) const
Return folder name to index.
Definition: TrigCOOLUpdateHelper.cxx:231
calibdata.exception
exception
Definition: calibdata.py:496
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
hist_file_dump.f
f
Definition: hist_file_dump.py:135
IROBDataProviderSvc::VROBFRAG
std::vector< const ROBF * > VROBFRAG
Definition: IROBDataProviderSvc.h:27
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
TrigCOOLUpdateHelper::TrigCOOLUpdateHelper
TrigCOOLUpdateHelper(const std::string &type, const std::string &name, const IInterface *parent)
Definition: TrigCOOLUpdateHelper.cxx:31
FolderInfo
Struct to hold CLID <-> folder name mapping.
Definition: TrigCOOLUpdateHelper.h:36
CaloCellTimeCorrFiller.folderName
string folderName
Definition: CaloCellTimeCorrFiller.py:20
TrigCOOLUpdateHelper::m_ctpRobId
Gaudi::Property< uint32_t > m_ctpRobId
Definition: TrigCOOLUpdateHelper.h:132
TrigCOOLUpdateHelper.h
Helper tool for COOL updates.
TrigCOOLUpdateHelper::m_coolFolderName
Gaudi::Property< std::string > m_coolFolderName
Definition: TrigCOOLUpdateHelper.h:126
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
errorcheck.h
Helpers for checking error return status codes and reporting errors.
DataHandle< CondAttrListCollection >
TrigCOOLUpdateHelper::start
virtual StatusCode start() override
Definition: TrigCOOLUpdateHelper.cxx:51
TrigCOOLUpdateHelper::resetFolder
StatusCode resetFolder(const std::string &folder)
Reset COOL folder.
Definition: TrigCOOLUpdateHelper.cxx:131
makeDTCalibBlob_pickPhase.folders
folders
Definition: makeDTCalibBlob_pickPhase.py:346
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TrigCOOLUpdateHelper::m_robDataProviderSvc
ServiceHandle< IROBDataProviderSvc > m_robDataProviderSvc
Definition: TrigCOOLUpdateHelper.h:121
python.CTPfragment.ExtraPayload
ExtraPayload
Definition: CTPfragment.py:25
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
DEBUG
#define DEBUG
Definition: page_access.h:11
plotBeamSpotMon.mon
mon
Definition: plotBeamSpotMon.py:67
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
TrigCOOLUpdateHelper::stop
virtual StatusCode stop() override
Definition: TrigCOOLUpdateHelper.cxx:57
TrigCOOLUpdateHelper::hltCoolUpdate
StatusCode hltCoolUpdate(const EventContext &ctx)
Perform COOL udpates if needed.
Definition: TrigCOOLUpdateHelper.cxx:171
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
CaloCondBlobAlgs_fillNoiseFromASCII.folder
folder
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:56
IIOVDbSvc::KeyInfo
Filled by IIOVDbSvc::getKeyInfo.
Definition: IIOVDbSvc.h:44
AthAlgTool
Definition: AthAlgTool.h:26
FolderUpdate
Folder update entry.
Definition: TrigCOOLUpdateHelper.h:44
python.CTPfragment.FolderEntry
FolderEntry
Definition: CTPfragment.py:24
Monitored::Timer
A monitored timer.
Definition: MonitoredTimer.h:32
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37