Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-17 08:36:52

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     bool trackFpes = true;
0081     std::vector<FpeMask> fpeMasks{};
0082     bool failOnFirstFpe = false;
0083     std::size_t fpeStackTraceLength = 8;
0084   };
0085 
0086   explicit Sequencer(const Config &cfg);
0087 
0088   /// Add a context decorator to the set of context decorators.
0089   ///
0090   /// @throws std::invalid_argument if the decorator is NULL.
0091   void addContextDecorator(std::shared_ptr<IContextDecorator> decorator);
0092 
0093   /// Add a reader to the set of readers.
0094   ///
0095   /// @throws std::invalid_argument if the reader is NULL.
0096   void addReader(std::shared_ptr<IReader> reader);
0097 
0098   /// Append an algorithm to the sequence of algorithms.
0099   ///
0100   /// @throws std::invalid_argument if the algorithm is NULL.
0101   void addAlgorithm(std::shared_ptr<IAlgorithm> algorithm);
0102 
0103   /// Append a sequence element to the sequence
0104   ///
0105   /// @throws std::invalid_argument if the element is NULL.
0106   void addElement(const std::shared_ptr<SequenceElement> &element);
0107 
0108   /// Add a writer to the set of writers.
0109   ///
0110   /// @throws std::invalid_argument if the writer is NULL.
0111   void addWriter(std::shared_ptr<IWriter> writer);
0112 
0113   /// Add an alias to the whiteboard.
0114   void addWhiteboardAlias(const std::string &aliasName,
0115                           const std::string &objectName);
0116 
0117   ActsPlugins::FpeMonitor::Result fpeResult() const;
0118 
0119   /// Run the event loop.
0120   ///
0121   /// @return status code compatible with the `main()` return code
0122   /// @returns EXIT_SUCCESS when everying worked without problems
0123   /// @returns EXIT_FAILURE if something went wrong
0124   ///
0125   /// @note If the number of events to process is undefined, the sequencer
0126   /// will process events until the first reader signals the end-of-file. If
0127   /// given, it sets an upper bound.
0128   ///
0129   /// This function is intended to be run as the last thing in the tool
0130   /// main function and its return value can be used directly as the program
0131   /// return value, i.e.
0132   ///
0133   ///     int main(int argc, char* argv[])
0134   ///     {
0135   ///         Sequencer::Config cfg;
0136   ///         ... // configure the sequencer
0137   ///         Sequencer seq;
0138   ///         ... // set up the algorithms
0139   ///         return seq.run();
0140   ///     }
0141   ///
0142   /// This will run the start-of-run hook for all configured services, run all
0143   /// configured readers, algorithms, and writers for each event, then invoke
0144   /// the end-of-run hook for all configured writers.
0145   int run();
0146 
0147   /// Get const access to the config
0148   const Config &config() const { return m_cfg; }
0149 
0150  private:
0151   /// List of all configured algorithm names.
0152   std::vector<std::string> listAlgorithmNames() const;
0153   /// Determine range of (requested) events;
0154   /// [std::numeric_limits<std::size_t>::max(),
0155   /// std::numeric_limits<std::size_t>::max()) for error.
0156   std::pair<std::size_t, std::size_t> determineEventsRange() const;
0157 
0158   std::pair<std::string, std::size_t> fpeMaskCount(
0159       const boost::stacktrace::stacktrace &st, ActsPlugins::FpeType type) const;
0160 
0161   void fpeReport() const;
0162 
0163   struct SequenceElementWithFpeResult {
0164     std::shared_ptr<SequenceElement> sequenceElement;
0165     std::unique_ptr<
0166         tbb::enumerable_thread_specific<ActsPlugins::FpeMonitor::Result>>
0167         fpeResult = std::make_unique<
0168             tbb::enumerable_thread_specific<ActsPlugins::FpeMonitor::Result>>();
0169   };
0170 
0171   Config m_cfg;
0172   tbbWrap::task_arena m_taskArena;
0173   std::vector<std::shared_ptr<IContextDecorator>> m_decorators;
0174   std::vector<std::shared_ptr<IReader>> m_readers;
0175   std::vector<std::shared_ptr<IWriter>> m_writers;
0176   std::vector<SequenceElementWithFpeResult> m_sequenceElements;
0177   std::unique_ptr<const Acts::Logger> m_logger;
0178 
0179   WhiteBoard::AliasMapType m_whiteboardObjectAliases;
0180 
0181   DataHandleBase::StateMapType m_whiteBoardState;
0182 
0183   std::atomic<std::size_t> m_nSkippedEvents = 0;
0184   std::atomic<std::size_t> m_nUnmaskedFpe = 0;
0185 
0186   const Acts::Logger &logger() const { return *m_logger; }
0187 };
0188 
0189 std::ostream &operator<<(std::ostream &os, const Sequencer::FpeMask &m);
0190 
0191 }  // namespace ActsExamples