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.

This commit is contained in:
Gordon McCann 2022-07-14 16:31:09 -04:00
parent cfb08567c0
commit 24df93a0f7
18 changed files with 429 additions and 223 deletions

View File

@ -1,5 +1,4 @@
Format: scaler_param_name assoc_binary_file_name_without_runID 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) 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 Data_CH5@V1730_89 beamint
CH1@V1730_89_Data t2

View File

@ -28,6 +28,9 @@ target_sources(EventBuilderCore PRIVATE
SlowSort.cpp SlowSort.cpp
CompassRun.cpp CompassRun.cpp
SlowSort.h SlowSort.h
EVBParameters.h
EVBWorkspace.h
EVBWorkspace.cpp
) )
target_link_libraries(EventBuilderCore PUBLIC target_link_libraries(EventBuilderCore PUBLIC

View File

@ -8,7 +8,6 @@
Written by G.W. McCann Oct. 2020 Written by G.W. McCann Oct. 2020
*/ */
#include "EventBuilder.h"
#include "CompassFile.h" #include "CompassFile.h"
namespace EventBuilder { namespace EventBuilder {

View File

@ -9,24 +9,16 @@
Updated to also handle scaler data. -- GWM Oct. 2020 Updated to also handle scaler data. -- GWM Oct. 2020
*/ */
#include "EventBuilder.h"
#include "CompassRun.h" #include "CompassRun.h"
#include "RunCollector.h"
#include "SlowSort.h" #include "SlowSort.h"
#include "FlagHandler.h" #include "FlagHandler.h"
namespace EventBuilder { namespace EventBuilder {
CompassRun::CompassRun() : CompassRun::CompassRun(const EVBParameters& params, const std::shared_ptr<EVBWorkspace>& workspace) :
directory(""), m_scalerinput(""), runNum(0), m_buffersize(200000), m_scaler_flag(false) m_params(params), m_workspace(workspace), m_runNum(0), m_scaler_flag(false)
{ {
m_smap.SetFile(m_params.timeShiftFile);
}
CompassRun::CompassRun(const std::string& dir, size_t bsize) :
directory(dir), m_scalerinput(""), runNum(0), m_buffersize(bsize), m_scaler_flag(false)
{
} }
CompassRun::~CompassRun() {} CompassRun::~CompassRun() {}
@ -35,7 +27,7 @@ namespace EventBuilder {
/*Load em into a map*/ /*Load em into a map*/
void CompassRun::SetScalers() void CompassRun::SetScalers()
{ {
std::ifstream input(m_scalerinput); std::ifstream input(m_params.scalerFile);
if(!input.is_open()) return; if(!input.is_open()) return;
m_scaler_flag = true; m_scaler_flag = true;
@ -47,7 +39,7 @@ namespace EventBuilder {
while(input>>filename) while(input>>filename)
{ {
input>>varname; 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<int64_t>(varname.c_str(), init); m_scaler_map[filename] = TParameter<int64_t>(varname.c_str(), init);
} }
input.close(); input.close();
@ -55,17 +47,14 @@ namespace EventBuilder {
bool CompassRun::GetBinaryFiles() bool CompassRun::GetBinaryFiles()
{ {
std::string prefix = ""; auto files = m_workspace->GetTempFiles();
std::string suffix = ".BIN"; //binaries
RunCollector grabber(directory, prefix, suffix);
grabber.GrabAllFiles();
m_datafiles.clear(); //so that the CompassRun can be reused 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; bool scalerd;
m_totalHits = 0; //reset total run size m_totalHits = 0; //reset total run size
for(auto& entry : grabber.GetFileList()) for(auto& entry : files)
{ {
//Handle scaler files, if they exist //Handle scaler files, if they exist
if(m_scaler_flag) if(m_scaler_flag)
@ -83,7 +72,7 @@ namespace EventBuilder {
if(scalerd) if(scalerd)
continue; 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); 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 //Any time we have a file that fails to be found, we terminate the whole process
if(!m_datafiles[m_datafiles.size() - 1].IsOpen()) if(!m_datafiles[m_datafiles.size() - 1].IsOpen())
@ -130,18 +119,18 @@ namespace EventBuilder {
{ {
std::pair<CompassHit, bool*> earliestHit = std::make_pair(CompassHit(), nullptr); std::pair<CompassHit, bool*> earliestHit = std::make_pair(CompassHit(), nullptr);
for(unsigned int i=startIndex; i<m_datafiles.size(); i++) for(unsigned int i=m_startIndex; i<m_datafiles.size(); i++)
{ {
if(m_datafiles[i].CheckHitHasBeenUsed()) if(m_datafiles[i].CheckHitHasBeenUsed())
m_datafiles[i].GetNextHit(); m_datafiles[i].GetNextHit();
if(m_datafiles[i].IsEOF()) if(m_datafiles[i].IsEOF())
{ {
if(i == startIndex) if(i == m_startIndex)
startIndex++; m_startIndex++;
continue; continue;
} }
else if(i == startIndex) else if(i == m_startIndex)
{ {
earliestHit = std::make_pair(m_datafiles[i].GetCurrentHit(), m_datafiles[i].GetUsedFlagPtr()); earliestHit = std::make_pair(m_datafiles[i].GetCurrentHit(), m_datafiles[i].GetUsedFlagPtr());
} }
@ -153,7 +142,7 @@ namespace EventBuilder {
if(earliestHit.second == nullptr) if(earliestHit.second == nullptr)
return false; //Make sure that there actually was a hit return false; //Make sure that there actually was a hit
hit = earliestHit.first; m_hit = earliestHit.first;
*earliestHit.second = true; *earliestHit.second = true;
return true; return true;
} }
@ -163,15 +152,15 @@ namespace EventBuilder {
TFile* output = TFile::Open(name.c_str(), "RECREATE"); TFile* output = TFile::Open(name.c_str(), "RECREATE");
TTree* outtree = new TTree("Data", "Data"); TTree* outtree = new TTree("Data", "Data");
outtree->Branch("Board", &hit.board); outtree->Branch("Board", &m_hit.board);
outtree->Branch("Channel", &hit.channel); outtree->Branch("Channel", &m_hit.channel);
outtree->Branch("Energy", &hit.energy); outtree->Branch("Energy", &m_hit.energy);
outtree->Branch("EnergyShort", &hit.energyShort); outtree->Branch("EnergyShort", &m_hit.energyShort);
outtree->Branch("EnergyCal", &hit.energyCalibrated); outtree->Branch("EnergyCal", &m_hit.energyCalibrated);
outtree->Branch("Timestamp", &hit.timestamp); outtree->Branch("Timestamp", &m_hit.timestamp);
outtree->Branch("Flags", &hit.flags); outtree->Branch("Flags", &m_hit.flags);
outtree->Branch("Ns", &hit.Ns); outtree->Branch("Ns", &m_hit.Ns);
outtree->Branch("Samples", &hit.samples); outtree->Branch("Samples", &m_hit.samples);
if(!m_smap.IsSet()) if(!m_smap.IsSet())
{ {
@ -187,7 +176,7 @@ namespace EventBuilder {
return; return;
} }
startIndex = 0; //Reset the startIndex m_startIndex = 0; //Reset the startIndex
unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0; unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0;
if(flush == 0) if(flush == 0)
@ -215,10 +204,11 @@ namespace EventBuilder {
output->Close(); 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"); TFile* output = TFile::Open(name.c_str(), "RECREATE");
TTree* outtree = new TTree("SortTree", "SortTree"); TTree* outtree = new TTree("SortTree", "SortTree");
std::vector<DPPChannel> event;
outtree->Branch("event", &event); outtree->Branch("event", &event);
if(!m_smap.IsSet()) if(!m_smap.IsSet())
@ -235,8 +225,8 @@ namespace EventBuilder {
} }
startIndex = 0; m_startIndex = 0;
SlowSort coincidizer(window); SlowSort coincidizer(m_params.slowCoincidenceWindow);
bool killFlag = false; bool killFlag = false;
uint64_t count = 0, flush = m_totalHits*0.01, flush_count = 0; uint64_t count = 0, flush = m_totalHits*0.01, flush_count = 0;
@ -259,7 +249,7 @@ namespace EventBuilder {
killFlag = true; killFlag = true;
} }
else else
coincidizer.AddHitToEvent(hit); coincidizer.AddHitToEvent(m_hit);
if(coincidizer.IsEventReady()) if(coincidizer.IsEventReady())
{ {

View File

@ -10,9 +10,10 @@
#ifndef COMPASSRUN_H #ifndef COMPASSRUN_H
#define COMPASSRUN_H #define COMPASSRUN_H
#include "EVBParameters.h"
#include "EVBWorkspace.h"
#include "CompassFile.h" #include "CompassFile.h"
#include "DataStructs.h" #include "DataStructs.h"
#include "RunCollector.h"
#include "ShiftMap.h" #include "ShiftMap.h"
#include "ProgressCallback.h" #include "ProgressCallback.h"
#include <TParameter.h> #include <TParameter.h>
@ -22,15 +23,11 @@ namespace EventBuilder {
class CompassRun class CompassRun
{ {
public: public:
CompassRun(); CompassRun(const EVBParameters& params, const std::shared_ptr<EVBWorkspace>& workspace);
CompassRun(const std::string& dir, size_t bsize);
~CompassRun(); ~CompassRun();
inline void SetDirectory(const std::string& dir) { directory = dir; } inline void SetRunNumber(int n) { m_runNum = n; };
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); }
void Convert2RawRoot(const std::string& name); 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 SetProgressCallbackFunc(ProgressCallbackFunc& func) { m_progressCallback = func; }
inline void SetProgressFraction(double frac) { m_progressFraction = frac; } inline void SetProgressFraction(double frac) { m_progressFraction = frac; }
@ -41,20 +38,19 @@ namespace EventBuilder {
void SetScalers(); void SetScalers();
void ReadScalerData(const std::string& filename); void ReadScalerData(const std::string& filename);
std::string directory, m_scalerinput; EVBParameters m_params;
std::shared_ptr<EVBWorkspace> m_workspace;
std::vector<CompassFile> m_datafiles; std::vector<CompassFile> 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; ShiftMap m_smap;
std::unordered_map<std::string, TParameter<int64_t>> m_scaler_map; //maps scaler files to the TParameter to be saved std::unordered_map<std::string, TParameter<int64_t>> m_scaler_map; //maps scaler files to the TParameter to be saved
//Potential branch variables //Potential branch variables
CompassHit hit; CompassHit m_hit;
std::vector<DPPChannel> event;
//what run is this //what run is this
int runNum; int m_runNum;
uint64_t m_totalHits; uint64_t m_totalHits;
uint64_t m_buffersize;
//Scaler switch //Scaler switch
bool m_scaler_flag; bool m_scaler_flag;

View File

@ -6,20 +6,19 @@
Written by G.W. McCann Oct. 2020 Written by G.W. McCann Oct. 2020
*/ */
#include "EventBuilder.h"
#include <cstdlib>
#include "EVBApp.h" #include "EVBApp.h"
#include "RunCollector.h"
#include "CompassRun.h" #include "CompassRun.h"
#include "SlowSort.h" #include "SlowSort.h"
namespace EventBuilder { namespace EventBuilder {
EVBApp::EVBApp() : EVBApp::EVBApp() :
m_rmin(0), m_rmax(0), m_workspace(nullptr), m_progressFraction(0.1)
m_progressFraction(0.1), m_workspace("none"), m_shiftfile("none"),
m_scalerfile("none"), m_buffersize(200000), m_SlowWindow(0)
{ {
if(EnforceDictonaryLinked()) //Avoid symbol stripping
{
EVB_INFO("Dictionary loaded");
}
SetProgressCallbackFunc(BIND_PROGRESS_CALLBACK_FUNCTION(EVBApp::DefaultProgressCallback)); SetProgressCallbackFunc(BIND_PROGRESS_CALLBACK_FUNCTION(EVBApp::DefaultProgressCallback));
} }
@ -33,6 +32,18 @@ namespace EventBuilder {
EVB_INFO("Percent of run built: {0}", fraction*100); 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) bool EVBApp::ReadConfigFile(const std::string& fullpath)
{ {
EVB_INFO("Reading in EVB configuration from file {0}...", fullpath); EVB_INFO("Reading in EVB configuration from file {0}...", fullpath);
@ -45,22 +56,22 @@ namespace EventBuilder {
std::string junk; std::string junk;
std::getline(input, junk); std::getline(input, junk);
input>>junk>>m_workspace; input>>junk>>m_params.workspaceDir;
input>>junk; input>>junk;
std::getline(input, junk); std::getline(input, junk);
std::getline(input, junk); std::getline(input, junk);
input>>junk>>m_scalerfile; input>>junk>>m_params.scalerFile;
input>>junk; input>>junk;
std::getline(input, junk); std::getline(input, junk);
std::getline(input, junk); std::getline(input, junk);
input>>junk>>m_shiftfile; input>>junk>>m_params.timeShiftFile;
input>>junk>>m_SlowWindow; input>>junk>>m_params.slowCoincidenceWindow;
input>>junk; input>>junk;
std::getline(input, junk); std::getline(input, junk);
std::getline(input, junk); std::getline(input, junk);
input>>junk>>m_rmin; input>>junk>>m_params.runMin;
input>>junk>>m_rmax; input>>junk>>m_params.runMax;
input>>junk>>m_buffersize; input>>junk>>m_params.bufferSize;
input.close(); input.close();
@ -81,19 +92,19 @@ namespace EventBuilder {
} }
output<<"-------Data Location----------"<<std::endl; output<<"-------Data Location----------"<<std::endl;
output<<"WorkspaceDirectory: "<<m_workspace<<std::endl; output<<"WorkspaceDirectory: "<<m_params.workspaceDir<<std::endl;
output<<"-------------------------------"<<std::endl; output<<"-------------------------------"<<std::endl;
output<<"------Experimental Inputs------"<<std::endl; output<<"------Experimental Inputs------"<<std::endl;
output<<"ScalerFile: "<<m_scalerfile<<std::endl; output<<"ScalerFile: "<<m_params.scalerFile<<std::endl;
output<<"-------------------------------"<<std::endl; output<<"-------------------------------"<<std::endl;
output<<"-------Timing Information------"<<std::endl; output<<"-------Timing Information------"<<std::endl;
output<<"BoardOffsetFile: "<<m_shiftfile<<std::endl; output<<"BoardOffsetFile: "<<m_params.timeShiftFile<<std::endl;
output<<"SlowCoincidenceWindow(ps): "<<m_SlowWindow<<std::endl; output<<"SlowCoincidenceWindow(ps): "<<m_params.slowCoincidenceWindow<<std::endl;
output<<"-------------------------------"<<std::endl; output<<"-------------------------------"<<std::endl;
output<<"--------Run Information--------"<<std::endl; output<<"--------Run Information--------"<<std::endl;
output<<"MinRun: "<<m_rmin<<std::endl; output<<"MinRun: "<<m_params.runMin<<std::endl;
output<<"MaxRun: "<<m_rmax<<std::endl; output<<"MaxRun: "<<m_params.runMax<<std::endl;
output<<"BufferSize: "<<m_buffersize<<std::endl; output<<"BufferSize: "<<m_params.bufferSize<<std::endl;
output<<"-------------------------------"<<std::endl; output<<"-------------------------------"<<std::endl;
output.close(); output.close();
@ -104,55 +115,56 @@ namespace EventBuilder {
void EVBApp::Convert2RawRoot() void EVBApp::Convert2RawRoot()
{ {
std::string rawroot_dir = m_workspace+"/raw_root/"; if(m_workspace == nullptr || !m_workspace->IsValid())
std::string unpack_dir = m_workspace+"/temp_binary/"; {
std::string binary_dir = m_workspace+"/raw_binary/"; EVB_ERROR("Unable to perform operation due to bad workspace.");
EVB_INFO("Converting binary archives to ROOT files over run range [{0}, {1}]",m_rmin,m_rmax); 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; CompassRun converter(m_params, m_workspace);
std::string unpack_command, wipe_command;
CompassRun converter(unpack_dir, m_buffersize);
converter.SetShiftMap(m_shiftfile);
converter.SetScalerInput(m_scalerfile);
converter.SetProgressCallbackFunc(m_progressCallback); converter.SetProgressCallbackFunc(m_progressCallback);
converter.SetProgressFraction(m_progressFraction); converter.SetProgressFraction(m_progressFraction);
int result; int count = 0;
EVB_INFO("Beginning conversion..."); 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"; rawfile = rawroot_dir + "compass_run_"+ std::to_string(i) + ".root";
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir; EVB_INFO("Converting file {0}...", rawfile);
wipe_command = "rm -r "+unpack_dir+"*.BIN"; m_workspace->ClearTempDirectory();
if(m_workspace->UnpackBinaryRunToTemp(i))
result = system(unpack_command.c_str()); {
converter.Convert2RawRoot(rawfile); converter.SetRunNumber(i);
result = system(wipe_command.c_str()); 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() void EVBApp::MergeROOTFiles()
{ {
std::string merge_file = m_workspace+"/merged/run_"+std::to_string(m_rmin)+"_"+std::to_string(m_rmax)+".root"; if(m_workspace == nullptr || !m_workspace->IsValid())
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); 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); 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..."); 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()!"); EVB_ERROR("Unable to find files for merge at EVBApp::MergeROOTFiles()!");
return; return;
@ -162,19 +174,18 @@ namespace EventBuilder {
void EVBApp::Convert2SortedRoot() void EVBApp::Convert2SortedRoot()
{ {
std::string sortroot_dir = m_workspace+"/sorted/"; if(m_workspace == nullptr || !m_workspace->IsValid())
std::string unpack_dir = m_workspace+"/temp_binary/"; {
std::string binary_dir = m_workspace+"/raw_binary/"; EVB_ERROR("Unable to perform operation due to bad workspace.");
EVB_INFO("Converting binary archives to event built ROOT files over run range [{0}, {1}]",m_rmin,m_rmax); 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; CompassRun converter(m_params, m_workspace);
std::string unpack_command, wipe_command;
CompassRun converter(unpack_dir, m_buffersize);
converter.SetShiftMap(m_shiftfile);
converter.SetScalerInput(m_scalerfile);
converter.SetProgressCallbackFunc(m_progressCallback); converter.SetProgressCallbackFunc(m_progressCallback);
converter.SetProgressFraction(m_progressFraction); converter.SetProgressFraction(m_progressFraction);
@ -182,22 +193,20 @@ namespace EventBuilder {
EVB_INFO("Beginning conversion..."); EVB_INFO("Beginning conversion...");
int count=0; 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"; sortfile = sortroot_dir +"run_"+std::to_string(i)+ ".root";
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir; EVB_INFO("Converting file {0}...", sortfile);
wipe_command = "rm -r "+unpack_dir+"*.BIN";
m_workspace->ClearTempDirectory();
result = system(unpack_command.c_str()); if(m_workspace->UnpackBinaryRunToTemp(i))
converter.Convert2SortedRoot(sortfile, m_SlowWindow); {
result = system(wipe_command.c_str()); converter.SetRunNumber(i);
count++; converter.Convert2SortedRoot(sortfile);
count++;
}
m_workspace->ClearTempDirectory();
} }
if(count==0) if(count==0)
EVB_WARN("Conversion failed, no archives were found!"); EVB_WARN("Conversion failed, no archives were found!");
@ -205,11 +214,4 @@ namespace EventBuilder {
EVB_INFO("Conversion complete."); 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; }
} }

View File

@ -9,7 +9,8 @@
#ifndef EVBAPP_H #ifndef EVBAPP_H
#define EVBAPP_H #define EVBAPP_H
#include "RunCollector.h" #include "EVBParameters.h"
#include "EVBWorkspace.h"
#include "ProgressCallback.h" #include "ProgressCallback.h"
namespace EventBuilder { namespace EventBuilder {
@ -28,20 +29,8 @@ namespace EventBuilder {
void Convert2SortedRoot(); void Convert2SortedRoot();
void Convert2RawRoot(); void Convert2RawRoot();
void SetRunRange(int rmin, int rmax); void SetParameters(const EVBParameters& params);
void SetWorkDirectory(const std::string& dir); inline const EVBParameters& GetParameters() { return m_params; }
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 DefaultProgressCallback(int64_t curVal, int64_t totalVal); void DefaultProgressCallback(int64_t curVal, int64_t totalVal);
inline void SetProgressCallbackFunc(const ProgressCallbackFunc& function) { m_progressCallback = function; } inline void SetProgressCallbackFunc(const ProgressCallbackFunc& function) { m_progressCallback = function; }
@ -55,19 +44,10 @@ namespace EventBuilder {
}; };
private: private:
int m_rmin, m_rmax;
double m_progressFraction; double m_progressFraction;
EVBParameters m_params;
std::shared_ptr<EVBWorkspace> 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; ProgressCallbackFunc m_progressCallback;
}; };

20
src/evb/EVBParameters.h Normal file
View File

@ -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

192
src/evb/EVBWorkspace.cpp Normal file
View File

@ -0,0 +1,192 @@
#include "EVBWorkspace.h"
#include <filesystem>
#include <TFile.h>
#include <TChain.h>
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<std::string> EVBWorkspace::GetBinaryRunRange(int runMin, int runMax)
{
std::vector<std::string> 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<std::string> EVBWorkspace::GetBuiltRunRange(int runMin, int runMax)
{
std::vector<std::string> 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<std::string> EVBWorkspace::GetTempFiles()
{
std::vector<std::string> 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<std::filesystem::path> 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; i<files.size(); i++)
{
if(!std::filesystem::remove(files[i]))
{
EVB_ERROR("Unable to clear temp directory {0}! File-like entry {1} could not be deleted. Please manually clear the directory.",
m_tempDir, files[i].string());
return false;
}
}
return true;
}
bool EVBWorkspace::MergeBuiltFiles(const std::string& outputname, int runMin, int runMax)
{
auto files = GetBuiltRunRange(runMin, runMax);
if(files.size() == 0)
return false;
TFile* output = TFile::Open(outputname.c_str(), "RECREATE");
if(!output->IsOpen())
{
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;
}
}

45
src/evb/EVBWorkspace.h Normal file
View File

@ -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<std::string> GetBinaryRunRange(int runMin, int runMax);
std::vector<std::string> GetBuiltRunRange(int runMin, int runMax);
bool UnpackBinaryRunToTemp(int run); //Currently Linux/MacOS only. Windows support to come.
std::vector<std::string> 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

View File

@ -1,4 +1,3 @@
#include "EventBuilder.h"
#include "FlagHandler.h" #include "FlagHandler.h"
namespace EventBuilder { namespace EventBuilder {

View File

@ -1,4 +1,3 @@
#include "EventBuilder.h"
#include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/sinks/stdout_color_sinks.h"
namespace EventBuilder { namespace EventBuilder {

View File

@ -5,7 +5,6 @@
Written by G.W. McCann Oct. 2020 Written by G.W. McCann Oct. 2020
*/ */
#include "EventBuilder.h"
#include "OrderChecker.h" #include "OrderChecker.h"
namespace EventBuilder { namespace EventBuilder {

View File

@ -9,7 +9,6 @@
Written by G.W. McCann Oct. 2020 Written by G.W. McCann Oct. 2020
*/ */
#include "EventBuilder.h"
#include "ShiftMap.h" #include "ShiftMap.h"
namespace EventBuilder { namespace EventBuilder {

View File

@ -7,7 +7,6 @@
* *
*Refurbished and updated Jan 2020 GWM *Refurbished and updated Jan 2020 GWM
*/ */
#include "EventBuilder.h"
#include "SlowSort.h" #include "SlowSort.h"
namespace EventBuilder { namespace EventBuilder {

View File

@ -5,7 +5,6 @@
Written by G.W. McCann Oct. 2020 Written by G.W. McCann Oct. 2020
*/ */
#include "EventBuilder.h"
#include "Stopwatch.h" #include "Stopwatch.h"
namespace EventBuilder { namespace EventBuilder {

View File

@ -1,5 +1,4 @@
#include "EVBMainFrame.h" #include "EVBMainFrame.h"
#include "FileViewFrame.h"
#include <TGLabel.h> #include <TGLabel.h>
#include <TGTextBuffer.h> #include <TGTextBuffer.h>
#include <TApplication.h> #include <TApplication.h>
@ -31,7 +30,6 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) :
TGLabel* workLabel = new TGLabel(WorkFrame, "Workspace Directory:"); TGLabel* workLabel = new TGLabel(WorkFrame, "Workspace Directory:");
fWorkField = new TGTextEntry(WorkFrame, new TGTextBuffer(120), WORKDIR); fWorkField = new TGTextEntry(WorkFrame, new TGTextBuffer(120), WORKDIR);
fWorkField->Resize(w*0.25, fWorkField->GetDefaultHeight()); fWorkField->Resize(w*0.25, fWorkField->GetDefaultHeight());
fWorkField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateWorkdir()");
fOpenWorkButton = new TGTextButton(WorkFrame, "Open"); fOpenWorkButton = new TGTextButton(WorkFrame, "Open");
fOpenWorkButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenWorkdir()"); fOpenWorkButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenWorkdir()");
WorkFrame->AddFrame(workLabel, lhints); 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:"); TGLabel* smaplabel = new TGLabel(SMapFrame, "Board Shift File:");
fSMapField = new TGTextEntry(SMapFrame, new TGTextBuffer(120), SMAP); fSMapField = new TGTextEntry(SMapFrame, new TGTextBuffer(120), SMAP);
fSMapField->Resize(w*0.25, fSMapField->GetDefaultHeight()); fSMapField->Resize(w*0.25, fSMapField->GetDefaultHeight());
fSMapField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateSMap()");
fOpenSMapButton = new TGTextButton(SMapFrame, "Open"); fOpenSMapButton = new TGTextButton(SMapFrame, "Open");
fOpenSMapButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenSMapfile()"); fOpenSMapButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenSMapfile()");
SMapFrame->AddFrame(smaplabel, lhints); 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); TGHorizontalFrame *ScalerFrame = new TGHorizontalFrame(NameFrame, w, h*0.1);
TGLabel* sclabel = new TGLabel(ScalerFrame, "Scaler File: "); TGLabel* sclabel = new TGLabel(ScalerFrame, "Scaler File: ");
fScalerField = new TGTextEntry(ScalerFrame, new TGTextBuffer(120), SCALER); fScalerField = new TGTextEntry(ScalerFrame, new TGTextBuffer(120), SCALER);
fScalerField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateScaler()");
fOpenScalerButton = new TGTextButton(ScalerFrame, "Open"); fOpenScalerButton = new TGTextButton(ScalerFrame, "Open");
fOpenScalerButton->Connect("Clicked()","EVBMainFrame", this, "DoOpenScalerfile()"); fOpenScalerButton->Connect("Clicked()","EVBMainFrame", this, "DoOpenScalerfile()");
ScalerFrame->AddFrame(sclabel, lhints); ScalerFrame->AddFrame(sclabel, lhints);
@ -121,8 +117,8 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) :
AddFrame(InputFrame, fchints); AddFrame(InputFrame, fchints);
AddFrame(PBFrame, fpbhints); AddFrame(PBFrame, fpbhints);
fBuilder.SetProgressCallbackFunc(BIND_PROGRESS_CALLBACK_FUNCTION(EVBMainFrame::SetProgressBarPosition)); m_builder.SetProgressCallbackFunc(BIND_PROGRESS_CALLBACK_FUNCTION(EVBMainFrame::SetProgressBarPosition));
fBuilder.SetProgressFraction(0.01); m_builder.SetProgressFraction(0.01);
SetWindowName("GWM Event Builder"); SetWindowName("GWM Event Builder");
MapSubwindows(); MapSubwindows();
Resize(); Resize();
@ -162,7 +158,12 @@ void EVBMainFrame::HandleMenuSelection(int id)
void EVBMainFrame::DoOpenWorkdir() 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() void EVBMainFrame::DoOpenSMapfile()
@ -192,17 +193,17 @@ void EVBMainFrame::DoRun()
{ {
case EventBuilder::EVBApp::Operation::Convert : case EventBuilder::EVBApp::Operation::Convert :
{ {
fBuilder.Convert2RawRoot(); m_builder.Convert2RawRoot();
break; break;
} }
case EventBuilder::EVBApp::Operation::Merge : case EventBuilder::EVBApp::Operation::Merge :
{ {
fBuilder.MergeROOTFiles(); m_builder.MergeROOTFiles();
break; break;
} }
case EventBuilder::EVBApp::Operation::ConvertSlow : case EventBuilder::EVBApp::Operation::ConvertSlow :
{ {
fBuilder.Convert2SortedRoot(); m_builder.Convert2SortedRoot();
break; break;
} }
} }
@ -217,12 +218,15 @@ void EVBMainFrame::HandleTypeSelection(int box, int entry)
bool EVBMainFrame::SetParameters() bool EVBMainFrame::SetParameters()
{ {
fBuilder.SetRunRange(fRMinField->GetIntNumber(), fRMaxField->GetIntNumber()); m_params.runMin = fRMinField->GetIntNumber();
fBuilder.SetSlowCoincidenceWindow(fSlowWindowField->GetNumber()); m_params.runMax = fRMaxField->GetIntNumber();
fBuilder.SetBufferSize(fBufferSizeField->GetNumber()); m_params.slowCoincidenceWindow = fSlowWindowField->GetNumber();
UpdateWorkdir(); m_params.bufferSize = fBufferSizeField->GetIntNumber();
UpdateSMap(); m_params.workspaceDir = fWorkField->GetText();
UpdateScaler(); m_params.timeShiftFile = fSMapField->GetText();
m_params.scalerFile = fScalerField->GetText();
m_builder.SetParameters(m_params);
return true; return true;
} }
@ -230,62 +234,46 @@ bool EVBMainFrame::SetParameters()
void EVBMainFrame::DisplayWorkdir(const char* dir) void EVBMainFrame::DisplayWorkdir(const char* dir)
{ {
fWorkField->SetText(dir); fWorkField->SetText(dir);
fBuilder.SetWorkDirectory(dir); SetParameters();
} }
void EVBMainFrame::DisplaySMap(const char* file) void EVBMainFrame::DisplaySMap(const char* file)
{ {
fSMapField->SetText(file); fSMapField->SetText(file);
fBuilder.SetBoardShiftFile(file); SetParameters();
} }
void EVBMainFrame::DisplayScaler(const char* file) void EVBMainFrame::DisplayScaler(const char* file)
{ {
fScalerField->SetText(file); fScalerField->SetText(file);
fBuilder.SetScalerFile(file); SetParameters();
} }
void EVBMainFrame::SaveConfig(const char* file) void EVBMainFrame::SaveConfig(const char* file)
{ {
std::string filename = file; std::string filename = file;
fBuilder.WriteConfigFile(filename); m_builder.WriteConfigFile(filename);
} }
void EVBMainFrame::LoadConfig(const char* file) void EVBMainFrame::LoadConfig(const char* file)
{ {
std::string filename = file; std::string filename = file;
fBuilder.ReadConfigFile(filename); m_builder.ReadConfigFile(filename);
m_params = m_builder.GetParameters();
fWorkField->SetText(fBuilder.GetWorkDirectory().c_str()); fWorkField->SetText(m_params.workspaceDir.c_str());
fSMapField->SetText(fBuilder.GetBoardShiftFile().c_str()); fSMapField->SetText(m_params.timeShiftFile.c_str());
fScalerField->SetText(fBuilder.GetScalerFile().c_str()); fScalerField->SetText(m_params.scalerFile.c_str());
fSlowWindowField->SetNumber(fBuilder.GetSlowCoincidenceWindow()); fSlowWindowField->SetNumber(m_params.slowCoincidenceWindow);
fRMaxField->SetIntNumber(fBuilder.GetRunMax()); fRMaxField->SetIntNumber(m_params.runMin);
fRMinField->SetIntNumber(fBuilder.GetRunMin()); 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() void EVBMainFrame::DisableAllInput()
{ {
fRunButton->SetState(kButtonDisabled); fRunButton->SetState(kButtonDisabled);

View File

@ -34,9 +34,6 @@ public:
void DisplayScaler(const char* file); void DisplayScaler(const char* file);
void SaveConfig(const char* file); void SaveConfig(const char* file);
void LoadConfig(const char* file); void LoadConfig(const char* file);
void UpdateWorkdir();
void UpdateSMap();
void UpdateScaler();
void RunMerge(const char* dir, const char* file); void RunMerge(const char* dir, const char* file);
void DisableAllInput(); void DisableAllInput();
void EnableAllInput(); void EnableAllInput();
@ -75,7 +72,8 @@ private:
TGFileInfo *fInfo; TGFileInfo *fInfo;
EventBuilder::EVBApp fBuilder; EventBuilder::EVBApp m_builder;
EventBuilder::EVBParameters m_params;
int counter; int counter;
UInt_t MAIN_W, MAIN_H; UInt_t MAIN_W, MAIN_H;