Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-09 08:51:50

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