1
0
Fork 0
mirror of https://github.com/gwm17/Specter.git synced 2024-11-22 18:28:52 -05:00

Initial commit

This commit is contained in:
Gordon McCann 2021-12-18 16:29:07 -05:00
commit 6e11a95205
13 changed files with 1669 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
*.o
*.so
*.a
!.gitignore

12
navigator.sublime-project Normal file
View File

@ -0,0 +1,12 @@
{
"folders":
[
{
"path": "."
}
],
"settings":
{
"SublimeLinter.linters.g++.args": ["-c","-Wall","-fsyntax-only","-std=c++17","-include${folder}/src/navpch.h","-Isrc/"]
}
}

622
navigator.sublime-workspace Normal file
View File

@ -0,0 +1,622 @@
{
"auto_complete":
{
"selected_items":
[
[
"ROO",
"ROOTIncludeDir"
],
[
"R",
"ROOTLibDir"
],
[
"fastic",
"fasticlabel"
],
[
"fB",
"fBField"
],
[
"SetPro",
"SetProgressFraction"
],
[
"Pro",
"ProgressCallbackFunc"
],
[
"SetPRo",
"SetProgressCallbackFunc"
],
[
"ch",
"channel_info"
],
[
"ran",
"random_device"
],
[
"is",
"isoFlag"
],
[
"cost",
"costheta_cm"
],
[
"cos",
"costheta_cm"
],
[
"avgth",
"avg_theta03"
],
[
"avg_theta",
"avg_theta03"
],
[
"angdis",
"angdist_title"
],
[
"rin",
"ringwedgeFlag"
],
[
"b3",
"b3b4_kes"
],
[
"b3_with",
"b3_withb4_theta"
],
[
"b1b",
"b1b3_eff"
],
[
"b1",
"b1b3_count"
],
[
"F",
"FRACTIONAL_STEP_PRECISION"
],
[
"Is",
"IsWedgeTopEdge"
],
[
"i",
"i"
],
[
"phi",
"phi_flat"
],
[
"m_n",
"m_nWedges"
],
[
"wedge",
"wedgetop"
],
[
"wed",
"wedgebottom"
],
[
"m_",
"m_deltaPhi_flat_wedge"
],
[
"m",
"m_deltaR_flat"
],
[
"ring",
"ringbottom"
],
[
"m_d",
"m_deltaPhi_flat_wedge"
],
[
"dleta",
"m_deltaR_flat_ring"
],
[
"m_deltaPhi",
"m_deltaPhi_flat_wedge"
],
[
"m_del",
"m_deltaR_flat_ring"
],
[
"phi_",
"phi_comp"
],
[
"r",
"r_comp"
],
[
"exp",
"expected_flat_p"
],
[
"delt",
"deltaPhi_per_wedge"
],
[
"del",
"deltaR_per_ring"
],
[
"z",
"z"
],
[
"det",
"detectors"
],
[
"deltaP",
"deltaPhi_per_wedge"
],
[
"delatPh",
"deltaPhi_per_wedge"
],
[
"m_we",
"m_wedgeCoords_tilt"
],
[
"m_ring",
"m_ringCoords_tilt"
],
[
"delta",
"deltaPhi_per_wedge"
],
[
"m_ringCoo",
"m_ringCoords_flat"
]
]
},
"buffers":
[
],
"build_system": "Packages/Makefile/Make.sublime-build",
"build_system_choices":
[
[
[
[
"Packages/C++/C++ Single File.sublime-build",
""
],
[
"Packages/C++/C++ Single File.sublime-build",
"Run"
],
[
"Packages/Makefile/Make.sublime-build",
""
],
[
"Packages/Makefile/Make.sublime-build",
"Clean"
]
],
[
"Packages/Makefile/Make.sublime-build",
""
]
],
[
[
[
"Packages/Makefile/Make.sublime-build",
""
],
[
"Packages/Makefile/Make.sublime-build",
"Clean"
]
],
[
"Packages/Makefile/Make.sublime-build",
""
]
]
],
"build_varint": "",
"command_palette":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
[
"Subli",
"SublimeLinter: Lint This View"
],
[
"Package Control: ",
"Package Control: Remove Package"
],
[
"Pack",
"Package Control: Install Package"
],
[
"SublimeLinter: Lin",
"SublimeLinter: Lint This View"
]
],
"width": 0.0
},
"console":
{
"height": 494.0,
"history":
[
]
},
"distraction_free":
{
"menu_visible": true,
"show_minimap": false,
"show_open_files": false,
"show_tabs": false,
"side_bar_visible": false,
"status_bar_visible": false
},
"expanded_folders":
[
"/home/gordon/Navigator"
],
"file_history":
[
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/EVBApp.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/.gitignore",
"/home/gordon/SPS_SABRE_EventBuilder/premake5.lua",
"/home/gordon/SPS_SABRE_EventBuilder/README.md",
"/home/gordon/SPS_SABRE_EventBuilder/src/guidict/FileViewFrame.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/EVBApp.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/guidict/EVBMainFrame.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/CMakeLists.txt",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/FP_kinematics.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/spsdict/CMakeLists.txt",
"/home/gordon/SPS_SABRE_EventBuilder/CMakeLists.txt",
"/home/gordon/SPS_SABRE_EventBuilder/src/gui_main.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/main.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/ChannelMap.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/Logger.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/Logger.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/EventBuilder.h",
"/home/gordon/SPS_SABRE_EventBuilder/EventBuilder.make",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/CompassRun.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/guidict/EVBMainFrame.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/guidict/gui_dict.cxx",
"/home/gordon/SPS_SABRE_EventBuilder/src/guidict/LinkDef_Gui.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/EventBuilder.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/vendor/spdlog/CMakeLists.txt",
"/home/gordon/SPS_SABRE_EventBuilder/src/guidict/G__GUIDict.cxx",
"/home/gordon/SPS_SABRE_EventBuilder/vendor/spdlog/include/spdlog/spdlog.h",
"/home/gordon/SPS_SABRE_EventBuilder/vendor/spdlog/include/spdlog/common.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/OrderChecker.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/MassLookup.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/CompassFile.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/SPSDict.make",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/ChannelMap.h",
"/home/gordon/SPS_SABRE_EventBuilder/objs/Debug/EventBuilder/EventBuilder.h",
"/home/gordon/SPS_SABRE_EventBuilder/objs/Debug/EventBuilder/EventBuilder.h.d",
"/home/gordon/SPS_SABRE_EventBuilder/objs/Debug/EventBuilder/EventBuilder.h.gch",
"/home/gordon/SPS_SABRE_EventBuilder/src/spsdict/DataStructs.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/Stopwatch.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/SlowSort.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/ShiftMap.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/SFPPlotter.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/SFPAnalyzer.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/RunCollector.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/FlagHandler.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/FastSort.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/CutHandler.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/spsdict/DataStructs.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/src/guidict/CMakeLists.txt",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/SFPPlotter.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/CompassRun.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/ProgressCallback.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/guidict/FileViewFrame.h",
"/home/gordon/SPS_SABRE_EventBuilder/sps-sabre-evb.sublime-project",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/MassLookup.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/FP_kinematics.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/FlagHandler.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/FastSort.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/ShiftMap.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/CompassHit.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/CompassFile.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/SlowSort.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/Stopwatch.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/SFPAnalyzer.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/RunCollector.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/OrderChecker.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/CutHandler.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/evb/EventBuilder.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/spsdict/LinkDef_sps.h",
"/home/gordon/SPS_SABRE_EventBuilder/makefile",
"/home/gordon/SPS_SABRE_EventBuilder/build/Makefile",
"/home/gordon/SPS_SABRE_EventBuilder/include/EVBMainFrame.h",
"/home/gordon/SPS_SABRE_EventBuilder/src/gui/EVBMainFrame.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/include/EVBApp.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/RunCollector.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/CompassRun.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/EventBuilder.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/CompassHit.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/EventBuilder.h.gch",
"/home/gordon/SPS_SABRE_EventBuilder/etc/ChannelMap_Feb2021_SABRE.txt",
"/home/gordon/SPS_SABRE_EventBuilder/etc/CutList_Feb2021_10B3hea.txt",
"/home/gordon/SPS_SABRE_EventBuilder/etc/ScalerFile_Feb2021_SABRE.txt",
"/home/gordon/SPS_SABRE_EventBuilder/src/gui/FileViewFrame.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/include/ChannelMap.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/SlowSort.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/MassLookup.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/SFPPlotter.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/CutHandler.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/ShiftMap.h",
"/home/gordon/SPS_SABRE_EventBuilder/etc/ShiftMap_Feb2021_SABRE.txt",
"/home/gordon/SPS_SABRE_EventBuilder/include/DataStructs.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/CompassFile.h",
"/home/gordon/SPS_SABRE_EventBuilder/include/GWMEventBuilder.h",
"/home/gordon/SabreRecon/src/Histogrammer.cpp",
"/home/gordon/SPS_SABRE_EventBuilder/include/FP_kinematics.h",
"/home/gordon/Kinematics/include/MaskApp.h",
"/home/gordon/Kinematics/src/MaskApp.cpp",
"/home/gordon/Kinematics/README.md",
"/home/gordon/Kinematics/premake5.lua",
"/home/gordon/Kinematics/src/Detectors/DetectorEfficiency.cpp",
"/home/gordon/Kinematics/include/DeadChannelMap.h",
"/home/gordon/Kinematics/etc/DeadChannels.txt",
"/home/gordon/Kinematics/include/Eloss_Tables.h",
"/home/gordon/Kinematics/include/LegendrePoly.h",
"/home/gordon/Kinematics/include/Vec3.h",
"/home/gordon/Kinematics/include/Vec4.h",
"/home/gordon/Kinematics/src/Vec3.cpp",
"/home/gordon/Kinematics/src/Vec4.cpp",
"/home/gordon/Kinematics/src/ThreeStepSystem.cpp",
"/home/gordon/Kinematics/src/MaskFile.cpp",
"/home/gordon/Kinematics/include/Nucleus.h",
"/home/gordon/Kinematics/include/MaskFile.h",
"/home/gordon/Kinematics/include/ThreeStepSystem.h",
"/home/gordon/Kinematics/src/TwoStepSystem.cpp",
"/home/gordon/Kinematics/include/TwoStepSystem.h",
"/home/gordon/Kinematics/src/OneStepSystem.cpp",
"/home/gordon/Kinematics/include/OneStepSystem.h",
"/home/gordon/Kinematics/src/DecaySystem.cpp",
"/home/gordon/Kinematics/include/DecaySystem.h",
"/home/gordon/Kinematics/include/ReactionSystem.h",
"/home/gordon/Kinematics/src/Nucleus.cpp",
"/home/gordon/Kinematics/include/KinematicsExceptions.h",
"/home/gordon/Kinematics/src/main.cpp",
"/home/gordon/Kinematics/input.txt",
"/home/gordon/Kinematics/src/Reaction.cpp",
"/home/gordon/Kinematics/src/LayeredTarget.cpp",
"/home/gordon/Kinematics/src/EnergyLoss.cpp",
"/home/gordon/Kinematics/include/EnergyLoss.h",
"/home/gordon/Kinematics/src/Target.cpp",
"/home/gordon/Kinematics/include/Reaction.h"
],
"find":
{
"height": 70.0
},
"find_in_files":
{
"height": 0.0,
"where_history":
[
]
},
"find_state":
{
"case_sensitive": false,
"find_history":
[
"FORCE_INCLUDE",
"std::endl",
"EVBApp::CONVERT",
"GWMEventBuilder",
"detectorPart",
"directory",
"runNum",
"StartEvent",
"&event",
"MASS.FindMass",
"MASS",
"GetElectronicStoppingPower",
"GetTotalStoppingPower",
"uint64_t",
"RxnType",
"Mask",
"Kinematics",
"*generator",
"MassLookup",
"PI",
"G3Vec",
"GZRotation",
"GYRotation",
"G3Vec",
"G4Vec",
"GYRotation",
"GXRotation",
"GZRotation",
"GYRotation",
"GXRotation",
"G3Vec",
"G4Vec",
"G3Vec",
"};",
";\n",
"deltaPhi_per_wedge",
"deltaR_per_ring",
"IsInside"
],
"highlight": true,
"in_selection": false,
"preserve_case": false,
"regex": false,
"replace_history":
[
"EVBApp::Operation::Convert",
"EVBApp",
"attribute",
"&m_event",
"MassLookup::GetInstance->FindMass",
"uint32_t",
"Mask::RxnType",
"MaskApp",
"RandomGenerator::GetInstance().GetGenerator()",
"M_PI",
"Vec3",
"ZRotation",
"YRotation",
"Vec3",
"Vec4",
"YRotation",
"XRotation",
"ZRotation",
"YRotation",
"XRotation",
"Vec3",
"Vec4",
"Vec3",
"m_deltaPhi_flat_wedge",
"m_deltaR_flat_ring",
"GetTrajectoryCoordinates"
],
"reverse": false,
"scrollbar_highlights": true,
"show_context": true,
"use_buffer2": true,
"use_gitignore": true,
"whole_word": false,
"wrap": true
},
"groups":
[
{
"sheets":
[
]
}
],
"incremental_find":
{
"height": 30.0
},
"input":
{
"height": 68.0
},
"layout":
{
"cells":
[
[
0,
0,
1,
1
]
],
"cols":
[
0.0,
1.0
],
"rows":
[
0.0,
1.0
]
},
"menu_visible": true,
"output.SublimeLinter":
{
"height": 132.0
},
"output.exec":
{
"height": 133.0
},
"output.find_results":
{
"height": 0.0
},
"output.mdpopups":
{
"height": 0.0
},
"pinned_build_system": "",
"project": "navigator.sublime-project",
"replace":
{
"height": 56.0
},
"save_all_on_build": true,
"select_file":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
],
"width": 0.0
},
"select_project":
{
"height": 500.0,
"last_filter": "",
"selected_items":
[
[
"",
"~/GWM_EventBuilder/eventbuilder.sublime-project"
]
],
"width": 380.0
},
"select_symbol":
{
"height": 0.0,
"last_filter": "",
"selected_items":
[
],
"width": 0.0
},
"selected_group": 0,
"settings":
{
},
"show_minimap": true,
"show_open_files": false,
"show_tabs": true,
"side_bar_visible": true,
"side_bar_width": 290.0,
"status_bar_visible": true,
"template_settings":
{
}
}

