Skip to content

Commit 48e1a14

Browse files
committed
Option to create configParams metadat from json dumps
With the option `--collect-config-files` provided, the AODProducer will collect the json dumps of ConfigParams made by the upstream processes and will add them as `<configName> : <configParam json>` TObjString pairs in the AOD metadata. Once the DPL supports collecting META/<PROCNAME>/0 sporadic inputs, the metadata will be created directly from these inputs, so this option will not be needed for the data processing. But in the case of MC, collecting json files via this option is the only way to add configs to the AOD metadata.
1 parent 47bf750 commit 48e1a14

2 files changed

Lines changed: 111 additions & 1 deletion

File tree

Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ class AODProducerWorkflowDPL : public Task
246246
return std::uint64_t(mStartIR.toLong()) + relativeTime_to_LocalBC(relativeTimeStampInNS);
247247
}
248248

249+
bool collectConfigFiles(std::vector<TString>& keys, std::vector<TString>& values, int indent = -1);
250+
249251
bool mThinTracks{false};
250252
bool mPropTracks{false};
251253
bool mPropMuons{false};
@@ -280,6 +282,7 @@ class AODProducerWorkflowDPL : public Task
280282
bool mEnableFITextra = false;
281283
bool mEnableTRDextra = false;
282284
bool mFieldON = false;
285+
bool mCollectConfigFiles = false;
283286
const float cSpeed = 0.029979246f; // speed of light in TOF units
284287

285288
GID::mask_t mInputSources;

Detectors/AOD/src/AODProducerWorkflowSpec.cxx

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
#include "Framework/TableBuilder.h"
5555
#include "Framework/CCDBParamSpec.h"
5656
#include "CommonUtils/TreeStreamRedirector.h"
57+
#include "CommonUtils/KeyValParam.h"
58+
#include "CommonUtils/NameConf.h"
5759
#include "FT0Base/Geometry.h"
5860
#include "GlobalTracking/MatchTOF.h"
5961
#include "ReconstructionDataFormats/Cascade.h"
@@ -88,6 +90,7 @@
8890
#include "MathUtils/Utils.h"
8991
#include "Math/SMatrix.h"
9092
#include "TString.h"
93+
#include <fnmatch.h>
9194
#include <limits>
9295
#include <map>
9396
#include <numeric>
@@ -1902,6 +1905,8 @@ void AODProducerWorkflowDPL::init(InitContext& ic)
19021905

19031906
mUseSigFiltMC = ic.options().get<bool>("mc-signal-filt");
19041907

