From 24df93a0f7ba15136398d8f6e225f96aeaa134ba Mon Sep 17 00:00:00 2001 From: gwm17 Date: Thu, 14 Jul 2022 16:31:09 -0400 Subject: [PATCH] Big update. Implement EVBWorkspace to handle cross-platform directory detection and creation as needed. Remove ugly system calls where possible. Remove extraneous include of pch. Note that std::filesystem clashes with ROOT GUI libs. --- etc/ScalerFile_Feb2021_SABRE.txt | 3 +- src/evb/CMakeLists.txt | 3 + src/evb/CompassFile.cpp | 1 - src/evb/CompassRun.cpp | 72 +++++------- src/evb/CompassRun.h | 24 ++-- src/evb/EVBApp.cpp | 170 +++++++++++++-------------- src/evb/EVBApp.h | 32 +----- src/evb/EVBParameters.h | 20 ++++ src/evb/EVBWorkspace.cpp | 192 +++++++++++++++++++++++++++++++ src/evb/EVBWorkspace.h | 45 ++++++++ src/evb/FlagHandler.cpp | 1 - src/evb/Logger.cpp | 1 - src/evb/OrderChecker.cpp | 1 - src/evb/ShiftMap.cpp | 1 - src/evb/SlowSort.cpp | 1 - src/evb/Stopwatch.cpp | 1 - src/guidict/EVBMainFrame.cpp | 78 ++++++------- src/guidict/EVBMainFrame.h | 6 +- 18 files changed, 429 insertions(+), 223 deletions(-) create mode 100644 src/evb/EVBParameters.h create mode 100644 src/evb/EVBWorkspace.cpp create mode 100644 src/evb/EVBWorkspace.h diff --git a/etc/ScalerFile_Feb2021_SABRE.txt b/etc/ScalerFile_Feb2021_SABRE.txt index 89eeee6..b567ac3 100644 --- a/etc/ScalerFile_Feb2021_SABRE.txt +++ b/etc/ScalerFile_Feb2021_SABRE.txt @@ -1,5 +1,4 @@ Format: scaler_param_name assoc_binary_file_name_without_runID NOTE: As of this version, scalers are pure counting parameters (the total events will be counted and saved as a TParameter with the data) -CH0@V1730_89_Data t1 -CH1@V1730_89_Data t2 +Data_CH5@V1730_89 beamint diff --git a/src/evb/CMakeLists.txt b/src/evb/CMakeLists.txt index 78386dc..3505c74 100644 --- a/src/evb/CMakeLists.txt +++ b/src/evb/CMakeLists.txt @@ -28,6 +28,9 @@ target_sources(EventBuilderCore PRIVATE SlowSort.cpp CompassRun.cpp SlowSort.h + EVBParameters.h + EVBWorkspace.h + EVBWorkspace.cpp ) target_link_libraries(EventBuilderCore PUBLIC diff --git a/src/evb/CompassFile.cpp b/src/evb/CompassFile.cpp index 622682e..78b9ce3 100644 --- a/src/evb/CompassFile.cpp +++ b/src/evb/CompassFile.cpp @@ -8,7 +8,6 @@ Written by G.W. McCann Oct. 2020 */ -#include "EventBuilder.h" #include "CompassFile.h" namespace EventBuilder { diff --git a/src/evb/CompassRun.cpp b/src/evb/CompassRun.cpp index 41c912d..df462be 100644 --- a/src/evb/CompassRun.cpp +++ b/src/evb/CompassRun.cpp @@ -9,24 +9,16 @@ Updated to also handle scaler data. -- GWM Oct. 2020 */ -#include "EventBuilder.h" #include "CompassRun.h" -#include "RunCollector.h" #include "SlowSort.h" #include "FlagHandler.h" namespace EventBuilder { - - CompassRun::CompassRun() : - directory(""), m_scalerinput(""), runNum(0), m_buffersize(200000), m_scaler_flag(false) + + CompassRun::CompassRun(const EVBParameters& params, const std::shared_ptr& workspace) : + m_params(params), m_workspace(workspace), m_runNum(0), m_scaler_flag(false) { - - } - - CompassRun::CompassRun(const std::string& dir, size_t bsize) : - directory(dir), m_scalerinput(""), runNum(0), m_buffersize(bsize), m_scaler_flag(false) - { - + m_smap.SetFile(m_params.timeShiftFile); } CompassRun::~CompassRun() {} @@ -35,7 +27,7 @@ namespace EventBuilder { /*Load em into a map*/ void CompassRun::SetScalers() { - std::ifstream input(m_scalerinput); + std::ifstream input(m_params.scalerFile); if(!input.is_open()) return; m_scaler_flag = true; @@ -47,7 +39,7 @@ namespace EventBuilder { while(input>>filename) { input>>varname; - filename = directory+filename+"_run_"+std::to_string(runNum)+".BIN"; + filename = m_workspace->GetTempDir()+filename+"_run_"+std::to_string(m_runNum)+".BIN"; m_scaler_map[filename] = TParameter(varname.c_str(), init); } input.close(); @@ -55,17 +47,14 @@ namespace EventBuilder { bool CompassRun::GetBinaryFiles() { - std::string prefix = ""; - std::string suffix = ".BIN"; //binaries - RunCollector grabber(directory, prefix, suffix); - grabber.GrabAllFiles(); - + auto files = m_workspace->GetTempFiles(); + m_datafiles.clear(); //so that the CompassRun can be reused - m_datafiles.reserve(grabber.GetFileList().size()); + m_datafiles.reserve(files.size()); //To avoid move semantics use reserve. Moving std::ifstream is dangerous bool scalerd; m_totalHits = 0; //reset total run size - for(auto& entry : grabber.GetFileList()) + for(auto& entry : files) { //Handle scaler files, if they exist if(m_scaler_flag) @@ -83,7 +72,7 @@ namespace EventBuilder { if(scalerd) continue; } - m_datafiles.emplace_back(entry, m_buffersize); + m_datafiles.emplace_back(entry, m_params.bufferSize); m_datafiles[m_datafiles.size()-1].AttachShiftMap(&m_smap); //Any time we have a file that fails to be found, we terminate the whole process if(!m_datafiles[m_datafiles.size() - 1].IsOpen()) @@ -130,18 +119,18 @@ namespace EventBuilder { { std::pair earliestHit = std::make_pair(CompassHit(), nullptr); - for(unsigned int i=startIndex; iBranch("Board", &hit.board); - outtree->Branch("Channel", &hit.channel); - outtree->Branch("Energy", &hit.energy); - outtree->Branch("EnergyShort", &hit.energyShort); - outtree->Branch("EnergyCal", &hit.energyCalibrated); - outtree->Branch("Timestamp", &hit.timestamp); - outtree->Branch("Flags", &hit.flags); - outtree->Branch("Ns", &hit.Ns); - outtree->Branch("Samples", &hit.samples); + outtree->Branch("Board", &m_hit.board); + outtree->Branch("Channel", &m_hit.channel); + outtree->Branch("Energy", &m_hit.energy); + outtree->Branch("EnergyShort", &m_hit.energyShort); + outtree->Branch("EnergyCal", &m_hit.energyCalibrated); + outtree->Branch("Timestamp", &m_hit.timestamp); + outtree->Branch("Flags", &m_hit.flags); + outtree->Branch("Ns", &m_hit.Ns); + outtree->Branch("Samples", &m_hit.samples); if(!m_smap.IsSet()) { @@ -187,7 +176,7 @@ namespace EventBuilder { return; } - startIndex = 0; //Reset the startIndex + m_startIndex = 0; //Reset the startIndex unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0; if(flush == 0) @@ -215,10 +204,11 @@ namespace EventBuilder { output->Close(); } - void CompassRun::Convert2SortedRoot(const std::string& name, double window) { + void CompassRun::Convert2SortedRoot(const std::string& name) { TFile* output = TFile::Open(name.c_str(), "RECREATE"); TTree* outtree = new TTree("SortTree", "SortTree"); + std::vector event; outtree->Branch("event", &event); if(!m_smap.IsSet()) @@ -235,8 +225,8 @@ namespace EventBuilder { } - startIndex = 0; - SlowSort coincidizer(window); + m_startIndex = 0; + SlowSort coincidizer(m_params.slowCoincidenceWindow); bool killFlag = false; uint64_t count = 0, flush = m_totalHits*0.01, flush_count = 0; @@ -259,7 +249,7 @@ namespace EventBuilder { killFlag = true; } else - coincidizer.AddHitToEvent(hit); + coincidizer.AddHitToEvent(m_hit); if(coincidizer.IsEventReady()) { diff --git a/src/evb/CompassRun.h b/src/evb/CompassRun.h index a679365..c5be11e 100644 --- a/src/evb/CompassRun.h +++ b/src/evb/CompassRun.h @@ -10,9 +10,10 @@ #ifndef COMPASSRUN_H #define COMPASSRUN_H +#include "EVBParameters.h" +#include "EVBWorkspace.h" #include "CompassFile.h" #include "DataStructs.h" -#include "RunCollector.h" #include "ShiftMap.h" #include "ProgressCallback.h" #include @@ -22,15 +23,11 @@ namespace EventBuilder { class CompassRun { public: - CompassRun(); - CompassRun(const std::string& dir, size_t bsize); + CompassRun(const EVBParameters& params, const std::shared_ptr& workspace); ~CompassRun(); - inline void SetDirectory(const std::string& dir) { directory = dir; } - inline void SetScalerInput(const std::string& filename) { m_scalerinput = filename; } - inline void SetRunNumber(int n) { runNum = n; }; - inline void SetShiftMap(const std::string& filename) { m_smap.SetFile(filename); } + inline void SetRunNumber(int n) { m_runNum = n; }; void Convert2RawRoot(const std::string& name); - void Convert2SortedRoot(const std::string& name, double window); + void Convert2SortedRoot(const std::string& name); inline void SetProgressCallbackFunc(ProgressCallbackFunc& func) { m_progressCallback = func; } inline void SetProgressFraction(double frac) { m_progressFraction = frac; } @@ -41,20 +38,19 @@ namespace EventBuilder { void SetScalers(); void ReadScalerData(const std::string& filename); - std::string directory, m_scalerinput; + EVBParameters m_params; + std::shared_ptr m_workspace; std::vector m_datafiles; - unsigned int startIndex; //this is the file we start looking at; increases as we finish files. + unsigned int m_startIndex; //this is the file we start looking at; increases as we finish files. ShiftMap m_smap; std::unordered_map> m_scaler_map; //maps scaler files to the TParameter to be saved //Potential branch variables - CompassHit hit; - std::vector event; + CompassHit m_hit; //what run is this - int runNum; + int m_runNum; uint64_t m_totalHits; - uint64_t m_buffersize; //Scaler switch bool m_scaler_flag; diff --git a/src/evb/EVBApp.cpp b/src/evb/EVBApp.cpp index 2a8188b..37c0077 100644 --- a/src/evb/EVBApp.cpp +++ b/src/evb/EVBApp.cpp @@ -6,20 +6,19 @@ Written by G.W. McCann Oct. 2020 */ -#include "EventBuilder.h" -#include #include "EVBApp.h" -#include "RunCollector.h" #include "CompassRun.h" #include "SlowSort.h" namespace EventBuilder { EVBApp::EVBApp() : - m_rmin(0), m_rmax(0), - m_progressFraction(0.1), m_workspace("none"), m_shiftfile("none"), - m_scalerfile("none"), m_buffersize(200000), m_SlowWindow(0) + m_workspace(nullptr), m_progressFraction(0.1) { + if(EnforceDictonaryLinked()) //Avoid symbol stripping + { + EVB_INFO("Dictionary loaded"); + } SetProgressCallbackFunc(BIND_PROGRESS_CALLBACK_FUNCTION(EVBApp::DefaultProgressCallback)); } @@ -33,6 +32,18 @@ namespace EventBuilder { EVB_INFO("Percent of run built: {0}", fraction*100); } + void EVBApp::SetParameters(const EVBParameters& params) + { + if(m_params.workspaceDir != params.workspaceDir) + { + m_workspace.reset(new EVBWorkspace(params.workspaceDir)); + if(!m_workspace->IsValid()) + EVB_ERROR("Unable to process new parameters due to bad workspace"); + } + + m_params = params; + } + bool EVBApp::ReadConfigFile(const std::string& fullpath) { EVB_INFO("Reading in EVB configuration from file {0}...", fullpath); @@ -45,22 +56,22 @@ namespace EventBuilder { std::string junk; std::getline(input, junk); - input>>junk>>m_workspace; + input>>junk>>m_params.workspaceDir; input>>junk; std::getline(input, junk); std::getline(input, junk); - input>>junk>>m_scalerfile; + input>>junk>>m_params.scalerFile; input>>junk; std::getline(input, junk); std::getline(input, junk); - input>>junk>>m_shiftfile; - input>>junk>>m_SlowWindow; + input>>junk>>m_params.timeShiftFile; + input>>junk>>m_params.slowCoincidenceWindow; input>>junk; std::getline(input, junk); std::getline(input, junk); - input>>junk>>m_rmin; - input>>junk>>m_rmax; - input>>junk>>m_buffersize; + input>>junk>>m_params.runMin; + input>>junk>>m_params.runMax; + input>>junk>>m_params.bufferSize; input.close(); @@ -81,19 +92,19 @@ namespace EventBuilder { } output<<"-------Data Location----------"<IsValid()) + { + EVB_ERROR("Unable to perform operation due to bad workspace."); + return; + } + + std::string rawroot_dir = m_workspace->GetSortedDir(); + EVB_INFO("Converting binary archives to ROOT files over run range [{0}, {1}]", m_params.runMin, m_params.runMax); - grabber.SetSearchParams(binary_dir, "", ".tar.gz",0,1000); + std::string rawfile; - std::string rawfile, binfile; - std::string unpack_command, wipe_command; - - CompassRun converter(unpack_dir, m_buffersize); - converter.SetShiftMap(m_shiftfile); - converter.SetScalerInput(m_scalerfile); + CompassRun converter(m_params, m_workspace); converter.SetProgressCallbackFunc(m_progressCallback); converter.SetProgressFraction(m_progressFraction); - int result; + int count = 0; EVB_INFO("Beginning conversion..."); - for(int i=m_rmin; i<=m_rmax; i++) + for(int i=m_params.runMin; i<=m_params.runMax; i++) { - binfile = grabber.GrabFile(i); - if(binfile == "") - continue; - converter.SetRunNumber(i); - EVB_INFO("Converting file {0}...", binfile); rawfile = rawroot_dir + "compass_run_"+ std::to_string(i) + ".root"; - unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir; - wipe_command = "rm -r "+unpack_dir+"*.BIN"; - - result = system(unpack_command.c_str()); - converter.Convert2RawRoot(rawfile); - result = system(wipe_command.c_str()); - + EVB_INFO("Converting file {0}...", rawfile); + m_workspace->ClearTempDirectory(); + if(m_workspace->UnpackBinaryRunToTemp(i)) + { + converter.SetRunNumber(i); + converter.Convert2RawRoot(rawfile); + ++count; + } + m_workspace->ClearTempDirectory(); } - EVB_INFO("Conversion complete."); + if(count != 0) + EVB_INFO("Conversion complete."); + else + EVB_WARN("Nothing converted, no files found in the range [{0}, {1}]", m_params.runMin, m_params.runMax); } void EVBApp::MergeROOTFiles() { - std::string merge_file = m_workspace+"/merged/run_"+std::to_string(m_rmin)+"_"+std::to_string(m_rmax)+".root"; - std::string file_dir = m_workspace+"/analyzed/"; - EVB_INFO("Merging ROOT files into single file for runs in range [{0}, {1}]", m_rmin, m_rmax); + if(m_workspace == nullptr || !m_workspace->IsValid()) + { + EVB_ERROR("Unable to perform operation due to bad workspace."); + return; + } + + std::string merge_file = m_workspace->GetMergedDir() + "run_" + std::to_string(m_params.runMin)+"_"+std::to_string(m_params.runMax)+".root"; + EVB_INFO("Merging ROOT files into single file for runs in range [{0}, {1}]", m_params.runMin, m_params.runMax); EVB_INFO("Merged file will be named {0}", merge_file); - std::string prefix = ""; - std::string suffix = ".root"; - grabber.SetSearchParams(file_dir, prefix, suffix,m_rmin,m_rmax); EVB_INFO("Starting merge..."); - if(!grabber.Merge_TChain(merge_file)) + if(!m_workspace->MergeBuiltFiles(merge_file, m_params.runMin, m_params.runMax)) { EVB_ERROR("Unable to find files for merge at EVBApp::MergeROOTFiles()!"); return; @@ -162,19 +174,18 @@ namespace EventBuilder { void EVBApp::Convert2SortedRoot() { - std::string sortroot_dir = m_workspace+"/sorted/"; - std::string unpack_dir = m_workspace+"/temp_binary/"; - std::string binary_dir = m_workspace+"/raw_binary/"; - EVB_INFO("Converting binary archives to event built ROOT files over run range [{0}, {1}]",m_rmin,m_rmax); + if(m_workspace == nullptr || !m_workspace->IsValid()) + { + EVB_ERROR("Unable to perform operation due to bad workspace."); + return; + } + + std::string sortroot_dir = m_workspace->GetBuiltDir(); + EVB_INFO("Converting binary archives to event built ROOT files over run range [{0}, {1}]", m_params.runMin, m_params.runMax); - grabber.SetSearchParams(binary_dir,"",".tar.gz",m_rmin,m_rmax); + std::string sortfile; - std::string sortfile, binfile; - std::string unpack_command, wipe_command; - - CompassRun converter(unpack_dir, m_buffersize); - converter.SetShiftMap(m_shiftfile); - converter.SetScalerInput(m_scalerfile); + CompassRun converter(m_params, m_workspace); converter.SetProgressCallbackFunc(m_progressCallback); converter.SetProgressFraction(m_progressFraction); @@ -182,22 +193,20 @@ namespace EventBuilder { EVB_INFO("Beginning conversion..."); int count=0; - for(int i=m_rmin; i<= m_rmax; i++) + for(int i=m_params.runMin; i<= m_params.runMax; i++) { - binfile = grabber.GrabFile(i); - if(binfile == "") - continue; - converter.SetRunNumber(i); - EVB_INFO("Converting file {0}...",binfile); sortfile = sortroot_dir +"run_"+std::to_string(i)+ ".root"; - unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir; - wipe_command = "rm -r "+unpack_dir+"*.BIN"; - - result = system(unpack_command.c_str()); - converter.Convert2SortedRoot(sortfile, m_SlowWindow); - result = system(wipe_command.c_str()); - count++; + EVB_INFO("Converting file {0}...", sortfile); + + m_workspace->ClearTempDirectory(); + if(m_workspace->UnpackBinaryRunToTemp(i)) + { + converter.SetRunNumber(i); + converter.Convert2SortedRoot(sortfile); + count++; + } + m_workspace->ClearTempDirectory(); } if(count==0) EVB_WARN("Conversion failed, no archives were found!"); @@ -205,11 +214,4 @@ namespace EventBuilder { EVB_INFO("Conversion complete."); } - void EVBApp::SetRunRange(int rmin, int rmax) { EVB_TRACE("Min Run, max run set to [{0}, {1}]", rmin, rmax); m_rmin = rmin; m_rmax = rmax; } - void EVBApp::SetWorkDirectory(const std::string& fullpath) { EVB_TRACE("Workspace set to {0}", fullpath); m_workspace = fullpath; } - void EVBApp::SetBoardShiftFile(const std::string& name) { EVB_TRACE("Shift file set to {0}", name); m_shiftfile = name; } - void EVBApp::SetSlowCoincidenceWindow(double window) { EVB_TRACE("Slow Coincidence Window set to {0}",window); m_SlowWindow = window; } - void EVBApp::SetScalerFile(const std::string& fullpath) { EVB_TRACE("Scaler file set to {0}", fullpath); m_scalerfile = fullpath; } - void EVBApp::SetBufferSize(uint64_t bufsize) { EVB_TRACE("Buffer size set to {0} hits", bufsize); m_buffersize = bufsize; } - } diff --git a/src/evb/EVBApp.h b/src/evb/EVBApp.h index 66b7a6c..4245e95 100644 --- a/src/evb/EVBApp.h +++ b/src/evb/EVBApp.h @@ -9,7 +9,8 @@ #ifndef EVBAPP_H #define EVBAPP_H -#include "RunCollector.h" +#include "EVBParameters.h" +#include "EVBWorkspace.h" #include "ProgressCallback.h" namespace EventBuilder { @@ -28,20 +29,8 @@ namespace EventBuilder { void Convert2SortedRoot(); void Convert2RawRoot(); - void SetRunRange(int rmin, int rmax); - void SetWorkDirectory(const std::string& dir); - void SetChannelMap(const std::string& name); - void SetBoardShiftFile(const std::string& name); - void SetSlowCoincidenceWindow(double window); - void SetScalerFile(const std::string& fullpath); - void SetBufferSize(uint64_t bufsize); - - inline int GetRunMin() const { return m_rmin; } - inline int GetRunMax() const { return m_rmax; } - inline std::string GetWorkDirectory() const { return m_workspace; } - inline double GetSlowCoincidenceWindow() const { return m_SlowWindow; } - inline std::string GetBoardShiftFile() const { return m_shiftfile; } - inline std::string GetScalerFile() const { return m_scalerfile; } + void SetParameters(const EVBParameters& params); + inline const EVBParameters& GetParameters() { return m_params; } void DefaultProgressCallback(int64_t curVal, int64_t totalVal); inline void SetProgressCallbackFunc(const ProgressCallbackFunc& function) { m_progressCallback = function; } @@ -55,19 +44,10 @@ namespace EventBuilder { }; private: - - int m_rmin, m_rmax; double m_progressFraction; + EVBParameters m_params; + std::shared_ptr m_workspace; - std::string m_workspace; - std::string m_shiftfile; - std::string m_scalerfile; - - uint64_t m_buffersize; - double m_SlowWindow; - - RunCollector grabber; - ProgressCallbackFunc m_progressCallback; }; diff --git a/src/evb/EVBParameters.h b/src/evb/EVBParameters.h new file mode 100644 index 0000000..8d22df3 --- /dev/null +++ b/src/evb/EVBParameters.h @@ -0,0 +1,20 @@ +#ifndef EVB_PARAMETERS_H +#define EVB_PARAMETERS_H + +namespace EventBuilder { + + struct EVBParameters + { + std::string workspaceDir = ""; + std::string timeShiftFile = ""; + std::string scalerFile = ""; + + int runMin = 0; + int runMax = 0; + + double slowCoincidenceWindow = 3.0e6; + size_t bufferSize = 2000; + }; +} + +#endif \ No newline at end of file diff --git a/src/evb/EVBWorkspace.cpp b/src/evb/EVBWorkspace.cpp new file mode 100644 index 0000000..7e278a7 --- /dev/null +++ b/src/evb/EVBWorkspace.cpp @@ -0,0 +1,192 @@ +#include "EVBWorkspace.h" +#include +#include +#include + +namespace EventBuilder { + + static bool CheckSubDirectory(const std::string& path) + { + bool status = true; + EVB_TRACE("Checking subdirectory {0}", path); + if(!std::filesystem::exists(path)) + { + status = std::filesystem::create_directory(path); + if(!status) + { + EVB_ERROR("Unable to create subdirectory {0}. Please check the pathing.", path); + return status; + } + EVB_INFO("Created subdirectory {0}", path); + } + else + EVB_INFO("Found subdirectory {0}", path); + return status; + } + + EVBWorkspace::EVBWorkspace(const std::string& workspace) : + m_isValid(false), m_workspace(workspace) + { + Init(); + } + + EVBWorkspace::~EVBWorkspace() {} + + void EVBWorkspace::Init() + { + m_isValid = true; + if(!std::filesystem::exists(m_workspace)) + { + EVB_TRACE("Workspace {0} does not exist. Attempting to create the workspace directory...", m_workspace); + m_isValid = std::filesystem::create_directory(m_workspace); + if(!m_isValid) + { + EVB_ERROR("Unable to create workspace {0}. Please check the pathing.", m_workspace); + return; + } + EVB_INFO("Created workspace directory {0}.", m_workspace); + } + else + EVB_INFO("Found workspace directory {0}.", m_workspace); + + EVB_TRACE("Looking for required workspace subdirectories..."); + + m_binaryDir = m_workspace + "raw_binary/"; + m_tempDir = m_workspace + "temp_binary/"; + m_sortedDir = m_workspace + "sorted/"; + m_builtDir = m_workspace + "built/"; + + //Check all subdirectories. Terminate if any of them are bad + m_isValid = CheckSubDirectory(m_binaryDir); + if(!m_isValid) + return; + m_isValid = CheckSubDirectory(m_tempDir); + if(!m_isValid) + return; + m_isValid = CheckSubDirectory(m_sortedDir); + if(!m_isValid) + return; + m_isValid = CheckSubDirectory(m_builtDir); + } + + std::string EVBWorkspace::GetBinaryRun(int run) + { + std::string file; + std::string runID = "run_" + std::to_string(run) + ".tar.gz"; + for(auto& entry : std::filesystem::directory_iterator(m_binaryDir)) + { + if(entry.is_regular_file() && entry.path().filename().string() == runID) + { + return entry.path().string(); + } + } + return ""; + } + + std::string EVBWorkspace::GetBuiltRun(int run) + { + std::string file; + std::string runID = "run_" + std::to_string(run) + ".root"; + for(auto& entry : std::filesystem::directory_iterator(m_builtDir)) + { + if(entry.is_regular_file() && entry.path().filename().string() == runID) + { + return entry.path().string(); + } + } + return ""; + } + + std::vector EVBWorkspace::GetBinaryRunRange(int runMin, int runMax) + { + std::vector list; + std::string temp; + for(int run=runMin; run<=runMax; run++) + temp = GetBinaryRun(run); + if(!temp.empty()) + list.push_back(temp); + + return list; + } + + std::vector EVBWorkspace::GetBuiltRunRange(int runMin, int runMax) + { + std::vector list; + std::string temp; + for(int run=runMin; run<=runMax; run++) + temp = GetBuiltRun(run); + if(!temp.empty()) + list.push_back(temp); + + return list; + } + + bool EVBWorkspace::UnpackBinaryRunToTemp(int run) + { + std::string runfile = GetBinaryRun(run); + std::string unpack_command = "tar -xzf "+runfile+" --directory "+m_tempDir; + int sys_return = system(unpack_command.c_str()); + if(sys_return == 0) + return true; + else + return false; + } + + std::vector EVBWorkspace::GetTempFiles() + { + std::vector list; + for(auto& entry : std::filesystem::directory_iterator(m_tempDir)) + { + if(entry.is_regular_file() && entry.path().filename().extension().string() == ".BIN") + list.push_back(entry.path().string()); + } + + return list; + } + + bool EVBWorkspace::ClearTempDirectory() + { + std::vector files; + for(auto& entry : std::filesystem::directory_iterator(m_tempDir)) + { + if(entry.is_regular_file()) + files.push_back(entry.path()); + else + EVB_WARN("Detected non-file element in temp directory {0} named {1}", m_tempDir, entry.path().string()); + } + + for(size_t i=0; iIsOpen()) + { + EVB_ERROR("Could not open output file {0} for merge", outputname); + output->Close(); + return false; + } + + TChain* chain = new TChain("SortTree", "SortTree"); + for(auto& entry : files) + chain->Add(entry.c_str()); + chain->Merge(output, 0, "fast"); + output->Close(); + return true; + } +} \ No newline at end of file diff --git a/src/evb/EVBWorkspace.h b/src/evb/EVBWorkspace.h new file mode 100644 index 0000000..988555e --- /dev/null +++ b/src/evb/EVBWorkspace.h @@ -0,0 +1,45 @@ +#ifndef EVB_WORKSPACE_H +#define EVB_WORKSPACE_H + +namespace EventBuilder { + + class EVBWorkspace + { + public: + EVBWorkspace(const std::string& workspace); + ~EVBWorkspace(); + + inline const bool IsValid() const { return m_isValid; } + + inline std::string GetBinaryDir() const { return m_binaryDir; } + inline std::string GetTempDir() const { return m_tempDir; } + inline std::string GetSortedDir() const { return m_sortedDir; } + inline std::string GetBuiltDir() const { return m_builtDir; } + inline std::string GetMergedDir() const { return m_mergedDir; } + + std::vector GetBinaryRunRange(int runMin, int runMax); + std::vector GetBuiltRunRange(int runMin, int runMax); + + bool UnpackBinaryRunToTemp(int run); //Currently Linux/MacOS only. Windows support to come. + std::vector GetTempFiles(); + bool ClearTempDirectory(); + //Maybe offload to another class? Idk. Feel like EVBWorkspace shouldn't know about ROOT + bool MergeBuiltFiles(const std::string& outputname, int runMin, int runMax); + + private: + void Init(); + std::string GetBinaryRun(int run); + std::string GetBuiltRun(int run); + bool m_isValid; + + std::string m_workspace; + + std::string m_binaryDir; + std::string m_tempDir; + std::string m_sortedDir; + std::string m_builtDir; + std::string m_mergedDir; + }; +} + +#endif \ No newline at end of file diff --git a/src/evb/FlagHandler.cpp b/src/evb/FlagHandler.cpp index 4982621..30519b5 100644 --- a/src/evb/FlagHandler.cpp +++ b/src/evb/FlagHandler.cpp @@ -1,4 +1,3 @@ -#include "EventBuilder.h" #include "FlagHandler.h" namespace EventBuilder { diff --git a/src/evb/Logger.cpp b/src/evb/Logger.cpp index b3b76e3..3fdcdee 100644 --- a/src/evb/Logger.cpp +++ b/src/evb/Logger.cpp @@ -1,4 +1,3 @@ -#include "EventBuilder.h" #include "spdlog/sinks/stdout_color_sinks.h" namespace EventBuilder { diff --git a/src/evb/OrderChecker.cpp b/src/evb/OrderChecker.cpp index 7eaa636..601f0cc 100644 --- a/src/evb/OrderChecker.cpp +++ b/src/evb/OrderChecker.cpp @@ -5,7 +5,6 @@ Written by G.W. McCann Oct. 2020 */ -#include "EventBuilder.h" #include "OrderChecker.h" namespace EventBuilder { diff --git a/src/evb/ShiftMap.cpp b/src/evb/ShiftMap.cpp index 2cc4e58..d615498 100644 --- a/src/evb/ShiftMap.cpp +++ b/src/evb/ShiftMap.cpp @@ -9,7 +9,6 @@ Written by G.W. McCann Oct. 2020 */ -#include "EventBuilder.h" #include "ShiftMap.h" namespace EventBuilder { diff --git a/src/evb/SlowSort.cpp b/src/evb/SlowSort.cpp index a18702a..6317ab0 100644 --- a/src/evb/SlowSort.cpp +++ b/src/evb/SlowSort.cpp @@ -7,7 +7,6 @@ * *Refurbished and updated Jan 2020 GWM */ -#include "EventBuilder.h" #include "SlowSort.h" namespace EventBuilder { diff --git a/src/evb/Stopwatch.cpp b/src/evb/Stopwatch.cpp index bf5441d..f368943 100644 --- a/src/evb/Stopwatch.cpp +++ b/src/evb/Stopwatch.cpp @@ -5,7 +5,6 @@ Written by G.W. McCann Oct. 2020 */ -#include "EventBuilder.h" #include "Stopwatch.h" namespace EventBuilder { diff --git a/src/guidict/EVBMainFrame.cpp b/src/guidict/EVBMainFrame.cpp index d43a82f..ae39acc 100644 --- a/src/guidict/EVBMainFrame.cpp +++ b/src/guidict/EVBMainFrame.cpp @@ -1,5 +1,4 @@ #include "EVBMainFrame.h" -#include "FileViewFrame.h" #include #include #include @@ -31,7 +30,6 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) : TGLabel* workLabel = new TGLabel(WorkFrame, "Workspace Directory:"); fWorkField = new TGTextEntry(WorkFrame, new TGTextBuffer(120), WORKDIR); fWorkField->Resize(w*0.25, fWorkField->GetDefaultHeight()); - fWorkField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateWorkdir()"); fOpenWorkButton = new TGTextButton(WorkFrame, "Open"); fOpenWorkButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenWorkdir()"); WorkFrame->AddFrame(workLabel, lhints); @@ -42,7 +40,6 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) : TGLabel* smaplabel = new TGLabel(SMapFrame, "Board Shift File:"); fSMapField = new TGTextEntry(SMapFrame, new TGTextBuffer(120), SMAP); fSMapField->Resize(w*0.25, fSMapField->GetDefaultHeight()); - fSMapField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateSMap()"); fOpenSMapButton = new TGTextButton(SMapFrame, "Open"); fOpenSMapButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenSMapfile()"); SMapFrame->AddFrame(smaplabel, lhints); @@ -52,7 +49,6 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) : TGHorizontalFrame *ScalerFrame = new TGHorizontalFrame(NameFrame, w, h*0.1); TGLabel* sclabel = new TGLabel(ScalerFrame, "Scaler File: "); fScalerField = new TGTextEntry(ScalerFrame, new TGTextBuffer(120), SCALER); - fScalerField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateScaler()"); fOpenScalerButton = new TGTextButton(ScalerFrame, "Open"); fOpenScalerButton->Connect("Clicked()","EVBMainFrame", this, "DoOpenScalerfile()"); ScalerFrame->AddFrame(sclabel, lhints); @@ -121,8 +117,8 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) : AddFrame(InputFrame, fchints); AddFrame(PBFrame, fpbhints); - fBuilder.SetProgressCallbackFunc(BIND_PROGRESS_CALLBACK_FUNCTION(EVBMainFrame::SetProgressBarPosition)); - fBuilder.SetProgressFraction(0.01); + m_builder.SetProgressCallbackFunc(BIND_PROGRESS_CALLBACK_FUNCTION(EVBMainFrame::SetProgressBarPosition)); + m_builder.SetProgressFraction(0.01); SetWindowName("GWM Event Builder"); MapSubwindows(); Resize(); @@ -162,7 +158,12 @@ void EVBMainFrame::HandleMenuSelection(int id) void EVBMainFrame::DoOpenWorkdir() { - new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, WORKDIR); + new TGFileDialog(gClient->GetRoot(), this, kDOpen, fInfo); + if(fInfo->fFilename) + { + std::string path_wtrailer = fInfo->fFilename + std::string("/"); + DisplayWorkdir(path_wtrailer.c_str()); + } } void EVBMainFrame::DoOpenSMapfile() @@ -192,17 +193,17 @@ void EVBMainFrame::DoRun() { case EventBuilder::EVBApp::Operation::Convert : { - fBuilder.Convert2RawRoot(); + m_builder.Convert2RawRoot(); break; } case EventBuilder::EVBApp::Operation::Merge : { - fBuilder.MergeROOTFiles(); + m_builder.MergeROOTFiles(); break; } case EventBuilder::EVBApp::Operation::ConvertSlow : { - fBuilder.Convert2SortedRoot(); + m_builder.Convert2SortedRoot(); break; } } @@ -217,12 +218,15 @@ void EVBMainFrame::HandleTypeSelection(int box, int entry) bool EVBMainFrame::SetParameters() { - fBuilder.SetRunRange(fRMinField->GetIntNumber(), fRMaxField->GetIntNumber()); - fBuilder.SetSlowCoincidenceWindow(fSlowWindowField->GetNumber()); - fBuilder.SetBufferSize(fBufferSizeField->GetNumber()); - UpdateWorkdir(); - UpdateSMap(); - UpdateScaler(); + m_params.runMin = fRMinField->GetIntNumber(); + m_params.runMax = fRMaxField->GetIntNumber(); + m_params.slowCoincidenceWindow = fSlowWindowField->GetNumber(); + m_params.bufferSize = fBufferSizeField->GetIntNumber(); + m_params.workspaceDir = fWorkField->GetText(); + m_params.timeShiftFile = fSMapField->GetText(); + m_params.scalerFile = fScalerField->GetText(); + + m_builder.SetParameters(m_params); return true; } @@ -230,62 +234,46 @@ bool EVBMainFrame::SetParameters() void EVBMainFrame::DisplayWorkdir(const char* dir) { fWorkField->SetText(dir); - fBuilder.SetWorkDirectory(dir); + SetParameters(); } void EVBMainFrame::DisplaySMap(const char* file) { fSMapField->SetText(file); - fBuilder.SetBoardShiftFile(file); + SetParameters(); } void EVBMainFrame::DisplayScaler(const char* file) { fScalerField->SetText(file); - fBuilder.SetScalerFile(file); + SetParameters(); } void EVBMainFrame::SaveConfig(const char* file) { std::string filename = file; - fBuilder.WriteConfigFile(filename); + m_builder.WriteConfigFile(filename); } void EVBMainFrame::LoadConfig(const char* file) { std::string filename = file; - fBuilder.ReadConfigFile(filename); + m_builder.ReadConfigFile(filename); + m_params = m_builder.GetParameters(); - fWorkField->SetText(fBuilder.GetWorkDirectory().c_str()); - fSMapField->SetText(fBuilder.GetBoardShiftFile().c_str()); - fScalerField->SetText(fBuilder.GetScalerFile().c_str()); + fWorkField->SetText(m_params.workspaceDir.c_str()); + fSMapField->SetText(m_params.timeShiftFile.c_str()); + fScalerField->SetText(m_params.scalerFile.c_str()); - fSlowWindowField->SetNumber(fBuilder.GetSlowCoincidenceWindow()); + fSlowWindowField->SetNumber(m_params.slowCoincidenceWindow); - fRMaxField->SetIntNumber(fBuilder.GetRunMax()); - fRMinField->SetIntNumber(fBuilder.GetRunMin()); + fRMaxField->SetIntNumber(m_params.runMin); + fRMinField->SetIntNumber(m_params.runMax); + fBufferSizeField->SetIntNumber(m_params.bufferSize); } -void EVBMainFrame::UpdateWorkdir() -{ - const char* dir = fWorkField->GetText(); - fBuilder.SetWorkDirectory(dir); -} - -void EVBMainFrame::UpdateSMap() -{ - const char* file = fSMapField->GetText(); - fBuilder.SetBoardShiftFile(file); -} - -void EVBMainFrame::UpdateScaler() -{ - const char* file = fScalerField->GetText(); - fBuilder.SetScalerFile(file); -} - void EVBMainFrame::DisableAllInput() { fRunButton->SetState(kButtonDisabled); diff --git a/src/guidict/EVBMainFrame.h b/src/guidict/EVBMainFrame.h index 0196ae4..7f01bb9 100644 --- a/src/guidict/EVBMainFrame.h +++ b/src/guidict/EVBMainFrame.h @@ -34,9 +34,6 @@ public: void DisplayScaler(const char* file); void SaveConfig(const char* file); void LoadConfig(const char* file); - void UpdateWorkdir(); - void UpdateSMap(); - void UpdateScaler(); void RunMerge(const char* dir, const char* file); void DisableAllInput(); void EnableAllInput(); @@ -75,7 +72,8 @@ private: TGFileInfo *fInfo; - EventBuilder::EVBApp fBuilder; + EventBuilder::EVBApp m_builder; + EventBuilder::EVBParameters m_params; int counter; UInt_t MAIN_W, MAIN_H;