Merge pull request #3 from sesps/devel

Update to new CoMPASS binary format (ver > 2.0) and switch to more compatible cmake build system
This commit is contained in:
Gordon McCann 2022-06-30 13:02:44 -04:00 committed by GitHub
commit 93c8f6f5df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 284 additions and 415 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@ pics/
images/ images/
build/ build/
objs/ objs/
.vscode/
###file types to ignore### ###file types to ignore###
*.swp *.swp

20
CMakeLists.txt Normal file
View File

@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.16)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_POSITION_INDEPENDENT_CODE On)
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_BUILD_TYPE "Release")
message("Building release")
else()
message("Building debug")
endif()
project(SPS_SABRE_EventBuilder)
find_package(ROOT REQUIRED COMPONENTS Gui)
set(EVB_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin)
set(EVB_LIBRARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib)
add_subdirectory(src)

View File

@ -1,22 +1,22 @@
# SPS-SABRE Data Analysis Package # SPS-SABRE Data Analysis Package
Version 4 Version 4
This is a software package designed to help experimenters analyze data from SPS-SABRE at FSU. This is a software package designed to help experimenters analyze data from SPS-SABRE at FSU.
It can convert CoMPASS data to ROOT, sort the data in time, build events, perform preliminary analysis and provide basic plots. Programs are built using make, and a make file is included. Simply using the command make will build all programs. It can convert CoMPASS data to ROOT, sort the data in time, build events, perform preliminary analysis and provide basic plots.
WHEN TESTING, RUN WITH WIDE WINDOWS
## Installation ## Installation
To install the event builder, the Premake build system is used. To install Premake, simply go to the [Premake](https://premake.github.io/) site and Download the right prebuilt binary for your system (there's no need to try and build from source). Place the binary in a location on your path so that you can call it on the commandline by simply typing `premake5`. To build and install the event builder, the CMake build system is used. To build, simply run the following commands from the SPS_SABRE_EventBuilder directory:
```
mkdir build
cd build
cmake ..
make
```
To clone the repository use `git clone --recursive https://github.com/sesps/SPS_SABRE_EventBuilder.git`. If you're using the devel branch be sure to specify this with the `--branch` flag. The recursive flag is important; this tells github to pull all submodules associated with the repository. To clone the repository use `git clone --recursive https://github.com/sesps/SPS_SABRE_EventBuilder.git`. If you're using the devel branch be sure to specify this with the `--branch` flag. The recursive flag is important; this tells github to pull all submodules associated with the repository.
Once the repository is cloned, go into the event builder directory and locate the file `premake5.lua`. This is the file which contains the build rules for this project. You will need to specify the location of your `ROOT` install so that we can properly find headers and libraries using the parameters ROOTIncludeDir and ROOTLibDir (lines 8 and 9 of premake5.lua). On unix style systems these paths can be found easily using the `root-config` tool. Simply run `root-config --cflags` and copy the path after the `-I` to ROOTIncludeDir and run `root-config --glibs` and copy the path after the `-L` to ROOTLibDir. Once the `ROOT` paths are set, run the command `premake5 gmake2` on Linux or Mac for a Makefile style build, or `premake5 Xcode4` to build an XCode project on Mac. Then the program can be built using the standard methods of the chosen build type (i.e. `make` or XCode Build).
The binaries are installed to the `bin` directory of the event builder, and should be run from the event builder directory (i.e. `./bin/EventBuilderGui`). The binaries are installed to the `bin` directory of the event builder, and should be run from the event builder directory (i.e. `./bin/EventBuilderGui`).
In general, one should only build for Release (this is the default), for maximum optimization. However, it can be useful to run in Debug (in make do `make config=debug`) when testing new features. In general, one should only build for Release (this is the default), for maximum optimization. However, it can be useful to run in Debug (change the cmake command to `cmake -DCMAKE_BUILD_TYPE_DEBUG ..`) when testing new features.
Note: On Mac, if you have XCode installed, it is best to build through XCode. Results when linking can be unreliable otherwise.
## EventBuilder vs. EventBuilderGui ## EventBuilder vs. EventBuilderGui
There are two programs provided. They are `EventBuilderGui` and `EventBuilder`. The first is a full GUI version of the event builder. The GUI supports all conversion methods and the plotting tool. There are two programs provided. They are `EventBuilderGui` and `EventBuilder`. The first is a full GUI version of the event builder. The GUI supports all conversion methods and the plotting tool.
@ -90,6 +90,6 @@ size (again center the peak on 0, the width of the peak becomes the fast window)
Currently the pipeline supports declaring individual digitizer channels as scalers. These channels will be used a pure counting measures. To make a channel a scaler, put the CoMPASS formated name of the channel and board (check the given etc/ScalerFile.txt for an example) in a text file along with a parameter name for the scaler to be saved as. These files are then processed outside of the event building loop, which can greatly increase the computational speed. Future versions will include scaler rates as well. Currently the pipeline supports declaring individual digitizer channels as scalers. These channels will be used a pure counting measures. To make a channel a scaler, put the CoMPASS formated name of the channel and board (check the given etc/ScalerFile.txt for an example) in a text file along with a parameter name for the scaler to be saved as. These files are then processed outside of the event building loop, which can greatly increase the computational speed. Future versions will include scaler rates as well.
## System Requirements ## System Requirements
Only tested with `ROOT` 6.14, mileage may vary - Requires ROOT version which supports CMake dictionary generation
Uses C++11 standards - Requires CMake > 3.16
Only compatible with MacOSX and Linux - This version is for data from CAEN CoMPASS > 2.0. Data from older CoMPASS versions are not compatible.

5
include/.gitignore vendored
View File

@ -1,5 +0,0 @@
###ignore pch###
*.gch
###include this###
!.gitignore

View File

@ -1,82 +0,0 @@
/*DataStructs.h
*Data structures for analysis. To be implemented as a dictionary for ROOT in LinkDef
*Based on: FocalPlane_SABRE.h
*Gordon M. Oct. 2019
*/
#ifndef DATA_STRUCTS_H
#define DATA_STRUCTS_H
#include <vector>
struct DPPChannel
{
double Timestamp;
int Channel, Board, Energy, EnergyShort;
int Flags;
};
struct DetectorHit
{
double Long=-1, Short=-1, Time=-1;
int Ch=-1;
};
struct SabreDetector
{
std::vector<DetectorHit> rings;
std::vector<DetectorHit> wedges;
};
struct FPDetector
{
std::vector<DetectorHit> delayFL, delayFR, delayBL, delayBR;
std::vector<DetectorHit> anodeF, anodeB, scintL, scintR, cathode;
std::vector<DetectorHit> monitor;
};
struct CoincEvent
{
FPDetector focalPlane;
SabreDetector sabreArray[5]; //index = ChannelMap Id# -1
};
struct ProcessedEvent
{
double fp1_tdiff = -1e6, fp2_tdiff = -1e6, fp1_tsum = -1, fp2_tsum = -1,
fp1_tcheck = -1, fp2_tcheck = -1;
double fp1_y=-1, fp2_y=-1;
double anodeFront = -1, anodeBack = -1, scintRight = -1, scintLeft = -1;
double scintRightShort = -1, scintLeftShort = -1;
double cathode = -1;
double xavg = -1e6, x1 = -1e6, x2 = -1e6;
double theta = -1e6;
double sabreRingE[5] = {-1,-1,-1,-1,-1}, sabreWedgeE[5] = {-1,-1,-1,-1,-1};
double sabreRingChannel[5] = {-1,-1,-1,-1,-1}, sabreWedgeChannel[5] = {-1,-1,-1,-1,-1};
double sabreRingTime[5] = {-1,-1,-1,-1,-1}, sabreWedgeTime[5] = {-1,-1,-1,-1,-1};
double delayFrontRightE = -1, delayFrontLeftE = -1;
double delayBackRightE = -1, delayBackLeftE = -1;
double delayFrontRightShort = -1, delayFrontLeftShort = -1;
double delayBackRightShort = -1, delayBackLeftShort = -1;
double anodeFrontTime = -1, anodeBackTime = -1;
double scintRightTime = -1, scintLeftTime = -1;
double delayFrontMaxTime = -1, delayBackMaxTime = -1;
double delayFrontLeftTime = -1, delayFrontRightTime = -1;
double delayBackLeftTime = -1, delayBackRightTime = -1;
double cathodeTime = -1;
double monitorE = -1, monitorShort = -1;
double monitorTime = -1;
SabreDetector sabreArray[5]; //index = ChannelMap Id# -1
};
/*
ROOT does a bad job of ensuring that header-only type dictionaries (the only type they explicity accept)
are linked when compiled as shared libraries (the recommended method). As a work around, as a dummy function that
ensures the library is linked (better than no-as-needed which I dont think is in general supported across platforms)
*/
bool EnforceDictionaryLinked();
#endif

7
lib/.gitignore vendored
View File

@ -1,7 +0,0 @@
###ignore these files####
*.dylib
*.so
*.pcm
###keep this one###
!.gitignore

View File

@ -1,217 +0,0 @@
workspace "EVB"
architecture "x64"
configurations {
"Release",
"Debug"
}
ROOTIncludeDir = "/home/gordon/cern/root-6.22.02/root-install/include"
ROOTLibDir = "/home/gordon/cern/root-6.22.02/root-install/lib"
project "SPSDict"
kind "SharedLib"
language "C++"
cppdialect "c++11"
targetdir "./lib/"
objdir "./objs/"
prebuildcommands {
"rootcint -f src/spsdict/sps_dict.cxx src/spsdict/DataStructs.h src/spsdict/LinkDef_sps.h",
"{COPY} src/spsdict/*.pcm ./lib/"
}
postbuildcommands {
"{COPY} src/spsdict/DataStructs.h ./include/"
}
files {
"src/spsdict/DataStructs.h",
"src/spsdict/*.cpp",
"src/spsdict/*.cxx"
}
includedirs {
"./",
"src/spsdict",
}
sysincludedirs {
ROOTIncludeDir
}
libdirs {
ROOTLibDir
}
links {
"Gui", "Core", "Imt", "RIO", "Net", "Hist",
"Graf", "Graf3d", "Gpad", "ROOTDataFrame", "ROOTVecOps",
"Tree", "TreePlayer", "Rint", "Postscript", "Matrix",
"Physics", "MathCore", "Thread", "MultiProc", "m", "dl"
}
filter "system:macosx or linux"
linkoptions {
"-pthread",
"-rdynamic"
}
filter "configurations:Debug"
symbols "On"
filter "configurations:Release"
optimize "On"
project "EventBuilderCore"
kind "StaticLib"
language "C++"
cppdialect "c++11"
targetdir "./lib/"
objdir "./objs/"
pchheader "EventBuilder.h"
pchsource "./src/EventBuilder.cpp"
files {
"src/spsdict/DataStructs.h",
"src/evb/*.cpp",
"src/evb/*.h"
}
defines "ETC_DIR_PATH=\"./etc/\""
includedirs {
"./",
"src/",
"vendor/spdlog/include",
"src/evb",
"src/spsdict",
"src/guidict"
}
sysincludedirs {
ROOTIncludeDir
}
libdirs {
ROOTLibDir,
}
links {
"SPSDict", "Gui", "Core", "Imt", "RIO", "Net", "Hist",
"Graf", "Graf3d", "Gpad", "ROOTDataFrame", "ROOTVecOps",
"Tree", "TreePlayer", "Rint", "Postscript", "Matrix",
"Physics", "MathCore", "Thread", "MultiProc", "m", "dl"
}
filter "system:macosx or linux"
linkoptions {
"-pthread",
"-rdynamic"
}
filter "configurations:Debug"
symbols "On"
filter "configurations:Release"
optimize "On"
project "EventBuilderGui"
kind "ConsoleApp"
language "C++"
cppdialect "c++11"
targetdir "./bin/"
objdir "./objs/"
prebuildcommands {
"rootcint -f src/guidict/gui_dict.cxx src/guidict/EVBMainFrame.h src/guidict/FileViewFrame.h src/guidict/LinkDef_Gui.h",
"{COPY} src/guidict/*.pcm ./bin/"
}
files {
"src/guidict/FileViewFrame.h",
"src/guidict/EVBMainFrame.h",
"src/guidict/*.cpp",
"src/guidict/gui_dict.cxx",
"src/gui_main.cpp"
}
includedirs {
"./",
"vendor/spdlog/include",
"src/evb",
"src/spsdict",
"src/guidict"
}
sysincludedirs {
ROOTIncludeDir
}
libdirs {
ROOTLibDir,
}
links {
"EventBuilderCore", "SPSDict", "Gui", "Core", "Imt", "RIO", "Net", "Hist",
"Graf", "Graf3d", "Gpad", "ROOTDataFrame", "ROOTVecOps",
"Tree", "TreePlayer", "Rint", "Postscript", "Matrix",
"Physics", "MathCore", "Thread", "MultiProc", "m", "dl"
}
filter "system:macosx or linux"
linkoptions {
"-pthread",
"-rdynamic"
}
filter "configurations:Debug"
symbols "On"
filter "configurations:Release"
optimize "On"
project "EventBuilder"
kind "ConsoleApp"
language "C++"
cppdialect "c++11"
targetdir "./bin/"
objdir "./objs/"
files {
"src/main.cpp"
}
includedirs {
"src/",
"vendor/spdlog/include",
"src/evb",
"src/spsdict",
"src/guidict"
}
sysincludedirs {
ROOTIncludeDir
}
libdirs {
ROOTLibDir,
}
links {
"EventBuilderCore", "SPSDict", "Gui", "Core", "Imt", "RIO", "Net", "Hist",
"Graf", "Graf3d", "Gpad", "ROOTDataFrame", "ROOTVecOps",
"Tree", "TreePlayer", "Rint", "Postscript", "Matrix",
"Physics", "MathCore", "Thread", "MultiProc", "m", "dl"
}
filter "system:macosx or linux"
linkoptions {
"-pthread",
"-rdynamic"
}
filter "configurations:Debug"
symbols "On"
filter "configurations:Release"
optimize "On"

3
src/.gitignore vendored
View File

@ -1,3 +0,0 @@
###ignore the root dictionary generated file###
*.cxx
!.gitignore

25
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,25 @@
add_subdirectory(spsdict)
add_subdirectory(guidict)
add_subdirectory(evb)
add_executable(EventBuilder)
target_include_directories(EventBuilder SYSTEM PUBLIC ../vendor/spdlog/include ${ROOT_INCLUDE_DIRS} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_sources(EventBuilder PRIVATE main.cpp)
target_link_libraries(EventBuilder
SPSDict
EventBuilderCore
${ROOT_LIBRARIES}
)
set_target_properties(EventBuilder PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${EVB_BINARY_DIR})
add_executable(EventBuilderGui)
target_include_directories(EventBuilderGui SYSTEM PUBLIC ../vendor/spdlog/include ${ROOT_INCLUDE_DIRS} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_sources(EventBuilderGui PRIVATE gui_main.cpp)
target_link_libraries(EventBuilderGui
SPSDict
GuiDict
EventBuilderCore
${ROOT_LIBRARIES}
)
set_target_properties(EventBuilderGui PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${EVB_BINARY_DIR})

52
src/evb/CMakeLists.txt Normal file
View File

@ -0,0 +1,52 @@
add_library(EventBuilderCore STATIC)
target_include_directories(EventBuilderCore SYSTEM PUBLIC ../../vendor/spdlog/include ${ROOT_INCLUDE_DIRS}
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../
)
target_precompile_headers(EventBuilderCore PRIVATE ../EventBuilder.h)
target_sources(EventBuilderCore PRIVATE
ChannelMap.cpp
CompassRun.h
FlagHandler.cpp
MassLookup.h
SFPAnalyzer.h
Stopwatch.cpp
ChannelMap.h
CutHandler.cpp
FlagHandler.h
OrderChecker.cpp
SFPPlotter.cpp
Stopwatch.h
CutHandler.h
FP_kinematics.cpp
OrderChecker.h
SFPPlotter.h
CompassFile.cpp
EVBApp.cpp
FP_kinematics.h
ProgressCallback.h
ShiftMap.cpp
CompassFile.h
EVBApp.h
Logger.cpp
RunCollector.cpp
ShiftMap.h
CompassHit.h
FastSort.cpp
Logger.h
RunCollector.h
SlowSort.cpp
CompassRun.cpp
FastSort.h
MassLookup.cpp
SFPAnalyzer.cpp
SlowSort.h
)
target_link_libraries(EventBuilderCore PUBLIC
SPSDict
${ROOT_LIBRARIES}
)
set_target_properties(EventBuilderCore PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${EVB_LIBRARY_DIR})

View File

@ -14,26 +14,22 @@
namespace EventBuilder { namespace EventBuilder {
CompassFile::CompassFile() : CompassFile::CompassFile() :
m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_file(std::make_shared<std::ifstream>()), eofFlag(false) m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_hitsize(0), m_buffersize(0),
m_file(std::make_shared<std::ifstream>()), m_eofFlag(false)
{ {
m_buffersize = bufsize*hitsize;
hitBuffer.resize(m_buffersize);
} }
CompassFile::CompassFile(const std::string& filename) : 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_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_hitsize(0), m_buffersize(0),
m_file(std::make_shared<std::ifstream>()), m_eofFlag(false)
{ {
m_buffersize = bufsize*hitsize;
hitBuffer.resize(m_buffersize);
Open(filename); Open(filename);
} }
CompassFile::CompassFile(const std::string& filename, int bsize) : CompassFile::CompassFile(const std::string& filename, int bsize) :
m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_bufsize(bsize), m_hitsize(0),
bufsize(bsize), m_file(std::make_shared<std::ifstream>()), eofFlag(false) m_buffersize(0), m_file(std::make_shared<std::ifstream>()), m_eofFlag(false)
{ {
m_buffersize = bufsize*hitsize;
hitBuffer.resize(m_buffersize);
Open(filename); Open(filename);
} }
@ -44,21 +40,24 @@ namespace EventBuilder {
void CompassFile::Open(const std::string& filename) void CompassFile::Open(const std::string& filename)
{ {
eofFlag = false; m_eofFlag = false;
hitUsedFlag = true; m_hitUsedFlag = true;
m_filename = filename; m_filename = filename;
m_file->open(m_filename, std::ios::binary | std::ios::in); m_file->open(m_filename, std::ios::binary | std::ios::in);
m_file->seekg(0, std::ios_base::end); m_file->seekg(0, std::ios_base::end);
m_size = m_file->tellg(); m_size = m_file->tellg();
m_nHits = m_size/24; if(m_size == 2)
if(m_size == 0)
{ {
eofFlag = true; m_eofFlag = true;
} }
else else
{ {
m_file->seekg(0, std::ios_base::beg); m_file->seekg(0, std::ios_base::beg);
ReadHeader();
m_nHits = m_size/m_hitsize;
m_buffersize = m_hitsize*m_bufsize;
m_hitBuffer.resize(m_buffersize);
} }
} }
@ -70,27 +69,39 @@ namespace EventBuilder {
} }
} }
int CompassFile::GetHitSize() void CompassFile::ReadHeader()
{ {
if(!IsOpen()) if(!IsOpen())
{ {
EVB_WARN("Unable to get hit size from file {0}, sending invalid value.", m_filename); EVB_WARN("Unable to read header from file. State not validated", m_filename);
return 0; return;
} }
char* firstHit = new char[24]; //A compass hit by default has 24 bytes (at least in our setup) char* header = new char[2];
m_file->read(header, 2);
m_file->read(firstHit, 24); m_header = *((uint16_t*)header);
m_hitsize = 16; //default hitsize of 16 bytes
firstHit += 16; if(IsEnergy())
int nsamples = *((uint32_t*) firstHit); m_hitsize += 2;
if(IsEnergyCalibrated())
m_file->seekg(0, std::ios_base::beg); m_hitsize += 8;
if(IsEnergyShort())
delete[] firstHit; m_hitsize += 2;
if(IsWaves())
return 24 + nsamples*16; {
EVB_ERROR("Waveforms are not supported by the SPS_SABRE_EventBuilder. The wave data will be skipped.");
m_hitsize += 5;
char* firstHit = new char[m_hitsize]; //A compass hit by default has 24 bytes (at least in our setup)
m_file->read(firstHit, m_hitsize);
firstHit += m_hitsize - 4;
uint32_t nsamples = *((uint32_t*) firstHit);
m_hitsize += nsamples * 2; //Each sample is a 2 byte data value
m_file->seekg(0, std::ios_base::beg);
m_file->read(header, 2);
delete[] firstHit;
}
delete[] header;
} }
/* /*
@ -105,7 +116,7 @@ namespace EventBuilder {
{ {
if(!IsOpen()) return true; if(!IsOpen()) return true;
if((bufferIter == nullptr || bufferIter == bufferEnd) && !IsEOF()) if((m_bufferIter == nullptr || m_bufferIter == m_bufferEnd) && !IsEOF())
{ {
GetNextBuffer(); GetNextBuffer();
} }
@ -113,10 +124,10 @@ namespace EventBuilder {
if(!IsEOF()) if(!IsEOF())
{ {
ParseNextHit(); ParseNextHit();
hitUsedFlag = false; m_hitUsedFlag = false;
} }
return eofFlag; return m_eofFlag;
} }
/* /*
@ -131,34 +142,52 @@ namespace EventBuilder {
if(m_file->eof()) if(m_file->eof())
{ {
eofFlag = true; m_eofFlag = true;
return; return;
} }
m_file->read(hitBuffer.data(), hitBuffer.size()); m_file->read(m_hitBuffer.data(), m_hitBuffer.size());
bufferIter = hitBuffer.data(); m_bufferIter = m_hitBuffer.data();
bufferEnd = bufferIter + m_file->gcount(); //one past the last datum m_bufferEnd = m_bufferIter + m_file->gcount(); //one past the last datum
} }
void CompassFile::ParseNextHit() void CompassFile::ParseNextHit()
{ {
m_currentHit.board = *((uint16_t*)bufferIter); m_currentHit.board = *((uint16_t*)m_bufferIter);
bufferIter += 2; m_bufferIter += 2;
m_currentHit.channel = *((uint16_t*)bufferIter); m_currentHit.channel = *((uint16_t*)m_bufferIter);
bufferIter += 2; m_bufferIter += 2;
m_currentHit.timestamp = *((uint64_t*)bufferIter); m_currentHit.timestamp = *((uint64_t*)m_bufferIter);
bufferIter += 8; m_bufferIter += 8;
m_currentHit.lgate = *((uint16_t*)bufferIter); if(IsEnergy())
bufferIter += 2; {
m_currentHit.sgate = *((uint16_t*)bufferIter); m_currentHit.energy = *((uint16_t*)m_bufferIter);
bufferIter += 2; m_bufferIter += 2;
m_currentHit.flags = *((uint32_t*)bufferIter); }
bufferIter += 4; if(IsEnergyCalibrated())
m_currentHit.Ns = *((uint32_t*)bufferIter); {
bufferIter += 4; m_currentHit.energyCalibrated = *((uint64_t*)m_bufferIter);
m_bufferIter += 8;
}
if(IsEnergyShort())
{
m_currentHit.energyShort = *((uint16_t*)m_bufferIter);
m_bufferIter += 2;
}
m_currentHit.flags = *((uint32_t*)m_bufferIter);
m_bufferIter += 4;
if(IsWaves())
{
m_currentHit.waveCode = *((uint8_t*)m_bufferIter);
m_bufferIter += 1;
m_currentHit.Ns = *((uint32_t*)m_bufferIter);
m_bufferIter += 4;
m_bufferIter += 2*m_currentHit.Ns;
//Skip wavedata for SPS_SABRE_EventBuilder
}
if(m_smap != nullptr) if(m_smap != nullptr)
{ //memory safety { //memory safety

View File

@ -32,41 +32,55 @@ namespace EventBuilder {
inline bool IsOpen() const { return m_file->is_open(); }; inline bool IsOpen() const { return m_file->is_open(); };
inline CompassHit GetCurrentHit() const { return m_currentHit; } inline CompassHit GetCurrentHit() const { return m_currentHit; }
inline std::string GetName() const { return m_filename; } 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 bool CheckHitHasBeenUsed() const { return m_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 void SetHitHasBeenUsed() { m_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 IsEOF() const { return m_eofFlag; } //see if we've read all available data
inline bool* GetUsedFlagPtr() { return &hitUsedFlag; } inline bool* GetUsedFlagPtr() { return &m_hitUsedFlag; }
inline void AttachShiftMap(ShiftMap* map) { m_smap = map; } inline void AttachShiftMap(ShiftMap* map) { m_smap = map; }
inline unsigned int GetSize() const { return m_size; } inline unsigned int GetSize() const { return m_size; }
inline unsigned int GetNumberOfHits() const { return m_nHits; } inline unsigned int GetNumberOfHits() const { return m_nHits; }
private: private:
int GetHitSize(); void ReadHeader();
void ParseNextHit(); void ParseNextHit();
void GetNextBuffer(); void GetNextBuffer();
inline bool IsEnergy() { return (m_header & CoMPASSHeaders::Energy) != 0; }
inline bool IsEnergyCalibrated() { return (m_header & CoMPASSHeaders::EnergyCalibrated) != 0; }
inline bool IsEnergyShort() { return (m_header & CoMPASSHeaders::EnergyShort) != 0; }
inline bool IsWaves() { return (m_header & CoMPASSHeaders::Waves) != 0; }
using Buffer = std::vector<char>; using Buffer = std::vector<char>;
using FilePointer = std::shared_ptr<std::ifstream>; //to make this class copy/movable using FilePointer = std::shared_ptr<std::ifstream>; //to make this class copy/movable
std::string m_filename; std::string m_filename;
Buffer hitBuffer; Buffer m_hitBuffer;
char* bufferIter; char* m_bufferIter;
char* bufferEnd; char* m_bufferEnd;
ShiftMap* m_smap; //NOT owned by CompassFile. DO NOT delete ShiftMap* m_smap; //NOT owned by CompassFile. DO NOT delete
bool hitUsedFlag; bool m_hitUsedFlag;
int bufsize = 200000; //size of the buffer in hits int m_bufsize = 200000; //size of the buffer in hits
int hitsize = 24; //size of a CompassHit in bytes (without alignment padding) int m_hitsize; //size of a CompassHit in bytes (without alignment padding)
uint16_t m_header;
int m_buffersize; int m_buffersize;
CompassHit m_currentHit; CompassHit m_currentHit;
FilePointer m_file; FilePointer m_file;
bool eofFlag; bool m_eofFlag;
unsigned int m_size; //size of the file in bytes unsigned int m_size; //size of the file in bytes
unsigned int m_nHits; //number of hits in the file (m_size/24) unsigned int m_nHits; //number of hits in the file (m_size/24)
enum CoMPASSHeaders
{
Energy = 0x0001,
EnergyCalibrated = 0x0002,
EnergyShort = 0x0004,
Waves = 0x0008,
};
}; };
} }

View File

@ -3,16 +3,18 @@
namespace EventBuilder { namespace EventBuilder {
struct CompassHit struct CompassHit
{ {
uint16_t board = 400; uint16_t board = 400;
uint16_t channel = 400; uint16_t channel = 400;
uint64_t timestamp = 0; uint64_t timestamp = 0;
uint16_t lgate = 0; uint16_t energy = 0;
uint16_t sgate = 0; uint64_t energyCalibrated = 0;
uint32_t flags = 0; uint16_t energyShort = 0;
uint32_t Ns = 0; uint32_t flags = 0;
}; uint8_t waveCode = 0;
uint32_t Ns = 0;
};
} }

View File

@ -49,7 +49,7 @@ namespace EventBuilder {
while(input>>filename) while(input>>filename)
{ {
input>>varname; input>>varname;
filename = m_directory+filename+"_run_"+std::to_string(m_runNum)+".bin"; filename = m_directory+filename+"_run_"+std::to_string(m_runNum)+".BIN";
m_scaler_map[filename] = TParameter<Long64_t>(varname.c_str(), init); m_scaler_map[filename] = TParameter<Long64_t>(varname.c_str(), init);
} }
input.close(); input.close();
@ -58,7 +58,7 @@ namespace EventBuilder {
bool CompassRun::GetBinaryFiles() bool CompassRun::GetBinaryFiles()
{ {
std::string prefix = ""; std::string prefix = "";
std::string suffix = ".bin"; //binaries std::string suffix = ".BIN"; //binaries
RunCollector grabber(m_directory, prefix, suffix); RunCollector grabber(m_directory, prefix, suffix);
grabber.GrabAllFiles(); grabber.GrabAllFiles();
@ -168,8 +168,8 @@ namespace EventBuilder {
outtree->Branch("Board", &hit.board); outtree->Branch("Board", &hit.board);
outtree->Branch("Channel", &hit.channel); outtree->Branch("Channel", &hit.channel);
outtree->Branch("Energy", &hit.lgate); outtree->Branch("Energy", &hit.energy);
outtree->Branch("EnergyShort", &hit.sgate); outtree->Branch("EnergyShort", &hit.energyShort);
outtree->Branch("Timestamp", &hit.timestamp); outtree->Branch("Timestamp", &hit.timestamp);
outtree->Branch("Flags", &hit.flags); outtree->Branch("Flags", &hit.flags);

View File

@ -178,7 +178,7 @@ namespace EventBuilder {
EVB_INFO("Converting file {0}...", binfile); 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; unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
wipe_command = "rm -r "+unpack_dir+"*.bin"; wipe_command = "rm -r "+unpack_dir+"*.BIN";
sys_return = system(unpack_command.c_str()); sys_return = system(unpack_command.c_str());
converter.Convert2RawRoot(rawfile); converter.Convert2RawRoot(rawfile);
@ -238,7 +238,7 @@ namespace EventBuilder {
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; unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
wipe_command = "rm -r "+unpack_dir+"*.bin"; wipe_command = "rm -r "+unpack_dir+"*.BIN";
sys_return = system(unpack_command.c_str()); sys_return = system(unpack_command.c_str());
converter.Convert2SortedRoot(sortfile, m_mapfile, m_SlowWindow); converter.Convert2SortedRoot(sortfile, m_mapfile, m_SlowWindow);
@ -281,7 +281,7 @@ namespace EventBuilder {
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; unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
wipe_command = "rm -r "+unpack_dir+"*.bin"; wipe_command = "rm -r "+unpack_dir+"*.BIN";
sys_return = system(unpack_command.c_str()); sys_return = system(unpack_command.c_str());
converter.Convert2FastSortedRoot(sortfile, m_mapfile, m_SlowWindow, m_FastWindowSABRE, m_FastWindowIonCh); converter.Convert2FastSortedRoot(sortfile, m_mapfile, m_SlowWindow, m_FastWindowSABRE, m_FastWindowIonCh);
@ -324,7 +324,7 @@ namespace EventBuilder {
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; unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
wipe_command = "rm -r "+unpack_dir+"*.bin"; wipe_command = "rm -r "+unpack_dir+"*.BIN";
sys_return = system(unpack_command.c_str()); sys_return = system(unpack_command.c_str());
converter.Convert2SlowAnalyzedRoot(sortfile, m_mapfile, m_SlowWindow, m_ZT, m_AT, m_ZP, m_AP, m_ZE, m_AE, m_BKE, m_B, m_Theta); converter.Convert2SlowAnalyzedRoot(sortfile, m_mapfile, m_SlowWindow, m_ZT, m_AT, m_ZP, m_AP, m_ZE, m_AE, m_BKE, m_B, m_Theta);
@ -368,7 +368,7 @@ namespace EventBuilder {
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; unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
wipe_command = "rm -r "+unpack_dir+"*.bin"; wipe_command = "rm -r "+unpack_dir+"*.BIN";
sys_return = system(unpack_command.c_str()); sys_return = system(unpack_command.c_str());
converter.Convert2FastAnalyzedRoot(sortfile, m_mapfile, m_SlowWindow, m_FastWindowSABRE, m_FastWindowIonCh, m_ZT, m_AT, m_ZP, m_AP, m_ZE, m_AE, m_BKE, m_B, m_Theta); converter.Convert2FastAnalyzedRoot(sortfile, m_mapfile, m_SlowWindow, m_FastWindowSABRE, m_FastWindowIonCh, m_ZT, m_AT, m_ZP, m_AP, m_ZE, m_AE, m_BKE, m_B, m_Theta);

View File

@ -140,9 +140,9 @@ namespace EventBuilder {
if(ev.sabreRingE[i] != -1) //Again, at this point front&back are required if(ev.sabreRingE[i] != -1) //Again, at this point front&back are required
{ {
MyFill(table,"sabreRingE_NoCuts",2000,0,20,ev.sabreRingE[i]); MyFill(table,"sabreRingE_NoCuts",2000,0,20,ev.sabreRingE[i]);
MyFill(table,"sabreRingChannel_sabreRingE_NoCuts",144,0,144,ev.sabreRingChannel[i],200,0,20,ev.sabreRingE[i]); MyFill(table,"sabreRingChannel_sabreRingE_NoCuts",144,0,144,ev.sabreRingChannel[i],4096,0,16384,ev.sabreRingE[i]);
MyFill(table,"sabreWedgeE_NoCuts",2000,0,20,ev.sabreWedgeE[i]); MyFill(table,"sabreWedgeE_NoCuts",2000,0,20,ev.sabreWedgeE[i]);
MyFill(table,"sabreWedgeChannel_sabreWedgeE_NoCuts",144,0,144,ev.sabreWedgeChannel[i],200,0,20,ev.sabreWedgeE[i]); MyFill(table,"sabreWedgeChannel_sabreWedgeE_NoCuts",144,0,144,ev.sabreWedgeChannel[i],4096,0,16384,ev.sabreWedgeE[i]);
} }
} }

View File

@ -76,8 +76,8 @@ namespace EventBuilder {
{ {
DPPChannel curHit; DPPChannel curHit;
curHit.Timestamp = mhit.timestamp; curHit.Timestamp = mhit.timestamp;
curHit.Energy = mhit.lgate; curHit.Energy = mhit.energy;
curHit.EnergyShort = mhit.sgate; curHit.EnergyShort = mhit.energyShort;
curHit.Channel = mhit.channel; curHit.Channel = mhit.channel;
curHit.Board = mhit.board; curHit.Board = mhit.board;
curHit.Flags = mhit.flags; curHit.Flags = mhit.flags;

View File

@ -0,0 +1,23 @@
add_library(GuiDict SHARED)
target_include_directories(GuiDict SYSTEM PUBLIC ../../vendor/spdlog/include/ ${ROOT_INCLUDE_DIRS} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
ROOT_GENERATE_DICTIONARY(gui_dict EVBMainFrame.h FileViewFrame.h LINKDEF LinkDef_Gui.h MODULE GuiDict)
target_sources(GuiDict PRIVATE
FileViewFrame.h
FileViewFrame.cpp
EVBMainFrame.h
EVBMainFrame.cpp
)
target_link_libraries(GuiDict
EventBuilderCore
SPSDict
${ROOT_LIBRARIES}
)
set_target_properties(GuiDict PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${EVB_LIBRARY_DIR})
add_custom_command(TARGET GuiDict POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/libGuiDict_rdict.pcm
${EVB_LIBRARY_DIR}/libGuiDict_rdict.pcm
)

View File

@ -0,0 +1,17 @@
add_library(SPSDict SHARED)
target_include_directories(SPSDict SYSTEM PUBLIC ${ROOT_INCLUDE_DIRS} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
ROOT_GENERATE_DICTIONARY(sps_dict DataStructs.h LINKDEF LinkDef_sps.h MODULE SPSDict)
target_sources(SPSDict PRIVATE
DataStructs.h
DataStructs.cpp
)
target_link_libraries(SPSDict ${ROOT_LIBRARIES})
set_target_properties(SPSDict PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${EVB_LIBRARY_DIR})
add_custom_command(TARGET SPSDict POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/libSPSDict_rdict.pcm
${EVB_LIBRARY_DIR}/libSPSDict_rdict.pcm
)