diff --git a/Detectors/AOD/CMakeLists.txt b/Detectors/AOD/CMakeLists.txt index 7174760a64e6b..1cdb3aaf4c630 100644 --- a/Detectors/AOD/CMakeLists.txt +++ b/Detectors/AOD/CMakeLists.txt @@ -9,10 +9,11 @@ # 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 + INTERFACE O2::DetectorsVertexing O2::FT0Workflow O2::FDDWorkflow @@ -30,12 +31,18 @@ o2_add_library( 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 + 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 829f361e37bbc..919be44256834 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, bool useMC = true) : mInputSources(src), mDataRequest(dataRequest), mUseMC(useMC) {} + AODProducerWorkflowDPL(GID::mask_t src, std::shared_ptr dataRequest, std::string resFile, bool useMC = true) : mInputSources(src), mDataRequest(dataRequest), mResFile{resFile}, mUseMC(useMC) {} ~AODProducerWorkflowDPL() override = default; void init(InitContext& ic) final; void run(ProcessingContext& pc) final; @@ -206,6 +207,11 @@ class AODProducerWorkflowDPL : public Task int64_t mTFNumber{-1}; int mTruncate{1}; int mRecoOnly{0}; + TString mResFile{"AO2D"}; + TString mLPMProdTag{""}; + TString mAnchorPass{""}; + TString mAnchorProd{""}; + TString mRecoPass{""}; TStopwatch mTimer; // unordered map connects global indices and table indices of barrel tracks @@ -215,6 +221,9 @@ class AODProducerWorkflowDPL : public Task TripletsMap_t mToStore; + // MC production metadata holder + TMap mMetaData; + std::shared_ptr mDataRequest; // truncation is enabled by default @@ -354,7 +363,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 643393b26aed2..63b2cae8019d3 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 @@ -855,6 +858,10 @@ uint8_t AODProducerWorkflowDPL::getTRDPattern(const o2::trd::TrackTRD& track) void AODProducerWorkflowDPL::init(InitContext& ic) { mTimer.Stop(); + mLPMProdTag = ic.options().get("lpmp-prod-tag"); + mAnchorPass = ic.options().get("anchor-pass"); + mAnchorProd = ic.options().get("anchor-prod"); + mRecoPass = ic.options().get("reco-pass"); mTFNumber = ic.options().get("aod-timeframe-id"); mRecoOnly = ic.options().get("reco-mctracks-only"); mTruncate = ic.options().get("enable-truncation"); @@ -901,6 +908,34 @@ 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"` has to be used, + // so that metadata is not overwritten + mResFile += ".root"; + auto* fResFile = TFile::Open(mResFile, "UPDATE"); + if (!fResFile) { + LOGF(fatal, "Could not open file %s", mResFile); + } + if (!fResFile->FindObjectAny("metaData")) { + // populating metadata map + TString dataType = mUseMC ? "MC" : "RAW"; + mMetaData.Add(new TObjString("DataType"), new TObjString(dataType)); + mMetaData.Add(new TObjString("Run"), new TObjString("3")); + TString O2Version = o2::fullVersion(); + TString ROOTVersion = ROOT_RELEASE; + mMetaData.Add(new TObjString("O2Version"), new TObjString(O2Version)); + mMetaData.Add(new TObjString("ROOTVersion"), new TObjString(ROOTVersion)); + mMetaData.Add(new TObjString("RecoPassName"), new TObjString(mRecoPass)); + mMetaData.Add(new TObjString("AnchorProduction"), new TObjString(mAnchorProd)); + mMetaData.Add(new TObjString("AnchorPassName"), new TObjString(mAnchorPass)); + mMetaData.Add(new TObjString("LPMProductionTag"), new TObjString(mLPMProdTag)); + LOGF(info, "Metadata: writing into %s", mResFile); + fResFile->WriteObject(&mMetaData, "metaData"); + } else { + LOGF(fatal, "Metadata: target file %s already has metadata", mResFile); + } + fResFile->Close(); + mTimer.Reset(); } @@ -991,7 +1026,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) int runNumber = int(dh->runNumber); if (mTFNumber == -1L) { // TODO has to be made globally unique (by using absolute time of TF). For now is unique within the run - tfNumber = dh->tfCounter; //getTFNumber(startIR, runNumber); + tfNumber = dh->tfCounter; // getTFNumber(startIR, runNumber); } else { tfNumber = mTFNumber; } @@ -1327,7 +1362,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(); @@ -1366,10 +1401,14 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool useMC) "aod-producer-workflow", dataRequest->inputs, outputs, - AlgorithmSpec{adaptFromTask(src, dataRequest, useMC)}, + AlgorithmSpec{adaptFromTask(src, dataRequest, resFile, useMC)}, Options{ ConfigParamSpec{"aod-timeframe-id", VariantType::Int64, -1L, {"Set timeframe number"}}, ConfigParamSpec{"enable-truncation", VariantType::Int, 1, {"Truncation parameter: 1 -- on, != 1 -- off"}}, + ConfigParamSpec{"lpmp-prod-tag", VariantType::String, "", {"LPMProductionTag"}}, + ConfigParamSpec{"anchor-pass", VariantType::String, "", {"AnchorPassName"}}, + ConfigParamSpec{"anchor-prod", VariantType::String, "", {"AnchorProduction"}}, + ConfigParamSpec{"reco-pass", VariantType::String, "", {"RecoPassName"}}, 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);