View File

@ -0,0 +1,171 @@
/*
CompassFile.cpp
Wrapper class around a shared pointer to an ifstream. Here the shared pointer is used
to overcome limitations of the ifstream class, namely that it is written such that ifstream
cannot be modified by move semantics. Contains all information needed to parse a single binary
CompassFile. Currently has a class wide defined buffer size; may want to make this user input
in the future.
Written by G.W. McCann Oct. 2020
*/
#include <navpch.h>
#include "CompassFile.h"
namespace Navigator {
CompassFile::CompassFile() :
m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_file(std::make_shared<std::ifstream>()), eofFlag(false)
{
m_buffersize = bufsize*hitsize;
hitBuffer.resize(m_buffersize);
}
CompassFile::CompassFile(const std::string& filename) :
m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_file(std::make_shared<std::ifstream>()), eofFlag(false)
{
m_buffersize = bufsize*hitsize;
hitBuffer.resize(m_buffersize);
Open(filename);
}
CompassFile::CompassFile(const std::string& filename, int bsize) :
m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true),
bufsize(bsize), m_file(std::make_shared<std::ifstream>()), eofFlag(false)
{
m_buffersize = bufsize*hitsize;
hitBuffer.resize(m_buffersize);
Open(filename);
}
CompassFile::~CompassFile()
{
Close();
}
void CompassFile::Open(const std::string& filename)
{
eofFlag = false;
hitUsedFlag = true;
m_filename = filename;
m_file->open(m_filename, std::ios::binary | std::ios::in);
m_file->seekg(0, std::ios_base::end);
m_size = m_file->tellg();
m_nHits = m_size/24;
if(m_size == 0)
{
eofFlag = true;
}
else
{
m_file->seekg(0, std::ios_base::beg);
}
}
void CompassFile::Close()
{
if(IsOpen())
{
m_file->close();
}
}
int CompassFile::GetHitSize()
{
if(!IsOpen())
{
EVB_WARN("Unable to get hit size from file {0}, sending invalid value.", m_filename);
return 0;
}
char* firstHit = new char[24]; //A compass hit by default has 24 bytes (at least in our setup)
m_file->read(firstHit, 24);
firstHit += 16;
int nsamples = *((uint32_t*) firstHit);
m_file->seekg(0, std::ios_base::beg);
delete[] firstHit;
return 24 + nsamples*16;
}
/*
GetNextHit() is the function which... gets the next hit
Has to check if the buffer needs refilled/filled for the first time
Upon pulling a hit, sets the UsedFlag to false, letting the next level know
that the hit should be free game.
If the file cannot be opened, signals as though file is EOF
*/
bool CompassFile::GetNextHit()
{
if(!IsOpen()) return true;
if((bufferIter == nullptr || bufferIter == bufferEnd) && !IsEOF())
{
GetNextBuffer();
}
if(!IsEOF())
{
ParseNextHit();
hitUsedFlag = false;
}
return eofFlag;
}
/*
GetNextBuffer() ... self-explanatory name
Note tht this is where the EOF flag is set. The EOF is only singaled
after the LAST buffer is completely read (i.e literally no more data). ifstream sets its eof
bit upon pulling the last buffer, but this class waits until that entire
last buffer is read to singal EOF (the true end of file).
*/
void CompassFile::GetNextBuffer()
{
if(m_file->eof())
{
eofFlag = true;
return;
}
m_file->read(hitBuffer.data(), hitBuffer.size());
bufferIter = hitBuffer.data();
bufferEnd = bufferIter + m_file->gcount(); //one past the last datum
}
void CompassFile::ParseNextHit()
{
m_currentHit.board = *((uint16_t*)bufferIter);
bufferIter += 2;
m_currentHit.channel = *((uint16_t*)bufferIter);
bufferIter += 2;
m_currentHit.timestamp = *((uint64_t*)bufferIter);
bufferIter += 8;
m_currentHit.lgate = *((uint16_t*)bufferIter);
bufferIter += 2;
m_currentHit.sgate = *((uint16_t*)bufferIter);
bufferIter += 2;
m_currentHit.flags = *((uint32_t*)bufferIter);
bufferIter += 4;
m_currentHit.Ns = *((uint32_t*)bufferIter);
bufferIter += 4;
if(m_smap != nullptr)
{ //memory safety
int gchan = m_currentHit.channel + m_currentHit.board*16;
m_currentHit.timestamp += m_smap->GetShift(gchan);
}
}
}