1908+
mCollectConfigFiles = ic.options().get<bool>("collect-config-files");
1909+
19051910
// set no truncation if selected by user
19061911
if (mTruncate != 1) {
19071912
LOG(info) << "Truncation is not used!";
@@ -2670,6 +2675,10 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc)
26702675
mMetaDataVals = {dataType, "3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag, mUser};
26712676
add_additional_meta_info(mMetaDataKeys, mMetaDataVals);
26722677

2678+
if (mCollectConfigFiles) {
2679+
collectConfigFiles(mMetaDataKeys, mMetaDataVals);
2680+
}
2681+
26732682
pc.outputs().snapshot(Output{"AMD", "AODMetadataKeys", 0}, mMetaDataKeys);
26742683
pc.outputs().snapshot(Output{"AMD", "AODMetadataVals", 0}, mMetaDataVals);
26752684

@@ -3405,6 +3414,102 @@ std::vector<uint8_t> AODProducerWorkflowDPL::fillBCFlags(const o2::globaltrackin
34053414
return flags;
34063415
}
34073416

3417+
bool AODProducerWorkflowDPL::collectConfigFiles(std::vector<TString>& keys, std::vector<TString>& values, int indent)
3418+
{
3419+
// collect JSON-files of ConfigParams dumped by different upstream processors and add to medata
3420+
static std::string pattern, directory;
3421+
static size_t cachedNumberOfFiles = 0, cachedTotalFileSize = 0;
3422+
static bool first = true, discard = false;
3423+
if (discard) {
3424+
return false;
3425+
}
3426+
std::error_code ec;
3427+
if (first) {
3428+
first = false;
3429+
pattern = o2::base::NameConf::Instance().getConfigOutputFileName("*");
3430+
auto dir = o2::conf::KeyValParam::Instance().getOutputDir();
3431+
if (dir == "/dev/null") {
3432+
LOGP(warn, "ConfigParams output is disabled, abandoning {} files collection for metadata", pattern);
3433+
discard = true;
3434+
return false;
3435+
}
3436+
directory = (dir.empty() || dir == "none") ? "." : dir;
3437+
if (!std::filesystem::is_directory(directory, ec)) {
3438+
LOGP(error, R"(No directory "{}" is found to look for {} configuration files)", directory, pattern);
3439+
discard = true;
3440+
return false;
3441+
}
3442+
}
3443+
static std::unordered_map<std::string, std::string> cachedMap;
3444+
std::vector<std::filesystem::path> files;
3445+
size_t currentTotalFileSize = 0;
3446+
3447+
for (const auto& entry : std::filesystem::directory_iterator(directory)) {
3448+
if (!entry.is_regular_file()) {
3449+
continue;
3450+
}
3451+
const std::string fileName = entry.path().filename().string();
3452+
if (fnmatch(pattern.c_str(), fileName.c_str(), 0) != 0) {
3453+
continue;
3454+
}
3455+
const auto fileSize = entry.file_size(ec);
3456+
if (ec) {
3457+
LOGP(error, "Cannot determine size of file {}, reason: {}", entry.path().string(), ec.message());
3458+
}
3459+
files.push_back(entry.path());
3460+
currentTotalFileSize += static_cast<size_t>(fileSize);
3461+
}
3462+
3463+
if (files.size() != cachedNumberOfFiles || currentTotalFileSize != cachedTotalFileSize) { // need to create a new map
3464+
cachedNumberOfFiles = files.size();
3465+
cachedTotalFileSize = currentTotalFileSize;
3466+
cachedMap.clear();
3467+
}
3468+
3469+
if (!files.empty() && cachedMap.empty()) {
3470+
for (const auto& fname : files) {
3471+
std::ifstream input(fname);
3472+
if (!input) {
3473+
LOGP(error, "Cannot open JSON file {}", fname.string());
3474+
cachedTotalFileSize = 0; // will trigger a new trial next time
3475+
continue;
3476+
}
3477+
nlohmann::json document;
3478+
try {
3479+
input >> document;
3480+
} catch (const nlohmann::json::parse_error& e) {
3481+
LOGP(error, "Cannot parse JSON file {}, reason: {}", fname.string(), e.what());
3482+
cachedTotalFileSize = 0; // will trigger a new trial next time
3483+
continue;
3484+
}
3485+
3486+
if (!document.is_object()) {
3487+
LOGP(error, "Top-level JSON value is not an object in file: {}", fname.string());
3488+
cachedTotalFileSize = 0; // will trigger a new trial next time
3489+
continue;
3490+
}
3491+
3492+
for (auto it = document.begin(); it != document.end(); ++it) {
3493+
const std::string& key = it.key();
3494+
if (cachedMap.find(key) != cachedMap.end()) {
3495+
LOGP(error, "Duplicate top-level key {} in file {}", key, fname.string());
3496+
continue;
3497+
}
3498+
LOGP(info, "Adding json config {} from file {} to AOD metadata", key, fname.string());
3499+
nlohmann::json valueDocument = nlohmann::json::object();
3500+
valueDocument[key] = it.value();
3501+
cachedMap[key] = valueDocument.dump(indent);
3502+
}
3503+
}
3504+
}
3505+
3506+
for (const auto& kv : cachedMap) {
3507+
keys.push_back(kv.first.c_str());
3508+
values.push_back(kv.second.c_str());
3509+
}
3510+
return true;
3511+
}
3512+
34083513
void AODProducerWorkflowDPL::endOfStream(EndOfStreamContext& /*ec*/)
34093514
{
34103515
LOGF(info, "aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
@@ -3565,7 +3670,9 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo
35653670
ConfigParamSpec{"trackqc-tpc-pt", VariantType::Float, 0.2f, {"Keep TPC standalone track with this pt"}},
35663671
ConfigParamSpec{"with-streamers", VariantType::String, "", {"Bit-mask to steer writing of intermediate streamer files"}},
35673672
ConfigParamSpec{"seed", VariantType::Int, 0, {"Set seed for random generator used for sampling (0 (default) means using a random_device)"}},
3568-
ConfigParamSpec{"mc-signal-filt", VariantType::Bool, false, {"Enable usage of signal filtering (only for MC with embedding)"}}}};
3673+
ConfigParamSpec{"mc-signal-filt", VariantType::Bool, false, {"Enable usage of signal filtering (only for MC with embedding)"}},
3674+
ConfigParamSpec{"collect-config-files", VariantType::Bool, false, {"Collect ConfigParams json files written by upsteam processors"}},
3675+
}};
35693676
}
35703677

35713678
} // namespace o2::aodproducer

0 commit comments

Comments
 (0)