Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-29 08:27: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 
0006 #include "JComponentManager.h"
0007 #include <JANA/JEventProcessor.h>
0008 #include <JANA/JMultifactory.h>
0009 #include <JANA/JFactoryGenerator.h>
0010 #include <JANA/JEventUnfolder.h>
0011 #include <JANA/JEventFolder.h>
0012 #include <JANA/Utils/JAutoActivator.h>
0013 
0014 JComponentManager::JComponentManager() {
0015     SetPrefix("jana");
0016 }
0017 
0018 JComponentManager::~JComponentManager() {
0019 
0020     for (auto* src_gen : m_src_gens) {
0021         delete src_gen;
0022     }
0023     for (auto* fac_gen : m_fac_gens) {
0024         delete fac_gen;
0025     }
0026 
0027     for (auto* src : m_evt_srces) {
0028         LOG_TRACE(GetLogger()) << "Destroying source with type=" << src->GetTypeName();
0029         delete src;
0030     }
0031     for (auto* unfolder : m_unfolders) {
0032         LOG_TRACE(GetLogger()) << "Destroying unfolder with type=" << unfolder->GetTypeName();
0033         delete unfolder;
0034     }
0035     for (auto* folder : m_folders) {
0036         LOG_TRACE(GetLogger()) << "Destroying folder with type=" << folder->GetTypeName();
0037         delete folder;
0038     }
0039 
0040     // The order of deletion here sadly matters, because GlueX likes to fill
0041     // histograms inside component destructors. Thus event processors must be destroyed after 
0042     // all other components, and the last component to be destroyed should be the _first_ event 
0043     // processor, because that's the one that is usually provided by the main program and handles 
0044     // the ROOT output file. We may eventually want to move all ROOT file operations to a separate
0045     // JService which would be closed and destroyed after all other components.
0046 
0047     for (int i=m_evt_procs.size()-1; i >= 0; --i) {
0048         LOG_TRACE(GetLogger()) << "Destroying processor with type=" << m_evt_procs[i]->GetTypeName();
0049         delete m_evt_procs[i];
0050     }
0051 }
0052 
0053 void JComponentManager::Init() {
0054     // Because this is an 'internal' JService, it works a little differently than user-provided
0055     // JServices. Specifically, we have to fetch parameters _after_ plugin loading because some 
0056     // plugins want to set parameter values that JComponentManager needs (most notably janadot). 
0057     // We handle parameters in configure_components() instead.
0058 }
0059 
0060 void JComponentManager::ConfigureComponents() {
0061 
0062     m_params->SetDefaultParameter("event_source_type", m_user_evt_src_typename, "Manually specifies which JEventSource should open the input file");
0063     m_params->SetDefaultParameter("record_call_stack", 
0064                                   m_enable_call_graph_recording,
0065                                   "Records a trace of who called each factory. Reduces performance but necessary for plugins such as janadot.")
0066             ->SetIsAdvanced(true);
0067     m_params->SetDefaultParameter("jana:nevents", m_nevents, "Max number of events that sources can emit");
0068     m_params->SetDefaultParameter("jana:nskip", m_nskip, "Number of events that sources should skip before starting emitting");
0069     m_params->SetDefaultParameter("autoactivate", m_autoactivate, "List of factories to activate regardless of what the event processors request. Format is typename:tag,typename:tag");
0070 
0071 
0072     bool output_processed_event_numbers = false;
0073     m_params->SetDefaultParameter("jana:output_processed_event_numbers", output_processed_event_numbers, "Write the sequence of processed event numbers to file");
0074     m_params->FilterParameters(m_default_tags, "DEFTAG:");
0075 
0076     // Look for factories to auto-activate
0077     if (!m_autoactivate.empty() || output_processed_event_numbers) {
0078         m_evt_procs.insert(m_evt_procs.begin(), new JAutoActivator);
0079         // We add this to the _front_ of the evt_procs vector so that it is run _first_
0080         // JAutoActivator will re-parse the autoactivate list by itself
0081     }
0082 
0083     // Give all components a JApplication pointer and a logger
0084     PreinitializeComponents();
0085 
0086     // Resolve all event sources now that all plugins have been loaded
0087     // (Note that we need to wire the event source generators beforehand)
0088     ResolveEventSources();
0089 
0090     // Call Summarize() and Init() in order to populate JComponentSummary and JParameterManager, respectively
0091     InitializeComponents();
0092 }
0093 
0094 void JComponentManager::PreinitializeComponents() {
0095     for (auto* src : m_evt_srces) {
0096         src->Wire(GetApplication());
0097     }
0098     for (auto* proc : m_evt_procs) {
0099         proc->Wire(GetApplication());
0100     }
0101     for (auto* fac_gen : m_fac_gens) {
0102         fac_gen->SetApplication(GetApplication());
0103         //fac_gen->SetLogger(m_logging->get_logger(fac_gen->GetLoggerName()));
0104     }
0105     for (auto* src_gen : m_src_gens) {
0106         src_gen->SetJApplication(GetApplication());
0107         //src_gen->SetLogger(m_logging->get_logger(src_gen->GetLoggerName()));
0108     }
0109     for (auto* unfolder : m_unfolders) {
0110         unfolder->Wire(GetApplication());
0111     }
0112     for (auto* folder : m_folders) {
0113         folder->Wire(GetApplication());
0114     }
0115 }
0116 
0117 void JComponentManager::InitializeComponents() {
0118     // For now, this only computes the summary for all components except factories.
0119     // However, we are likely to eventually want summaries to access information only
0120     // available after component initialization, specifically parameters. In this case, 
0121     // we would move responsibility for source, unfolder, and processor initialization 
0122     // out from the JArrowTopology and into here.
0123 
0124     // Event sources
0125     for (auto * src : m_evt_srces) {
0126         src->Summarize(m_summary);
0127     }
0128 
0129     // Event processors
0130     for (auto * evt_proc : m_evt_procs) {
0131         evt_proc->Summarize(m_summary);
0132     }
0133 
0134     // Unfolders
0135     for (auto * unfolder : m_unfolders) {
0136         unfolder->Summarize(m_summary);
0137     }
0138 
0139     // Unfolders
0140     for (auto * folder : m_folders) {
0141         folder->Summarize(m_summary);
0142     }
0143 
0144     JFactorySet dummy_fac_set;
0145     for (auto* fac_gen : m_fac_gens) {
0146         // TODO: Get rid of this
0147         fac_gen->GenerateFactories(&dummy_fac_set);
0148     }
0149 
0150     // Factories
0151     for (auto* fac : dummy_fac_set.GetAllFactories()) {
0152         try {
0153             // Run Init() on each factory in order to capture any parameters 
0154             // (and eventually services) that are retrieved via GetApplication().
0155             fac->SetApplication(GetApplication());
0156             fac->DoInit();
0157         }
0158         catch (...) {
0159             // Swallow any exceptions!
0160             // Everything in dummy_fac_set will be destroyed immediately after this.
0161             // The same exception will be thrown from a fresh factory
0162             // set once processing begins, unless the factory is never used.
0163         }
0164         fac->Summarize(m_summary);
0165     }
0166 }
0167 
0168 void JComponentManager::NextPlugin(std::string plugin_name) {
0169     // We defer resolving event sources until we have finished loading all plugins
0170     m_current_plugin_name = plugin_name;
0171 }
0172 
0173 void JComponentManager::Add(std::string event_source_name) {
0174     m_src_names.push_back(event_source_name);
0175 }
0176 
0177 void JComponentManager::Add(JEventSourceGenerator *source_generator) {
0178     source_generator->SetPluginName(m_current_plugin_name);
0179     m_src_gens.push_back(source_generator);
0180 }
0181 
0182 void JComponentManager::Add(JFactoryGenerator *factory_generator) {
0183     factory_generator->SetPluginName(m_current_plugin_name);
0184     m_fac_gens.push_back(factory_generator);
0185 }
0186 
0187 void JComponentManager::Add(JEventSource *event_source) {
0188     event_source->SetPluginName(m_current_plugin_name);
0189     m_evt_srces.push_back(event_source);
0190 }
0191 
0192 void JComponentManager::Add(JEventProcessor *processor) {
0193     processor->SetPluginName(m_current_plugin_name);
0194     m_evt_procs.push_back(processor);
0195 }
0196 
0197 void JComponentManager::Add(JEventUnfolder* unfolder) {
0198     unfolder->SetPluginName(m_current_plugin_name);
0199     m_unfolders.push_back(unfolder);
0200 }
0201 
0202 void JComponentManager::Add(JEventFolder* folder) {
0203     folder->SetPluginName(m_current_plugin_name);
0204     m_folders.push_back(folder);
0205 }
0206 
0207 void JComponentManager::ConfigureEvent(JEvent& event) {
0208     auto* factory_set = event.GetFactorySet();
0209     for (auto gen : m_fac_gens) {
0210         gen->GenerateFactories(factory_set);
0211     }
0212     event.SetDefaultTags(m_default_tags);
0213     event.GetJCallGraphRecorder()->SetEnabled(m_enable_call_graph_recording);
0214     event.SetJApplication(GetApplication());
0215 }
0216 
0217 
0218 
0219 void JComponentManager::ResolveEventSources() {
0220 
0221     m_user_evt_src_gen = ResolveUserEventSourceGenerator();
0222     for (auto& source_name : m_src_names) {
0223         auto* generator = ResolveEventSource(source_name);
0224         auto source = generator->MakeJEventSource(source_name);
0225         source->SetPluginName(generator->GetPluginName());
0226         source->Wire(GetApplication());
0227         m_evt_srces.push_back(source);
0228     }
0229 
0230     for (auto source : m_evt_srces) {
0231         // If nskip/nevents are set individually on JEventSources, respect those. Otherwise use global values.
0232         // Note that this is not what we usually want when we have multiple event sources. It would make more sense to
0233         // take the nskip/nevent slice across the stream of events emitted by each JEventSource in turn.
0234         if (source->GetNSkip() == 0) source->SetNSkip(m_nskip);
0235         if (source->GetNEvents() == 0) source->SetNEvents(m_nevents);
0236     }
0237 }
0238 
0239 JEventSourceGenerator *JComponentManager::ResolveEventSource(std::string source_name) const {
0240 
0241     // Always use the user override if they provided one
0242     if (m_user_evt_src_gen != nullptr) {
0243         return m_user_evt_src_gen;
0244     }
0245 
0246     // Otherwise determine the best via CheckOpenable()
0247     JEventSourceGenerator* best_gen = nullptr;
0248     double best_likelihood = 0.0;
0249     for (auto* gen : m_src_gens) {
0250         auto likelihood = gen->CheckOpenable(source_name);
0251         if (best_likelihood < likelihood) {
0252             best_likelihood = likelihood;
0253             best_gen = gen;
0254         }
0255     }
0256 
0257     // If we found the best, use that
0258     if (best_gen != nullptr) {
0259         return best_gen;
0260     }
0261 
0262     // Otherwise, report the problem and throw
0263     throw JException("Unable to open event source \"%s\": No suitable generator found!", source_name.c_str());
0264 }
0265 
0266 
0267 JEventSourceGenerator* JComponentManager::ResolveUserEventSourceGenerator() const {
0268 
0269     // If the user didn't specify an EVENT_SOURCE_TYPE, do nothing
0270     if (m_user_evt_src_typename == "") return nullptr;
0271 
0272     // Attempt to find the user event source generator
0273     for (auto* evt_src_gen : m_src_gens) {
0274         if (evt_src_gen->GetType() == m_user_evt_src_typename) {
0275             // Found! Save and exit
0276             return evt_src_gen;
0277         }
0278     }
0279 
0280     // No user event source generator found; generate a message and throw
0281     std::ostringstream os;
0282     os << "You specified event source type \"" << m_user_evt_src_typename << "\"" << std::endl;
0283     os << "be used to read the event sources but no such type exists." << std::endl;
0284     os << "Here is a list of available source types:" << std::endl << std::endl;
0285     for (auto * evt_src_gen : m_src_gens) {
0286         os << "    " << evt_src_gen->GetType() << std::endl;
0287     }
0288     os << std::endl;
0289     throw JException(os.str());
0290 
0291 }
0292 
0293 std::vector<JEventSourceGenerator*>& JComponentManager::get_evt_src_gens() {
0294     return m_src_gens;
0295 }
0296 
0297 std::vector<JEventSource*>& JComponentManager::get_evt_srces() {
0298     return m_evt_srces;
0299 }
0300 
0301 std::vector<JEventSourceGenerator*>& JComponentManager::GetSourceGenerators() {
0302     return m_src_gens;
0303 }
0304 
0305 std::vector<JEventSource*>& JComponentManager::GetSources() {
0306     return m_evt_srces;
0307 }
0308 
0309 std::vector<JEventProcessor*>& JComponentManager::GetProcessors() {
0310     return m_evt_procs;
0311 }
0312 
0313 std::vector<JFactoryGenerator*>& JComponentManager::GetFactoryGenerators() {
0314     return m_fac_gens;
0315 }
0316 
0317 std::vector<JEventUnfolder*>& JComponentManager::GetUnfolders() {
0318     return m_unfolders;
0319 }
0320 
0321 std::vector<JEventFolder*>& JComponentManager::GetFolders() {
0322     return m_folders;
0323 }
0324 
0325 const JComponentSummary& JComponentManager::GetComponentSummary() {
0326     return m_summary;
0327 }
0328