View File

@ -0,0 +1,73 @@
/*
CompassFile.h
Wrapper class around a shared pointer to an ifstream. Here the shared pointer is used
to overcome limitations of the ifstream class, namely that it is written such that ifstream
cannot be modified by move semantics. Contains all information needed to parse a single binary
CompassFile. Currently has a class wide defined buffer size; may want to make this user input
in the future.
Written by G.W. McCann Oct. 2020
*/
#ifndef COMPASSFILE_H
#define COMPASSFILE_H
#include "CompassHit.h"
#include "ShiftMap.h"
namespace Navigator {
class CompassFile
{
public:
CompassFile();
CompassFile(const std::string& filename);
CompassFile(const std::string& filename, int bsize);
~CompassFile();
void Open(const std::string& filename);
void Close();
bool GetNextHit();
inline bool IsOpen() const { return m_file->is_open(); };
inline CompassHit GetCurrentHit() const { return m_currentHit; }
inline std::string GetName() const { return m_filename; }
inline bool CheckHitHasBeenUsed() const { return hitUsedFlag; } //query to find out if we've used the current hit
inline void SetHitHasBeenUsed() { hitUsedFlag = true; } //flip the flag to indicate the current hit has been used
inline bool IsEOF() const { return eofFlag; } //see if we've read all available data
inline bool* GetUsedFlagPtr() { return &hitUsedFlag; }
inline void AttachShiftMap(ShiftMap* map) { m_smap = map; }
inline unsigned int GetSize() const { return m_size; }
inline unsigned int GetNumberOfHits() const { return m_nHits; }
private:
int GetHitSize();
void ParseNextHit();
void GetNextBuffer();
using Buffer = std::vector<char>;
using FilePointer = std::shared_ptr<std::ifstream>; //to make this class copy/movable
std::string m_filename;
Buffer hitBuffer;
char* bufferIter;
char* bufferEnd;
ShiftMap* m_smap; //NOT owned by CompassFile. DO NOT delete
bool hitUsedFlag;
int bufsize = 200000; //size of the buffer in hits
int hitsize = 24; //size of a CompassHit in bytes (without alignment padding)
int m_buffersize;
CompassHit m_currentHit;
FilePointer m_file;
bool eofFlag;
unsigned int m_size; //size of the file in bytes
unsigned int m_nHits; //number of hits in the file (m_size/24)
};
}
#endif

