Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: Factory parameters show up in parameters table #311

Merged
merged 3 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/libraries/JANA/JApplication.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,14 @@ void JApplication::Initialize() {
plugin_loader->attach_plugins(component_manager.get());

// Give all components a JApplication pointer and a logger
component_manager->configure_components();
component_manager->preinitialize_components();

// Resolve all event sources now that all plugins have been loaded
component_manager->resolve_event_sources();

// Call Init() for all factories/multifactories. This populates the ParameterManager
component_manager->initialize_factories();

// Set desired nthreads. We parse the 'nthreads' parameter two different ways for backwards compatibility.
m_desired_nthreads = 1;
m_params->SetDefaultParameter("nthreads", m_desired_nthreads, "Desired number of worker threads, or 'Ncores' to use all available cores.");
Expand Down
102 changes: 63 additions & 39 deletions src/libraries/JANA/JEventSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class JEventSource : public jana::omni::JComponent, public jana::omni::JHasOutpu
virtual ~JEventSource() = default;


// `Init` is where the user requests parameters and services. If the user requests all parameters and services here,
// JANA can report them back to the user without having to open the resource and run the topology.

virtual void Init() {}

// To be implemented by the user
/// `Open` is called by JANA when it is ready to accept events from this event source. The implementor should open
Expand Down Expand Up @@ -112,78 +116,98 @@ class JEventSource : public jana::omni::JComponent, public jana::omni::JHasOutpu
}


// Wrappers for calling Open and GetEvent in a safe way
virtual void DoInit() {
if (m_status == Status::Uninitialized) {
CallWithJExceptionWrapper("JEventSource::Init", [&](){ Init();});
m_status = Status::Initialized;
LOG_INFO(GetLogger()) << "Initialized JEventSource '" << GetTypeName() << "' ('" << GetResourceName() << "')" << LOG_END;
}
else {
throw JException("Attempted to initialize a JEventSource that is not uninitialized!");
}
}

