From 120c8895dce695eaab642808110568a183229cbb Mon Sep 17 00:00:00 2001 From: Gordon McCann Date: Tue, 4 Jan 2022 11:31:49 -0500 Subject: [PATCH] Finally added working Compass offline data source. Proper synchronization of source access, creation, destruction --- Navigator/src/Navigator/Application.cpp | 20 ++--- Navigator/src/Navigator/Events/PhysicsEvent.h | 14 +++- .../src/Navigator/Physics/CompassRun.cpp | 72 +++++++++++++++++- Navigator/src/Navigator/Physics/CompassRun.h | 23 +++--- .../src/Navigator/Physics/DataSource.cpp | 25 ++++++ Navigator/src/Navigator/Physics/DataSource.h | 36 +++++++++ .../Navigator/Physics/PhysicsEventBuilder.cpp | 76 ++++++++++++++++--- .../Navigator/Physics/PhysicsEventBuilder.h | 7 +- 8 files changed, 232 insertions(+), 41 deletions(-) create mode 100644 Navigator/src/Navigator/Physics/DataSource.cpp create mode 100644 Navigator/src/Navigator/Physics/DataSource.h diff --git a/Navigator/src/Navigator/Application.cpp b/Navigator/src/Navigator/Application.cpp index fab7524..684ffda 100644 --- a/Navigator/src/Navigator/Application.cpp +++ b/Navigator/src/Navigator/Application.cpp @@ -24,12 +24,9 @@ namespace Navigator { Application::~Application() { - if(PhysicsEventBuilder::Get().IsRunning()) - { - NAV_INFO("Detaching PhysicsEventBuilder at shutdown"); - PhysicsEventBuilder::Get().DetachDataSource(); - DestroyPhysThread(); - } + NAV_INFO("Detaching PhysicsEventBuilder at shutdown"); + PhysicsEventBuilder::Get().DetachDataSource(); + DestroyPhysThread(); } void Application::DestroyPhysThread() @@ -70,9 +67,12 @@ namespace Navigator { NAV_INFO("Stopping the event builder..."); DestroyPhysThread(); } - PhysicsEventBuilder::Get().AttachDataSource(); - NAV_INFO("Starting the event builder..."); - m_physThread = new std::thread(&PhysicsEventBuilder::Run, std::ref(PhysicsEventBuilder::Get())); + PhysicsEventBuilder::Get().AttachDataSource(event.GetSourceLocation(), event.GetSourceType()); + if(PhysicsEventBuilder::Get().IsRunning()) + { + NAV_INFO("Starting the event builder..."); + m_physThread = new std::thread(&PhysicsEventBuilder::Run, std::ref(PhysicsEventBuilder::Get())); + } return true; } @@ -98,7 +98,7 @@ namespace Navigator { void Application::Run() { - PhysicsStartEvent junk; + PhysicsStartEvent junk("/media/gordon/GordonData/gwm17/NavTests/data/", DataSource::SourceType::CompassOffline); OnEvent(junk); while(m_runFlag) { diff --git a/Navigator/src/Navigator/Events/PhysicsEvent.h b/Navigator/src/Navigator/Events/PhysicsEvent.h index 52e4f0e..64a839c 100644 --- a/Navigator/src/Navigator/Events/PhysicsEvent.h +++ b/Navigator/src/Navigator/Events/PhysicsEvent.h @@ -2,21 +2,31 @@ #define PHYSICS_EVENT_H #include "Event.h" +#include "Navigator/Physics/DataSource.h" namespace Navigator { class PhysicsStartEvent : public Event { public: - PhysicsStartEvent() {} + PhysicsStartEvent(const std::string& loc, DataSource::SourceType type) : + m_sourceLocation(loc), m_sourceType(type) + {} + + inline std::string GetSourceLocation() { return m_sourceLocation; } + inline DataSource::SourceType GetSourceType() { return m_sourceType; } std::string ToString() const override { - return "Starting PhysicsEventBuilder"; + return "Starting PhysicsEventBuilder with DataSource of type {0} at location {1}" + m_sourceLocation + ConvertDataSourceTypeToString(m_sourceType); } EVENT_CATEGORY_SETUP(EventCategoryPhysics); EVENT_TYPE_SETUP(PhysicsStart); + + private: + std::string m_sourceLocation; + DataSource::SourceType m_sourceType; }; class PhysicsStopEvent : public Event diff --git a/Navigator/src/Navigator/Physics/CompassRun.cpp b/Navigator/src/Navigator/Physics/CompassRun.cpp index 8e51a7f..d6050a5 100644 --- a/Navigator/src/Navigator/Physics/CompassRun.cpp +++ b/Navigator/src/Navigator/Physics/CompassRun.cpp @@ -14,18 +14,65 @@ namespace Navigator { CompassRun::CompassRun() : - m_directory("") + DataSource(), m_directory("") { } CompassRun::CompassRun(const std::string& dir) : - m_directory(dir) + DataSource(), m_directory(dir) { - + CollectFiles(); } CompassRun::~CompassRun() {} + void CompassRun::CollectFiles() + { + int nfiles=0; + for(auto& item : std::filesystem::directory_iterator(m_directory)) + { + if(item.path().extension() == m_extension) + nfiles++; + } + + m_datafiles.clear(); + m_datafiles.reserve(nfiles); + for(auto& item : std::filesystem::directory_iterator(m_directory)) + { + if(item.path().extension() == m_extension) + { + m_datafiles.emplace_back(item.path().string()); + } + } + + long total_hits=0; + for(auto& file : m_datafiles) + { + + if(!file.IsOpen()) + { + NAV_ERROR("Unable to open file with name {0}", file.GetName()); + m_validFlag = false; + return; + } + + if(m_smap.IsValid()) + file.AttachShiftMap(&m_smap); + + total_hits += file.GetNumberOfHits(); + } + + if(m_datafiles.size() == 0) + { + NAV_WARN("Unable to find any files with extension {0} in directory {1}. CompassRun killed.", m_extension, m_directory); + m_validFlag = false; + } + else + { + NAV_INFO("Succesfully opened {0} files with {1} total hits", nfiles, total_hits); + m_validFlag = true; + } + } /* GetHitsFromFiles() is the function which actually retrieves and sorts the data from the individual files. There are several tricks which allow this to happen. First is that, after sorting, it is impossible @@ -62,9 +109,26 @@ namespace Navigator { if(earliestHit.second == nullptr) return false; //Make sure that there actually was a hit - hit = earliestHit.first; + m_hit = earliestHit.first; *earliestHit.second = true; return true; } + CompassHit CompassRun::GetData() + { + if(!IsValid()) + { + NAV_ERROR("Trying to access CompassRun data when invalid, bug detected!"); + return CompassHit(); + } + + if(GetHitsFromFiles()) + return m_hit; + else + { + m_validFlag = false; + return m_hit; + } + } + } \ No newline at end of file diff --git a/Navigator/src/Navigator/Physics/CompassRun.h b/Navigator/src/Navigator/Physics/CompassRun.h index adcae7b..71a349b 100644 --- a/Navigator/src/Navigator/Physics/CompassRun.h +++ b/Navigator/src/Navigator/Physics/CompassRun.h @@ -10,39 +10,38 @@ #ifndef COMPASSRUN_H #define COMPASSRUN_H +#include "DataSource.h" #include "CompassFile.h" #include "ShiftMap.h" +#include namespace Navigator { - class CompassRun + class CompassRun : public DataSource { public: CompassRun(); CompassRun(const std::string& dir); - ~CompassRun(); - inline void SetDirectory(const std::string& dir) { m_directory = dir; } - inline void SetRunNumber(int n) { m_runNum = n; } + virtual ~CompassRun(); + virtual CompassHit GetData() override; + inline void SetDirectory(const std::string& dir) { m_directory = dir; CollectFiles(); } inline void SetShiftMap(const std::string& filename) { m_smap.SetFile(filename); } private: + void CollectFiles(); bool GetHitsFromFiles(); - std::string m_directory; + std::filesystem::path m_directory; + const std::string m_extension = ".bin"; std::vector m_datafiles; unsigned int startIndex; //this is the file we start looking at; increases as we finish files. ShiftMap m_smap; + + CompassHit m_hit; - //Potential branch variables - CompassHit hit; - - //what run is this - int m_runNum; unsigned int m_totalHits; - - //Scaler switch }; } diff --git a/Navigator/src/Navigator/Physics/DataSource.cpp b/Navigator/src/Navigator/Physics/DataSource.cpp new file mode 100644 index 0000000..16b4bb9 --- /dev/null +++ b/Navigator/src/Navigator/Physics/DataSource.cpp @@ -0,0 +1,25 @@ +#include "DataSource.h" +#include "CompassRun.h" + +namespace Navigator { + + DataSource* CreateDataSource(const std::string& loc, DataSource::SourceType type) + { + switch(type) + { + case DataSource::SourceType::CompassOffline : return new CompassRun(loc); + case DataSource::SourceType::CompassOnline : return nullptr; + case DataSource::SourceType::None : return nullptr; + } + } + + std::string ConvertDataSourceTypeToString(DataSource::SourceType type) + { + switch(type) + { + case DataSource::SourceType::None: return "None"; + case DataSource::SourceType::CompassOnline : return "CompassOnline"; + case DataSource::SourceType::CompassOffline : return "CompassOffline"; + } + } +} \ No newline at end of file diff --git a/Navigator/src/Navigator/Physics/DataSource.h b/Navigator/src/Navigator/Physics/DataSource.h new file mode 100644 index 0000000..084aac8 --- /dev/null +++ b/Navigator/src/Navigator/Physics/DataSource.h @@ -0,0 +1,36 @@ +#ifndef DATA_SOURCE_H +#define DATA_SOURCE_H + +#include "CompassHit.h" + +namespace Navigator { + + class DataSource + { + public: + enum class SourceType + { + None, + CompassOnline, + CompassOffline + }; + + DataSource() : + m_validFlag(false) + { + } + + virtual ~DataSource() {}; + virtual CompassHit GetData() = 0; + inline bool IsValid() { return m_validFlag; } + + protected: + bool m_validFlag; + }; + + DataSource* CreateDataSource(const std::string& loc, DataSource::SourceType type); + + std::string ConvertDataSourceTypeToString(DataSource::SourceType type); +} + +#endif \ No newline at end of file diff --git a/Navigator/src/Navigator/Physics/PhysicsEventBuilder.cpp b/Navigator/src/Navigator/Physics/PhysicsEventBuilder.cpp index df23dae..912e554 100644 --- a/Navigator/src/Navigator/Physics/PhysicsEventBuilder.cpp +++ b/Navigator/src/Navigator/Physics/PhysicsEventBuilder.cpp @@ -3,12 +3,14 @@ //temp #include "CompassHit.h" +//GWM Jan. 3 2021 -- Make DataSource to unique ptr + namespace Navigator { PhysicsEventBuilder* PhysicsEventBuilder::s_instance = nullptr; PhysicsEventBuilder::PhysicsEventBuilder() : - m_runFlag(false) + m_runFlag(false), m_source(nullptr) { if(s_instance != nullptr) { @@ -18,16 +20,37 @@ namespace Navigator { s_instance = this; } - PhysicsEventBuilder::~PhysicsEventBuilder() {} - - void PhysicsEventBuilder::AttachDataSource() + PhysicsEventBuilder::~PhysicsEventBuilder() { - m_runFlag = true; + } + + void PhysicsEventBuilder::AttachDataSource(const std::string& loc, DataSource::SourceType type) + { + std::lock_guard lock(m_sourceLock); //Auto free lock at end of scope + NAV_INFO("Attempting to attach phyiscs data source at location {0}", loc); + + m_runFlag = false; + + m_source.reset(CreateDataSource(loc, type)); + if(m_source->IsValid()) + { + NAV_INFO("Attach successful. Enabling data pull..."); + m_runFlag = true; + } + else + { + NAV_ERROR("DataSource attach failed... check for error conditions."); + m_source.reset(nullptr); + } } void PhysicsEventBuilder::DetachDataSource() { + std::lock_guard lock(m_sourceLock); + NAV_INFO("Detaching physics data source..."); m_runFlag = false; + m_source.reset(nullptr); + NAV_INFO("Detach successful"); } void PhysicsEventBuilder::PushStage(AnalysisStage* stage) @@ -38,27 +61,56 @@ namespace Navigator { void PhysicsEventBuilder::Run() { if(!m_runFlag) - NAV_WARN("Trying to Run PhysicsEventBuilder without a Data Source, nothing will happen!"); + { + NAV_WARN("Trying to Run PhysicsEventBuilder without a Data Source, killing thread!"); + } + + CompassHit hit; + //temp - CompassHit hit; - m_rawSort.SetCoincidenceWindow(2); + m_rawSort.SetCoincidenceWindow(2000000); while(m_runFlag) { + + //small scope for locking access to the data source + { + std::lock_guard lock(m_sourceLock); + if(m_source == nullptr) // safety for stop occuring while running + { + continue; + } + else if(m_source->IsValid()) + { + hit = m_source->GetData(); + } + + /* + Looks funny, but two conditions lead to !IsValid(). Either source prev. shutdown, + OR we reached end of source, indicated after prev. data grab + */ + if(!m_source->IsValid()) + { + NAV_INFO("End of data source."); + m_runFlag = false; + continue; + } + } + //NAV_INFO("Doing a physics"); - hit.timestamp++; if(m_rawSort.IsHitInWindow(hit)) { - NAV_INFO("Adding hit to event..."); + //NAV_INFO("Adding hit to event with timestamp {0}", hit.timestamp); m_rawSort.AddHit(hit); } else { - NAV_INFO("Obtaining built event..."); + //NAV_INFO("Obtaining built event..."); auto event = m_rawSort.GetRawPhysicsEvent(); - NAV_INFO("Built event size: {0}", event.size()); + //NAV_INFO("Built event size: {0}", event.size()); m_rawSort.ClearRawPhysicsEvent(); } + } } diff --git a/Navigator/src/Navigator/Physics/PhysicsEventBuilder.h b/Navigator/src/Navigator/Physics/PhysicsEventBuilder.h index 7fde135..63c5065 100644 --- a/Navigator/src/Navigator/Physics/PhysicsEventBuilder.h +++ b/Navigator/src/Navigator/Physics/PhysicsEventBuilder.h @@ -5,6 +5,7 @@ #include "AnalysisStack.h" #include "AnalysisStage.h" #include "PhysicsHitSort.h" +#include "DataSource.h" #include #include @@ -18,7 +19,7 @@ namespace Navigator { void Run(); - void AttachDataSource(); + void AttachDataSource(const std::string& loc, DataSource::SourceType type); void DetachDataSource(); void SetCoincidenceWindow(uint64_t window) { m_rawSort.SetCoincidenceWindow(window); } @@ -33,6 +34,10 @@ namespace Navigator { static PhysicsEventBuilder* s_instance; PhysicsHitSort m_rawSort; + std::mutex m_sourceLock; + + std::unique_ptr m_source; + }; PhysicsEventBuilder* CreatePhysicsEventBuilder();