View File

@ -0,0 +1,19 @@
#ifndef COMPASS_HIT_H
#define COMPASS_HIT_H
namespace Navigator {
struct CompassHit
{
uint16_t board = 400;
uint16_t channel = 400;
uint64_t timestamp = 0;
uint16_t lgate = 0;
uint16_t sgate = 0;
uint32_t flags = 0;
uint32_t Ns = 0;
};
}
#endif

View File

@ -0,0 +1,543 @@
/*
CompassRun.cpp
Class designed as abstraction of a collection of binary files that represent the total data in a single
Compass data run. It handles the user input (shift maps, file collection etc.) and creates a list of
CompassFiles from which to draw data. It then draws data from these files, organizes them in time,
and writes to a ROOT file for further processing.
Written by G.W. McCann Oct. 2020
Updated to also handle scaler data. -- GWM Oct. 2020
*/
#include <navpch.h>
#include "CompassRun.h"
#include "RunCollector.h"
#include "SlowSort.h"
#include "FastSort.h"
#include "SFPAnalyzer.h"
#include "FlagHandler.h"
namespace Navigator {
CompassRun::CompassRun() :
m_directory(""), m_scalerinput(""), m_runNum(0), m_scaler_flag(false), m_progressFraction(0.1)
{
}
CompassRun::CompassRun(const std::string& dir) :
m_directory(dir), m_scalerinput(""), m_runNum(0), m_scaler_flag(false), m_progressFraction(0.1)
{
}
CompassRun::~CompassRun() {}
/*Load em into a map*/
void CompassRun::SetScalers()
{
std::ifstream input(m_scalerinput);
if(!input.is_open())
return;
m_scaler_flag = true;
std::string junk, filename, varname;
Long64_t init = 0;
std::getline(input, junk);
std::getline(input, junk);
m_scaler_map.clear();
while(input>>filename)
{
input>>varname;
filename = m_directory+filename+"_run_"+std::to_string(m_runNum)+".bin";
m_scaler_map[filename] = TParameter<Long64_t>(varname.c_str(), init);
}
input.close();
}
bool CompassRun::GetBinaryFiles()
{
std::string prefix = "";
std::string suffix = ".bin"; //binaries
RunCollector grabber(m_directory, prefix, suffix);
grabber.GrabAllFiles();
m_datafiles.clear(); //so that the CompassRun can be reused
m_datafiles.reserve(grabber.GetFileList().size());
bool scalerd;
m_totalHits = 0; //reset total run size
for(auto& entry : grabber.GetFileList())
{
//Handle scaler files, if they exist
if(m_scaler_flag)
{
scalerd = false;
for(auto& scaler_pair : m_scaler_map)
{
if(entry == scaler_pair.first)
{
ReadScalerData(entry);
scalerd = true;
break;
}
}
if(scalerd)
continue;
}
m_datafiles.emplace_back(entry);
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())
return false;
m_totalHits += m_datafiles[m_datafiles.size()-1].GetNumberOfHits();
}
return true;
}
/*
Pure counting of scalers. Potential upgrade path to something like
average count rate etc.
*/
void CompassRun::ReadScalerData(const std::string& filename)
{
if(!m_scaler_flag)
return;
Long64_t count;
count = 0;
CompassFile file(filename);
auto& this_param = m_scaler_map[file.GetName()];
while(true)
{
file.GetNextHit();
if(file.IsEOF())
break;
count++;
}
this_param.SetVal(count);
}
/*
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
to determine which file the data originally came from (short of parsing the name of the file against board/channel).
However, we need to let the file know that we want it to pull the next hit. To do this, a pointer to the UsedFlag of the file
is retrieved along with the data. This flag is flipped so that on the next hit cycle a new hit is pulled. Second is the use
of a rolling start index. Once a file has gone EOF, we no longer need it. If this is the first file in the list, we can just skip
that index all together. In this way, the loop can go from N times to N-1 times.
*/
bool CompassRun::GetHitsFromFiles()
{
std::pair<CompassHit, bool*> earliestHit = std::make_pair(CompassHit(), nullptr);
for(unsigned int i=startIndex; i<m_datafiles.size(); i++)
{
if(m_datafiles[i].CheckHitHasBeenUsed())
m_datafiles[i].GetNextHit();
if(m_datafiles[i].IsEOF())
{
if(i == startIndex)
startIndex++;
continue;
}
else if(i == startIndex)
{
earliestHit = std::make_pair(m_datafiles[i].GetCurrentHit(), m_datafiles[i].GetUsedFlagPtr());
}
else if(m_datafiles[i].GetCurrentHit().timestamp < earliestHit.first.timestamp)
{
earliestHit = std::make_pair(m_datafiles[i].GetCurrentHit(), m_datafiles[i].GetUsedFlagPtr());
}
}
if(earliestHit.second == nullptr)
return false; //Make sure that there actually was a hit
hit = earliestHit.first;
*earliestHit.second = true;
return true;
}
void CompassRun::Convert2RawRoot(const std::string& name) {
TFile* output = TFile::Open(name.c_str(), "RECREATE");
TTree* outtree = new TTree("Data", "Data");
outtree->Branch("Board", &hit.board);
outtree->Branch("Channel", &hit.channel);
outtree->Branch("Energy", &hit.lgate);
outtree->Branch("EnergyShort", &hit.sgate);
outtree->Branch("Timestamp", &hit.timestamp);
outtree->Branch("Flags", &hit.flags);
if(!m_smap.IsValid())
{
EVB_WARN("Bad shift map ({0}) at CompassRun::Convert(), shifts all set to 0.", m_smap.GetFilename());
}
SetScalers();
if(!GetBinaryFiles())
{
EVB_ERROR("Unable to find binary files at CompassRun::Convert(), exiting!");
return;
}
unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0;
startIndex = 0; //Reset the startIndex
if(flush == 0)
flush = 1;
while(true)
{
count++;
if(count == flush)
{ //Progress Log
count = 0;
flush_count++;
m_progressCallback(flush_count*flush, m_totalHits);
}
if(!GetHitsFromFiles())
break;
outtree->Fill();
}
output->cd();
outtree->Write(outtree->GetName(), TObject::kOverwrite);
for(auto& entry : m_scaler_map)
entry.second.Write();
output->Close();
}
void CompassRun::Convert2SortedRoot(const std::string& name, const std::string& mapfile, double window)
{
TFile* output = TFile::Open(name.c_str(), "RECREATE");
TTree* outtree = new TTree("SortTree", "SortTree");
outtree->Branch("event", &event);
if(!m_smap.IsValid())
{
EVB_WARN("Bad shift map ({0}) at CompassRun::Convert2SortedRoot(), shifts all set to 0.", m_smap.GetFilename());
}
SetScalers();
if(!GetBinaryFiles())
{
EVB_ERROR("Unable to find binary files at CompassRun::Convert2SortedRoot(), exiting!");
return;
}
unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0;
startIndex = 0;
SlowSort coincidizer(window, mapfile);
bool killFlag = false;
if(flush == 0)
flush = 1;
while(true)
{
count++;
if(count == flush)
{
count = 0;
flush_count++;
m_progressCallback(flush_count*flush, m_totalHits);
}
if(!GetHitsFromFiles())
{
coincidizer.FlushHitsToEvent();
killFlag = true;
}
else
coincidizer.AddHitToEvent(hit);
if(coincidizer.IsEventReady())
{
event = coincidizer.GetEvent();
outtree->Fill();
if(killFlag) break;
}
}
output->cd();
outtree->Write(outtree->GetName(), TObject::kOverwrite);
for(auto& entry : m_scaler_map)
entry.second.Write();
coincidizer.GetEventStats()->Write();
output->Close();
}
void CompassRun::Convert2FastSortedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window)
{
TFile* output = TFile::Open(name.c_str(), "RECREATE");
TTree* outtree = new TTree("SortTree", "SortTree");
outtree->Branch("event", &event);
if(!m_smap.IsValid())
{
EVB_WARN("Bad shift map ({0}) at CompassRun::Convert2FastSortedRoot(), shifts all set to 0.", m_smap.GetFilename());
}
SetScalers();
if(!GetBinaryFiles())
{
EVB_ERROR("Unable to find binary files at CompassRun::Convert2FastSortedRoot(), exiting!");
return;
}
unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0;
startIndex = 0;
CoincEvent this_event;
std::vector<CoincEvent> fast_events;
SlowSort coincidizer(window, mapfile);
FastSort speedyCoincidizer(fsi_window, fic_window);
FlagHandler flagger;
bool killFlag = false;
if(flush == 0)
flush = 1;
while(true)
{
count++;
if(count == flush)
{
count = 0;
flush_count++;
m_progressCallback(flush_count*flush, m_totalHits);
}
if(!GetHitsFromFiles())
{
coincidizer.FlushHitsToEvent();
killFlag = true;
}
else
{
flagger.CheckFlag(hit.board, hit.channel, hit.flags);
coincidizer.AddHitToEvent(hit);
}
if(coincidizer.IsEventReady())
{
this_event = coincidizer.GetEvent();
fast_events = speedyCoincidizer.GetFastEvents(this_event);
for(auto& entry : fast_events)
{
event = entry;
outtree->Fill();
}
if(killFlag)
break;
}
}
output->cd();
outtree->Write(outtree->GetName(), TObject::kOverwrite);
for(auto& entry : m_scaler_map)
entry.second.Write();
coincidizer.GetEventStats()->Write();
output->Close();
}
void CompassRun::Convert2SlowAnalyzedRoot(const std::string& name, const std::string& mapfile, double window,
int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta)
{
TFile* output = TFile::Open(name.c_str(), "RECREATE");
TTree* outtree = new TTree("SPSTree", "SPSTree");
outtree->Branch("event", &pevent);
if(!m_smap.IsValid())
{
EVB_WARN("Bad shift map ({0}) at CompassRun::Convert2SlowAnalyzedRoot(), shifts all set to 0.", m_smap.GetFilename());
}
SetScalers();
if(!GetBinaryFiles())
{
EVB_ERROR("Unable to find binary files at CompassRun::Convert2SlowAnalyzedRoot(), exiting!");
return;
}
unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0;
startIndex = 0;
CoincEvent this_event;
SlowSort coincidizer(window, mapfile);
SFPAnalyzer analyzer(zt, at, zp, ap, ze, ae, bke, theta, b);
std::vector<TParameter<Double_t>> parvec;
parvec.reserve(9);
parvec.emplace_back("ZT", zt);
parvec.emplace_back("AT", at);
parvec.emplace_back("ZP", zp);
parvec.emplace_back("AP", ap);
parvec.emplace_back("ZE", ze);
parvec.emplace_back("AE", ae);
parvec.emplace_back("Bfield", b);
parvec.emplace_back("BeamKE", bke);
parvec.emplace_back("Theta", theta);
bool killFlag = false;
if(flush == 0)
flush = 1;
while(true)
{
count++;
if(count == flush)
{
count = 0;
flush_count++;
m_progressCallback(flush_count*flush, m_totalHits);
}
if(!GetHitsFromFiles())
{
coincidizer.FlushHitsToEvent();
killFlag = true;
}
else
{
coincidizer.AddHitToEvent(hit);
}
if(coincidizer.IsEventReady())
{
this_event = coincidizer.GetEvent();
pevent = analyzer.GetProcessedEvent(this_event);
outtree->Fill();
if(killFlag)
break;
}
}
output->cd();
outtree->Write(outtree->GetName(), TObject::kOverwrite);
for(auto& entry : m_scaler_map)
entry.second.Write();
for(auto& entry : parvec)
entry.Write();
coincidizer.GetEventStats()->Write();
analyzer.GetHashTable()->Write();
analyzer.ClearHashTable();
output->Close();
}
void CompassRun::Convert2FastAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window,
int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta)
{
TFile* output = TFile::Open(name.c_str(), "RECREATE");
TTree* outtree = new TTree("SPSTree", "SPSTree");
outtree->Branch("event", &pevent);
if(!m_smap.IsValid())
{
EVB_WARN("Bad shift map ({0}) at CompassRun::Convert2FastAnalyzedRoot(), shifts all set to 0.", m_smap.GetFilename());
}
SetScalers();
if(!GetBinaryFiles())
{
EVB_ERROR("Unable to find binary files at CompassRun::Convert2FastAnalyzedRoot(), exiting!");
return;
}
unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0;
startIndex = 0;
CoincEvent this_event;
std::vector<CoincEvent> fast_events;
SlowSort coincidizer(window, mapfile);
FastSort speedyCoincidizer(fsi_window, fic_window);
SFPAnalyzer analyzer(zt, at, zp, ap, ze, ae, bke, theta, b);
std::vector<TParameter<Double_t>> parvec;
parvec.reserve(9);
parvec.emplace_back("ZT", zt);
parvec.emplace_back("AT", at);
parvec.emplace_back("ZP", zp);
parvec.emplace_back("AP", ap);
parvec.emplace_back("ZE", ze);
parvec.emplace_back("AE", ae);
parvec.emplace_back("Bfield", b);
parvec.emplace_back("BeamKE", bke);
parvec.emplace_back("Theta", theta);
FlagHandler flagger;
bool killFlag = false;
if(flush == 0)
flush = 1;
while(true)
{
count++;
if(count == flush)
{
count = 0;
flush_count++;
m_progressCallback(flush_count*flush, m_totalHits);
}
if(!GetHitsFromFiles())
{
coincidizer.FlushHitsToEvent();
killFlag = true;
}
else
{
flagger.CheckFlag(hit.board, hit.channel, hit.flags);
coincidizer.AddHitToEvent(hit);
}
if(coincidizer.IsEventReady())
{
this_event = coincidizer.GetEvent();
fast_events = speedyCoincidizer.GetFastEvents(this_event);
for(auto& entry : fast_events)
{
pevent = analyzer.GetProcessedEvent(entry);
outtree->Fill();
}
if(killFlag)
break;
}
}
output->cd();
outtree->Write(outtree->GetName(), TObject::kOverwrite);
for(auto& entry : m_scaler_map)
entry.second.Write();
for(auto& entry : parvec)
entry.Write();
coincidizer.GetEventStats()->Write();
analyzer.GetHashTable()->Write();
analyzer.ClearHashTable();
output->Close();
}
}

