Project
Loading...
Searching...
No Matches
Plugin.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#include "Framework/Plugins.h"
17#include "Framework/Signpost.h"
19#include "AODWriterHelpers.h"
20#include <TFile.h>
21#include <TMap.h>
22#include <TGrid.h>
23#include <TObjString.h>
24#include <TString.h>
25#include <fmt/format.h>
26#include <memory>
27
28O2_DECLARE_DYNAMIC_LOG(analysis_support);
29
36
43
50
51using namespace o2::framework;
54 {
56 .name = "analysis-run-summary",
57 .init = [](ServiceRegistryRef ref, DeviceState&, fair::mq::ProgOptions&) -> ServiceHandle {
58 return ServiceHandle{TypeIdHelpers::uniqueId<RunSummary>(), nullptr, ServiceKind::Serial, "analysis-run-summary"};
59 },
60 .summaryHandling = [](ServiceMetricsInfo const& info) {
61 LOGP(info, "## Analysis Run Summary ##");
63 for (size_t mi = 0; mi < info.deviceMetricsInfos.size(); ++mi) {
64 DeviceMetricsInfo &metrics = info.deviceMetricsInfos[mi];
65 for (size_t li = 0; li < metrics.metricLabels.size(); ++li) {
66 MetricLabel const&label = metrics.metricLabels[li];
67 if (strcmp(label.label, "aod-file-read-info") != 0) {
68 continue;
69 }
70 MetricInfo const&metric = metrics.metrics[li];
71 auto &files = metrics.stringMetrics[metric.storeIdx];
72 if (metric.filledMetrics) {
73 LOGP(info, "### Files read stats ###");
74 }
75 for (size_t fi = 0; fi < metric.filledMetrics; ++fi) {
76 LOGP(info, "{}", files[fi % files.size()].data);
77 }
78 }
79 } },
80 .kind = ServiceKind::Serial};
81 }
82};
83
84std::vector<std::string> getListOfTables(std::unique_ptr<TFile>& f)
85{
86 std::vector<std::string> r;
87 TList* keyList = f->GetListOfKeys();
88
89 for (auto key : *keyList) {
90 if (!std::string_view(key->GetName()).starts_with("DF_")) {
91 continue;
92 }
93 auto* d = (TDirectory*)f->Get(key->GetName());
94 TList* branchList = d->GetListOfKeys();
95 for (auto b : *branchList) {
96 r.emplace_back(b->GetName());
97 }
98 break;
99 }
100 return r;
101}
102auto readMetadata(std::unique_ptr<TFile>& currentFile) -> std::vector<ConfigParamSpec>
103{
104 // Get the metadata, if any
105 auto m = (TMap*)currentFile->Get("metaData");
106 if (!m) {
107 return {};
108 }
109 std::vector<ConfigParamSpec> results;
110 auto it = m->MakeIterator();
111
112 // Serialise metadata into a ; separated string with : separating key and value
113 bool first = true;
114 while (auto obj = it->Next()) {
115 if (first) {
116 LOGP(info, "Metadata for file \"{}\":", currentFile->GetName());
117 first = false;
118 }
119 auto objString = (TObjString*)m->GetValue(obj);
120 LOGP(info, "- {}: {}", obj->GetName(), objString->String().Data());
121 std::string key = "aod-metadata-" + std::string(obj->GetName());
122 char const* value = strdup(objString->String());
123 results.push_back(ConfigParamSpec{key, VariantType::String, value, {"Metadata in AOD"}});
124 }
125
126 return results;
127}
128
131 {
132 return new ConfigDiscovery{
133 .init = []() {},
134 .discover = [](ConfigParamRegistry& registry, int argc, char** argv) -> std::vector<ConfigParamSpec> {
135 auto filename = registry.get<std::string>("aod-file");
136 if (filename.empty()) {
137 return {};
138 }
139 if (filename.at(0) == '@') {
140 filename.erase(0, 1);
141 // read the text file and set filename to the contents of the first line
142 std::ifstream file(filename);
143 if (!file.is_open()) {
144 LOGP(fatal, "Couldn't open file \"{}\"!", filename);
145 }
146 std::getline(file, filename);
147 file.close();
148 }
149 if (filename.rfind("alien://", 0) == 0) {
150 TGrid::Connect("alien://");
151 }
152 LOGP(info, "Loading metadata from file {} in PID {}", filename, getpid());
153 std::unique_ptr<TFile> currentFile{TFile::Open(filename.c_str())};
154 if (currentFile.get() == nullptr) {
155 LOGP(fatal, "Couldn't open file \"{}\"!", filename);
156 }
157 std::vector<ConfigParamSpec> results = readMetadata(currentFile);
158 const bool metaDataEmpty = results.empty();
159 auto tables = getListOfTables(currentFile);
160 if (tables.empty() == false) {
161 results.push_back(ConfigParamSpec{"aod-metadata-tables", VariantType::ArrayString, tables, {"Tables in first AOD"}});
162 }
163
164 // Found metadata already in the main file.
165 if (!metaDataEmpty) {
166 results.push_back(ConfigParamSpec{"aod-metadata-source", VariantType::String, filename, {"File from which the metadata was extracted."}});
167 return results;
168 }
169
170 if (!registry.isSet("aod-parent-access-level") || registry.get<int>("aod-parent-access-level") == 0) {
171 LOGP(info, "No metadata found in file \"{}\" and parent level 0 prevents further lookup.", filename);
172 results.push_back(ConfigParamSpec{"aod-metadata-disable", VariantType::String, "1", {"Metadata not found in AOD"}});
173 return results;
174 }
175
176 // Lets try in parent file.
177 auto parentFiles = (TMap*)currentFile->Get("parentFiles");
178 if (!parentFiles) {
179 LOGP(info, "No metadata found in file \"{}\"", filename);
180 results.push_back(ConfigParamSpec{"aod-metadata-disable", VariantType::String, "1", {"Metadata not found in AOD"}});
181 return results;
182 }
183 LOGP(info, "No metadata found in file \"{}\", checking in its parents.", filename);
184 for (auto* p : *parentFiles) {
185 std::string parentFilename = ((TPair*)p)->Value()->GetName();
186 // Do the replacement. Notice this will require changing aod-parent-base-path-replacement to be
187 // a workflow option (because the metadata itself is potentially changing the topology).
188 if (registry.isSet("aod-parent-base-path-replacement")) {
189 auto parentFileReplacement = registry.get<std::string>("aod-parent-base-path-replacement");
190 auto pos = parentFileReplacement.find(';');
191 if (pos == std::string::npos) {
192 throw std::runtime_error(fmt::format("Invalid syntax in aod-parent-base-path-replacement: \"{}\"", parentFileReplacement.c_str()));
193 }
194 auto from = parentFileReplacement.substr(0, pos);
195 auto to = parentFileReplacement.substr(pos + 1);
196 pos = parentFilename.find(from);
197 if (pos != std::string::npos) {
198 parentFilename.replace(pos, from.length(), to);
199 }
200 }
201
202 if (parentFilename.starts_with("alien://")) {
203 TGrid::Connect("alien://");
204 }
205
206 std::unique_ptr<TFile> parentFile{TFile::Open(parentFilename.c_str())};
207 if (parentFile.get() == nullptr) {
208 LOGP(fatal, "Couldn't open derived file \"{}\"!", parentFilename);
209 }
210 results = readMetadata(parentFile);
211 // Found metadata already in the main file.
212 if (!results.empty()) {
213 auto tables = getListOfTables(parentFile);
214 if (tables.empty() == false) {
215 results.push_back(ConfigParamSpec{"aod-metadata-tables", VariantType::ArrayString, tables, {"Tables in first AOD"}});
216 }
217 results.push_back(ConfigParamSpec{"aod-metadata-source", VariantType::String, filename, {"File from which the metadata was extracted."}});
218 return results;
219 }
220 LOGP(info, "No metadata found in file \"{}\" nor in its parent file \"{}\"", filename, parentFilename);
221 break;
222 }
223 results.push_back(ConfigParamSpec{"aod-metadata-disable", VariantType::String, "1", {"Metadata not found in AOD"}});
224 return results;
225 }};
226 }
227};
228
std::vector< std::string > getListOfTables(std::unique_ptr< TFile > &f)
Definition Plugin.cxx:84
auto readMetadata(std::unique_ptr< TFile > &currentFile) -> std::vector< ConfigParamSpec >
Definition Plugin.cxx:102
#define DEFINE_DPL_PLUGIN_INSTANCE(NAME, KIND)
Definition Plugins.h:112
#define DEFINE_DPL_PLUGINS_END
Definition Plugins.h:115
#define DEFINE_DPL_PLUGINS_BEGIN
Definition Plugins.h:107
uint16_t pos
Definition RawData.h:3
#define O2_DECLARE_DYNAMIC_LOG(name)
Definition Signpost.h:473
StringRef key
const GLfloat * m
Definition glcorearb.h:4066
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
Definition glcorearb.h:5500
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLboolean r
Definition glcorearb.h:1233
GLint ref
Definition glcorearb.h:291
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::string filename()
ConfigDiscovery * create() override
Definition Plugin.cxx:130
o2::framework::AlgorithmSpec create(o2::framework::ConfigContext const &config) override
Definition Plugin.cxx:31
o2::framework::AlgorithmSpec create(o2::framework::ConfigContext const &config) override
Definition Plugin.cxx:38
o2::framework::AlgorithmSpec create(o2::framework::ConfigContext const &config) override
Definition Plugin.cxx:45
o2::framework::ServiceSpec * create() final
Definition Plugin.cxx:53
Helper class for an algorithm which is loaded as a plugin.
Running state information of a given device.
Definition DeviceState.h:34
std::string name
Name of the service.
static AlgorithmSpec rootFileReaderCallback(ConfigContext const &context)
static AlgorithmSpec getOutputObjHistWriter(ConfigContext const &context)
static AlgorithmSpec getOutputTTreeWriter(ConfigContext const &context)