Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Common/Utils/include/CommonUtils/IRFrameSelector.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class IRFrameSelector
}

void clear();
size_t loadIRFrames(const std::string& fname);
size_t loadIRFrames(const std::string& fname, size_t margin = 0);
void applyMargins(size_t bwd, size_t fwd, long shift, bool removeOverlaps = true);
void print(bool lst = false) const;

Expand Down
11 changes: 5 additions & 6 deletions Common/Utils/src/IRFrameSelector.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ long IRFrameSelector::check(o2::dataformats::IRFrame fr, size_t bwd, size_t fwd)
return ans;
}

size_t IRFrameSelector::loadIRFrames(const std::string& fname)
size_t IRFrameSelector::loadIRFrames(const std::string& fname, size_t margin)
{
// read IRFrames to filter from the file
std::unique_ptr<TFile> tfl(TFile::Open(fname.c_str()));
Expand Down Expand Up @@ -155,15 +155,14 @@ size_t IRFrameSelector::loadIRFrames(const std::string& fname)
toBeSorted = true;
}
}

if (!done) {
LOGP(fatal, "Did not find neither tree nor vector of IRFrames in {}", fname);
}
if (toBeSorted) {
LOGP(info, "Sorting {} IRFrames", mOwnList.size());
std::sort(mOwnList.begin(), mOwnList.end(), [](const auto& a, const auto& b) { return a.getMin() < b.getMin(); });
}
if (!true) {
LOGP(fatal, "Did not find neither tree nor vector of IRFrames in {}", fname);
}
setSelectedIRFrames(mOwnList);
setSelectedIRFrames(mOwnList, margin, margin);
return mOwnList.size();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ struct CTFReaderInp {
std::string remoteRegex{};
std::string metricChannel{};
std::string fileIRFrames{};
uint32_t selectIRFramesExtraBCMargin = 0;
std::string fileRunTimeSpans{};
std::string dictOpt{};
std::vector<int> ctfIDs{};
Expand Down
7 changes: 3 additions & 4 deletions Detectors/CTF/workflow/src/CTFReaderSpec.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,9 @@ void CTFReaderSpec::init(InitContext& ic)
mFileFetcher->setFailThreshold(ic.options().get<float>("fetch-failure-threshold"));
mFileFetcher->start();
if (!mInput.fileIRFrames.empty()) {
mIRFrameSelector.loadIRFrames(mInput.fileIRFrames);
const auto& hbfu = o2::raw::HBFUtils::Instance();
mTFLength = hbfu.nHBFPerTF;
LOGP(info, "IRFrames will be selected from {}, assumed TF length: {} HBF", mInput.fileIRFrames, mTFLength);
mIRFrameSelector.loadIRFrames(mInput.fileIRFrames, mInput.selectIRFramesExtraBCMargin);
mTFLength = o2::raw::HBFUtils::Instance().nHBFPerTF;
LOGP(info, "IRFrames will be selected from {} with {} margin, assumed TF length: {} HBF", mInput.fileIRFrames, mInput.selectIRFramesExtraBCMargin, mTFLength);
mIFRamesOut = true;
}
if (!mInput.fileRunTimeSpans.empty()) {
Expand Down
10 changes: 7 additions & 3 deletions Detectors/CTF/workflow/src/ctf-reader-workflow.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,15 @@ void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
options.push_back(ConfigParamSpec{"ctf-data-subspec", VariantType::Int, 0, {"subspec to use for decoded CTF messages (use non-0 if CTF writer will be attached downstream)"}});
options.push_back(ConfigParamSpec{"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings"}});
options.push_back(ConfigParamSpec{"ir-frames-files", VariantType::String, "", {"If non empty, inject selected IRFrames from this file"}});
options.push_back(ConfigParamSpec{"ir-frames-extra-margin", VariantType::UInt32, uint32_t(0), {"Impose additional FWD/BWD BC margin on selected IRFrames"}});
options.push_back(ConfigParamSpec{"run-time-span-file", VariantType::String, "", {"If non empty, inject selected IRFrames from this text file (run, min/max orbit or unix time)"}});
options.push_back(ConfigParamSpec{"skip-skimmed-out-tf", VariantType::Bool, false, {"Do not process TFs with empty IR-Frame coverage"}});
options.push_back(ConfigParamSpec{"invert-irframe-selection", VariantType::Bool, false, {"Select only frames mentioned in ir-frames-file (skip-skimmed-out-tf applied to TF not selected!)"}});
//
options.push_back(ConfigParamSpec{"its-digits", VariantType::Bool, false, {"convert ITS clusters to digits"}});
options.push_back(ConfigParamSpec{"its-select-ir-frames", VariantType::Bool, false, {"select ITS rofs matching ITFrames"}});
options.push_back(ConfigParamSpec{"mft-digits", VariantType::Bool, false, {"convert MFT clusters to digits"}});
options.push_back(ConfigParamSpec{"mft-select-ir-frames", VariantType::Bool, false, {"select ITS rofs matching ITFrames"}});
//
options.push_back(ConfigParamSpec{"emcal-decoded-subspec", VariantType::Int, 0, {"subspec to use for decoded EMCAL data"}});
//
Expand Down Expand Up @@ -134,6 +137,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
ctfInput.sup0xccdb = !configcontext.options().get<bool>("send-diststf-0xccdb");
ctfInput.minSHM = std::stoul(configcontext.options().get<std::string>("timeframes-shm-limit"));
ctfInput.fileIRFrames = configcontext.options().get<std::string>("ir-frames-files");
ctfInput.selectIRFramesExtraBCMargin = configcontext.options().get<uint32_t>("ir-frames-extra-margin");
ctfInput.fileRunTimeSpans = configcontext.options().get<std::string>("run-time-span-file");
ctfInput.skipSkimmedOutTF = configcontext.options().get<bool>("skip-skimmed-out-tf");
ctfInput.invertIRFramesSelection = configcontext.options().get<bool>("invert-irframe-selection");
Expand All @@ -145,7 +149,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
if (rateLimitingIPCID > -1 && !chanFmt.empty()) {
ctfInput.metricChannel = fmt::format(fmt::runtime(chanFmt), o2::framework::ChannelSpecHelpers::defaultIPCFolder(), rateLimitingIPCID);
}
if (!ctfInput.fileRunTimeSpans.empty()) {
if (!ctfInput.fileRunTimeSpans.empty() || !ctfInput.fileIRFrames.empty()) {
ctfInput.skipSkimmedOutTF = true;
}
if (!ctfInput.fileIRFrames.empty() && !ctfInput.fileRunTimeSpans.empty()) {
Expand Down Expand Up @@ -190,11 +194,11 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
// add decoders for all allowed detectors.
if (ctfInput.detMask[DetID::ITS]) {
bool doStag = o2::itsmft::DPLAlpideParamInitializer::isITSStaggeringEnabled(configcontext);
addSpecs(o2::itsmft::getITSEntropyDecoderSpec(verbosity, doStag, configcontext.options().get<bool>("its-digits"), ctfInput.subspec, ctfInput.dictOpt));
addSpecs(o2::itsmft::getITSEntropyDecoderSpec(verbosity, doStag, configcontext.options().get<bool>("its-digits"), configcontext.options().get<bool>("its-select-ir-frames"), ctfInput.subspec, ctfInput.dictOpt));
}
if (ctfInput.detMask[DetID::MFT]) {
bool doStag = o2::itsmft::DPLAlpideParamInitializer::isMFTStaggeringEnabled(configcontext);
addSpecs(o2::itsmft::getMFTEntropyDecoderSpec(verbosity, doStag, configcontext.options().get<bool>("mft-digits"), ctfInput.subspec, ctfInput.dictOpt));
addSpecs(o2::itsmft::getMFTEntropyDecoderSpec(verbosity, doStag, configcontext.options().get<bool>("mft-digits"), configcontext.options().get<bool>("mft-select-ir-frames"), ctfInput.subspec, ctfInput.dictOpt));
}
if (ctfInput.detMask[DetID::TPC]) {
addSpecs(o2::tpc::getEntropyDecoderSpec(verbosity, ctfInput.subspec, ctfInput.dictOpt));
Expand Down
2 changes: 2 additions & 0 deletions Detectors/GlobalTracking/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,5 @@ if (OpenMP_CXX_FOUND)
target_compile_definitions(${targetName} PRIVATE WITH_OPENMP)
target_link_libraries(${targetName} PRIVATE OpenMP::OpenMP_CXX)
endif()

add_subdirectory(macros)
14 changes: 14 additions & 0 deletions Detectors/GlobalTracking/macros/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2019-2026 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.

o2_add_test_root_macro(selectPVIRFrames.C
PUBLIC_LINK_LIBRARIES O2::GlobalTracking
LABELS glo)
48 changes: 48 additions & 0 deletions Detectors/GlobalTracking/macros/selectPVIRFrames.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2019-2026 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 selectPVIRFrames.C
/// \brief Macro to select IRFrames for specific vertices

#if !defined(__CLING__) || defined(__ROOTCLING__)
#include <algorithm>>
#include <vector>

#include <TFile.h>
#include <TTree.h>

#include "ReconstructionDataFormats/PrimaryVertex.h"
#include "CommonDataFormat/IRFrame.h"
#endif

void selectPVIRFrames(const char* fName = "o2_primary_vertex.root")
{
auto fPVs = TFile::Open(fName);
TTree* tPVs = (TTree*)fPVs->Get("o2sim");
std::vector<o2::dataformats::PrimaryVertex> pvArr, *pvArrPtr{&pvArr};
tPVs->SetBranchAddress("PrimaryVertex", &pvArrPtr);
std::vector<o2::dataformats::IRFrame> irFrames;
for (Long64_t iEntry{0}; tPVs->LoadTree(iEntry) >= 0; ++iEntry) {
tPVs->GetEntry(iEntry);
for (const auto& pv : pvArr) {
// make selection of pvs
if (pv.getNContributors() > 3000) {
irFrames.emplace_back(pv.getIRMin(), pv.getIRMax());
}
}
}
// sort to make sure they are in the correct order
std::sort(irFrames.begin(), irFrames.end(), [](const auto& a, const auto& b) { return a.getMin() < b.getMin(); });
printf("Selected %zu irFrames\n", irFrames.size());
auto fIRFrames = TFile::Open("irFrames.root", "RECREATE");
fIRFrames->WriteObjectAny(&irFrames, "std::vector<o2::dataformats::IRFrame>", "irframes");
fIRFrames->Close();
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ template <int N>
class EntropyDecoderSpec : public o2::framework::Task
{
public:
EntropyDecoderSpec(int verbosity, bool doStag, bool getDigits = false, const std::string& ctfdictOpt = "none");
EntropyDecoderSpec(int verbosity, bool doStag, bool selectIRFrames, bool getDigits = false, const std::string& ctfdictOpt = "none");
~EntropyDecoderSpec() override = default;
void init(o2::framework::InitContext& ic) final;
void run(o2::framework::ProcessingContext& pc) final;
Expand All @@ -51,6 +51,7 @@ class EntropyDecoderSpec : public o2::framework::Task
const NoiseMap* mNoiseMap = nullptr;
LookUp mPattIdConverter;
bool mDoStaggering{false};
bool mSelectIRFrames{false};
bool mGetDigits{false};
bool mMaskNoise{false};
bool mUseClusterDictionary{true};
Expand All @@ -60,8 +61,8 @@ class EntropyDecoderSpec : public o2::framework::Task
};

/// create a processor spec
framework::DataProcessorSpec getITSEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt);
framework::DataProcessorSpec getMFTEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt);
framework::DataProcessorSpec getITSEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, bool selectIRFrames, unsigned int sspec, const std::string& ctfdictOpt);
framework::DataProcessorSpec getMFTEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, bool selectIRFrames, unsigned int sspec, const std::string& ctfdictOpt);

} // namespace itsmft
} // namespace o2
Expand Down
40 changes: 32 additions & 8 deletions Detectors/ITSMFT/common/workflow/src/EntropyDecoderSpec.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ std::string EntropyDecoderSpec<N>::getBinding(const std::string& name, int spec)
}

