commit 6e11a95205186bd75e9e4de69ff598f158cb7b3a Author: Gordon McCann Date: Sat Dec 18 16:29:07 2021 -0500 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..16ba64b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.o +*.so +*.a + +!.gitignore \ No newline at end of file diff --git a/navigator.sublime-project b/navigator.sublime-project new file mode 100644 index 0000000..adc9cbc --- /dev/null +++ b/navigator.sublime-project @@ -0,0 +1,12 @@ +{ + "folders": + [ + { + "path": "." + } + ], + "settings": + { + "SublimeLinter.linters.g++.args": ["-c","-Wall","-fsyntax-only","-std=c++17","-include${folder}/src/navpch.h","-Isrc/"] + } +} \ No newline at end of file diff --git a/navigator.sublime-workspace b/navigator.sublime-workspace new file mode 100644 index 0000000..d94f4eb --- /dev/null +++ b/navigator.sublime-workspace @@ -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": + { + } +} diff --git a/src/Navigator/CompassFile.cpp b/src/Navigator/CompassFile.cpp new file mode 100644 index 0000000..964a1fc --- /dev/null +++ b/src/Navigator/CompassFile.cpp @@ -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 +#include "CompassFile.h" + +namespace Navigator { + + CompassFile::CompassFile() : + m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_file(std::make_shared()), 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()), 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()), 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); + } + + } + +} \ No newline at end of file diff --git a/src/Navigator/CompassFile.h b/src/Navigator/CompassFile.h new file mode 100644 index 0000000..b0b31d7 --- /dev/null +++ b/src/Navigator/CompassFile.h @@ -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; + + using FilePointer = std::shared_ptr; //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 diff --git a/src/Navigator/CompassHit.h b/src/Navigator/CompassHit.h new file mode 100644 index 0000000..f2d292f --- /dev/null +++ b/src/Navigator/CompassHit.h @@ -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 diff --git a/src/Navigator/CompassRun.cpp b/src/Navigator/CompassRun.cpp new file mode 100644 index 0000000..e159861 --- /dev/null +++ b/src/Navigator/CompassRun.cpp @@ -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 +#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(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 earliestHit = std::make_pair(CompassHit(), nullptr); + for(unsigned int i=startIndex; iBranch("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 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> 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 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> 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(); + } +} \ No newline at end of file diff --git a/src/Navigator/CompassRun.h b/src/Navigator/CompassRun.h new file mode 100644 index 0000000..85375ed --- /dev/null +++ b/src/Navigator/CompassRun.h @@ -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 + +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 m_datafiles; + unsigned int 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; + 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 diff --git a/src/Navigator/Logger.cpp b/src/Navigator/Logger.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/Navigator/Logger.h b/src/Navigator/Logger.h new file mode 100644 index 0000000..b7e9745 --- /dev/null +++ b/src/Navigator/Logger.h @@ -0,0 +1,5 @@ +#ifndef LOGGER_H +#define LOGGER_H + +#include "spdlog/spdlog.h" +#include "spdlog/fmt/" \ No newline at end of file diff --git a/src/Navigator/ShiftMap.cpp b/src/Navigator/ShiftMap.cpp new file mode 100644 index 0000000..f7aca80 --- /dev/null +++ b/src/Navigator/ShiftMap.cpp @@ -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 +#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; + } + +} \ No newline at end of file diff --git a/src/Navigator/ShiftMap.h b/src/Navigator/ShiftMap.h new file mode 100644 index 0000000..08751a0 --- /dev/null +++ b/src/Navigator/ShiftMap.h @@ -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 m_map; + + }; + +} + +#endif diff --git a/src/navpch.h b/src/navpch.h new file mode 100644 index 0000000..54deab9 --- /dev/null +++ b/src/navpch.h @@ -0,0 +1,20 @@ +#ifndef NAVPCH_H +#define NAVPCH_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + + +#endif \ No newline at end of file