|
||||
File indexing completed on 2025-01-18 10:17:38
0001 0002 // Copyright 2020, Jefferson Science Associates, LLC. 0003 // Subject to the terms in the LICENSE file found in the top-level directory. 0004 0005 #pragma once 0006 0007 #include <JANA/Components/JComponent.h> 0008 #include <JANA/Components/JHasOutputs.h> 0009 #include <JANA/JEvent.h> 0010 #include <JANA/JException.h> 0011 #include <JANA/JFactoryGenerator.h> 0012 0013 0014 class JFactoryGenerator; 0015 class JApplication; 0016 class JFactory; 0017 0018 0019 class JEventSource : public jana::components::JComponent, 0020 public jana::components::JHasOutputs { 0021 0022 public: 0023 /// Result describes what happened the last time a GetEvent() was attempted. 0024 /// If Emit() or GetEvent() reaches an error state, it should throw a JException instead. 0025 enum class Result { Success, FailureTryAgain, FailureFinished }; 0026 0027 /// The user is supposed to _throw_ RETURN_STATUS::kNO_MORE_EVENTS or kBUSY from GetEvent() 0028 enum class RETURN_STATUS { kSUCCESS, kNO_MORE_EVENTS, kBUSY, kTRY_AGAIN, kERROR, kUNKNOWN }; 0029 0030 0031 private: 0032 std::string m_resource_name; 0033 std::atomic_ullong m_events_emitted {0}; 0034 std::atomic_ullong m_events_finished {0}; 0035 uint64_t m_nskip = 0; 0036 uint64_t m_nevents = 0; 0037 bool m_enable_finish_event = false; 0038 bool m_enable_get_objects = false; 0039 bool m_enable_preprocess = false; 0040 0041 0042 public: 0043 explicit JEventSource(std::string resource_name, JApplication* app = nullptr) 0044 : m_resource_name(std::move(resource_name)) { 0045 m_app = app; 0046 } 0047 0048 JEventSource() = default; 0049 virtual ~JEventSource() = default; 0050 0051 0052 // `Init` is where the user requests parameters and services. If the user requests all parameters and services here, 0053 // JANA can report them back to the user without having to open the resource and run the topology. 0054 0055 virtual void Init() {} 0056 0057 0058 /// `Open` is called by JANA when it is ready to accept events from this event source. The implementor should open 0059 /// file pointers or sockets here, instead of in the constructor. This is because the implementor won't know how many 0060 /// or which event sources the user will decide to activate within one job. Thus the implementor can avoid problems 0061 /// such as running out of file pointers, or multiple event sources attempting to bind to the same socket. 0062 0063 virtual void Open() {} 0064 0065 0066 // `Emit` is called by JANA in order to emit a fresh event into the stream, when using CallbackStyle::ExpertMode. 0067 // It is very similar to GetEvent(), except the user returns a Result status code instead of throwing an exception. 0068 // Exceptions are reserved for unrecoverable errors. It accepts an out parameter JEvent. If there is another 0069 // entry in the file, or another message waiting at the socket, the user reads the data into the JEvent and returns 0070 // Result::Success, at which point JANA pushes the JEvent onto the downstream queue. If there is no data waiting yet, 0071 // the user returns Result::FailureTryAgain, at which point JANA recycles the JEvent to the pool. If there is no more 0072 // data, the user returns Result::FailureFinished, at which point JANA recycles the JEvent to the pool and calls Close(). 0073 0074 virtual Result Emit(JEvent&) { return Result::Success; }; 0075 0076 0077 /// For work that should be done in parallel on a JEvent, but is tightly coupled to the JEventSource for some reason. 0078 /// Called after Emit() by JEventMapArrow 0079 virtual void Preprocess(const JEvent&) const {}; 0080 0081 0082 /// `FinishEvent` is used to notify the `JEventSource` that an event has been completely processed. This is the final 0083 /// chance to interact with the `JEvent` before it is either cleared and recycled, or deleted. Although it is 0084 /// possible to use this for freeing JObjects stored in the JEvent , this is strongly discouraged in favor of putting 0085 /// that logic on the destructor, RAII-style. Instead, this callback should be used for updating and freeing state 0086 /// owned by the JEventSource, e.g. raw data which is keyed off of run number and therefore shared among multiple 0087 /// JEvents. `FinishEvent` is also well-suited for use with `EventGroup`s, e.g. to notify someone that a batch of 0088 /// events has finished, or to implement "barrier events". 0089 0090 virtual void FinishEvent(JEvent&) {}; 0091 0092 0093 /// `Close` is called by JANA when it is finished accepting events from this event source. Here is where you should 0094 /// cleanly close files, sockets, etc. Although GetEvent() knows when (for instance) there are no more events in a 0095 /// file, the logic for closing needs to live here because there are other ways a computation may end besides 0096 /// running out of events in a file. For instance, the user may want to process a limited number of events using 0097 /// the `jana:nevents` parameter, or they may want to terminate the computation manually using Ctrl-C. 0098 0099 virtual void Close() {} 0100 0101 0102 /// `GetEvent` is called by JANA in order to emit a fresh event into the stream. JANA manages the entire lifetime of 0103 /// the JEvent. The `JEvent` being passed in is empty and merely needs to hydrated as follows: 0104 0105 /// 1. `SetRunNumber()` 0106 /// 2. `SetEventNumber()` 0107 /// 3. `Insert<T>()` raw data of type `T` into the `JEvent` container. Note that `T` should be a child class, such as 0108 /// `FADC250DigiHit`, not a parent class such as `JObject` or `TObject`. Also note that `Insert` transfers 0109 /// ownership of the data to that JEvent. If the data is shared among multiple `JEvents`, e.g. BOR data, 0110 /// use `SetFactoryFlags(JFactory::NOT_OBJECT_OWNER)` 0111 0112 /// Note that JEvents are usually recycled. Although all reconstruction data is cleared before `GetEvent` is called, 0113 /// the constituent `JFactories` may retain some state, e.g. statistics, or calibration data keyed off of run number. 0114 0115 /// If an event cannot be emitted, either because the resource is not ready or because we have reached the end of 0116 /// the event stream, the implementor should throw the corresponding `RETURN_STATUS`. The user should NEVER throw 0117 /// `RETURN_STATUS SUCCESS` because this will hurt performance. Instead, they should simply return normally. 0118 0119 virtual void GetEvent(std::shared_ptr<JEvent>) {}; 0120 0121 0122 /// `GetObjects` was historically used for lazily unpacking data from a JEvent and putting it into a "dummy" JFactory. 0123 /// This mechanism has been replaced by `JEvent::Insert`. All lazy evaluation should happen in a (non-dummy) 0124 /// JFactory, whereas eager evaluation should happen in `JEventSource::GetEvent` via `JEvent::Insert`. 0125 0126 virtual bool GetObjects(const std::shared_ptr<const JEvent>&, JFactory*) { 0127 return false; 0128 } 0129 0130 0131 // Getters 0132 0133 std::string GetResourceName() const { return m_resource_name; } 0134 0135 [[deprecated]] 0136 uint64_t GetEventCount() const { return m_events_emitted; }; 0137 uint64_t GetEmittedEventCount() const { return m_events_emitted; }; 0138 uint64_t GetFinishedEventCount() const { return m_events_finished; }; 0139 0140 [[deprecated]] 0141 virtual std::string GetType() const { return m_type_name; } 0142 0143 [[deprecated]] 0144 std::string GetName() const { return m_resource_name; } 0145 0146 bool IsGetObjectsEnabled() const { return m_enable_get_objects; } 0147 bool IsFinishEventEnabled() const { return m_enable_finish_event; } 0148 bool IsPreprocessEnabled() const { return m_enable_preprocess; } 0149 0150 uint64_t GetNSkip() { return m_nskip; } 0151 uint64_t GetNEvents() { return m_nevents; } 0152 0153 virtual std::string GetVDescription() const { 0154 return "<description unavailable>"; 0155 } ///< Optional for getting description via source rather than JEventSourceGenerator 0156 0157 0158 // Setters 0159 0160 void SetResourceName(std::string resource_name) { m_resource_name = resource_name; } 0161 0162 /// EnableFinishEvent() is intended to be called by the user in the constructor in order to 0163 /// tell JANA to call the provided FinishEvent method after all JEventProcessors 0164 /// have finished with a given event. This should only be enabled when absolutely necessary 0165 /// (e.g. for backwards compatibility) because it introduces contention for the JEventSource mutex, 0166 /// which will hurt performance. Conceptually, FinishEvent isn't great, and so should be avoided when possible. 0167 void EnableFinishEvent(bool enable=true) { m_enable_finish_event = enable; } 0168 void EnableGetObjects(bool enable=true) { m_enable_get_objects = enable; } 0169 void EnablePreprocess(bool enable=true) { m_enable_preprocess = enable; } 0170 0171 void SetNEvents(uint64_t nevents) { m_nevents = nevents; }; 0172 void SetNSkip(uint64_t nskip) { m_nskip = nskip; }; 0173 0174 0175 // Internal 0176 0177 [[deprecated("Replaced by JEventSource::DoOpen()")]] 0178 void DoInitialize(); 0179 0180 virtual void DoInit(); 0181 0182 void DoOpen(bool with_lock=true); 0183 0184 void DoClose(bool with_lock=true); 0185 0186 Result DoNext(std::shared_ptr<JEvent> event); 0187 0188 Result DoNextCompatibility(std::shared_ptr<JEvent> event); 0189 0190 void DoFinishEvent(JEvent& event); 0191 0192 void Summarize(JComponentSummary& summary) const override; 0193 0194 0195 }; 0196 0197
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |