Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-15 09:43:11

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Utilities/Logger.hpp"
0012 #include "ActsExamples/Framework/DataHandle.hpp"
0013 #include "ActsExamples/Framework/IAlgorithm.hpp"
0014 #include "ActsExamples/Framework/IContextDecorator.hpp"
0015 #include "ActsExamples/Framework/IReader.hpp"
0016 #include "ActsExamples/Framework/IWriter.hpp"
0017 #include "ActsExamples/Framework/SequenceElement.hpp"
0018 #include "ActsExamples/Framework/WhiteBoard.hpp"
0019 #include "ActsExamples/Utilities/tbbWrap.hpp"
0020 #include "ActsPlugins/FpeMonitoring/FpeMonitor.hpp"
0021 
0022 #include <cstddef>
0023 #include <memory>
0024 #include <optional>
0025 #include <stdexcept>
0026 #include <string>
0027 #include <utility>
0028 #include <vector>
0029 
0030 #include <tbb/enumerable_thread_specific.h>
0031 
0032 namespace ActsExamples {
0033 
0034 using IterationCallback = void (*)();
0035 
0036 /// Custom exception class so FPE failures can be caught
0037 class FpeFailure : public std::runtime_error {
0038   using std::runtime_error::runtime_error;
0039 };
0040 
0041 class SequenceConfigurationException : public std::runtime_error {
0042  public:
0043   explicit SequenceConfigurationException(const std::string &message)
0044       : std::runtime_error{"Sequence configuration error: " + message} {}
0045 };
0046 
0047 /// A simple algorithm sequencer for event processing.
0048 ///
0049 /// This is the backbone of the framework. It reads events from file,
0050 /// runs the configured algorithms for each event, and writes selected data
0051 /// back to a file.
0052 class Sequencer {
0053  public:
0054   struct FpeMask {
0055     std::string file;
0056     std::pair<std::size_t, std::size_t> lines;
0057     ActsPlugins::FpeType type{};
0058     std::size_t count = 0;
0059   };
0060 
0061   struct Config {
0062     /// number of events to skip at the beginning
0063     std::size_t skip = 0;
0064     /// number of events to process, std::numeric_limits<std::size_t>::max() to
0065     /// process all available events
0066     std::optional<std::size_t> events = std::nullopt;
0067     /// logging level
0068     Acts::Logging::Level logLevel = Acts::Logging::INFO;
0069     /// number of parallel threads to run, negative for automatic
0070     /// determination
0071     int numThreads = -1;
0072     /// output directory for timing information, empty for working directory
0073     std::string outputDir;
0074     /// output name of the timing file
0075     std::string outputTimingFile = "timing.csv";
0076     /// Callback that is invoked in the event loop.
0077     /// @warning This function can be called from multiple threads and should therefore be thread-safe
0078     IterationCallback iterationCallback = []() {};
0079 
0080     /// If true, FPEs are tracked.
0081     bool trackFpes = true;
0082     /// If true, FPEs are masked and reported.
0083     std::vector<FpeMask> fpeMasks{};
0084     /// If true, the first FPE encountered makes Sequencer::run() fail.
0085     bool failOnFirstFpe = false;
0086     /// If false, unmasked FPEs are reported but do not make Sequencer::run()
0087     /// fail.
0088     bool failOnUnmaskedFpe = true;
0089     /// The number of stack frames to include in the FPE report.
0090     std::size_t fpeStackTraceLength = 8;
0091   };
0092 
0093   explicit Sequencer(const Config &cfg);
0094 
0095   /// Add a context decorator to the set of context decorators.
0096   ///
0097   /// @throws std::invalid_argument if the decorator is NULL.
0098   void addContextDecorator(std::shared_ptr<IContextDecorator> decorator);
0099 
0100   /// Add a reader to the set of readers.
0101   ///
0102   /// @throws std::invalid_argument if the reader is NULL.
0103   void addReader(std::shared_ptr<IReader> reader);
0104 
0105   /// Append an algorithm to the sequence of algorithms.
0106   ///
0107   /// @throws std::invalid_argument if the algorithm is NULL.
0108   void addAlgorithm(std::shared_ptr<IAlgorithm> algorithm);
0109 
0110   /// Append a sequence element to the sequence
0111   ///
0112   /// @throws std::invalid_argument if the element is NULL.
0113   void addElement(const std::shared_ptr<SequenceElement> &element);
0114 
0115   /// Add a writer to the set of writers.
0116   ///
0117   /// @throws std::invalid_argument if the writer is NULL.
0118   void addWriter(std::shared_ptr<IWriter> writer);
0119 
0120   /// Add an alias to the whiteboard.
0121   void addWhiteboardAlias(const std::string &aliasName,
0122                           const std::string &objectName);
0123 
0124   ActsPlugins::FpeMonitor::Result fpeResult() const;
0125 
0126   /// Run the event loop.
0127   ///
0128   /// @return status code compatible with the `main()` return code
0129   /// @returns EXIT_SUCCESS when everying worked without problems
0130   /// @returns EXIT_FAILURE if something went wrong
0131   ///
0132   /// @note If the number of events to process is undefined, the sequencer
0133   /// will process events until the first reader signals the end-of-file. If
0134   /// given, it sets an upper bound.
0135   ///
0136   /// This function is intended to be run as the last thing in the tool
0137   /// main function and its return value can be used directly as the program
0138   /// return value, i.e.
0139   ///
0140   ///     int main(int argc, char* argv[])
0141   ///     {
0142   ///         Sequencer::Config cfg;
0143   ///         ... // configure the sequencer
0144   ///         Sequencer seq;
0145   ///         ... // set up the algorithms
0146   ///         return seq.run();
0147   ///     }
0148   ///
0149   /// This will run the start-of-run hook for all configured services, run all
0150   /// configured readers, algorithms, and writers for each event, then invoke
0151   /// the end-of-run hook for all configured writers.
0152   int run();
0153 
0154   /// Get const access to the config
0155   const Config &config() const { return m_cfg; }
0156 
0157  private:
0158   /// List of all configured algorithm names.
0159   std::vector<std::string> listAlgorithmNames() const;
0160   /// Determine range of (requested) events;
0161   /// [std::numeric_limits<std::size_t>::max(),
0162   /// std::numeric_limits<std::size_t>::max()) for error.
0163   std::pair<std::size_t, std::size_t> determineEventsRange() const;
0164 
0165   std::pair<std::string, std::size_t> fpeMaskCount(
0166       const boost::stacktrace::stacktrace &st, ActsPlugins::FpeType type) const;
0167 
0168   void fpeReport() const;
0169 
0170   struct SequenceElementWithFpeResult {
0171     std::shared_ptr<SequenceElement> sequenceElement;
0172     std::unique_ptr<
0173         tbb::enumerable_thread_specific<ActsPlugins::FpeMonitor::Result>>
0174         fpeResult = std::make_unique<
0175             tbb::enumerable_thread_specific<ActsPlugins::FpeMonitor::Result>>();
0176   };
0177 
0178   Config m_cfg;
0179   tbbWrap::task_arena m_taskArena;
0180   std::vector<std::shared_ptr<IContextDecorator>> m_decorators;
0181   std::vector<std::shared_ptr<IReader>> m_readers;
0182   std::vector<std::shared_ptr<IWriter>> m_writers;
0183   std::vector<SequenceElementWithFpeResult> m_sequenceElements;
0184   std::unique_ptr<const Acts::Logger> m_logger;
0185 
0186   WhiteBoard::AliasMapType m_whiteboardObjectAliases;
0187 
0188   DataHandleBase::StateMapType m_whiteBoardState;
0189 
0190   std::atomic<std::size_t> m_nSkippedEvents = 0;
0191   std::atomic<std::size_t> m_nUnmaskedFpe = 0;
0192 
0193   const Acts::Logger &logger() const { return *m_logger; }
0194 };
0195 
0196 std::ostream &operator<<(std::ostream &os, const Sequencer::FpeMask &m);
0197 
0198 }  // namespace ActsExamples