View File

@ -0,0 +1,74 @@
/*
CompassRun.h
Class designed as abstraction of a collection of binary files that represent the total data in a single
Compass data run. It handles the user input (shift maps, file collection etc.) and creates a list of
CompassFiles from which to draw data. It then draws data from these files, organizes them in time,
and writes to a ROOT file for further processing.
Written by G.W. McCann Oct. 2020
*/
#ifndef COMPASSRUN_H
#define COMPASSRUN_H
#include "CompassFile.h"
#include "DataStructs.h"
#include "RunCollector.h"
#include "ShiftMap.h"
#include "ProgressCallback.h"
#include <TParameter.h>
namespace Navigator {
class CompassRun
{
public:
CompassRun();
CompassRun(const std::string& dir);
~CompassRun();
inline void SetDirectory(const std::string& dir) { m_directory = dir; }
inline void SetScalerInput(const std::string& filename) { m_scalerinput = filename; }
inline void SetRunNumber(int n) { m_runNum = n; }
inline void SetShiftMap(const std::string& filename) { m_smap.SetFile(filename); }
void Convert2RawRoot(const std::string& name);
void Convert2SortedRoot(const std::string& name, const std::string& mapfile, double window);
void Convert2FastSortedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window);
void Convert2SlowAnalyzedRoot(const std::string& name, const std::string& mapfile, double window,
int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta);
void Convert2FastAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window,
int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta);
inline void SetProgressCallbackFunc(const ProgressCallbackFunc& function) { m_progressCallback = function; }
inline void SetProgressFraction(double frac) { m_progressFraction = frac; }
private:
bool GetBinaryFiles();
bool GetHitsFromFiles();
void SetScalers();
void ReadScalerData(const std::string& filename);
std::string m_directory, m_scalerinput;
std::vector<CompassFile> m_datafiles;
unsigned int startIndex; //this is the file we start looking at; increases as we finish files.
ShiftMap m_smap;
std::unordered_map<std::string, TParameter<Long64_t>> m_scaler_map; //maps scaler files to the TParameter to be saved
//Potential branch variables
CompassHit hit;
CoincEvent event;
ProcessedEvent pevent;
//what run is this
int m_runNum;
unsigned int m_totalHits;
//Scaler switch
bool m_scaler_flag;
ProgressCallbackFunc m_progressCallback;
double m_progressFraction;
};
}
#endif

