Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-06 10:24:10

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/JException.h>
0008 #include <JANA/Utils/JAny.h>
0009 #include <JANA/Utils/JEventLevel.h>
0010 #include <JANA/Utils/JCallGraphRecorder.h>
0011 #include <JANA/Components/JComponent.h>
0012 #include <JANA/Components/JHasInputs.h>
0013 #include <JANA/Components/JHasOutputs.h>
0014 #include <JANA/Components/JHasRunCallbacks.h>
0015 #include <JANA/JVersion.h>
0016 #if JANA2_HAVE_PODIO
0017 #include <JANA/Components/JPodioOutput.h>
0018 #endif
0019 #include <JANA/Components/JLightweightOutput.h>
0020 
0021 #include <string>
0022 #include <typeindex>
0023 #include <memory>
0024 #include <vector>
0025 
0026 
0027 class JEvent;
0028 class JObject;
0029 class JApplication;
0030 
0031 class JFactory : public jana::components::JComponent,
0032                  public jana::components::JHasRunCallbacks,
0033                  public jana::components::JHasInputs,
0034                  public jana::components::JHasOutputs {
0035 public:
0036 
0037     enum class Status {Uninitialized, Unprocessed, Processed, Inserted, Excepted, Finished};
0038     enum class CreationStatus { NotCreatedYet, Created, Inserted, InsertedViaGetObjects, NeverCreated };
0039 
0040     enum JFactory_Flags_t {
0041         JFACTORY_NULL = 0x00,    // Not used anywhere
0042         PERSISTENT = 0x01,       // Used heavily. Possibly better served by JServices, hierarchical events, or event groups. 
0043         WRITE_TO_OUTPUT = 0x02,  // Set in halld_recon but not read except by JANA1 janaroot and janacontrol plugins
0044         NOT_OBJECT_OWNER = 0x04, // Used heavily. Small conflict with PODIO subset collections, which do the same thing at a different level
0045         REGENERATE = 0x08        // Replaces JANA1 JFactory_base::use_factory and JFactory::GetCheckSourceFirst()
0046     };
0047 
0048     JFactory() {
0049         // Use CallbackStyle::ExpertMode any time we are NOT using JFactoryT
0050         // This retains backwards compatibility but also moves new code forward by default
0051         SetCallbackStyle(CallbackStyle::ExpertMode);
0052     }
0053     virtual ~JFactory() = default;
0054 
0055     void SetTag(std::string tag) {
0056         GetFirstDatabundle()->SetShortName(tag);
0057     }
0058 
0059     std::string GetTag() const { 
0060         auto db = GetFirstDatabundle();
0061         if (db->HasShortName()) {
0062             return db->GetShortName();
0063         }
0064         return db->GetUniqueName();
0065     }
0066 
0067     std::string GetObjectName() const { return mObjectName; }
0068 
0069     void SetObjectName(std::string object_name) { mObjectName = object_name; }
0070 
0071     std::string GetFactoryName() const { return m_type_name; }
0072     Status GetStatus() const { return mStatus; }
0073     CreationStatus GetCreationStatus() const { return mCreationStatus; }
0074     JCallGraphRecorder::JDataOrigin GetInsertOrigin() const { return m_insert_origin; } ///< If objects were placed here by JEvent::Insert() this records whether that call was made from a source or factory.
0075 
0076     uint32_t GetPreviousRunNumber(void) const { return mPreviousRunNumber; }
0077 
0078     void SetFactoryName(std::string factoryName) { SetTypeName(factoryName); }
0079     void SetStatus(Status status){ mStatus = status; }
0080     void SetCreationStatus(CreationStatus status){ mCreationStatus = status; }
0081     void SetInsertOrigin(JCallGraphRecorder::JDataOrigin origin) { m_insert_origin = origin; } ///< Called automatically by JEvent::Insert() to records whether that call was made by a source or factory.
0082 
0083     void SetPreviousRunNumber(uint32_t aRunNumber) { mPreviousRunNumber = aRunNumber; }
0084 
0085     virtual void SetFactoryFlag(JFactory_Flags_t f) {
0086         switch (f) {
0087             case JFactory::PERSISTENT: SetPersistentFlag(true); break;
0088             case JFactory::REGENERATE: SetRegenerateFlag(false); break;
0089             case JFactory::WRITE_TO_OUTPUT: SetWriteToOutputFlag(false); break;
0090             default: throw JException("Unsupported factory flag");
0091         }
0092     };
0093 
0094     void SetPersistentFlag(bool persistent) { mPersistent = persistent; }
0095     void SetRegenerateFlag(bool regenerate) { mRegenerate = regenerate; }
0096     void SetWriteToOutputFlag(bool write_to_output) { mWriteToOutput = write_to_output; }
0097     bool GetWriteToOutputFlag() { return mWriteToOutput; }
0098 
0099     /// Get data source value depending on how objects came to be here. (Used mainly by JEvent::Get() )
0100     inline JCallGraphRecorder::JDataSource GetDataSource() const {
0101         JCallGraphRecorder::JDataSource datasource = JCallGraphRecorder::DATA_FROM_FACTORY;
0102          if( mCreationStatus == JFactory::CreationStatus::Inserted ){
0103             if( m_insert_origin == JCallGraphRecorder::ORIGIN_FROM_SOURCE ){
0104                 datasource = JCallGraphRecorder::DATA_FROM_SOURCE;
0105             }else{
0106                 datasource = JCallGraphRecorder::DATA_FROM_CACHE; // Really came from factory, but if Inserted, it was a secondary data type.
0107             }
0108         }
0109         return datasource;
0110     }
0111 
0112     std::type_index GetObjectType() const {
0113         return GetFirstDatabundle()->GetTypeIndex();
0114     }
0115 
0116     std::size_t GetNumObjects() const {
0117         return GetFirstDatabundle()->GetSize();
0118     }
0119 
0120     void ClearData() {
0121         if (this->mStatus == JFactory::Status::Uninitialized) {
0122             return;
0123         }
0124 
0125         if (mPersistent) {
0126             // Persistence is a property of both the factory AND the databundle
0127             // - "Don't re-run this factory on the next event"
0128             // - "Don't clear this databundle every time the JEvent gets recycled"
0129             // Factory is persistent <=> All databundles are persistent
0130             // We ARE allowing databundles to be persistent even if they don't have a JFactory
0131             // We don't have a way to enforce this generally yet
0132             return;
0133         }
0134 
0135         this->mStatus = JFactory::Status::Unprocessed;
0136         this->mCreationStatus = JFactory::CreationStatus::NotCreatedYet;
0137 
0138         for (auto* output: GetOutputs()) {
0139             output->ClearData();
0140         }
0141         for (auto* variadic_output : GetVariadicOutputs()) {
0142             variadic_output->ClearData();
0143         }
0144     }
0145 
0146 
0147     // Overloaded by user Factories
0148     virtual void Process(const std::shared_ptr<const JEvent>&) {}      // CallbackStyle::LegacyMode
0149     virtual void Process(const JEvent&) {}                             // CallbackStyle::ExpertMode
0150     virtual void Finish() {}
0151 
0152 
0153 
0154     /// Access the encapsulated data, performing an upcast if necessary. This is useful for extracting data from
0155     /// all JFactories<T> where T extends a parent class S, such as JObject or TObject, in contexts where T is not known
0156     /// or it would introduce an unwanted coupling. The main application is for building DSTs.
0157     ///
0158     /// Be aware of the following caveats:
0159     /// - The factory's object type must not use virtual inheritance.
0160     /// - If JFactory::Process hasn't already been called, this will return an empty vector. This will NOT call JFactory::Process.
0161     /// - Someone must call JFactoryT<T>::EnableGetAs<S>, preferably the constructor. Otherwise, this will return an empty vector.
0162     /// - If S isn't a base class of T, this will return an empty vector.
0163     template<typename S>
0164     std::vector<S*> GetAs();
0165 
0166 
0167 
0168     /// Create() calls JFactory::Init,BeginRun,Process in an invariant-preserving way without knowing the exact
0169     /// type of object contained. In order to access these objects when all you have is a JFactory*, use JFactory::GetAs().
0170     virtual void Create(const std::shared_ptr<const JEvent>& event);
0171     virtual void Create(const JEvent& event);
0172 
0173     void DoInit();
0174     void DoFinish();
0175     void Summarize(JComponentSummary& summary) const override;
0176 
0177     virtual void Set(const std::vector<JObject *>&) { throw JException("Not supported!"); }
0178 
0179 
0180 protected:
0181 
0182     bool mRegenerate = false;
0183     bool mWriteToOutput = true;
0184     bool mPersistent = false;
0185 
0186     int32_t mPreviousRunNumber = -1;
0187     bool mInsideCreate = false; // Use this to detect cycles in factory dependencies
0188     std::string mObjectName;
0189 
0190     mutable Status mStatus = Status::Uninitialized;
0191     mutable JCallGraphRecorder::JDataOrigin m_insert_origin = JCallGraphRecorder::ORIGIN_NOT_AVAILABLE; // (see note at top of JCallGraphRecorder.h)
0192 
0193     CreationStatus mCreationStatus = CreationStatus::NotCreatedYet;
0194 };
0195 
0196 // We are moving away from JFactory::GetAs because it only considers the first databundle
0197 template<typename S>
0198 std::vector<S*> JFactory::GetAs() {
0199     return GetFirstDatabundle()->GetAs<S>();
0200 }
0201 
0202