diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt index d0f96a63d987fac94b688a2b2487926e2dd1372c..c18903ab4dfe8f42ae0b54fedad23b8cf62583ee 100644 --- a/algo/CMakeLists.txt +++ b/algo/CMakeLists.txt @@ -106,6 +106,7 @@ install( base/Prelude.h base/RecoParams.h base/SubChain.h + base/Types.h ca/simd/CaSimd.h ca/simd/CaSimdVc.h ca/simd/CaSimdPseudo.h diff --git a/algo/base/Options.cxx b/algo/base/Options.cxx index 79fc95edaa37741fabfef741bf3365b1b9898115..f49b7db2e9d27b0dfc4a72b4ed0bd925b59ac67d 100644 --- a/algo/base/Options.cxx +++ b/algo/base/Options.cxx @@ -6,9 +6,23 @@ #include <boost/program_options.hpp> #include <iostream> +#include <iterator> #include <unordered_map> using namespace cbm::algo; +namespace po = boost::program_options; + + +namespace std +{ + template<class T> + std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) + { + copy(v.begin(), v.end(), std::ostream_iterator<T>(os, " ")); + return os; + } +} // namespace std + void validate(boost::any& v, const std::vector<std::string>& values, severity_level*, int) { @@ -18,22 +32,19 @@ void validate(boost::any& v, const std::vector<std::string>& values, severity_le {"info", severity_level::info}, {"warning", severity_level::warning}, {"error", severity_level::error}, {"fatal", severity_level::fatal}}; - namespace po = boost::program_options; - po::validators::check_first_occurrence(v); const std::string& s = po::validators::get_single_string(values); auto it = levels.find(s); - if (it == levels.end()) { throw po::validation_error(po::validation_error::invalid_option_value); } + if (it == levels.end()) throw po::validation_error(po::validation_error::invalid_option_value); v = it->second; } Options::Options(int argc, char** argv) { - namespace po = boost::program_options; po::options_description required("Required options"); // clang-format off @@ -56,9 +67,15 @@ Options::Options(int argc, char** argv) "URI specifying monitor output (e.g. file:/tmp/monitor.txt, influx1:login:8086:cbmreco_status). Prints to cout when no argument is given. Monitor is disabled when flag is not set.") ("log-file,L", po::value(&fLogFile)->value_name("<file>"), "write log messages to file") - ("num-ts,n", po::value<int>(&fNumTimeslices)->default_value(-1)->value_name("<num>"), + ("output,o", po::value(&fOutputTypes)->multitoken()->default_value({RecoData::Hit})->value_name("<types>"), + "comma seperated list of reconstruction output types (hit, digi, ...)") + ("steps", po::value(&fRecoSteps)->multitoken()->default_value({Step::LocalReco})->value_name("<steps>"), + "comma seperated list of reconstruction steps (upack, digitrigger, localreco, ...)") + ("systems,s", po::value(&fDetectors)->multitoken()->default_value({Detector::STS})->value_name("<detectors>"), + "comma seperated list of detectors to process (sts, mvd, ...)") + ("num-ts,n", po::value(&fNumTimeslices)->default_value(-1)->value_name("<num>"), "Stop after <num> timeslices (-1 = all)") - ("skip-ts,s", po::value(&fSkipTimeslices)->default_value(0)->value_name("<num>"), + ("skip-ts", po::value(&fSkipTimeslices)->default_value(0)->value_name("<num>"), "Skip first <num> timeslices") ("times,t", po::bool_switch(&fCollectKernelTimes)->default_value(false), "print kernel times") diff --git a/algo/base/Options.h b/algo/base/Options.h index 7ee203f890c3cbbcf4ee18c947bdb0e1aecb58be..bc67dae908892eb33c8c5a7da7dace92a22c78d3 100644 --- a/algo/base/Options.h +++ b/algo/base/Options.h @@ -4,7 +4,11 @@ #ifndef CBM_ALGO_BASE_OPTIONS_H #define CBM_ALGO_BASE_OPTIONS_H +#include "Types.h" + +#include <set> #include <string> +#include <vector> #include "compat/Filesystem.h" #include "log.hpp" @@ -28,6 +32,21 @@ namespace cbm::algo int NumTimeslices() const { return fNumTimeslices; } int SkipTimeslices() const { return fSkipTimeslices; } + const std::vector<Step>& Steps() const { return fRecoSteps; } + bool HasStep(Step step) const { return std::find(fRecoSteps.begin(), fRecoSteps.end(), step) != fRecoSteps.end(); } + const std::vector<RecoData>& OutputTypes() const { return fOutputTypes; } + bool HasOutput(RecoData recoData) const + { + return std::find(fOutputTypes.begin(), fOutputTypes.end(), recoData) != fOutputTypes.end(); + } + + const std::vector<Detector>& Detectors() const { return fDetectors; } + bool HasDetector(Detector detector) const + { + return std::find(fDetectors.begin(), fDetectors.end(), detector) != fDetectors.end(); + } + + private: std::string fParamsDir; // TODO: can we make this a std::path? std::string fInputLocator; @@ -38,6 +57,9 @@ namespace cbm::algo bool fCollectKernelTimes = false; int fNumTimeslices = -1; int fSkipTimeslices = 0; + std::vector<Step> fRecoSteps; + std::vector<RecoData> fOutputTypes; + std::vector<Detector> fDetectors; }; } // namespace cbm::algo diff --git a/algo/base/Types.h b/algo/base/Types.h new file mode 100644 index 0000000000000000000000000000000000000000..12c5682b5305a2ae8a16e670df29b20af3e3d7d3 --- /dev/null +++ b/algo/base/Types.h @@ -0,0 +1,51 @@ +/* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main + SPDX-License-Identifier: GPL-3.0-only + Authors: Felix Weiglhofer [committer] */ +#ifndef CBM_BASE_TYPES_H +#define CBM_BASE_TYPES_H + +#include "util/EnumDict.h" + +namespace cbm::algo +{ + + enum class Detector + { + STS, + TOF, + }; + + enum class Step + { + Unpack, + DigiTrigger, + LocalReco, + }; + + enum class RecoData + { + Digi, + Cluster, + Hit, + }; + +} // namespace cbm::algo + +CBM_ENUM_DICT(cbm::algo::Detector, + {"STS", Detector::STS}, + {"TOF", Detector::TOF} +); + +CBM_ENUM_DICT(cbm::algo::Step, + {"Unpack", Step::Unpack}, + {"DigiTrigger", Step::DigiTrigger}, + {"LocalReco", Step::LocalReco} +); + +CBM_ENUM_DICT(cbm::algo::RecoData, + {"Digi", RecoData::Digi}, + {"Cluster", RecoData::Cluster}, + {"Hit", RecoData::Hit} +); + +#endif diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx index 490967f7531f9716636dadab6bc2a7463e386fd5..b8c5b8bc244bc56b9071014ba2ef5e05e921fdf7 100644 --- a/algo/global/Reco.cxx +++ b/algo/global/Reco.cxx @@ -18,9 +18,20 @@ using namespace cbm::algo; Reco::Reco() {} Reco::~Reco() {} +void Reco::Validate(const Options& opts) +{ + if (!fs::exists(opts.ParamsDir())) { + throw std::runtime_error("ParamsDir does not exist: " + opts.ParamsDir().string()); + } + + if (opts.HasDetector(Detector::TOF)) { throw std::runtime_error("TOF not implemented yet"); } +} + void Reco::Init(const Options& opts) { - if (fInitialized) { throw std::runtime_error("Chain already initialized"); } + if (fInitialized) throw std::runtime_error("Chain already initialized"); + + Validate(opts); fContext.opts = opts; SetContext(&fContext); diff --git a/algo/global/Reco.h b/algo/global/Reco.h index 9d1bf89e73cbbee1ef81da34939572a8518fe1b7..d485da35348bc116cbf49138e5a735a07651c076 100644 --- a/algo/global/Reco.h +++ b/algo/global/Reco.h @@ -43,8 +43,7 @@ namespace cbm::algo sts::UnpackChain fUnpack; sts::HitfinderChain fStsHitFinder; - // Util functions - void AddTiming(xpu::timings& timings); + void Validate(const Options& opts); }; } // namespace cbm::algo