0
src/Navigator/Logger.cpp Normal file
View File

5
src/Navigator/Logger.h Normal file
View File

@ -0,0 +1,5 @@
#ifndef LOGGER_H
#define LOGGER_H
#include "spdlog/spdlog.h"
#include "spdlog/fmt/"

View File

@ -0,0 +1,85 @@
/*
ShiftMap.h
New class to act a go-between for timestamp shifts to channels. Takes in a
formated file containing data for shifts and then stores them in an unordered_map.
Key is a global compass channel (board#*16 + channel). Shifts in ps.
Note: Timestamps are now shifted in binary conversion. This means that shifts *MUST*
be stored as Long64_t types. No decimals!
Written by G.W. McCann Oct. 2020
*/
#include <navpch.h>
#include "ShiftMap.h"
namespace Navigator {
ShiftMap::ShiftMap() :
m_filename(""), m_validFlag(false)
{
}
ShiftMap::ShiftMap(const std::string& filename) :
m_filename(filename), m_validFlag(false)
{
ParseFile();
}
ShiftMap::~ShiftMap() {}
void ShiftMap::SetFile(const std::string& filename)
{
m_filename = filename;
ParseFile();
}
uint64_t ShiftMap::GetShift(int gchan)
{
if(!m_validFlag)
return 0;
auto iter = m_map.find(gchan);
if(iter == m_map.end())
return 0;
else
return iter->second;
}
void ShiftMap::ParseFile()
{
m_validFlag = false;
std::ifstream input(m_filename);
if(!input.is_open())
return;
int board, channel, gchan;
uint64_t shift;
std::string junk, temp;
std::getline(input, junk);
std::getline(input, junk);
while(input>>board)
{
input>>temp;
input>>shift;
if(temp == "all") //keyword to set all channels in this board to same shift
{
for(int i=0; i<16; i++)
{
gchan = board*16 + i;
m_map[gchan] = shift;
}
}
else
{
channel = stoi(temp);
gchan = channel + board*16;
m_map[gchan] = shift;
}
}
m_validFlag = true;
}
}

