diff --git a/DataFormats/Detectors/GlobalTracking/include/DataFormatsGlobalTracking/RecoContainer.h b/DataFormats/Detectors/GlobalTracking/include/DataFormatsGlobalTracking/RecoContainer.h index 5d91c63258e57..037898a3786a3 100644 --- a/DataFormats/Detectors/GlobalTracking/include/DataFormatsGlobalTracking/RecoContainer.h +++ b/DataFormats/Detectors/GlobalTracking/include/DataFormatsGlobalTracking/RecoContainer.h @@ -172,6 +172,9 @@ class Decay3Body; class Decay3BodyIndex; class StrangeTrack; class TrackCosmics; +struct TrackCosmicsExtended; +struct CosmicsTFInfo; +struct TFIDInfo; class GlobalFwdTrack; class MatchInfoFwd; class TrackMCHMID; @@ -253,6 +256,7 @@ struct DataRequest { void requestCPVClusters(bool mc); void requestCoscmicTracks(bool mc); + void requestCosmicExtTracks(bool mc); // MC is not supported, argument is for uniformity void requestPrimaryVertices(bool mc); void requestPrimaryVerticesTMP(bool mc); @@ -324,6 +328,9 @@ struct RecoContainer { // slots for cosmics enum CosmicsSlots { COSM_TRACKS, COSM_TRACKS_MC, + COSMEXT_TRACKS, // extended cosmics (with clusters), no MC + COSMEXT_TFINFO, // per-TF info of the extended cosmics + COSMEXT_TFID, // TFIDInfo of the extended cosmics NCOSMSLOTS }; // slots to register ITS/MFT clusters data (per layer, or all layers together in the slot 0) @@ -371,6 +378,7 @@ struct RecoContainer { std::unique_ptr> mcMIDTracks; o2::ctp::LumiInfo mCTPLumi; + std::shared_ptr cosmExtHolder[3]; // owners of the extended cosmics, TF info and TFID objects deserialized from the messages gsl::span clusterShMapTPC; ///< externally set TPC clusters sharing map gsl::span occupancyMapTPC; ///< externally set TPC clusters occupancy map @@ -429,6 +437,7 @@ struct RecoContainer { void addEMCALCells(o2::framework::ProcessingContext& pc, bool mc); void addCosmicTracks(o2::framework::ProcessingContext& pc, bool mc); + void addCosmicExtTracks(o2::framework::ProcessingContext& pc, bool mc); void addPVertices(o2::framework::ProcessingContext& pc, bool mc); void addPVerticesTMP(o2::framework::ProcessingContext& pc, bool mc); @@ -755,6 +764,12 @@ struct RecoContainer { auto getCosmicTracks() const { return cosmPool.getSpan(COSM_TRACKS); } auto getCosmicTrackMCLabels() const { return cosmPool.getSpan(COSM_TRACKS_MC); } + // Extended cosmic tracks (with clusters); the user must include DataFormatsGlobalTracking/TrackCosmicsExtended.h and CommonDataFormat/TFIDInfo.h + const o2::dataformats::TrackCosmicsExtended& getCosmicExtTrack(int i) const { return cosmPool.get_as(COSMEXT_TRACKS, i); } + auto getCosmicExtTracks() const { return cosmPool.getSpan(COSMEXT_TRACKS); } + const o2::dataformats::CosmicsTFInfo& getCosmicExtTFInfo() const { return cosmPool.get_as(COSMEXT_TFINFO, 0); } + const o2::dataformats::TFIDInfo& getCosmicExtTFID() const { return cosmPool.get_as(COSMEXT_TFID, 0); } + // IRFrames where ITS was reconstructed and tracks were seen (e.g. sync.w-flow mult. selection) auto getIRFramesITS() const { return getSpan(GTrackID::ITS, VARIA); } diff --git a/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx b/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx index f54ef9aa5b0bf..a2ff513247595 100644 --- a/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx +++ b/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx @@ -31,6 +31,8 @@ #include "ReconstructionDataFormats/VtxTrackIndex.h" #include "ReconstructionDataFormats/VtxTrackRef.h" #include "ReconstructionDataFormats/TrackCosmics.h" +#include "DataFormatsGlobalTracking/TrackCosmicsExtended.h" +#include "CommonDataFormat/TFIDInfo.h" #include "ReconstructionDataFormats/TrackMCHMID.h" #include "DataFormatsITSMFT/TrkClusRef.h" #include "DataFormatsITSMFT/TopologyDictionary.h" @@ -429,6 +431,17 @@ void DataRequest::requestCoscmicTracks(bool mc) requestMap["Cosmics"] = mc; } +void DataRequest::requestCosmicExtTracks(bool mc) +{ + addInput({"cosmicsExt", "GLO", "COSMFULL", 0, Lifetime::Timeframe}); + addInput({"cosmicsExtTF", "GLO", "COSMFULLTF", 0, Lifetime::Timeframe}); + addInput({"cosmicsExtTFID", "GLO", "COSMFULLTFID", 0, Lifetime::Timeframe}); + if (mc) { + LOG(error) << "Extended cosmics do not support MC truth"; + } + requestMap["CosmicsExt"] = false; +} + void DataRequest::requestPrimaryVertices(bool mc) { addInput({"pvtx", "GLO", "PVTX", 0, Lifetime::Timeframe}); @@ -825,6 +838,11 @@ void RecoContainer::collectData(ProcessingContext& pc, const DataRequest& reques addCosmicTracks(pc, req->second); } + req = reqMap.find("CosmicsExt"); + if (req != reqMap.end()) { + addCosmicExtTracks(pc, req->second); + } + req = reqMap.find("PVertex"); if (req != reqMap.end()) { addPVertices(pc, req->second); @@ -903,6 +921,27 @@ void RecoContainer::addPVerticesTMP(ProcessingContext& pc, bool mc) } } +//____________________________________________________________ +void RecoContainer::addCosmicExtTracks(ProcessingContext& pc, bool mc) +{ + using o2::dataformats::CosmicsTFInfo; + using o2::dataformats::TFIDInfo; + using o2::dataformats::TrackCosmicsExtended; + // the messages are ROOT-serialized, keep the deserialized objects alive until the next TF + std::shared_ptr> cosm = pc.inputs().get*>("cosmicsExt"); + std::shared_ptr tfInfo = pc.inputs().get("cosmicsExtTF"); + std::shared_ptr tfID = pc.inputs().get("cosmicsExtTFID"); + cosmPool.registerContainer(*cosm, COSMEXT_TRACKS); + cosmPool.registerContainer(gsl::span(tfInfo.get(), 1), COSMEXT_TFINFO); + cosmPool.registerContainer(gsl::span(tfID.get(), 1), COSMEXT_TFID); + cosmExtHolder[0] = std::move(cosm); + cosmExtHolder[1] = std::move(tfInfo); + cosmExtHolder[2] = std::move(tfID); + if (mc) { + LOG(error) << "Extended cosmics do not support MC truth"; + } +} + //____________________________________________________________ void RecoContainer::addCosmicTracks(ProcessingContext& pc, bool mc) { diff --git a/Detectors/GlobalTrackingWorkflow/CMakeLists.txt b/Detectors/GlobalTrackingWorkflow/CMakeLists.txt index 69f5ff9379944..442b8d21d6aa7 100644 --- a/Detectors/GlobalTrackingWorkflow/CMakeLists.txt +++ b/Detectors/GlobalTrackingWorkflow/CMakeLists.txt @@ -67,6 +67,11 @@ o2_add_executable(match-workflow SOURCES src/cosmics-match-workflow.cxx PUBLIC_LINK_LIBRARIES O2::GlobalTrackingWorkflow O2::TOFWorkflowIO) +o2_add_executable(reader-workflow + COMPONENT_NAME cosmic-ext + SOURCES src/cosmic-ext-reader-workflow.cxx + PUBLIC_LINK_LIBRARIES O2::GlobalTrackingWorkflow) + o2_add_executable(vertexing-workflow COMPONENT_NAME primary SOURCES src/primary-vertexing-workflow.cxx diff --git a/Detectors/GlobalTrackingWorkflow/helpers/include/GlobalTrackingWorkflowHelpers/InputHelper.h b/Detectors/GlobalTrackingWorkflow/helpers/include/GlobalTrackingWorkflowHelpers/InputHelper.h index 39323ba95012e..6c4df09384268 100644 --- a/Detectors/GlobalTrackingWorkflow/helpers/include/GlobalTrackingWorkflowHelpers/InputHelper.h +++ b/Detectors/GlobalTrackingWorkflow/helpers/include/GlobalTrackingWorkflowHelpers/InputHelper.h @@ -40,6 +40,7 @@ class InputHelper static int addInputSpecsSVertex(const o2::framework::ConfigContext& configcontext, o2::framework::WorkflowSpec& specs); static int addInputSpecsStrangeTrack(const o2::framework::ConfigContext& configcontext, o2::framework::WorkflowSpec& specs, bool mc); static int addInputSpecsCosmics(const o2::framework::ConfigContext& configcontext, o2::framework::WorkflowSpec& specs, bool mc); + static int addInputSpecsCosmicsExtended(const o2::framework::ConfigContext& configcontext, o2::framework::WorkflowSpec& specs); static int addInputSpecsIRFramesITS(const o2::framework::ConfigContext& configcontext, o2::framework::WorkflowSpec& specs); }; diff --git a/Detectors/GlobalTrackingWorkflow/helpers/src/GlobalTrackClusterReader.cxx b/Detectors/GlobalTrackingWorkflow/helpers/src/GlobalTrackClusterReader.cxx index a004432643763..7dffb852b740a 100644 --- a/Detectors/GlobalTrackingWorkflow/helpers/src/GlobalTrackClusterReader.cxx +++ b/Detectors/GlobalTrackingWorkflow/helpers/src/GlobalTrackClusterReader.cxx @@ -35,6 +35,7 @@ void customize(std::vector& workflowOptions) {"primary-vertices", VariantType::Bool, false, {"read primary vertices"}}, {"secondary-vertices", VariantType::Bool, false, {"read secondary vertices"}}, {"cosmic", VariantType::Bool, false, {"read cosmic tracks"}}, + {"cosmic-ext", VariantType::Bool, false, {"read extended cosmic tracks with clusters"}}, {"ir-frames-its", VariantType::Bool, false, {"read ITS IR frames"}}, {"disable-root-input", o2::framework::VariantType::Bool, false, {"disable reading root files, essentially making this workflow void, but needed for compatibility"}}, {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}}; @@ -56,9 +57,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) bool pv = cfgc.options().get("primary-vertices"); bool sv = cfgc.options().get("secondary-vertices"); bool cosm = cfgc.options().get("cosmic"); + bool cosmExt = cfgc.options().get("cosmic-ext"); bool irits = cfgc.options().get("ir-frames-its"); - if (!cfgc.helpOnCommandLine() && srcTrk.none() && srcCl.none() && !(pv || sv || cosm || irits)) { + if (!cfgc.helpOnCommandLine() && srcTrk.none() && srcCl.none() && !(pv || sv || cosm || cosmExt || irits)) { throw std::runtime_error("nothing requested to read"); } auto srcMtc = srcTrk & ~GlobalTrackID::getSourceMask(GlobalTrackID::MFTMCH); // Do not request MFTMCH matches @@ -72,6 +74,9 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) if (cosm) { InputHelper::addInputSpecsCosmics(cfgc, specs, useMC); } + if (cosmExt) { + InputHelper::addInputSpecsCosmicsExtended(cfgc, specs); + } if (irits) { InputHelper::addInputSpecsIRFramesITS(cfgc, specs); } diff --git a/Detectors/GlobalTrackingWorkflow/helpers/src/InputHelper.cxx b/Detectors/GlobalTrackingWorkflow/helpers/src/InputHelper.cxx index e4c1e40b3a4d3..44b70500f37fa 100644 --- a/Detectors/GlobalTrackingWorkflow/helpers/src/InputHelper.cxx +++ b/Detectors/GlobalTrackingWorkflow/helpers/src/InputHelper.cxx @@ -31,6 +31,7 @@ #include "GlobalTrackingWorkflowReaders/SecondaryVertexReaderSpec.h" #include "GlobalTrackingWorkflowReaders/StrangenessTrackingReaderSpec.h" #include "GlobalTrackingWorkflowReaders/TrackCosmicsReaderSpec.h" +#include "GlobalTrackingWorkflowReaders/TrackCosmicsExtendedReaderSpec.h" #include "GlobalTrackingWorkflowReaders/IRFrameReaderSpec.h" #include "TOFWorkflowIO/ClusterReaderSpec.h" #include "TOFWorkflowIO/TOFMatchedReaderSpec.h" @@ -225,6 +226,16 @@ int InputHelper::addInputSpecsCosmics(const o2::framework::ConfigContext& config return 0; } +// attach extended cosmic tracks reader +int InputHelper::addInputSpecsCosmicsExtended(const o2::framework::ConfigContext& configcontext, o2::framework::WorkflowSpec& specs) +{ + if (configcontext.options().get("disable-root-input")) { + return 0; + } + specs.emplace_back(o2::globaltracking::getTrackCosmicsExtendedReaderSpec()); + return 0; +} + // attach vector of ITS reconstructed IRFrames int InputHelper::addInputSpecsIRFramesITS(const o2::framework::ConfigContext& configcontext, o2::framework::WorkflowSpec& specs) { diff --git a/Detectors/GlobalTrackingWorkflow/readers/CMakeLists.txt b/Detectors/GlobalTrackingWorkflow/readers/CMakeLists.txt index 2db7019f67756..0689bfd146d73 100644 --- a/Detectors/GlobalTrackingWorkflow/readers/CMakeLists.txt +++ b/Detectors/GlobalTrackingWorkflow/readers/CMakeLists.txt @@ -11,6 +11,7 @@ o2_add_library(GlobalTrackingWorkflowReaders SOURCES src/TrackCosmicsReaderSpec.cxx + src/TrackCosmicsExtendedReaderSpec.cxx src/SecondaryVertexReaderSpec.cxx src/PrimaryVertexReaderSpec.cxx src/StrangenessTrackingReaderSpec.cxx @@ -20,6 +21,7 @@ o2_add_library(GlobalTrackingWorkflowReaders src/MatchedMCHMIDReaderSpec.cxx src/IRFrameReaderSpec.cxx PUBLIC_LINK_LIBRARIES O2::ReconstructionDataFormats + O2::DataFormatsGlobalTracking O2::DataFormatsITSMFT O2::SimulationDataFormat) diff --git a/Detectors/GlobalTrackingWorkflow/readers/include/GlobalTrackingWorkflowReaders/TrackCosmicsExtendedReaderSpec.h b/Detectors/GlobalTrackingWorkflow/readers/include/GlobalTrackingWorkflowReaders/TrackCosmicsExtendedReaderSpec.h new file mode 100644 index 0000000000000..8c904e48651f6 --- /dev/null +++ b/Detectors/GlobalTrackingWorkflow/readers/include/GlobalTrackingWorkflowReaders/TrackCosmicsExtendedReaderSpec.h @@ -0,0 +1,56 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file TrackCosmicsExtendedReaderSpec.h + +#ifndef O2_GLOBAL_TRACKCOSMICSEXTENDED_READER +#define O2_GLOBAL_TRACKCOSMICSEXTENDED_READER + +#include "TFile.h" +#include "TTree.h" + +#include "Framework/DataProcessorSpec.h" +#include "Framework/Task.h" +#include "DataFormatsGlobalTracking/TrackCosmicsExtended.h" +#include "CommonDataFormat/TFIDInfo.h" + +using namespace o2::framework; + +namespace o2 +{ +namespace globaltracking +{ + +class TrackCosmicsExtendedReader : public Task +{ + public: + TrackCosmicsExtendedReader() = default; + ~TrackCosmicsExtendedReader() override = default; + void init(InitContext& ic) final; + void run(ProcessingContext& pc) final; + + private: + void connectTree(const std::string& filename); + std::unique_ptr mFile; + std::unique_ptr mTree; + std::string mFileName = ""; + std::vector mCosmics, *mCosmicsPtr = &mCosmics; + o2::dataformats::CosmicsTFInfo mTFInfo, *mTFInfoPtr = &mTFInfo; + o2::dataformats::TFIDInfo mTFID, *mTFIDPtr = &mTFID; +}; + +/// create a processor spec to read the extended cosmics (as written by cosmics-full-writer) from a root file +framework::DataProcessorSpec getTrackCosmicsExtendedReaderSpec(); + +} // namespace globaltracking +} // namespace o2 + +#endif /* O2_GLOBAL_TRACKCOSMICSEXTENDED_READER */ diff --git a/Detectors/GlobalTrackingWorkflow/readers/src/TrackCosmicsExtendedReaderSpec.cxx b/Detectors/GlobalTrackingWorkflow/readers/src/TrackCosmicsExtendedReaderSpec.cxx new file mode 100644 index 0000000000000..d6c47753b41c4 --- /dev/null +++ b/Detectors/GlobalTrackingWorkflow/readers/src/TrackCosmicsExtendedReaderSpec.cxx @@ -0,0 +1,96 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// @file TrackCosmicsExtendedReaderSpec.cxx + +#include + +#include "Framework/ConfigParamRegistry.h" +#include "Framework/ControlService.h" +#include "GlobalTrackingWorkflowReaders/TrackCosmicsExtendedReaderSpec.h" +#include "CommonUtils/NameConf.h" +#include "CommonUtils/StringUtils.h" + +using namespace o2::framework; +using namespace o2::globaltracking; + +namespace o2 +{ +namespace globaltracking +{ +void TrackCosmicsExtendedReader::init(InitContext& ic) +{ + mFileName = o2::utils::Str::concat_string(o2::utils::Str::rectifyDirectory(ic.options().get("input-dir")), + ic.options().get("cosmics-full-infile")); + connectTree(mFileName); +} + +void TrackCosmicsExtendedReader::run(ProcessingContext& pc) +{ + auto ent = mTree->GetReadEntry() + 1; + // Same as in TrackCosmicsReader: publish empty containers if the tree has no entry left + const bool noEntry = ent >= mTree->GetEntries(); + if (noEntry) { + LOG(info) << "no entry to read, publishing empty output"; + mCosmics.clear(); + mTFInfo = {}; + mTFID = {}; + } else { + mTree->GetEntry(ent); + } + LOG(info) << "Pushing " << mCosmics.size() << " cosmics with clusters at entry " << ent; + + pc.outputs().snapshot(Output{"GLO", "COSMFULL", 0}, mCosmics); + pc.outputs().snapshot(Output{"GLO", "COSMFULLTF", 0}, mTFInfo); + pc.outputs().snapshot(Output{"GLO", "COSMFULLTFID", 0}, mTFID); + + if (noEntry || mTree->GetReadEntry() + 1 >= mTree->GetEntries()) { + pc.services().get().endOfStream(); + pc.services().get().readyToQuit(QuitRequest::Me); + } +} + +void TrackCosmicsExtendedReader::connectTree(const std::string& filename) +{ + mTree.reset(nullptr); // in case it was already loaded + mFile.reset(TFile::Open(filename.c_str())); + if (!mFile || mFile->IsZombie()) { + LOGP(fatal, "Failed to open {}", filename); + } + mTree.reset((TTree*)mFile->Get("cosmicsFull")); + if (!mTree) { + LOGP(fatal, "Tree cosmicsFull is not found in {}", filename); + } + mTree->SetBranchAddress("cosmics", &mCosmicsPtr); + mTree->SetBranchAddress("tfInfo", &mTFInfoPtr); + mTree->SetBranchAddress("tfID", &mTFIDPtr); + LOG(info) << "Loaded tree from " << filename << " with " << mTree->GetEntries() << " entries"; +} + +DataProcessorSpec getTrackCosmicsExtendedReaderSpec() +{ + std::vector outputs; + outputs.emplace_back("GLO", "COSMFULL", 0, Lifetime::Timeframe); + outputs.emplace_back("GLO", "COSMFULLTF", 0, Lifetime::Timeframe); + outputs.emplace_back("GLO", "COSMFULLTFID", 0, Lifetime::Timeframe); + + return DataProcessorSpec{ + "cosmic-ext-reader", + Inputs{}, + outputs, + AlgorithmSpec{adaptFromTask()}, + Options{ + {"cosmics-full-infile", VariantType::String, "o2_cosmics_full.root", {"Name of the input file"}}, + {"input-dir", VariantType::String, "none", {"Input directory"}}}}; +} + +} // namespace globaltracking +} // namespace o2 diff --git a/Detectors/GlobalTrackingWorkflow/src/cosmic-ext-reader-workflow.cxx b/Detectors/GlobalTrackingWorkflow/src/cosmic-ext-reader-workflow.cxx new file mode 100644 index 0000000000000..6487802faeaf0 --- /dev/null +++ b/Detectors/GlobalTrackingWorkflow/src/cosmic-ext-reader-workflow.cxx @@ -0,0 +1,45 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Framework/ConfigParamSpec.h" +#include "Framework/CallbacksPolicy.h" +#include "CommonUtils/ConfigurableParam.h" +#include "DetectorsRaw/HBFUtilsInitializer.h" + +using namespace o2::framework; + +void customize(std::vector& policies) +{ + o2::raw::HBFUtilsInitializer::addNewTimeSliceCallback(policies); +} + +void customize(std::vector& workflowOptions) +{ + std::vector options{ + {"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}}; + o2::raw::HBFUtilsInitializer::addConfigOption(options); + std::swap(workflowOptions, options); +} + +#include "Framework/runDataProcessing.h" +#include "GlobalTrackingWorkflowReaders/TrackCosmicsExtendedReaderSpec.h" + +WorkflowSpec defineDataProcessing(ConfigContext const& cc) +{ + WorkflowSpec specs; + o2::conf::ConfigurableParam::updateFromString(cc.options().get("configKeyValues")); + specs.emplace_back(o2::globaltracking::getTrackCosmicsExtendedReaderSpec()); + + // configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit + o2::raw::HBFUtilsInitializer hbfIni(cc, specs); + + return std::move(specs); +}