template <int N>
EntropyDecoderSpec<N>::EntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, const std::string& ctfdictOpt)
: mCTFCoder(o2::ctf::CTFCoderBase::OpType::Decoder, doStag, ctfdictOpt), mDoStaggering(doStag), mGetDigits(getDigits)
EntropyDecoderSpec<N>::EntropyDecoderSpec(int verbosity, bool doStag, bool selectIRFrames, bool getDigits, const std::string& ctfdictOpt)
: mCTFCoder(o2::ctf::CTFCoderBase::OpType::Decoder, doStag, ctfdictOpt), mDoStaggering(doStag), mSelectIRFrames(selectIRFrames), mGetDigits(getDigits)
{
mTimer.Stop();
mTimer.Reset();
Expand Down Expand Up @@ -96,6 +96,27 @@ void EntropyDecoderSpec<N>::run(ProcessingContext& pc)
}
ndigcl += compcl.size();
}
if (mSelectIRFrames) {
int nSelected{0};
/// mask ROF entries not matching with selected IRFrames
auto irFrames = pc.inputs().get<std::vector<o2::dataformats::IRFrame>>("selIRFrames");
for (auto& rof : rofs) {
bool masked = true;
for (const auto& irFrame : irFrames) {
const auto irStart = rof.getBCData(), irEnd = irStart + DPLAlpideParam<N>::Instance().getROFLengthInBC(iLayer);
o2::dataformats::IRFrame irROF(irStart, irEnd);
if (irFrame.isOutside(irROF) == o2::dataformats::IRFrame::Relation::Inside) {
++nSelected;
masked = false;
break;
}
}
if (masked) {
rof.setNEntries(0);
}
}
LOGP(info, "Selected {} out of {} rofs", nSelected, rofs.size());
}
}
pc.outputs().snapshot({nm + "ctfrep", 0}, iosize);
mTimer.Stop();
Expand Down Expand Up @@ -149,7 +170,7 @@ void EntropyDecoderSpec<N>::finaliseCCDB(o2::framework::ConcreteDataMatcher& mat
}