40
src/Navigator/ShiftMap.h Normal file
View File

@ -0,0 +1,40 @@
/*
ShiftMap.h
New class to act a go-between for timestamp shifts to channels. Takes in a
formated file containing data for shifts and then stores them in an unordered_map.
Key is a global compass channel (board#*16 + channel). Shifts in ps.
Note: Timestamps are now shifted in binary conversion. This means that shifts *MUST*
be stored as Long64_t types. No decimals!
Written by G.W. McCann Oct. 2020
*/
#ifndef SHIFTMAP_H
#define SHIFTMAP_H
namespace Navigator {
class ShiftMap
{
public:
ShiftMap();
ShiftMap(const std::string& filename);
~ShiftMap();
void SetFile(const std::string& filename);
inline bool IsValid() { return m_validFlag; }
inline std::string GetFilename() { return m_filename; }
uint64_t GetShift(int gchan);
private:
void ParseFile();
std::string m_filename;
bool m_validFlag;
std::unordered_map<int, uint64_t> m_map;
};
}
#endif

20
src/navpch.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef NAVPCH_H
#define NAVPCH_H
#include <iostream>
#include <fstream>
#include <memory>
#include <utility>
#include <algorithm>
#include <functional>
#include <string>
#include <sstream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <cstdint>
#endif