virtual void DoInitialize(bool with_lock=true) {
virtual void DoOpen(bool with_lock=true) {
if (with_lock) {
std::lock_guard<std::mutex> lock(m_mutex);
if (m_status == Status::Uninitialized) {
CallWithJExceptionWrapper("JEventSource::Open", [&](){ Open();});
if (GetResourceName().empty()) {
LOG_INFO(GetLogger()) << "Opened event source" << LOG_END;
}
else {
LOG_INFO(GetLogger()) << "Opened event source '" << GetResourceName() << "'" << LOG_END;
}
m_status = Status::Initialized;
if (m_status != Status::Initialized) {
throw JException("Attempted to open a JEventSource that hasn't been initialized!");
}
CallWithJExceptionWrapper("JEventSource::Open", [&](){ Open();});
if (GetResourceName().empty()) {
LOG_INFO(GetLogger()) << "Opened JEventSource '" << GetTypeName() << "'" << LOG_END;
}
else {
LOG_INFO(GetLogger()) << "Opened JEventSource '" << GetTypeName() << "' ('" << GetResourceName() << "')" << LOG_END;
}
m_status = Status::Opened;
}
else {
if (m_status == Status::Uninitialized) {
CallWithJExceptionWrapper("JEventSource::Open", [&](){ Open();});
if (GetResourceName().empty()) {
LOG_INFO(GetLogger()) << "Opened event source" << LOG_END;
}
else {
LOG_INFO(GetLogger()) << "Opened event source '" << GetResourceName() << "'" << LOG_END;
}
m_status = Status::Initialized;
if (m_status != Status::Initialized) {
throw JException("Attempted to open a JEventSource that hasn't been initialized!");
}
CallWithJExceptionWrapper("JEventSource::Open", [&](){ Open();});
if (GetResourceName().empty()) {
LOG_INFO(GetLogger()) << "Opened JEventSource '" << GetTypeName() << "'" << LOG_END;
}
else {
LOG_INFO(GetLogger()) << "Opened JEventSource '" << GetTypeName() << "' ('" << GetResourceName() << "')" << LOG_END;
}
m_status = Status::Opened;
}
}

virtual void DoFinalize(bool with_lock=true) {
virtual void DoClose(bool with_lock=true) {
if (with_lock) {
std::lock_guard<std::mutex> lock(m_mutex);

if (m_status != JEventSource::Status::Opened) return;

CallWithJExceptionWrapper("JEventSource::Close", [&](){ Close();});
if (GetResourceName().empty()) {
LOG_INFO(GetLogger()) << "Closed event source" << LOG_END;
LOG_INFO(GetLogger()) << "Closed JEventSource '" << GetTypeName() << "'" << LOG_END;
}
else {
LOG_INFO(GetLogger()) << "Closed event source '" << GetResourceName() << "'" << LOG_END;
LOG_INFO(GetLogger()) << "Closed JEventSource '" << GetTypeName() << "' ('" << GetResourceName() << "')" << LOG_END;
}
m_status = Status::Finalized;
m_status = Status::Closed;
}
else {
if (m_status != JEventSource::Status::Opened) return;

CallWithJExceptionWrapper("JEventSource::Close", [&](){ Close();});
if (GetResourceName().empty()) {
LOG_INFO(GetLogger()) << "Closed event source" << LOG_END;
LOG_INFO(GetLogger()) << "Closed JEventSource '" << GetTypeName() << "'" << LOG_END;
}
else {
LOG_INFO(GetLogger()) << "Closed event source '" << GetResourceName() << "'" << LOG_END;
LOG_INFO(GetLogger()) << "Closed JEventSource '" << GetTypeName() << "' ('" << GetResourceName() << "')" << LOG_END;
}
m_status = Status::Finalized;
m_status = Status::Closed;
}
}

Result DoNext(std::shared_ptr<JEvent> event) {

std::lock_guard<std::mutex> lock(m_mutex); // In general, DoNext must be synchronized.

if (m_status == Status::Uninitialized) {
throw JException("JEventSource has not been initialized!");
}

if (m_callback_style == CallbackStyle::LegacyMode) {
return DoNextCompatibility(event);
}

auto first_evt_nr = m_nskip;
auto last_evt_nr = m_nevents + m_nskip;

if (m_status == Status::Uninitialized) {
DoInitialize(false);
}
if (m_status == Status::Initialized) {
DoOpen(false);
}
if (m_status == Status::Opened) {
if (m_nevents != 0 && (m_event_count == last_evt_nr)) {
// We exit early (and recycle) because we hit our jana:nevents limit
DoFinalize(false);
DoClose(false);
return Result::FailureFinished;
}
// If we reach this point, we will need to actually read an event
Expand Down Expand Up @@ -219,7 +243,7 @@ class JEventSource : public jana::omni::JComponent, public jana::omni::JHasOutpu
else if (result == Result::FailureFinished) {
// We end up here if we tried to read an entry in a file, but found EOF
// or if we received a message from a socket that contained no data and indicated no more data will be coming
DoFinalize(false);
DoClose(false);
return Result::FailureFinished;
}
else if (result == Result::FailureTryAgain) {
Expand All @@ -231,7 +255,7 @@ class JEventSource : public jana::omni::JComponent, public jana::omni::JHasOutpu
throw JException("Invalid JEventSource::Result value!");
}
}
else { // status == Finalized
else { // status == Closed
return Result::FailureFinished;
}
}
Expand All @@ -242,10 +266,10 @@ class JEventSource : public jana::omni::JComponent, public jana::omni::JHasOutpu
auto last_evt_nr = m_nevents + m_nskip;

try {
if (m_status == Status::Uninitialized) {
DoInitialize(false);
}
if (m_status == Status::Initialized) {
DoOpen(false);
}
if (m_status == Status::Opened) {
if (m_event_count < first_evt_nr) {
// Skip these events due to nskip
event->SetEventNumber(m_event_count); // Default event number to event count
Expand All @@ -258,7 +282,7 @@ class JEventSource : public jana::omni::JComponent, public jana::omni::JHasOutpu
return Result::FailureTryAgain; // Reject this event and recycle it
} else if (m_nevents != 0 && (m_event_count == last_evt_nr)) {
// Declare ourselves finished due to nevents
DoFinalize(false); // Close out the event source as soon as it declares itself finished
DoClose(false); // Close out the event source as soon as it declares itself finished
return Result::FailureFinished;
} else {
// Actually emit an event.
Expand All @@ -279,7 +303,7 @@ class JEventSource : public jana::omni::JComponent, public jana::omni::JHasOutpu
m_event_count += 1;
return Result::Success; // Don't reject this event!
}
} else if (m_status == Status::Finalized) {
} else if (m_status == Status::Closed) {
return Result::FailureFinished;
} else {
throw JException("Invalid m_status");
Expand All @@ -288,7 +312,7 @@ class JEventSource : public jana::omni::JComponent, public jana::omni::JHasOutpu
catch (RETURN_STATUS rs) {

if (rs == RETURN_STATUS::kNO_MORE_EVENTS) {
DoFinalize(false);
DoClose(false);
return Result::FailureFinished;
}
else if (rs == RETURN_STATUS::kTRY_AGAIN || rs == RETURN_STATUS::kBUSY) {
Expand Down
14 changes: 10 additions & 4 deletions src/libraries/JANA/JFactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@

void JFactory::Create(const std::shared_ptr<const JEvent>& event) {

// We need this for JMultifactoryHelper. Eventually it should go away
auto app = event->GetJApplication();
if (app != nullptr) SetApplication(app);

if (mStatus == Status::Uninitialized) {
CallWithJExceptionWrapper("JFactory::Init", [&](){ Init(); });
mStatus = Status::Unprocessed;
Expand Down Expand Up @@ -43,3 +39,13 @@ void JFactory::Create(const std::shared_ptr<const JEvent>& event) {
mCreationStatus = CreationStatus::Created;
}
}

void JFactory::DoInit() {
if (GetApplication() == nullptr) {
throw JException("JFactory::DoInit(): Null JApplication pointer");
}
if (mStatus == Status::Uninitialized) {
CallWithJExceptionWrapper("JFactory::Init", [&](){ Init(); });
mStatus = Status::Unprocessed;
}
}
7 changes: 5 additions & 2 deletions src/libraries/JANA/JFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,13 @@ class JFactory : public jana::omni::JComponent {
template<typename S>
std::vector<S*> GetAs();



/// Create() calls JFactory::Init,BeginRun,Process in an invariant-preserving way without knowing the exact
/// type of object contained. It returns the number of objects created. In order to access said objects,
/// use JFactory::GetAs().
/// type of object contained. In order to access these objects when all you have is a JFactory*, use JFactory::GetAs().
virtual void Create(const std::shared_ptr<const JEvent>& event);
void DoInit();


virtual void Set(const std::vector<JObject *> &data) = 0;
virtual void Insert(JObject *data) = 0;
Expand Down
11 changes: 11 additions & 0 deletions src/libraries/JANA/JFactorySet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ bool JFactorySet::Add(JMultifactory *multifactory) {

auto helpers = multifactory->GetHelpers();
for (auto fac : helpers->GetAllFactories()) {
fac->SetApplication(multifactory->GetApplication());
Add(fac);
}
helpers->mIsFactoryOwner = false;
Expand Down Expand Up @@ -142,6 +143,16 @@ std::vector<JFactory*> JFactorySet::GetAllFactories() const {
return results;
}

//---------------------------------
// GetAllMultifactories
//---------------------------------
std::vector<JMultifactory*> JFactorySet::GetAllMultifactories() const {
std::vector<JMultifactory*> results;
for (auto f : mMultifactories) {
results.push_back(f);
}
return results;
}

//---------------------------------
// Merge
Expand Down
1 change: 1 addition & 0 deletions src/libraries/JANA/JFactorySet.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class JFactorySet : public JResettable
JFactory* GetFactory(const std::string& object_name, const std::string& tag="") const;
template<typename T> JFactoryT<T>* GetFactory(const std::string& tag = "") const;
std::vector<JFactory*> GetAllFactories() const;
std::vector<JMultifactory*> GetAllMultifactories() const;
template<typename T> std::vector<JFactoryT<T>*> GetAllFactories() const;

std::vector<JFactorySummary> Summarize() const;
Expand Down
12 changes: 12 additions & 0 deletions src/libraries/JANA/JMultifactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,15 @@ JFactorySet* JMultifactory::GetHelpers() {
return &mHelpers;
}

void JMultifactory::DoInit() {

std::lock_guard<std::mutex> lock(m_mutex);
if (m_status == Status::Uninitialized) {
CallWithJExceptionWrapper("JMultifactory::Init", [&](){
Init();
});
m_status = Status::Initialized;
}
}


2 changes: 2 additions & 0 deletions src/libraries/JANA/JMultifactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ class JMultifactory : public jana::omni::JComponent,
#endif

/// CALLED BY JANA

void DoInit();

void Execute(const std::shared_ptr<const JEvent>&);
// Should this be execute or create? Who is tracking that this is called at most once per event?
Expand Down
2 changes: 1 addition & 1 deletion src/libraries/JANA/Omni/JComponentFwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace omni {


struct JComponent {
enum class Status { Uninitialized, Initialized, Finalized };
enum class Status { Uninitialized, Initialized, Opened, Closed, Finalized };
enum class CallbackStyle { LegacyMode, ExpertMode, DeclarativeMode };

struct ParameterBase;
Expand Down
9 changes: 8 additions & 1 deletion src/libraries/JANA/Services/JComponentManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void JComponentManager::Init() {
}
}

void JComponentManager::configure_components() {
void JComponentManager::preinitialize_components() {
for (auto* src : m_evt_srces) {
src->SetApplication(GetApplication());
src->SetLogger(m_logging->get_logger(src->GetLoggerName()));
Expand All @@ -69,6 +69,13 @@ void JComponentManager::configure_components() {
}
}

void JComponentManager::initialize_factories() {
JFactorySet dummy_fac_set(m_fac_gens);
for (auto* fac : dummy_fac_set.GetAllFactories()) {
fac->DoInit();
}
}

void JComponentManager::next_plugin(std::string plugin_name) {
// We defer resolving event sources until we have finished loading all plugins
m_current_plugin_name = plugin_name;
Expand Down
3 changes: 2 additions & 1 deletion src/libraries/JANA/Services/JComponentManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ class JComponentManager : public JService {
void add(JEventProcessor* processor);
void add(JEventUnfolder* unfolder);

void configure_components();
void preinitialize_components();
void resolve_event_sources();
void initialize_factories();
JEventSourceGenerator* resolve_user_event_source_generator() const;
JEventSourceGenerator* resolve_event_source(std::string source_name) const;

Expand Down
10 changes: 5 additions & 5 deletions src/libraries/JANA/Topology/JEventSourceArrow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,17 @@ void JEventSourceArrow::process(Event* event, bool& success, JArrowMetrics::Stat
}

void JEventSourceArrow::initialize() {
// Initialization of individual sources happens on-demand, in order to keep us from having lots of open files
// We initialize everything immediately, but don't open any resources until we absolutely have to; see process(): source->DoNext()
for (JEventSource* source : m_sources) {
source->DoInit();
}
}

void JEventSourceArrow::finalize() {
// Generally JEventSources finalize themselves as soon as they detect that they have run out of events.
// However, we can't rely on the JEventSources turning themselves off since execution can be externally paused.
// Instead we leave everything open until we finalize the whole topology, and finalize remaining event sources then.
for (JEventSource* source : m_sources) {
if (source->GetStatus() == JEventSource::Status::Initialized) {
LOG_INFO(m_logger) << "Finalizing JEventSource '" << source->GetTypeName() << "' (" << source->GetResourceName() << ")" << LOG_END;
source->DoFinalize();
}
source->DoClose();
}
}
Loading
Loading