Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 08:58:14

0001 
0002 // Copyright 2023, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 #include <JANA/JFactory.h>
0006 #include <JANA/JEvent.h>
0007 #include <JANA/JEventSource.h>
0008 #include <JANA/Utils/JTypeInfo.h>
0009 
0010 
0011 class FlagGuard {
0012     bool* m_flag;
0013 public:
0014     FlagGuard(bool* flag) : m_flag(flag) {
0015         *m_flag = true;
0016     }
0017     ~FlagGuard() {
0018         *m_flag = false;
0019     }
0020 };
0021 
0022 void JFactory::Create(const std::shared_ptr<const JEvent>& event) {
0023     Create(*event.get());
0024 }
0025 
0026 void JFactory::Create(const JEvent& event) {
0027 
0028     if (mInsideCreate) {
0029         throw JException("Encountered a cycle in the factory dependency graph! Hint: Maybe this data was supposed to be inserted in the JEventSource");
0030     }
0031     FlagGuard insideCreateFlagGuard (&mInsideCreate); // No matter how we exit from Create() (particularly with exceptions) mInsideCreate will be set back to false
0032 
0033     if (m_app == nullptr && event.GetJApplication() != nullptr) {
0034         // These are usually set by JFactoryGeneratorT, but some user code has custom JFactoryGenerators which don't!
0035         // The design of JFactoryGenerator doesn't give us a better place to inject things
0036         m_app = event.GetJApplication();
0037         m_logger = m_app->GetJParameterManager()->GetLogger(GetLoggerName());
0038     }
0039 
0040     if (mStatus == Status::Uninitialized) {
0041         DoInit();
0042     }
0043 
0044     // How do we obtain our data? The priority is as follows:
0045     // 1. JFactory::Process() if REGENERATE flag is set
0046     // 2. JEvent::Insert()
0047     // 3. JEventSource::GetObjects() if source has GetObjects() enabled
0048     // 4. JFactory::Process()
0049 
0050     // ---------------------------------------------------------------------
0051     // 1. JFactory::Process() if REGENERATE flag is set
0052     // ---------------------------------------------------------------------
0053 
0054     if (mRegenerate) {
0055         if (mStatus == Status::Inserted) {
0056             // Status::Inserted indicates that the data came from either src->GetObjects() or evt->Insert()
0057             ClearData(); 
0058             // ClearData() resets mStatus to Unprocessed so that the data will be regenerated exactly once.
0059         }
0060         // After this point, control flow falls through to "4. JFactory::Process"
0061     }
0062     else {
0063 
0064         // ---------------------------------------------------------------------
0065         // 2. JEvent::Insert()
0066         // ---------------------------------------------------------------------
0067 
0068         if (mStatus == Status::Inserted) {
0069             // This may include data cached from eventsource->GetObjects().
0070             // Either way, short-circuit here, because the data is present.
0071             return;
0072         }
0073 
0074         // ---------------------------------------------------------------------
0075         // 3. JEventSource::GetObjects() if source has GetObjects() enabled
0076         // ---------------------------------------------------------------------
0077 
0078         auto src = event.GetJEventSource();
0079         if (src != nullptr && src->IsGetObjectsEnabled()) {
0080             bool found_data = false;
0081 
0082             CallWithJExceptionWrapper("JEventSource::GetObjects", [&](){ 
0083                 found_data = src->GetObjects(event.shared_from_this(), this); });
0084 
0085             if (found_data) {
0086                 mStatus = Status::Inserted;
0087                 mCreationStatus = CreationStatus::InsertedViaGetObjects;
0088                 return;
0089             }
0090         }
0091         // If neither "2. JEvent::Insert()" nor "3. JEventSource::GetObjects()" succeeded, fall through to "4. JFactory::Process()"
0092     }
0093 
0094     // ---------------------------------------------------------------------
0095     // 4. JFactory::Process()
0096     // ---------------------------------------------------------------------
0097 
0098     // If the data was Processed (instead of Inserted), it will be in cache, and we can just exit.
0099     // Otherwise we call Process() to create the data in the first place.
0100     if (mStatus == Status::Unprocessed) {
0101         auto run_number = event.GetRunNumber();
0102         if (mPreviousRunNumber != run_number) {
0103             if (mPreviousRunNumber != -1) {
0104                 CallWithJExceptionWrapper("JFactory::EndRun", [&](){ EndRun(); });
0105             }
0106             CallWithJExceptionWrapper("JFactory::ChangeRun", [&](){ ChangeRun(event.shared_from_this()); });
0107             CallWithJExceptionWrapper("JFactory::BeginRun", [&](){ BeginRun(event.shared_from_this()); });
0108             mPreviousRunNumber = run_number;
0109         }
0110         CallWithJExceptionWrapper("JFactory::Process", [&](){ Process(event.shared_from_this()); });
0111         mStatus = Status::Processed;
0112         mCreationStatus = CreationStatus::Created;
0113 
0114         for (auto* output : GetDatabundleOutputs()) {
0115             for (auto* databundle : output->databundles) {
0116                 databundle->SetStatus(JDatabundle::Status::Created);
0117             }
0118         }
0119     }
0120 }
0121 
0122 void JFactory::DoInit() {
0123     if (mStatus != Status::Uninitialized) {
0124         return;
0125     }
0126     for (auto* parameter : m_parameters) {
0127         parameter->Init(*(m_app->GetJParameterManager()), m_prefix);
0128     }
0129     for (auto* service : m_services) {
0130         service->Fetch(m_app);
0131     }
0132     CallWithJExceptionWrapper("JFactory::Init", [&](){ Init(); });
0133     mStatus = Status::Unprocessed;
0134 }
0135 
0136 void JFactory::DoFinish() {
0137     if (mStatus == Status::Unprocessed || mStatus == Status::Processed) {
0138         if (mPreviousRunNumber != -1) {
0139             CallWithJExceptionWrapper("JFactory::EndRun", [&](){ EndRun(); });
0140         }
0141         CallWithJExceptionWrapper("JFactory::Finish", [&](){ Finish(); });
0142         mStatus = Status::Finished;
0143     }
0144 }
0145 
0146 void JFactory::Summarize(JComponentSummary& summary) const {
0147 
0148     auto fs = new JComponentSummary::Component(
0149             "Factory",
0150             GetPrefix(),
0151             GetTypeName(),
0152             GetLevel(),
0153             GetPluginName());
0154 
0155     auto coll = new JComponentSummary::Collection(
0156             GetTag(), 
0157             GetTag(),
0158             GetObjectName(), 
0159             GetLevel());
0160 
0161     fs->AddOutput(coll);
0162     summary.Add(fs);
0163 }
0164 
0165