11 #include <boost/python/def.hpp>
12 #include <boost/python/overloads.hpp>
13 #include <boost/python/docstring_options.hpp>
14 #include <boost/python/list.hpp>
15 #include <boost/python/dict.hpp>
16 #include <boost/python/extract.hpp>
17 #include <boost/python/return_value_policy.hpp>
18 #include <boost/python/manage_new_object.hpp>
19 #include <boost/python/raw_function.hpp>
20 #include <boost/algorithm/string.hpp>
22 #include <framework/database/Database.h>
24 #include <framework/dataobjects/EventMetaData.h>
25 #include <framework/logging/Logger.h>
26 #include <framework/database/LocalDatabase.h>
27 #include <framework/database/ConditionsDatabase.h>
28 #include <framework/database/DatabaseChain.h>
29 #include <framework/database/DBStore.h>
30 #include <framework/database/PayloadFile.h>
32 #include <framework/database/PayloadProvider.h>
33 #include <framework/database/MetadataProvider.h>
34 #include <framework/database/LocalMetadataProvider.h>
35 #include <framework/database/CentralMetadataProvider.h>
36 #include <framework/database/Configuration.h>
57 conf.setInitialized(
false);
79 std::vector<DBQuery> query{
DBQuery{name,
true}};
81 entry.
updatePayload(query[0].revision, query[0].iov, query[0].filename, query[0].checksum, event);
91 const size_t testingPayloads = std::count_if(query.begin(), query.end(), [
this, &event](
auto & payload) {
93 payload.filename =
"";
96 for (auto& tmp : m_testingPayloads) {
97 if (tmp.get(event, payload)) return true;
102 if (testingPayloads == query.size())
return true;
105 m_metadataProvider->getPayloads(event.getExperiment(), event.getRun(), query);
106 }
catch (std::exception&) {
108 B2ERROR(
"Conditions data: Problem with payload metadata, trying to fall back to next provider ...");
109 nextMetadataProvider();
110 return getData(event, query);
113 const size_t payloadsLocated = std::count_if(query.begin(), query.end(), [
this](
auto & payload) {
115 if (!payload.filename.empty()) return true;
119 if (payload.revision == 0) return not payload.required;
121 if (not m_payloadProvider->find(payload)) {
125 auto loglevel = payload.required ? LogConfig::c_Error : LogConfig::c_Warning;
126 B2LOG(loglevel, 0,
"Conditions data: Could not find file for payload"
127 << LogVar(
"name", payload.name) << LogVar(
"revision", payload.revision)
128 << LogVar(
"checksum", payload.checksum) << LogVar(
"globaltag", payload.globaltag));
129 return not payload.required;
134 return payloadsLocated == query.size();
137 bool Database::storeData(std::list<DBImportQuery>& query)
139 return std::all_of(query.begin(), query.end(), [
this](
const auto &
import) {
140 return storeData(import.name, import.object, import.iov);
144 bool Database::storeData(
const std::string& name, TObject* obj,
const IntervalOfValidity& iov)
146 if (!m_payloadCreation) initialize();
147 auto result = m_payloadCreation->storeData(name, obj, iov);
150 for (
auto& testing : m_testingPayloads) {
157 std::string Database::getGlobalTags()
159 return boost::algorithm::join(m_globalTags,
",");
162 void Database::nextMetadataProvider()
164 if (m_metadataConfigurations.empty()) {
165 B2FATAL(
"Conditions data: No more metadata providers available");
167 auto provider = m_metadataConfigurations.back();
168 m_metadataConfigurations.pop_back();
170 if (
auto pos = provider.find(
"://"); pos != std::string::npos) {
172 auto protocol = provider.substr(0, pos);
173 boost::algorithm::to_lower(protocol);
174 if (protocol ==
"file") {
175 provider = provider.substr(pos + 3);
176 }
else if (protocol ==
"http" or protocol ==
"https") {
179 B2FATAL(
"Conditions data: Unknown metadata protocol, only supported protocols for payload metadata are file, http, https"
180 <<
LogVar(
"protocol", protocol));
185 m_metadataProvider = std::make_unique<Conditions::CentralMetadataProvider>(provider, m_usableTagStates);
187 m_metadataProvider = std::make_unique<Conditions::LocalMetadataProvider>(provider, m_usableTagStates);
189 }
catch (std::exception& e) {
190 B2WARNING(
"Conditions data: Metadata provider not usable, trying next one ..."
191 <<
LogVar(
"provider", provider) <<
LogVar(
"error",
e.what()));
192 return nextMetadataProvider();
195 if (!m_metadataProvider->setTags(m_globalTags)) {
196 B2FATAL(
"Conditions data: Problems with globaltag configuration, cannot continue");
200 void Database::initialize(
const EDatabaseState target)
202 if (m_configState >= target)
return;
203 auto conf = Conditions::Configuration::getInstance();
205 if (m_configState == c_PreInit) {
209 conf.setInitialized(
true);
210 m_globalTags = conf.getFinalListOfTags();
212 std::set<std::string> seen;
213 m_globalTags.erase(std::remove_if(m_globalTags.begin(), m_globalTags.end(),
214 [&seen](
const auto & tag) {
215 return not seen.insert(tag).second;
216 }), m_globalTags.end());
218 m_usableTagStates = conf.getUsableTagStates();
219 m_metadataConfigurations = conf.getMetadataProviders();
221 std::reverse(m_metadataConfigurations.begin(), m_metadataConfigurations.end());
222 m_configState = c_InitGlobaltagList;
225 if (m_configState >= target)
return;
226 if (m_configState == c_InitGlobaltagList) {
228 if (m_metadataConfigurations.empty()) {
229 m_metadataProvider = std::make_unique<Conditions::NullMetadataProvider>();
231 nextMetadataProvider();
234 if (!m_globalTags.empty()) {
236 if (m_globalTags.size() == 1) {
237 B2INFO(
"Conditions data: configured globaltag is " << m_globalTags[0]);
239 B2INFO(
"Conditions data: configured globaltags (highest priority first) are " << boost::algorithm::join(m_globalTags,
", "));
243 m_payloadProvider = std::make_unique<Conditions::PayloadProvider>(
244 conf.getPayloadLocations(),
245 conf.getDownloadCacheDirectory(),
246 conf.getDownloadLockTimeout()
249 m_payloadCreation = std::make_unique<Conditions::TestingPayloadStorage>(conf.getNewPayloadLocation());
251 m_testingPayloads.clear();
252 for (
const auto& path : conf.getTestingPayloadLocations()) {
253 B2INFO(
"Conditions data: configured to use testing payloads" <<
LogVar(
"location", path));
254 m_testingPayloads.emplace_back(path);
257 if (not m_testingPayloads.empty()) {
258 B2WARNING(R
"(Conditions data: configured to look for temporary tesing payloads from one or more local folders.
260 This will lead to non-reproducible results and is strictly only for testing purposes.
261 It is NOT ALLOWED for official productions or data analysis and any results obtained like this WILL NOT BE PUBLISHED.
264 m_configState = c_Ready;
269 #ifdef __INTEL_COMPILER
270 #pragma warning (disable:1478) //[[deprecated]]
271 #pragma warning (disable:1786) //[[deprecated("message")]]
273 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
276 void Database::exposePythonAPI()
279 namespace py = boost::python;
281 Database::Instance();
284 py::docstring_options options(
true,
true,
false);
286 py::def(
"reset_database", &Database::reset, (py::arg(
"keep_config") =
false),
287 R
"DOC(Reset the database setup to have no database sources
289 .. deprecated:: release-04-00-00
290 Please use `basf2.conditions` for all configuration of the conditions database)DOC");
291 py::def("use_database_chain", &DatabaseChain::createInstance,
292 (py::arg(
"resetIoVs") =
true, py::arg(
"loglevel") = LogConfig::c_Warning, py::arg(
"invertLogging") =
false),
294 Use a database chain. This function used to be necessary to enable usage of
295 multiple globaltags but has been deprecated.
297 .. deprecated:: release-04-00-00
298 This function is no longer needed and is just kept for compatibility.
299 In its current state it does nothing and ignores all arguments.
300 Please use `basf2.conditions` for all configuration of the conditions database
302 py::def("use_local_database", &LocalDatabase::createInstance,
303 (py::arg(
"filename"), py::arg(
"directory")=
"", py::arg(
"readonly")=
false,
304 py::arg(
"loglevel")=LogConfig::c_Warning, py::arg(
"invertLogging")=
false),
306 Use a local database backend: a single file containing the payload information in plain text.
309 filename (str): filename containing the payload information, defaults to
310 "database.txt". This file needs to exist.
311 directory (str): directory containing the payloads, defaults to the directory
312 of the database filename. This parameter doesn't have any effect anymore:
313 payloads **must** be in the same directory as the text file. If this parameter
314 is not empty and doesn't point to the same directory a error is raised.
315 readonly (bool): if True the database will refuse to create new payloads.
316 This parameter doesn't have any effect anymore. Local databases are always readonly
317 loglevel (LogLevel): The severity of messages from this backend when
318 payloads cannot be found. This parameter doesn't have any effect anymore.
319 invertLogging (bool): A flag to indicate whether logging of obtained
320 payloads should be inverted. This parameter doesn't have any effect anymore.
322 .. deprecated:: release-04-00-00
323 Most of the parameters don't have any effect anymore and are kept for compatibility
324 Please use `basf2.conditions` for all configuration of the conditions database.
328 py::docstring_options subOptions(
true,
false,
false);
330 py::def(
"use_central_database", &ConditionsDatabase::createDefaultInstance,
331 (py::arg(
"globalTag"), py::arg(
"loglevel")=LogConfig::c_Warning, py::arg(
"payloaddir")=
"centraldb"));
332 py::def(
"use_central_database", &ConditionsDatabase::createInstance,
333 (py::arg(
"globalTag"), py::arg(
"restBaseName"), py::arg(
"payloaddir"), py::arg(
"fileBaseLocal"),
334 py::arg(
"loglevel")=LogConfig::c_Warning, py::arg(
"invertLogging")=
false),
335 R
"DOCSTRING(use_central_database(globalTag, restBaseName=None, payloadDir="centraldb", fileBaseLocal=None, loglevel=LogLevel.WARNING, invertLogging=False)
337 Use the central database to obtain conditions data. Usually users should only
338 need to call this with one parameter which is the global tag to identify the
342 globalTag (str): name of the global tag to use for payload lookup
343 restBaseName (str): base URL for the REST api. This parameter is no longer supported,
344 any value other than an empty string will lead to an error.
345 fileBaseName (str): base directory to look for payloads instead of
346 downloading them. This parameter is no longer supported,
347 any value other than an empty string will lead to an error.
348 payloaddir (str): directory where to save downloaded payloads.
349 loglevel (LogLevel): The LogLevel of messages from this backend when
350 payloads cannot be found. This parameter is no longer supported and is ignored.
351 invertLogging (bool): A flag to indicate whether logging of obtained
352 payloads should be inverted. This parameter is no longer supported and is ignored.
354 .. deprecated:: release-04-00-00
355 Most of the parameters don't have any effect anymore and are kept for compatibility
356 Please use `basf2.conditions` for all configuration of the conditions database.
360 Conditions::Configuration::exposePythonAPI();