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