From 158de6848d3a8bfc4af3d2e91f5d8297b03571e0 Mon Sep 17 00:00:00 2001 From: nburmaso Date: Wed, 3 Nov 2021 00:18:54 +0100 Subject: [PATCH 1/3] Add metadata to AOD --- Detectors/AOD/CMakeLists.txt | 53 +++++++++++-------- .../AODProducerWorkflowSpec.h | 10 +++- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 48 +++++++++++------ Detectors/AOD/src/aod-producer-workflow.cxx | 3 +- 4 files changed, 73 insertions(+), 41 deletions(-) diff --git a/Detectors/AOD/CMakeLists.txt b/Detectors/AOD/CMakeLists.txt index 7174760a64e6b..b145a71ffb19a 100644 --- a/Detectors/AOD/CMakeLists.txt +++ b/Detectors/AOD/CMakeLists.txt @@ -9,33 +9,40 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -o2_add_library( +add_library(AODProducerWorkflow INTERFACE) + +target_link_libraries( AODProducerWorkflow - SOURCES src/AODProducerWorkflowSpec.cxx - PUBLIC_LINK_LIBRARIES - O2::DetectorsVertexing - O2::FT0Workflow - O2::FDDWorkflow - O2::FV0Workflow - O2::Framework - O2::GlobalTracking - O2::GlobalTrackingWorkflow - O2::ITSMFTWorkflow - O2::ITSWorkflow - O2::ITStracking - O2::MCHTracking - O2::MFTWorkflow - O2::MathUtils - O2::SimulationDataFormat - O2::Steer - O2::TPCWorkflow + INTERFACE + O2::DetectorsVertexing + O2::FT0Workflow + O2::FDDWorkflow + O2::FV0Workflow + O2::Framework + O2::GlobalTracking + O2::GlobalTrackingWorkflow + O2::ITSMFTWorkflow + O2::ITSWorkflow + O2::ITStracking + O2::MCHTracking + O2::MFTWorkflow + O2::MathUtils + O2::SimulationDataFormat + O2::Steer + O2::TPCWorkflow ) + +target_include_directories(AODProducerWorkflow INTERFACE include) + +add_library(internal::AODProducerWorkflow ALIAS AODProducerWorkflow) + o2_add_executable( - workflow - COMPONENT_NAME aod-producer - SOURCES src/aod-producer-workflow.cxx - PUBLIC_LINK_LIBRARIES O2::AODProducerWorkflow + workflow + COMPONENT_NAME aod-producer + SOURCES src/aod-producer-workflow.cxx src/AODProducerWorkflowSpec.cxx + PUBLIC_LINK_LIBRARIES internal::AODProducerWorkflow O2::Version ) + o2_add_executable( standalone-aod-producer COMPONENT_NAME reco diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h index dfc295f6ae2d9..135de1911564c 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h @@ -34,6 +34,7 @@ #include "ReconstructionDataFormats/VtxTrackIndex.h" #include "SimulationDataFormat/MCCompLabel.h" #include "Steer/MCKinematicsReader.h" +#include "TMap.h" #include "TStopwatch.h" #include @@ -191,7 +192,7 @@ typedef boost::unordered_map Triple class AODProducerWorkflowDPL : public Task { public: - AODProducerWorkflowDPL(GID::mask_t src, std::shared_ptr dataRequest) : mInputSources(src), mDataRequest(dataRequest) {} + AODProducerWorkflowDPL(GID::mask_t src, std::shared_ptr dataRequest, std::string resFile) : mInputSources(src), mDataRequest(dataRequest), mResFile(resFile) {} ~AODProducerWorkflowDPL() override = default; void init(InitContext& ic) final; void run(ProcessingContext& pc) final; @@ -204,6 +205,8 @@ class AODProducerWorkflowDPL : public Task int64_t mTFNumber{-1}; int mTruncate{1}; int mRecoOnly{0}; + TString mResFile{"AO2D"}; + TString mProdTag{"LHC21Axx"}; TStopwatch mTimer; // unordered map connects global indices and table indices of barrel tracks @@ -213,6 +216,9 @@ class AODProducerWorkflowDPL : public Task TripletsMap_t mToStore; + // MC production metadata holder + TMap mMetaData; + std::shared_ptr mDataRequest; // truncation is enabled by default @@ -352,7 +358,7 @@ class AODProducerWorkflowDPL : public Task }; /// create a processor spec -framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool useMC); +framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool useMC, std::string resFile); } // namespace o2::aodproducer diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 59d756d3e9c86..ad35053ba0ee6 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -52,10 +52,13 @@ #include "SimulationDataFormat/MCEventLabel.h" #include "SimulationDataFormat/MCTrack.h" #include "SimulationDataFormat/MCTruthContainer.h" +#include "O2Version.h" #include "TMath.h" #include "MathUtils/Utils.h" #include "Math/SMatrix.h" -#include +#include "TMatrixD.h" +#include "TString.h" +#include "TObjString.h" #include #include #include @@ -299,11 +302,6 @@ void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID, } else { auto contributorsGID = data.getSingleDetectorRefs(trackIndex); const auto& trackPar = data.getTrackParam(trackIndex); - if (contributorsGID[GIndex::Source::ITS].isIndexSet() || contributorsGID[GIndex::Source::ITSAB].isIndexSet()) { - int nClusters = itsTracks[contributorsGID[GIndex::ITS].getIndex()].getNClusters(); - float chi2 = itsTracks[contributorsGID[GIndex::ITS].getIndex()].getChi2(); - extraInfoHolder.itsChi2NCl = nClusters != 0 ? chi2 / (float)nClusters : 0; - } if (contributorsGID[GIndex::Source::ITS].isIndexSet()) { extraInfoHolder.itsClusterMap = itsTracks[contributorsGID[GIndex::ITS].getIndex()].getPattern(); } else if (contributorsGID[GIndex::Source::ITSAB].isIndexSet()) { // this is an ITS-TPC afterburner contributor @@ -658,14 +656,8 @@ void AODProducerWorkflowDPL::fillMCParticlesTable(o2::steer::MCKinematicsReader& } int statusCode = 0; uint8_t flags = 0; - if (!mcParticles[particle].isPrimary()) { - flags |= o2::aod::mcparticle::enums::ProducedByTransport; // mark as produced by transport - statusCode = mcParticles[particle].getProcess(); - } else { - statusCode = mcParticles[particle].getStatusCode(); - } if (source == 0) { - flags |= o2::aod::mcparticle::enums::FromBackgroundEvent; // mark as particle from background event + flags |= 1 << 1; // mark as particle from background event } float weight = 0.f; int mcMother0 = mcParticles[particle].getMotherTrackId(); @@ -857,6 +849,7 @@ uint8_t AODProducerWorkflowDPL::getTRDPattern(const o2::trd::TrackTRD& track) void AODProducerWorkflowDPL::init(InitContext& ic) { mTimer.Stop(); + mProdTag = ic.options().get("prod-tags"); mTFNumber = ic.options().get("aod-timeframe-id"); mRecoOnly = ic.options().get("reco-mctracks-only"); mTruncate = ic.options().get("enable-truncation"); @@ -903,6 +896,30 @@ void AODProducerWorkflowDPL::init(InitContext& ic) // Needed by MCH track extrapolation o2::base::GeometryManager::loadGeometry(); + // writing metadata if it's not yet in AOD file + // note: `--aod-writer-resmode "UPDATE"` have to be used, + // so that metadata is not overwritten + mResFile += ".root"; + auto* fResFile = TFile::Open(mResFile, "UPDATE"); + if (fResFile) { + if (!fResFile->FindObjectAny("metaData")) { + LOGF(info, "Metadata: writing into %s", mResFile); + // populating metadata map + mMetaData.Add(new TObjString("DataType"), new TObjString("MC")); + mMetaData.Add(new TObjString("Run"), new TObjString("3")); + TString converterVersion = "o2 "; + converterVersion += o2::fullVersion(); + converterVersion += " ; root "; + converterVersion += ROOT_RELEASE; + mMetaData.Add(new TObjString("Run3ConverterVersion"), new TObjString(converterVersion)); + mMetaData.Add(new TObjString("LPMProductionTag"), new TObjString(mProdTag)); + fResFile->WriteObject(&mMetaData, "metaData"); + } else { + LOGF(info, "Metadata: target file not found or metadata is already written"); + } + fResFile->Close(); + } + mTimer.Reset(); } @@ -1324,7 +1341,7 @@ void AODProducerWorkflowDPL::endOfStream(EndOfStreamContext& ec) mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); } -DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool useMC) +DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool useMC, std::string resFile) { std::vector outputs; auto dataRequest = std::make_shared(); @@ -1363,10 +1380,11 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool useMC) "aod-producer-workflow", dataRequest->inputs, outputs, - AlgorithmSpec{adaptFromTask(src, dataRequest)}, + AlgorithmSpec{adaptFromTask(src, dataRequest, resFile)}, Options{ ConfigParamSpec{"aod-timeframe-id", VariantType::Int64, -1L, {"Set timeframe number"}}, ConfigParamSpec{"enable-truncation", VariantType::Int, 1, {"Truncation parameter: 1 -- on, != 1 -- off"}}, + ConfigParamSpec{"prod-tags", VariantType::String, "LHC21Axx", {"Production tags"}}, ConfigParamSpec{"reco-mctracks-only", VariantType::Int, 0, {"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}}}}; } diff --git a/Detectors/AOD/src/aod-producer-workflow.cxx b/Detectors/AOD/src/aod-producer-workflow.cxx index 16c6ac8641ccd..5870875a56efd 100644 --- a/Detectors/AOD/src/aod-producer-workflow.cxx +++ b/Detectors/AOD/src/aod-producer-workflow.cxx @@ -42,12 +42,13 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) { o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); auto useMC = !configcontext.options().get("disable-mc"); + auto resFile = configcontext.options().get("aod-writer-resfile"); GID::mask_t allowedSrc = GID::getSourcesMask("ITS,MFT,MCH,TPC,ITS-TPC,ITS-TPC-TOF,TPC-TOF,MFT-MCH,FT0,FV0,FDD,TPC-TRD,ITS-TPC-TRD,FT0,FV0,FDD,ZDC"); GID::mask_t src = allowedSrc & GID::getSourcesMask(configcontext.options().get("info-sources")); WorkflowSpec specs; - specs.emplace_back(o2::aodproducer::getAODProducerWorkflowSpec(src, useMC)); + specs.emplace_back(o2::aodproducer::getAODProducerWorkflowSpec(src, useMC, resFile)); o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, src, src, src, useMC, src); o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, useMC); From 4f4663cc8409cdf3dff255d7af1f5606ad05a1cd Mon Sep 17 00:00:00 2001 From: nburmaso Date: Wed, 3 Nov 2021 09:05:09 +0100 Subject: [PATCH 2/3] Add metadata to AOD: parse production tags --- .../AODProducerWorkflowSpec.h | 2 +- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 24 +++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h index 135de1911564c..297fe21a45699 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h @@ -206,7 +206,7 @@ class AODProducerWorkflowDPL : public Task int mTruncate{1}; int mRecoOnly{0}; TString mResFile{"AO2D"}; - TString mProdTag{"LHC21Axx"}; + std::string mProdTags{"LHC21Axx,pass1,LHC15o,pass1"}; TStopwatch mTimer; // unordered map connects global indices and table indices of barrel tracks diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index ad35053ba0ee6..4556a0aa73560 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -849,7 +849,7 @@ uint8_t AODProducerWorkflowDPL::getTRDPattern(const o2::trd::TrackTRD& track) void AODProducerWorkflowDPL::init(InitContext& ic) { mTimer.Stop(); - mProdTag = ic.options().get("prod-tags"); + mProdTags = ic.options().get("prod-tags"); mTFNumber = ic.options().get("aod-timeframe-id"); mRecoOnly = ic.options().get("reco-mctracks-only"); mTruncate = ic.options().get("enable-truncation"); @@ -903,7 +903,19 @@ void AODProducerWorkflowDPL::init(InitContext& ic) auto* fResFile = TFile::Open(mResFile, "UPDATE"); if (fResFile) { if (!fResFile->FindObjectAny("metaData")) { - LOGF(info, "Metadata: writing into %s", mResFile); + std::vector vTags; + std::stringstream ss(mProdTags); + for (std::string tag; ss >> tag;) { + vTags.emplace_back(tag); + if (ss.peek() == ',') { + ss.ignore(); + } + } + // assuming all tags passed as in `prod-tags` description + TString LPMProdTag = vTags[0]; + TString anchorPass = vTags[1]; + TString anchorProd = vTags[2]; + TString recoPass = vTags[3]; // populating metadata map mMetaData.Add(new TObjString("DataType"), new TObjString("MC")); mMetaData.Add(new TObjString("Run"), new TObjString("3")); @@ -912,7 +924,11 @@ void AODProducerWorkflowDPL::init(InitContext& ic) converterVersion += " ; root "; converterVersion += ROOT_RELEASE; mMetaData.Add(new TObjString("Run3ConverterVersion"), new TObjString(converterVersion)); - mMetaData.Add(new TObjString("LPMProductionTag"), new TObjString(mProdTag)); + mMetaData.Add(new TObjString("RecoPassName"), new TObjString(recoPass)); + mMetaData.Add(new TObjString("AnchorProduction"), new TObjString(anchorProd)); + mMetaData.Add(new TObjString("AnchorPassName"), new TObjString(anchorPass)); + mMetaData.Add(new TObjString("LPMProductionTag"), new TObjString(LPMProdTag)); + LOGF(info, "Metadata: writing into %s", mResFile); fResFile->WriteObject(&mMetaData, "metaData"); } else { LOGF(info, "Metadata: target file not found or metadata is already written"); @@ -1384,7 +1400,7 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool useMC, std::s Options{ ConfigParamSpec{"aod-timeframe-id", VariantType::Int64, -1L, {"Set timeframe number"}}, ConfigParamSpec{"enable-truncation", VariantType::Int, 1, {"Truncation parameter: 1 -- on, != 1 -- off"}}, - ConfigParamSpec{"prod-tags", VariantType::String, "LHC21Axx", {"Production tags"}}, + ConfigParamSpec{"prod-tags", VariantType::String, "LHC21Axx,pass1,LHC15o,pass1", {"Comma separated list of production tags: `LPMProductionTag,AnchorPassName,AnchorProduction,RecoPassName`"}}, ConfigParamSpec{"reco-mctracks-only", VariantType::Int, 0, {"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}}}}; } From 220aa68a5d3e3ce8cb644228f758e00a9b823eae Mon Sep 17 00:00:00 2001 From: nburmaso Date: Wed, 3 Nov 2021 09:36:02 +0100 Subject: [PATCH 3/3] Add metadata to AOD: fix parsing --- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 4556a0aa73560..098e9dd5d064a 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -905,11 +905,10 @@ void AODProducerWorkflowDPL::init(InitContext& ic) if (!fResFile->FindObjectAny("metaData")) { std::vector vTags; std::stringstream ss(mProdTags); - for (std::string tag; ss >> tag;) { - vTags.emplace_back(tag); - if (ss.peek() == ',') { - ss.ignore(); - } + while (ss.good()) { + std::string substr; + std::getline(ss, substr, ','); + vTags.emplace_back(substr); } // assuming all tags passed as in `prod-tags` description TString LPMProdTag = vTags[0];