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