template <int N>
DataProcessorSpec getEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt)
DataProcessorSpec getEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, bool selectIRFrames, unsigned int sspec, const std::string& ctfdictOpt)
{
constexpr o2::header::DataOrigin Origin{N == o2::detectors::DetID::ITS ? o2::header::gDataOriginITS : o2::header::gDataOriginMFT};
constexpr o2::detectors::DetID ID{N == o2::detectors::DetID::ITS ? o2::detectors::DetID::ITS : o2::detectors::DetID::MFT};
Expand Down Expand Up @@ -181,25 +202,28 @@ DataProcessorSpec getEntropyDecoderSpec(int verbosity, bool doStag, bool getDigi
inputs.emplace_back(std::string{"ctfdict_"} + ID.getName(), Origin, "CTFDICT", 0, Lifetime::Condition, ccdbParamSpec(fmt::format("{}/Calib/CTFDictionaryTree", Origin.as<std::string>())));
}
inputs.emplace_back("trigoffset", "CTP", "Trig_Offset", 0, Lifetime::Condition, ccdbParamSpec("CTP/Config/TriggerOffsets"));
if (selectIRFrames) {
inputs.emplace_back("selIRFrames", "CTF", "SELIRFRAMES", Lifetime::Timeframe);
}

return DataProcessorSpec{
Origin == o2::header::gDataOriginITS ? "its-entropy-decoder" : "mft-entropy-decoder",
inputs,
outputs,
AlgorithmSpec{adaptFromTask<EntropyDecoderSpec<N>>(verbosity, doStag, getDigits, ctfdictOpt)},
AlgorithmSpec{adaptFromTask<EntropyDecoderSpec<N>>(verbosity, doStag, selectIRFrames, getDigits, ctfdictOpt)},
Options{{"mask-noise", VariantType::Bool, false, {"apply noise mask to digits or clusters (involves reclusterization)"}},
{"ignore-cluster-dictionary", VariantType::Bool, false, {"do not use cluster dictionary, always store explicit patterns"}},
{"ans-version", VariantType::String, {"version of ans entropy coder implementation to use"}}}};
}

framework::DataProcessorSpec getITSEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt)
framework::DataProcessorSpec getITSEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, bool selectIRFrames, unsigned int sspec, const std::string& ctfdictOpt)
{
return getEntropyDecoderSpec<o2::detectors::DetID::ITS>(verbosity, doStag, getDigits, sspec, ctfdictOpt);
return getEntropyDecoderSpec<o2::detectors::DetID::ITS>(verbosity, doStag, getDigits, selectIRFrames, sspec, ctfdictOpt);
}

framework::DataProcessorSpec getMFTEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, unsigned int sspec, const std::string& ctfdictOpt)
framework::DataProcessorSpec getMFTEntropyDecoderSpec(int verbosity, bool doStag, bool getDigits, bool selectIRFrames, unsigned int sspec, const std::string& ctfdictOpt)
{
return getEntropyDecoderSpec<o2::detectors::DetID::MFT>(verbosity, doStag, getDigits, sspec, ctfdictOpt);
return getEntropyDecoderSpec<o2::detectors::DetID::MFT>(verbosity, doStag, getDigits, selectIRFrames, sspec, ctfdictOpt);
}

} // namespace itsmft
Expand Down