mirror of
https://github.com/sesps/EventBuilder_Skeleton.git
synced 2024-11-25 11:38:51 -05:00
Merge pull request #1 from sesps/devel
Merging up changes. Highlights: switch to cmake and support new binary data structures of CoMPASS > 2.0
This commit is contained in:
commit
11adde1c57
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,12 +1,12 @@
|
|||
###directories to ignore###
|
||||
./rootfiles/
|
||||
./pics/
|
||||
./images/
|
||||
./hotfixes/
|
||||
.vscode/
|
||||
build/
|
||||
|
||||
###file types to ignore###
|
||||
*.swp
|
||||
*.o
|
||||
*.so
|
||||
*.a
|
||||
*.cxx
|
||||
*.root
|
||||
*.bin
|
||||
|
@ -15,6 +15,8 @@
|
|||
*.png
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
*.make
|
||||
Makefile
|
||||
event_log.txt
|
||||
.DS_Store
|
||||
|
||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "vendor/spdlog"]
|
||||
path = vendor/spdlog
|
||||
url = https://github.com/gabime/spdlog.git
|
20
CMakeLists.txt
Normal file
20
CMakeLists.txt
Normal 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(EventBuilder_Skeleton)
|
||||
|
||||
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)
|
25
README.md
25
README.md
|
@ -3,8 +3,18 @@ This is a program designed to be a launching point for event building data from
|
|||
|
||||
This code can in princple work with any setup that uses CAEN digitizers, as it requires no knowledge of the physical setup other than a coincidence window. It can also be used to build waveform data (THIS HAS NOT BEEN FULLY TESTED).
|
||||
|
||||
## GWMEVB vs. GWMEVB_CL
|
||||
There are two programs provided. They are `GWMEVB` and `GWMEVB_CL`. The first is a full GUI version of the event builder. The GUI supports all conversion methods and the plotting tool. The second is a commandline version.
|
||||
## Installation
|
||||
To install, first pull the repository and all submodules using `git clone --recursive https://github.com/sesps/EventBuilder_Skeleton.git`. The repository uses the CMake build system. To install simply run the following commands (for UNIX)
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
The executables are located in the `bin` directory of the EventBuilder_Skeleton, and should be run from the EventBuilder_Skeleton directory (as in `./bin/EventBuilderGui`).
|
||||
|
||||
## EventBuilder vs. EventBuilderGui
|
||||
There are two programs provided. They are `EventBuilder` and `EventBuilderGui`. The second is a full GUI version of the event builder. The GUI supports all conversion methods and the plotting tool. The first is a commandline version.
|
||||
|
||||
### Building Events
|
||||
The event building operation is the bulk of the analysis process. As files are being converted to ROOT from the raw CoMPASS binary, events are built using information given by the user. In particular the code asks the user to specify a workspace (a top level directory which contains the following sub directories: raw_binary, temp_binary, raw_root, sorted), a shift file, a scaler file, a coincidence window, and the size of the file buffer in number of hits.
|
||||
|
@ -31,11 +41,6 @@ The program is capable of merging several root files together using either `hadd
|
|||
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
|
||||
Only tested with `ROOT` 6.14, mileage may vary
|
||||
Uses C++11 standards
|
||||
Only compatible with MacOSX and Linux
|
||||
|
||||
## Compliling and Running
|
||||
To compile use the command `make`
|
||||
To clean run `make clean` and then run `make`
|
||||
For a complete rebuild use `make clean_header` as well as `make clean`.
|
||||
- Requires ROOT version which supports CMake dictionary generation
|
||||
- Requires CMake > 3.16
|
||||
- This version is for data from CAEN CoMPASS > 2.0. Data from older CoMPASS versions are not compatible.
|
|
@ -1,3 +0,0 @@
|
|||
Format: scaler_param_name assoc_binary_file_name_without_runID
|
||||
NOTE: As of this version, scalers are pure counting parameters (the total events will be counted and saved as a TParameter with the data)
|
||||
Data_CH5@V1730_89 beamint
|
|
@ -1,12 +0,0 @@
|
|||
Format: board channel/keyword shift
|
||||
NOTE: Do not delete these lines! If no shift is specified for a channel, no shift is applied. Use keyword 'all' to apply a uniform shift to all channels in a single board. Shifts are in ps.
|
||||
0 all 110000
|
||||
1 all 70000
|
||||
2 all 70000
|
||||
3 all -115000
|
||||
4 all 185000
|
||||
5 all 195000
|
||||
6 all 225000
|
||||
7 all 235000
|
||||
8 0 650000
|
||||
8 1 650000
|
11
etc/logo.txt
11
etc/logo.txt
|
@ -1,11 +0,0 @@
|
|||
_
|
||||
| |
|
||||
| |
|
||||
___ _ __ ___ ___ ____ _| |__ _ _______
|
||||
/ __|| ' \/ __|/ __| / __ ` | _ \| '__/ __ \
|
||||
\__ \| |\ \__ \\__ \| | | | | | | | | |__| |
|
||||
__) | |/ /__) |__) | |__| | |_| | | | ___/
|
||||
|___/| .__/|___/____/ \____,_|____/|_| \____|
|
||||
| |
|
||||
| |
|
||||
|_|
|
|
@ -1,3 +0,0 @@
|
|||
Format: scaler_param_name assoc_binary_file_name_without_runID
|
||||
NOTE: As of this version, scalers are pure counting parameters (the total events will be counted and saved as a TParameter with the data)
|
||||
CH5@V1730_89_Data beamint
|
|
@ -1,12 +0,0 @@
|
|||
Format: board channel/keyword shift
|
||||
NOTE: Do not delete these lines! If no shift is specified for a channel, no shift is applied. Use keyword 'all' to apply a uniform shift to all channels in a single board. Shifts are in ps.
|
||||
0 all 110000
|
||||
1 all 70000
|
||||
2 all 70000
|
||||
3 all 135000
|
||||
4 all 185000
|
||||
5 all 195000
|
||||
6 all 225000
|
||||
7 all 235000
|
||||
8 0 650000
|
||||
8 1 650000
|
5
include/.gitignore
vendored
5
include/.gitignore
vendored
|
@ -1,5 +0,0 @@
|
|||
###ignore pch###
|
||||
*.gch
|
||||
|
||||
###include this###
|
||||
!.gitignore
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
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"
|
||||
#include <memory>
|
||||
|
||||
class CompassFile {
|
||||
public:
|
||||
CompassFile();
|
||||
CompassFile(const std::string& filename);
|
||||
CompassFile(const std::string& filename, unsigned int bsize);
|
||||
~CompassFile();
|
||||
void Open(const std::string& filename);
|
||||
void Close();
|
||||
inline bool IsOpen() { return m_file->is_open(); };
|
||||
bool GetNextHit();
|
||||
inline CompassHit GetCurrentHit() const { return m_currentHit; };
|
||||
inline std::string GetName() { return m_filename; };
|
||||
inline bool CheckHitHasBeenUsed() { 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() { 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() { return m_size; };
|
||||
inline unsigned int GetNumberOfHits() { return m_nHits; };
|
||||
|
||||
|
||||
private:
|
||||
unsigned 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;
|
||||
unsigned int bufsize = 200000; //size of the buffer in hits
|
||||
unsigned int hitsize = 24; //size of a CompassHit in bytes (without alignment padding)
|
||||
unsigned 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
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef COMPASS_HIT_H
|
||||
#define COMPASS_HIT_H
|
||||
|
||||
struct CompassHit {
|
||||
UShort_t board = 400;
|
||||
UShort_t channel = 400;
|
||||
ULong64_t timestamp = 0;
|
||||
UShort_t lgate = 0;
|
||||
UShort_t sgate = 0;
|
||||
UInt_t flags = 0;
|
||||
UInt_t Ns = 0;
|
||||
std::vector<Int_t> samples;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
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 <TParameter.h>
|
||||
#include <TGProgressBar.h>
|
||||
#include <TSystem.h>
|
||||
|
||||
class CompassRun {
|
||||
public:
|
||||
CompassRun();
|
||||
CompassRun(const std::string& dir, unsigned int bsize);
|
||||
~CompassRun();
|
||||
inline void SetDirectory(const std::string& dir) { directory = dir; };
|
||||
inline void SetScalerInput(const std::string& filename) { m_scalerinput = filename; };
|
||||
inline void SetRunNumber(int n) { runNum = n; };
|
||||
inline void SetShiftMap(const std::string& filename) { m_smap.SetFile(filename); };
|
||||
void Convert2RawRoot(const std::string& name);
|
||||
void Convert2SortedRoot(const std::string& name, double window);
|
||||
|
||||
inline void AttachProgressBar(TGProgressBar* pb) { m_pb = pb; };
|
||||
|
||||
private:
|
||||
bool GetBinaryFiles();
|
||||
bool GetHitsFromFiles();
|
||||
void SetScalers();
|
||||
void ReadScalerData(const std::string& filename);
|
||||
void SetProgressBar();
|
||||
|
||||
std::string 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;
|
||||
std::vector<DPPChannel> event;
|
||||
|
||||
//what run is this
|
||||
int runNum;
|
||||
unsigned int m_totalHits;
|
||||
unsigned int m_buffersize;
|
||||
|
||||
//Scaler switch
|
||||
bool m_scaler_flag;
|
||||
|
||||
//GUI progress bar, if attached
|
||||
TGProgressBar* m_pb;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,18 +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
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct DPPChannel {
|
||||
Double_t Timestamp;
|
||||
Int_t Channel, Board, Energy, EnergyShort;
|
||||
Int_t Flags;
|
||||
vector<Int_t> Samples;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,59 +0,0 @@
|
|||
#ifndef FLAGHANDLER_H
|
||||
#define FLAGHANDLER_H
|
||||
|
||||
#include <map>
|
||||
|
||||
struct FlagCount {
|
||||
long total_counts=0;
|
||||
long dead_time=0;
|
||||
long time_roll=0;
|
||||
long time_reset=0;
|
||||
long fake_event=0;
|
||||
long mem_full=0;
|
||||
long trig_lost=0;
|
||||
long n_trig_lost=0;
|
||||
long sat_in_gate=0;
|
||||
long trig_1024=0;
|
||||
long sat_input=0;
|
||||
long n_trig_count=0;
|
||||
long event_not_matched=0;
|
||||
long fine_time=0;
|
||||
long pile_up=0;
|
||||
long pll_lock_loss=0;
|
||||
long over_temp=0;
|
||||
long adc_shutdown=0;
|
||||
};
|
||||
|
||||
class FlagHandler {
|
||||
public:
|
||||
FlagHandler();
|
||||
FlagHandler(const std::string& filename);
|
||||
~FlagHandler();
|
||||
void CheckFlag(int board, int channel, int flag);
|
||||
|
||||
const int DEAD_TIME = 0x00000001;
|
||||
const int TIME_ROLLOVER = 0x00000002;
|
||||
const int TIME_RESET = 0x00000004;
|
||||
const int FAKE_EVENT = 0x00000008;
|
||||
const int MEM_FULL = 0x00000010;
|
||||
const int TRIG_LOST = 0x00000020;
|
||||
const int N_TRIG_LOST = 0x00000040;
|
||||
const int SATURATING_IN_GATE = 0x00000080;
|
||||
const int TRIG_1024_COUNTED = 0x00000100;
|
||||
const int SATURATING_INPUT = 0x00000400;
|
||||
const int N_TRIG_COUNTED = 0x00000800;
|
||||
const int EVENT_NOT_MATCHED = 0x00001000;
|
||||
const int FINE_TIME = 0x00004000;
|
||||
const int PILE_UP = 0x00008000;
|
||||
const int PLL_LOCK_LOSS = 0x00080000;
|
||||
const int OVER_TEMP = 0x00100000;
|
||||
const int ADC_SHUTDOWN = 0x00200000;
|
||||
|
||||
private:
|
||||
std::ofstream log;
|
||||
std::map<int, FlagCount> event_count_map;
|
||||
|
||||
void WriteLog();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
GWMEventBuilder.h
|
||||
Class which represents the API of the event building environment. Wraps together the core concepts
|
||||
of the event builder, from conversion to plotting. Even intended to be able to archive data.
|
||||
Currently under development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#ifndef GWMEVENTBUILDER_H
|
||||
#define GWMEVENTBUILDER_H
|
||||
|
||||
#include "RunCollector.h"
|
||||
#include <TGProgressBar.h>
|
||||
|
||||
class GWMEventBuilder {
|
||||
public:
|
||||
GWMEventBuilder();
|
||||
~GWMEventBuilder();
|
||||
|
||||
bool ReadConfigFile(const std::string& filename);
|
||||
void WriteConfigFile(const std::string& filename);
|
||||
|
||||
void MergeROOTFiles();
|
||||
void Convert2SortedRoot();
|
||||
void Convert2RawRoot();
|
||||
|
||||
inline void SetAnalysisType(int type) { m_analysisType = type;};
|
||||
inline int GetAnalysisType() { return m_analysisType; };
|
||||
|
||||
inline void SetRunRange(int rmin, int rmax) { m_rmin = rmin; m_rmax = rmax; };
|
||||
inline void SetWorkDirectory(const std::string& fullpath) { m_workspace = fullpath; };
|
||||
inline void SetBoardShiftFile(const std::string& name) { m_shiftfile = name; };
|
||||
inline void SetScalerFile(const std::string& name) { m_scalerfile = name; };
|
||||
inline void SetSlowCoincidenceWindow(double window) { m_SlowWindow = window; };
|
||||
inline void SetBufferSize(unsigned int size) { m_buffersize = size; };
|
||||
|
||||
inline int GetRunMin() {return m_rmin;};
|
||||
inline int GetRunMax() {return m_rmax;};
|
||||
inline std::string GetWorkDirectory() {return m_workspace;};
|
||||
inline double GetSlowCoincidenceWindow() { return m_SlowWindow; };
|
||||
inline std::string GetBoardShiftFile() { return m_shiftfile; };
|
||||
inline std::string GetScalerFile() { return m_scalerfile; };
|
||||
inline unsigned int GetBufferSize() { return m_buffersize; };
|
||||
|
||||
inline void AttachProgressBar(TGProgressBar* pb) { m_pb = pb; };
|
||||
|
||||
enum BuildType {
|
||||
CONVERT,
|
||||
CONVERT_S,
|
||||
MERGE
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
int m_rmin, m_rmax;
|
||||
|
||||
std::string m_workspace;
|
||||
std::string m_shiftfile;
|
||||
std::string m_scalerfile;
|
||||
|
||||
double m_SlowWindow;
|
||||
|
||||
int m_analysisType;
|
||||
unsigned int m_buffersize;
|
||||
|
||||
RunCollector grabber;
|
||||
|
||||
TGProgressBar* m_pb;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,50 +0,0 @@
|
|||
/*RunCollector.h
|
||||
*Class that searches through a directory looking for files of a specified format.
|
||||
*Stores all filenames in a vector which can be accessed by other functions/classes for
|
||||
*further use. Can also use Merge() to combine all files using hadd into a single file.
|
||||
*Merge() is NOT RECOMMENDED in the analyzer program.
|
||||
*
|
||||
*Created Jan2020 by GWM
|
||||
*/
|
||||
|
||||
#ifndef RUNCOLLECTOR_H
|
||||
#define RUNCOLLECTOR_H
|
||||
|
||||
#include <TSystemDirectory.h>
|
||||
#include <TSystemFile.h>
|
||||
#include <TCollection.h>
|
||||
#include <TList.h>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class RunCollector {
|
||||
public:
|
||||
RunCollector();
|
||||
RunCollector(const string& dirname, const string& prefix, const string& suffix);
|
||||
RunCollector(const string& dirname, const string& prefix, const string& suffix, int min, int max);
|
||||
~RunCollector();
|
||||
void SetSearchParams(const string& dirname, const string& prefix, const string& suffix, int min, int max);
|
||||
int Merge_hadd(const string& outname);
|
||||
int Merge_TChain(const string& outname);
|
||||
int GrabAllFiles();
|
||||
int GrabFilesInRange();
|
||||
std::string GrabFile(int runNum);
|
||||
inline std::string GetSearchDir() {return dir.Data();};
|
||||
inline std::string GetSearchPrefix() {return run.Data();};
|
||||
inline std::string GetSearchSuffix() {return end.Data();};
|
||||
inline int GetRunMin() {return MinRun;};
|
||||
inline int GetRunMax() {return MaxRun;};
|
||||
vector<TString> filelist;
|
||||
|
||||
private:
|
||||
bool initFlag;
|
||||
TString dir;
|
||||
TString run;
|
||||
TString end;
|
||||
Int_t MaxRun, MinRun; //user run limits
|
||||
const Int_t LITERALMAX = 1000; //class run limit
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,50 +0,0 @@
|
|||
/*SlowSort.h
|
||||
*Class designed to first time-order raw data, and then based on a given coincidence window
|
||||
*sort the raw data into coincidence structures. Utilizes dictionary elements DPPChannel and
|
||||
*CoincEvent. Based on work by S. Balak, K. Macon, and E. Good from LSU.
|
||||
*
|
||||
*Gordon M. Oct. 2019
|
||||
*
|
||||
*Refurbished and updated Jan 2020 GWM
|
||||
*/
|
||||
#ifndef SLOW_SORT_H
|
||||
#define SLOW_SORT_H
|
||||
|
||||
#include "CompassHit.h"
|
||||
#include "DataStructs.h"
|
||||
#include <TH2.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class SlowSort {
|
||||
|
||||
public:
|
||||
SlowSort();
|
||||
SlowSort(double windowSize);
|
||||
~SlowSort();
|
||||
inline void SetWindowSize(double window) { coincWindow = window; };
|
||||
bool AddHitToEvent(CompassHit& mhit);
|
||||
vector<DPPChannel> GetEvent();
|
||||
inline TH2F* GetEventStats() { return event_stats; };
|
||||
void FlushHitsToEvent(); //For use with *last* hit list
|
||||
inline bool IsEventReady() { return eventFlag; };
|
||||
|
||||
private:
|
||||
void InitVariableMaps();
|
||||
void Reset();
|
||||
void StartEvent();
|
||||
void ProcessEvent();
|
||||
|
||||
double coincWindow;
|
||||
vector<DPPChannel> hitList;
|
||||
vector<DPPChannel> event;
|
||||
bool eventFlag;
|
||||
DPPChannel hit;
|
||||
|
||||
double startTime, previousHitTime;
|
||||
|
||||
TH2F* event_stats;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
Stopwatch.h
|
||||
Simple class designed to provide timing info on parts of the process.
|
||||
Only for use in development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#ifndef STOPWATCH_H
|
||||
#define STOPWATCH_H
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class Stopwatch {
|
||||
|
||||
public:
|
||||
Stopwatch();
|
||||
~Stopwatch();
|
||||
void Start();
|
||||
void Stop();
|
||||
double GetElapsedSeconds();
|
||||
double GetElapsedMilliseconds();
|
||||
|
||||
private:
|
||||
using Time = std::chrono::high_resolution_clock::time_point;
|
||||
using Clock = std::chrono::high_resolution_clock;
|
||||
|
||||
Time start_time, stop_time;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,15 +1,15 @@
|
|||
-------Data Location----------
|
||||
WorkspaceDirectory: /home/gwm17/working/GWM_EventBuilder/example
|
||||
WorkspaceDirectory: /home/gwm17/EventBuilder_Skeleton/example
|
||||
-------------------------------
|
||||
------Experimental Inputs------
|
||||
ScalerFile: /home/gwm17/working/GWM_EventBuilder/etc/ScalerFile.txt
|
||||
ScalerFile: /home/gwm17/EventBuilder_Skeleton/etc/ScalerFile.txt
|
||||
-------------------------------
|
||||
-------Timing Information------
|
||||
BoardOffsetFile: /home/gwm17/working/GWM_EventBuilder/etc/ShiftMap_April2020_newFormat_10102020.txt
|
||||
BoardOffsetFile: /home/gwm17/EventBuilder_Skeleton/etc/ShiftMap_April2020_newFormat_10102020.txt
|
||||
SlowCoincidenceWindow(ps): 1.5e+06
|
||||
-------------------------------
|
||||
--------Run Information--------
|
||||
MinRun: 75
|
||||
MaxRun: 75
|
||||
BufferSize(hits): 200000
|
||||
BufferSize: 200000
|
||||
-------------------------------
|
||||
|
|
7
lib/.gitignore
vendored
7
lib/.gitignore
vendored
|
@ -1,7 +0,0 @@
|
|||
###ignore these files####
|
||||
*.dylib
|
||||
*.so
|
||||
*.pcm
|
||||
|
||||
###keep this one###
|
||||
!.gitignore
|
96
makefile
96
makefile
|
@ -1,96 +0,0 @@
|
|||
OS_NAME := $(shell uname -s)
|
||||
CC=g++
|
||||
ROOTCFLAGS= `root-config --cflags`
|
||||
ROOTGLIBS=`root-config --glibs`
|
||||
|
||||
ROOTDICT_INCL=./
|
||||
CFLAGS= -std=c++11 -fPIC -g -Wall $(ROOTCFLAGS)
|
||||
INCLDIR=./include
|
||||
SRCDIR=./src
|
||||
BINDIR=./bin
|
||||
LIBDIR=./lib
|
||||
CPPFLAGS= -I$(INCLDIR)
|
||||
LDFLAGS=$(ROOTGLIBS)
|
||||
|
||||
EVBSRCDIR=$(SRCDIR)/evb
|
||||
GUISRCDIR=$(SRCDIR)/gui
|
||||
|
||||
OBJDIR=./objs
|
||||
|
||||
EVBSRC=$(wildcard $(EVBSRCDIR)/*.cpp)
|
||||
GUISRC=$(wildcard $(GUISRCDIR)/*.cpp)
|
||||
EVBOBJS=$(EVBSRC:$(EVBSRCDIR)/%.cpp=$(OBJDIR)/%.o)
|
||||
GUIOBJS=$(GUISRC:$(GUISRCDIR)/%.cpp=$(OBJDIR)/%.o)
|
||||
|
||||
DICT_PAGES= $(INCLDIR)/DataStructs.h $(INCLDIR)/LinkDef_evb.h
|
||||
DICT=$(SRCDIR)/evb_dict.cxx
|
||||
DICTOBJ=$(OBJDIR)/evb_dict.o
|
||||
DICTLIB=$(LIBDIR)/libEVBDict
|
||||
|
||||
GDICT_PAGES=$(INCLDIR)/EVBMainFrame.h $(INCLDIR)/FileViewFrame.h $(INCLDIR)/LinkDef_Gui.h
|
||||
GDICT=$(SRCDIR)/gui_dict.cxx
|
||||
GDICTOBJ=$(OBJDIR)/gui_dict.o
|
||||
|
||||
#entry points
|
||||
EVBGUIMSRC=$(SRCDIR)/gui_main.cpp
|
||||
EVBGUIMAIN=$(OBJDIR)/gui_main.o
|
||||
|
||||
EVBMSRC=$(SRCDIR)/main.cpp
|
||||
EVBMAIN=$(OBJDIR)/main.o
|
||||
|
||||
PCH_FILE=$(INCLDIR)/EventBuilder.h
|
||||
PCH=$(INCLDIR)/EventBuilder.h.gch
|
||||
|
||||
EVBEXE=$(BINDIR)/GWMEVB
|
||||
EVBCLEXE=$(BINDIR)/GWMEVB_CL
|
||||
|
||||
EXES = $(EVBEXE) $(EVBCLEXE)
|
||||
OBJS = $(EVBOBJS) $(GUIOBJS) $(DICTOBJ) $(GDICTOBJ) $(EVBGUIMAIN) $(EVBMAIN)
|
||||
|
||||
|
||||
.PHONY: all clean clean_header
|
||||
|
||||
all: $(PCH) $(EVBEXE) $(EVBCLEXE)
|
||||
|
||||
$(PCH): $(PCH_FILE)
|
||||
$(CC) $(CFLAGS) -x c++-header $^
|
||||
|
||||
$(EVBEXE): $(DICTOBJ) $(GDICTOBJ) $(EVBOBJS) $(GUIOBJS) $(EVBGUIMAIN)
|
||||
$(CC) $^ -o $@ $(LDFLAGS)
|
||||
|
||||
$(EVBCLEXE): $(DICTOBJ) $(EVBOBJS) $(EVBMAIN)
|
||||
$(CC) $^ -o $@ $(LDFLAGS)
|
||||
|
||||
$(DICTOBJ): $(DICT)
|
||||
$(CC) $(CFLAGS) -I $(ROOTDICT_INCL) -o $@ -c $^
|
||||
ifeq ($(OS_NAME), Darwin)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $@ -dynamiclib -o $(DICTLIB).dylib
|
||||
cp $(SRCDIR)/*.pcm $(LIBDIR)
|
||||
else
|
||||
ifeq ($(OS_NAME), Linux)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $@ -shared -o $(DICTLIB).so
|
||||
cp $(SRCDIR)/*.pcm $(LIBDIR)
|
||||
endif
|
||||
endif
|
||||
mv $(SRCDIR)/*.pcm ./$(BINDIR)/
|
||||
|
||||
$(GDICTOBJ): $(GDICT)
|
||||
$(CC) $(CFLAGS) -I $(ROOTDICT_INCL) -o $@ -c $^
|
||||
mv $(SRCDIR)/*.pcm $(BINDIR)/
|
||||
|
||||
$(DICT): $(DICT_PAGES)
|
||||
rootcint -f $@ $^
|
||||
|
||||
$(GDICT): $(GDICT_PAGES)
|
||||
rootcint -f $@ $^
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS) $(EXES) $(DICT) $(GDICT) $(DICTLIB) ./$(LIBDIR)/*.pcm ./$(BINDIR)/*.pcm
|
||||
|
||||
clean_header:
|
||||
$(RM) $(PCH)
|
||||
|
||||
VPATH= $(SRCDIR):$(EVBSRCDIR):$(GUISRCDIR)
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $^
|
3
objs/.gitignore
vendored
3
objs/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
### dont include any files, but include this dir ###
|
||||
*
|
||||
!.gitignore
|
25
src/CMakeLists.txt
Normal file
25
src/CMakeLists.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
add_subdirectory(evbdict)
|
||||
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
|
||||
EVBDict
|
||||
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
|
||||
EVBDict
|
||||
GuiDict
|
||||
EventBuilderCore
|
||||
${ROOT_LIBRARIES}
|
||||
)
|
||||
set_target_properties(EventBuilderGui PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${EVB_BINARY_DIR})
|
|
@ -24,5 +24,8 @@
|
|||
#include <THashTable.h>
|
||||
#include <TCutG.h>
|
||||
|
||||
//Mine
|
||||
#include "Logger.h"
|
||||
|
||||
|
||||
#endif
|
38
src/evb/CMakeLists.txt
Normal file
38
src/evb/CMakeLists.txt
Normal file
|
@ -0,0 +1,38 @@
|
|||
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
|
||||
CompassRun.h
|
||||
FlagHandler.cpp
|
||||
Stopwatch.cpp
|
||||
FlagHandler.h
|
||||
OrderChecker.cpp
|
||||
Stopwatch.h
|
||||
OrderChecker.h
|
||||
CompassFile.cpp
|
||||
EVBApp.cpp
|
||||
ProgressCallback.h
|
||||
ShiftMap.cpp
|
||||
CompassFile.h
|
||||
EVBApp.h
|
||||
Logger.cpp
|
||||
RunCollector.cpp
|
||||
ShiftMap.h
|
||||
CompassHit.h
|
||||
Logger.h
|
||||
RunCollector.h
|
||||
SlowSort.cpp
|
||||
CompassRun.cpp
|
||||
SlowSort.h
|
||||
)
|
||||
|
||||
target_link_libraries(EventBuilderCore PUBLIC
|
||||
EVBDict
|
||||
${ROOT_LIBRARIES}
|
||||
)
|
||||
|
||||
set_target_properties(EventBuilderCore PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${EVB_LIBRARY_DIR})
|
|
@ -11,154 +11,194 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "CompassFile.h"
|
||||
|
||||
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);
|
||||
}
|
||||
namespace EventBuilder {
|
||||
|
||||
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, unsigned 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();
|
||||
if(m_size <= 24) {
|
||||
eofFlag = true;
|
||||
m_nHits = 0;
|
||||
} else {
|
||||
m_file->seekg(0, std::ios_base::beg);
|
||||
hitsize = GetHitSize();
|
||||
m_buffersize = hitsize*bufsize;
|
||||
hitBuffer.resize(m_buffersize);
|
||||
m_nHits = m_size/hitsize;
|
||||
}
|
||||
}
|
||||
|
||||
void CompassFile::Close() {
|
||||
if(IsOpen()) {
|
||||
m_file->close();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CompassFile::GetHitSize() {
|
||||
if(!IsOpen()) {
|
||||
std::cerr<<"Unable to get hit size due to file not being open!"<<std::endl;
|
||||
return 0;
|
||||
CompassFile::CompassFile() :
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
char* firstHit = new char[24]; //A compass hit by default has 24 bytes (at least in our setup)
|
||||
|
||||
m_file->read(firstHit, 24);
|
||||
|
||||
uint32_t nsamples = *((uint32_t*) &firstHit[20]);
|
||||
|
||||
m_file->seekg(0, std::ios_base::beg);
|
||||
|
||||
delete[] firstHit;
|
||||
|
||||
return 24 + nsamples*4;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
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();
|
||||
CompassFile::CompassFile(const std::string& filename) :
|
||||
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)
|
||||
{
|
||||
Open(filename);
|
||||
}
|
||||
|
||||
if(!IsEOF()) {
|
||||
ParseNextHit();
|
||||
hitUsedFlag = false;
|
||||
CompassFile::CompassFile(const std::string& filename, int bsize) :
|
||||
m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_bufsize(bsize), m_hitsize(0),
|
||||
m_buffersize(0), m_file(std::make_shared<std::ifstream>()), m_eofFlag(false)
|
||||
{
|
||||
Open(filename);
|
||||
}
|
||||
|
||||
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;
|
||||
CompassFile::~CompassFile()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
m_file->read(hitBuffer.data(), hitBuffer.size());
|
||||
void CompassFile::Open(const std::string& filename)
|
||||
{
|
||||
m_eofFlag = false;
|
||||
m_hitUsedFlag = true;
|
||||
m_filename = filename;
|
||||
m_file->open(m_filename, std::ios::binary | std::ios::in);
|
||||
|
||||
bufferIter = hitBuffer.data();
|
||||
bufferEnd = bufferIter + m_file->gcount(); //one past the last datum
|
||||
m_file->seekg(0, std::ios_base::end);
|
||||
m_size = m_file->tellg();
|
||||
if(m_size == 2)
|
||||
{
|
||||
m_eofFlag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void CompassFile::Close()
|
||||
{
|
||||
if(IsOpen())
|
||||
{
|
||||
m_file->close();
|
||||
}
|
||||
}
|
||||
|
||||
void CompassFile::ParseNextHit() {
|
||||
void CompassFile::ReadHeader()
|
||||
{
|
||||
if(!IsOpen())
|
||||
{
|
||||
EVB_WARN("Unable to read header from file. State not validated", m_filename);
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentHit.board = *((UShort_t*)bufferIter);
|
||||
bufferIter += 2;
|
||||
m_currentHit.channel = *((UShort_t*)bufferIter);
|
||||
bufferIter += 2;
|
||||
m_currentHit.timestamp = *((ULong64_t*)bufferIter);
|
||||
bufferIter += 8;
|
||||
m_currentHit.lgate = *((UShort_t*)bufferIter);
|
||||
bufferIter += 2;
|
||||
m_currentHit.sgate = *((UShort_t*)bufferIter);
|
||||
bufferIter += 2;
|
||||
m_currentHit.flags = *((UInt_t*)bufferIter);
|
||||
bufferIter += 4;
|
||||
m_currentHit.Ns = *((UInt_t*)bufferIter);
|
||||
bufferIter += 4;
|
||||
char* header = new char[2];
|
||||
m_file->read(header, 2);
|
||||
m_header = *((uint16_t*)header);
|
||||
m_hitsize = 16; //default hitsize of 16 bytes
|
||||
if(IsEnergy())
|
||||
m_hitsize += 2;
|
||||
if(IsEnergyCalibrated())
|
||||
m_hitsize += 8;
|
||||
if(IsEnergyShort())
|
||||
m_hitsize += 2;
|
||||
if(IsWaves())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if(m_smap != nullptr) { //memory safety
|
||||
int gchan = m_currentHit.channel + m_currentHit.board*16;
|
||||
m_currentHit.timestamp += m_smap->GetShift(gchan);
|
||||
delete[] header;
|
||||
}
|
||||
|
||||
/*
|
||||
if(m_currentHit.Ns*2 + 24 != hitsize) {
|
||||
std::cerr<<"WARNING! Hit size does not match current value of samples... Try to proceed, but expect seg fault."<<std::endl;
|
||||
return;
|
||||
}
|
||||
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
|
||||
*/
|
||||
for(unsigned int i=0; i<m_currentHit.Ns; i++) {
|
||||
m_currentHit.samples.push_back(*((UShort_t*)bufferIter));
|
||||
bufferIter += 2;
|
||||
bool CompassFile::GetNextHit()
|
||||
{
|
||||
if(!IsOpen()) return true;
|
||||
|
||||
if((m_bufferIter == nullptr || m_bufferIter == m_bufferEnd) && !IsEOF())
|
||||
{
|
||||
GetNextBuffer();
|
||||
}
|
||||
|
||||
if(!IsEOF())
|
||||
{
|
||||
ParseNextHit();
|
||||
m_hitUsedFlag = false;
|
||||
}
|
||||
|
||||
return m_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())
|
||||
{
|
||||
m_eofFlag = true;
|
||||
return;
|
||||
}
|
||||
|
||||
m_file->read(m_hitBuffer.data(), m_hitBuffer.size());
|
||||
|
||||
m_bufferIter = m_hitBuffer.data();
|
||||
m_bufferEnd = m_bufferIter + m_file->gcount(); //one past the last datum
|
||||
|
||||
}
|
||||
|
||||
void CompassFile::ParseNextHit()
|
||||
{
|
||||
|
||||
m_currentHit.board = *((uint16_t*)m_bufferIter);
|
||||
m_bufferIter += 2;
|
||||
m_currentHit.channel = *((uint16_t*)m_bufferIter);
|
||||
m_bufferIter += 2;
|
||||
m_currentHit.timestamp = *((uint64_t*)m_bufferIter);
|
||||
m_bufferIter += 8;
|
||||
if(IsEnergy())
|
||||
{
|
||||
m_currentHit.energy = *((uint16_t*)m_bufferIter);
|
||||
m_bufferIter += 2;
|
||||
}
|
||||
if(IsEnergyCalibrated())
|
||||
{
|
||||
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;
|
||||
if(m_currentHit.samples.size() != m_currentHit.Ns)
|
||||
m_currentHit.samples.resize(m_currentHit.Ns);
|
||||
for(size_t i=0; i<m_currentHit.samples.size(); i++)
|
||||
{
|
||||
m_currentHit.samples[i] = *((uint16_t*)m_bufferIter);
|
||||
m_bufferIter += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_smap != nullptr)
|
||||
{ //memory safety
|
||||
int gchan = m_currentHit.channel + m_currentHit.board*m_channels_per_board;
|
||||
m_currentHit.timestamp += m_smap->GetShift(gchan);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
89
src/evb/CompassFile.h
Normal file
89
src/evb/CompassFile.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
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"
|
||||
#include <memory>
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
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 m_hitUsedFlag; } //query to find out if we've used the current hit
|
||||
inline void SetHitHasBeenUsed() { m_hitUsedFlag = true; } //flip the flag to indicate the current hit has been used
|
||||
inline bool IsEOF() const { return m_eofFlag; } //see if we've read all available data
|
||||
inline bool* GetUsedFlagPtr() { return &m_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:
|
||||
void ReadHeader();
|
||||
void ParseNextHit();
|
||||
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 FilePointer = std::shared_ptr<std::ifstream>; //to make this class copy/movable
|
||||
|
||||
std::string m_filename;
|
||||
Buffer m_hitBuffer;
|
||||
char* m_bufferIter;
|
||||
char* m_bufferEnd;
|
||||
ShiftMap* m_smap; //NOT owned by CompassFile. DO NOT delete
|
||||
|
||||
bool m_hitUsedFlag;
|
||||
int m_bufsize = 200000; //size of the buffer in hits
|
||||
int m_hitsize; //size of a CompassHit in bytes (without alignment padding)
|
||||
int m_channels_per_board = 16; //Number of channels per digitzer board, important for generating id!
|
||||
uint16_t m_header;
|
||||
int m_buffersize;
|
||||
|
||||
CompassHit m_currentHit;
|
||||
FilePointer m_file;
|
||||
bool m_eofFlag;
|
||||
unsigned int m_size; //size of the file in bytes
|
||||
unsigned int m_nHits; //number of hits in the file (m_size/24)
|
||||
|
||||
enum CoMPASSHeaders
|
||||
{
|
||||
Energy = 0x0001,
|
||||
EnergyCalibrated = 0x0002,
|
||||
EnergyShort = 0x0004,
|
||||
Waves = 0x0008,
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
22
src/evb/CompassHit.h
Normal file
22
src/evb/CompassHit.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef COMPASS_HIT_H
|
||||
#define COMPASS_HIT_H
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
struct CompassHit
|
||||
{
|
||||
uint16_t board = 400;
|
||||
uint16_t channel = 400;
|
||||
uint64_t timestamp = 0;
|
||||
uint16_t energy = 0;
|
||||
uint64_t energyCalibrated = 0;
|
||||
uint16_t energyShort = 0;
|
||||
uint32_t flags = 0;
|
||||
uint8_t waveCode = 0;
|
||||
uint32_t Ns = 0;
|
||||
std::vector<uint16_t> samples;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -15,247 +15,267 @@
|
|||
#include "SlowSort.h"
|
||||
#include "FlagHandler.h"
|
||||
|
||||
CompassRun::CompassRun() :
|
||||
directory(""), m_scalerinput(""), runNum(0), m_buffersize(200000), m_scaler_flag(false), m_pb(nullptr)
|
||||
{
|
||||
namespace EventBuilder {
|
||||
|
||||
}
|
||||
CompassRun::CompassRun() :
|
||||
directory(""), m_scalerinput(""), runNum(0), m_buffersize(200000), m_scaler_flag(false)
|
||||
{
|
||||
|
||||
CompassRun::CompassRun(const std::string& dir, unsigned int bsize) :
|
||||
directory(dir), m_scalerinput(""), runNum(0), m_buffersize(bsize), m_scaler_flag(false), m_pb(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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 = directory+filename+"_run_"+to_string(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(directory, prefix, suffix);
|
||||
grabber.GrabAllFiles();
|
||||
CompassRun::CompassRun(const std::string& dir, size_t bsize) :
|
||||
directory(dir), m_scalerinput(""), runNum(0), m_buffersize(bsize), m_scaler_flag(false)
|
||||
{
|
||||
|
||||
m_datafiles.clear(); //so that the CompassRun can be reused
|
||||
m_datafiles.reserve(grabber.filelist.size());
|
||||
bool scalerd;
|
||||
m_totalHits = 0; //reset total run size
|
||||
}
|
||||
|
||||
for(auto& entry : grabber.filelist) {
|
||||
//Handle scaler files, if they exist
|
||||
if(m_scaler_flag) {
|
||||
scalerd = false;
|
||||
for(auto& scaler_pair : m_scaler_map) {
|
||||
if(std::string(entry.Data()) == scaler_pair.first) {
|
||||
ReadScalerData(entry.Data());
|
||||
scalerd = true;
|
||||
break;
|
||||
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;
|
||||
int64_t init = 0;
|
||||
std::getline(input, junk);
|
||||
std::getline(input, junk);
|
||||
m_scaler_map.clear();
|
||||
while(input>>filename)
|
||||
{
|
||||
input>>varname;
|
||||
filename = directory+filename+"_run_"+std::to_string(runNum)+".BIN";
|
||||
m_scaler_map[filename] = TParameter<int64_t>(varname.c_str(), init);
|
||||
}
|
||||
input.close();
|
||||
}
|
||||
|
||||
bool CompassRun::GetBinaryFiles()
|
||||
{
|
||||
std::string prefix = "";
|
||||
std::string suffix = ".BIN"; //binaries
|
||||
RunCollector grabber(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;
|
||||
}
|
||||
if(scalerd) continue;
|
||||
}
|
||||
m_datafiles.emplace_back(entry.Data());
|
||||
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();
|
||||
}
|
||||
m_datafiles.emplace_back(entry, m_buffersize);
|
||||
m_datafiles[m_datafiles.size()-1].AttachShiftMap(&m_smap);
|
||||
//Any time we have a file that fails to be found, we terminate the whole process
|
||||
if(!m_datafiles[m_datafiles.size() - 1].IsOpen())
|
||||
return false;
|
||||
|
||||
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 = make_pair(CompassHit(), nullptr);
|
||||
for(unsigned int i=startIndex; i<m_datafiles.size(); i++) {
|
||||
if(m_datafiles[i].CheckHitHasBeenUsed()) {
|
||||
m_datafiles[i].GetNextHit();
|
||||
m_totalHits += m_datafiles[m_datafiles.size()-1].GetNumberOfHits();
|
||||
}
|
||||
|
||||
if(m_datafiles[i].IsEOF()) {
|
||||
if(i == startIndex) startIndex++;
|
||||
continue;
|
||||
} else if(i == startIndex) {
|
||||
earliestHit = make_pair(m_datafiles[i].GetCurrentHit(), m_datafiles[i].GetUsedFlagPtr());
|
||||
} else if(m_datafiles[i].GetCurrentHit().timestamp < earliestHit.first.timestamp) {
|
||||
earliestHit = make_pair(m_datafiles[i].GetCurrentHit(), m_datafiles[i].GetUsedFlagPtr());
|
||||
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;
|
||||
|
||||
int64_t 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);
|
||||
}
|
||||
|
||||
if(earliestHit.second == nullptr) return false; //Make sure that there actually was a hit
|
||||
hit = earliestHit.first;
|
||||
*earliestHit.second = true;
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
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()
|
||||
{
|
||||
|
||||
void CompassRun::Convert2RawRoot(const std::string& name) {
|
||||
TFile* output = TFile::Open(name.c_str(), "RECREATE");
|
||||
TTree* outtree = new TTree("Data", "Data");
|
||||
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();
|
||||
|
||||
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_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(!m_smap.IsSet()) {
|
||||
std::cerr<<"Bad shift map at CompassRun::Convert()."<<std::endl;
|
||||
std::cerr<<"Shifts will be locked to 0"<<std::endl;
|
||||
if(earliestHit.second == nullptr)
|
||||
return false; //Make sure that there actually was a hit
|
||||
hit = earliestHit.first;
|
||||
*earliestHit.second = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
SetScalers();
|
||||
void CompassRun::Convert2RawRoot(const std::string& name)
|
||||
{
|
||||
TFile* output = TFile::Open(name.c_str(), "RECREATE");
|
||||
TTree* outtree = new TTree("Data", "Data");
|
||||
|
||||
if(!GetBinaryFiles()) {
|
||||
std::cerr<<"Unable to open a file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
outtree->Branch("Board", &hit.board);
|
||||
outtree->Branch("Channel", &hit.channel);
|
||||
outtree->Branch("Energy", &hit.energy);
|
||||
outtree->Branch("EnergyShort", &hit.energyShort);
|
||||
outtree->Branch("EnergyCal", &hit.energyCalibrated);
|
||||
outtree->Branch("Timestamp", &hit.timestamp);
|
||||
outtree->Branch("Flags", &hit.flags);
|
||||
outtree->Branch("Ns", &hit.Ns);
|
||||
outtree->Branch("Samples", &hit.samples);
|
||||
|
||||
if(m_pb) SetProgressBar();
|
||||
if(!m_smap.IsSet())
|
||||
{
|
||||
std::cerr<<"Bad shift map at CompassRun::Convert()."<<std::endl;
|
||||
std::cerr<<"Shifts will be locked to 0"<<std::endl;
|
||||
}
|
||||
|
||||
startIndex = 0; //Reset the startIndex
|
||||
unsigned int count = 0, flush = m_totalHits*0.01, flush_count = 0;
|
||||
if(flush == 0) flush = 1;
|
||||
while(true) {
|
||||
count++;
|
||||
if(count == flush) { //Progress Log
|
||||
if(m_pb) {
|
||||
m_pb->Increment(count);
|
||||
gSystem->ProcessEvents();
|
||||
count=0;
|
||||
} else {
|
||||
SetScalers();
|
||||
|
||||
if(!GetBinaryFiles())
|
||||
{
|
||||
std::cerr<<"Unable to open a file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
startIndex = 0; //Reset the startIndex
|
||||
|
||||
unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0;
|
||||
if(flush == 0)
|
||||
flush = 1;
|
||||
|
||||
while(true)
|
||||
{
|
||||
count++;
|
||||
if(count == flush)
|
||||
{ //Progress Log
|
||||
count = 0;
|
||||
flush_count++;
|
||||
std::cout<<"\rPercent of run built: "<<flush_count*10<<"%"<<std::flush;
|
||||
m_progressCallback(flush*flush_count, 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, double window) {
|
||||
TFile* output = TFile::Open(name.c_str(), "RECREATE");
|
||||
TTree* outtree = new TTree("SortTree", "SortTree");
|
||||
|
||||
outtree->Branch("event", &event);
|
||||
|
||||
if(!m_smap.IsSet()) {
|
||||
std::cerr<<"Bad shift map at CompassRun::Convert()."<<std::endl;
|
||||
std::cerr<<"Shifts will be locked to 0"<<std::endl;
|
||||
}
|
||||
|
||||
SetScalers();
|
||||
|
||||
if(!GetBinaryFiles()) {
|
||||
std::cerr<<"Unable to open a file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_pb) SetProgressBar();
|
||||
|
||||
startIndex = 0;
|
||||
SlowSort coincidizer(window);
|
||||
bool killFlag = false;
|
||||
unsigned int count = 0, flush = m_totalHits*0.01, flush_count = 0;
|
||||
if(flush == 0) flush = 1;
|
||||
while(true) {
|
||||
count++;
|
||||
if(count == flush) {
|
||||
if(m_pb) {
|
||||
m_pb->Increment(count);
|
||||
gSystem->ProcessEvents();
|
||||
count=0;
|
||||
} else {
|
||||
count = 0;
|
||||
flush_count++;
|
||||
std::cout<<"\rPercent of run built: "<<flush_count*10<<"%"<<std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
if(!GetHitsFromFiles()) {
|
||||
coincidizer.FlushHitsToEvent();
|
||||
killFlag = true;
|
||||
} else {
|
||||
coincidizer.AddHitToEvent(hit);
|
||||
}
|
||||
|
||||
if(coincidizer.IsEventReady()) {
|
||||
event = coincidizer.GetEvent();
|
||||
if(!GetHitsFromFiles())
|
||||
break;
|
||||
outtree->Fill();
|
||||
if(killFlag) break;
|
||||
}
|
||||
|
||||
output->cd();
|
||||
outtree->Write(outtree->GetName(), TObject::kOverwrite);
|
||||
for(auto& entry : m_scaler_map)
|
||||
entry.second.Write();
|
||||
output->Close();
|
||||
}
|
||||
|
||||
output->cd();
|
||||
outtree->Write(outtree->GetName(), TObject::kOverwrite);
|
||||
for(auto& entry : m_scaler_map) {
|
||||
entry.second.Write();
|
||||
}
|
||||
coincidizer.GetEventStats()->Write();
|
||||
output->Close();
|
||||
}
|
||||
void CompassRun::Convert2SortedRoot(const std::string& name, double window) {
|
||||
TFile* output = TFile::Open(name.c_str(), "RECREATE");
|
||||
TTree* outtree = new TTree("SortTree", "SortTree");
|
||||
|
||||
outtree->Branch("event", &event);
|
||||
|
||||
if(!m_smap.IsSet())
|
||||
{
|
||||
std::cerr<<"Bad shift map at CompassRun::Convert()."<<std::endl;
|
||||
std::cerr<<"Shifts will be locked to 0"<<std::endl;
|
||||
}
|
||||
|
||||
SetScalers();
|
||||
|
||||
if(!GetBinaryFiles()) {
|
||||
std::cerr<<"Unable to open a file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
startIndex = 0;
|
||||
SlowSort coincidizer(window);
|
||||
bool killFlag = false;
|
||||
|
||||
uint64_t count = 0, flush = m_totalHits*0.01, flush_count = 0;
|
||||
if(flush == 0)
|
||||
flush = 1;
|
||||
|
||||
while(true)
|
||||
{
|
||||
count++;
|
||||
if(count == flush)
|
||||
{
|
||||
count = 0;
|
||||
flush_count++;
|
||||
m_progressCallback(flush*flush_count, 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::SetProgressBar() {
|
||||
m_pb->SetMax(m_totalHits);
|
||||
m_pb->SetMin(0);
|
||||
m_pb->SetPosition(0);
|
||||
gSystem->ProcessEvents();
|
||||
}
|
68
src/evb/CompassRun.h
Normal file
68
src/evb/CompassRun.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
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 EventBuilder {
|
||||
|
||||
class CompassRun
|
||||
{
|
||||
public:
|
||||
CompassRun();
|
||||
CompassRun(const std::string& dir, uint64_t bsize);
|
||||
~CompassRun();
|
||||
inline void SetDirectory(const std::string& dir) { directory = dir; }
|
||||
inline void SetScalerInput(const std::string& filename) { m_scalerinput = filename; }
|
||||
inline void SetRunNumber(int n) { runNum = n; };
|
||||
inline void SetShiftMap(const std::string& filename) { m_smap.SetFile(filename); }
|
||||
void Convert2RawRoot(const std::string& name);
|
||||
void Convert2SortedRoot(const std::string& name, double window);
|
||||
|
||||
inline void SetProgressCallbackFunc(ProgressCallbackFunc& func) { m_progressCallback = func; }
|
||||
inline void SetProgressFraction(double frac) { m_progressFraction = frac; }
|
||||
|
||||
private:
|
||||
bool GetBinaryFiles();
|
||||
bool GetHitsFromFiles();
|
||||
void SetScalers();
|
||||
void ReadScalerData(const std::string& filename);
|
||||
|
||||
std::string 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<int64_t>> m_scaler_map; //maps scaler files to the TParameter to be saved
|
||||
|
||||
//Potential branch variables
|
||||
CompassHit hit;
|
||||
std::vector<DPPChannel> event;
|
||||
|
||||
//what run is this
|
||||
int runNum;
|
||||
uint64_t m_totalHits;
|
||||
uint64_t m_buffersize;
|
||||
|
||||
//Scaler switch
|
||||
bool m_scaler_flag;
|
||||
|
||||
ProgressCallbackFunc m_progressCallback;
|
||||
double m_progressFraction;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
215
src/evb/EVBApp.cpp
Normal file
215
src/evb/EVBApp.cpp
Normal file
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
EVBApp.cpp
|
||||
Class which represents the API of the event building environment. Wraps together the core concepts
|
||||
of the event builder, from conversion to plotting. Even intended to be able to archive data.
|
||||
Currently under development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#include "EventBuilder.h"
|
||||
#include <cstdlib>
|
||||
#include "EVBApp.h"
|
||||
#include "RunCollector.h"
|
||||
#include "CompassRun.h"
|
||||
#include "SlowSort.h"
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
EVBApp::EVBApp() :
|
||||
m_rmin(0), m_rmax(0),
|
||||
m_progressFraction(0.1), m_workspace("none"), m_shiftfile("none"),
|
||||
m_scalerfile("none"), m_buffersize(200000), m_SlowWindow(0)
|
||||
{
|
||||
SetProgressCallbackFunc(BIND_PROGRESS_CALLBACK_FUNCTION(EVBApp::DefaultProgressCallback));
|
||||
}
|
||||
|
||||
EVBApp::~EVBApp()
|
||||
{
|
||||
}
|
||||
|
||||
void EVBApp::DefaultProgressCallback(long curVal, long totalVal)
|
||||
{
|
||||
double fraction = ((double)curVal)/totalVal;
|
||||
EVB_INFO("Percent of run built: {0}", fraction*100);
|
||||
}
|
||||
|
||||
bool EVBApp::ReadConfigFile(const std::string& fullpath)
|
||||
{
|
||||
EVB_INFO("Reading in EVB configuration from file {0}...", fullpath);
|
||||
std::ifstream input(fullpath);
|
||||
if(!input.is_open())
|
||||
{
|
||||
EVB_WARN("Read of EVB config failed, unable to open input file!");
|
||||
return false;
|
||||
}
|
||||
std::string junk;
|
||||
|
||||
std::getline(input, junk);
|
||||
input>>junk>>m_workspace;
|
||||
input>>junk;
|
||||
std::getline(input, junk);
|
||||
std::getline(input, junk);
|
||||
input>>junk>>m_scalerfile;
|
||||
input>>junk;
|
||||
std::getline(input, junk);
|
||||
std::getline(input, junk);
|
||||
input>>junk>>m_shiftfile;
|
||||
input>>junk>>m_SlowWindow;
|
||||
input>>junk;
|
||||
std::getline(input, junk);
|
||||
std::getline(input, junk);
|
||||
input>>junk>>m_rmin;
|
||||
input>>junk>>m_rmax;
|
||||
input>>junk>>m_buffersize;
|
||||
|
||||
input.close();
|
||||
|
||||
EVB_INFO("Successfully loaded EVB config.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EVBApp::WriteConfigFile(const std::string& fullpath)
|
||||
{
|
||||
|
||||
EVB_INFO("Writing EVB config to file {0}...",fullpath);
|
||||
std::ofstream output(fullpath);
|
||||
if(!output.is_open())
|
||||
{
|
||||
EVB_WARN("Failed to write to config to file {0}, unable to open file!", fullpath);
|
||||
return;
|
||||
}
|
||||
|
||||
output<<"-------Data Location----------"<<std::endl;
|
||||
output<<"WorkspaceDirectory: "<<m_workspace<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
output<<"------Experimental Inputs------"<<std::endl;
|
||||
output<<"ScalerFile: "<<m_scalerfile<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
output<<"-------Timing Information------"<<std::endl;
|
||||
output<<"BoardOffsetFile: "<<m_shiftfile<<std::endl;
|
||||
output<<"SlowCoincidenceWindow(ps): "<<m_SlowWindow<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
output<<"--------Run Information--------"<<std::endl;
|
||||
output<<"MinRun: "<<m_rmin<<std::endl;
|
||||
output<<"MaxRun: "<<m_rmax<<std::endl;
|
||||
output<<"BufferSize: "<<m_buffersize<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
|
||||
output.close();
|
||||
|
||||
EVB_INFO("Successfully wrote config to file.");
|
||||
|
||||
}
|
||||
|
||||
void EVBApp::Convert2RawRoot()
|
||||
{
|
||||
std::string rawroot_dir = m_workspace+"/raw_root/";
|
||||
std::string unpack_dir = m_workspace+"/temp_binary/";
|
||||
std::string binary_dir = m_workspace+"/raw_binary/";
|
||||
EVB_INFO("Converting binary archives to ROOT files over run range [{0}, {1}]",m_rmin,m_rmax);
|
||||
|
||||
grabber.SetSearchParams(binary_dir, "", ".tar.gz",0,1000);
|
||||
|
||||
std::string rawfile, binfile;
|
||||
std::string unpack_command, wipe_command;
|
||||
|
||||
CompassRun converter(unpack_dir, m_buffersize);
|
||||
converter.SetShiftMap(m_shiftfile);
|
||||
converter.SetScalerInput(m_scalerfile);
|
||||
converter.SetProgressCallbackFunc(m_progressCallback);
|
||||
converter.SetProgressFraction(m_progressFraction);
|
||||
|
||||
int result;
|
||||
|
||||
EVB_INFO("Beginning conversion...");
|
||||
for(int i=m_rmin; i<=m_rmax; i++)
|
||||
{
|
||||
binfile = grabber.GrabFile(i);
|
||||
if(binfile == "")
|
||||
continue;
|
||||
converter.SetRunNumber(i);
|
||||
EVB_INFO("Converting file {0}...", binfile);
|
||||
rawfile = rawroot_dir + "compass_run_"+ std::to_string(i) + ".root";
|
||||
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
|
||||
wipe_command = "rm -r "+unpack_dir+"*.BIN";
|
||||
|
||||
result = system(unpack_command.c_str());
|
||||
converter.Convert2RawRoot(rawfile);
|
||||
result = system(wipe_command.c_str());
|
||||
|
||||
}
|
||||
EVB_INFO("Conversion complete.");
|
||||
}
|
||||
|
||||
void EVBApp::MergeROOTFiles()
|
||||
{
|
||||
std::string merge_file = m_workspace+"/merged/run_"+std::to_string(m_rmin)+"_"+std::to_string(m_rmax)+".root";
|
||||
std::string file_dir = m_workspace+"/analyzed/";
|
||||
EVB_INFO("Merging ROOT files into single file for runs in range [{0}, {1}]", m_rmin, m_rmax);
|
||||
EVB_INFO("Merged file will be named {0}", merge_file);
|
||||
std::string prefix = "";
|
||||
std::string suffix = ".root";
|
||||
grabber.SetSearchParams(file_dir, prefix, suffix,m_rmin,m_rmax);
|
||||
EVB_INFO("Starting merge...");
|
||||
if(!grabber.Merge_TChain(merge_file))
|
||||
{
|
||||
EVB_ERROR("Unable to find files for merge at EVBApp::MergeROOTFiles()!");
|
||||
return;
|
||||
}
|
||||
EVB_INFO("Finished.");
|
||||
}
|
||||
|
||||
void EVBApp::Convert2SortedRoot()
|
||||
{
|
||||
std::string sortroot_dir = m_workspace+"/sorted/";
|
||||
std::string unpack_dir = m_workspace+"/temp_binary/";
|
||||
std::string binary_dir = m_workspace+"/raw_binary/";
|
||||
EVB_INFO("Converting binary archives to event built ROOT files over run range [{0}, {1}]",m_rmin,m_rmax);
|
||||
|
||||
grabber.SetSearchParams(binary_dir,"",".tar.gz",m_rmin,m_rmax);
|
||||
|
||||
std::string sortfile, binfile;
|
||||
std::string unpack_command, wipe_command;
|
||||
|
||||
CompassRun converter(unpack_dir, m_buffersize);
|
||||
converter.SetShiftMap(m_shiftfile);
|
||||
converter.SetScalerInput(m_scalerfile);
|
||||
converter.SetProgressCallbackFunc(m_progressCallback);
|
||||
converter.SetProgressFraction(m_progressFraction);
|
||||
|
||||
int result;
|
||||
EVB_INFO("Beginning conversion...");
|
||||
|
||||
int count=0;
|
||||
for(int i=m_rmin; i<= m_rmax; i++)
|
||||
{
|
||||
binfile = grabber.GrabFile(i);
|
||||
if(binfile == "")
|
||||
continue;
|
||||
converter.SetRunNumber(i);
|
||||
EVB_INFO("Converting file {0}...",binfile);
|
||||
|
||||
sortfile = sortroot_dir +"run_"+std::to_string(i)+ ".root";
|
||||
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
|
||||
wipe_command = "rm -r "+unpack_dir+"*.BIN";
|
||||
|
||||
result = system(unpack_command.c_str());
|
||||
converter.Convert2SortedRoot(sortfile, m_SlowWindow);
|
||||
result = system(wipe_command.c_str());
|
||||
count++;
|
||||
}
|
||||
if(count==0)
|
||||
EVB_WARN("Conversion failed, no archives were found!");
|
||||
else
|
||||
EVB_INFO("Conversion complete.");
|
||||
}
|
||||
|
||||
void EVBApp::SetRunRange(int rmin, int rmax) { EVB_TRACE("Min Run, max run set to [{0}, {1}]", rmin, rmax); m_rmin = rmin; m_rmax = rmax; }
|
||||
void EVBApp::SetWorkDirectory(const std::string& fullpath) { EVB_TRACE("Workspace set to {0}", fullpath); m_workspace = fullpath; }
|
||||
void EVBApp::SetBoardShiftFile(const std::string& name) { EVB_TRACE("Shift file set to {0}", name); m_shiftfile = name; }
|
||||
void EVBApp::SetSlowCoincidenceWindow(double window) { EVB_TRACE("Slow Coincidence Window set to {0}",window); m_SlowWindow = window; }
|
||||
void EVBApp::SetScalerFile(const std::string& fullpath) { EVB_TRACE("Scaler file set to {0}", fullpath); m_scalerfile = fullpath; }
|
||||
void EVBApp::SetBufferSize(uint64_t bufsize) { EVB_TRACE("Buffer size set to {0} hits", bufsize); m_buffersize = bufsize; }
|
||||
|
||||
}
|
76
src/evb/EVBApp.h
Normal file
76
src/evb/EVBApp.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
EVBApp.h
|
||||
Class which represents the API of the event building environment. Wraps together the core concepts
|
||||
of the event builder, from conversion to plotting. Even intended to be able to archive data.
|
||||
Currently under development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#ifndef EVBAPP_H
|
||||
#define EVBAPP_H
|
||||
|
||||
#include "RunCollector.h"
|
||||
#include "ProgressCallback.h"
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
class EVBApp
|
||||
{
|
||||
public:
|
||||
|
||||
EVBApp();
|
||||
~EVBApp();
|
||||
|
||||
bool ReadConfigFile(const std::string& filename);
|
||||
void WriteConfigFile(const std::string& filename);
|
||||
|
||||
void MergeROOTFiles();
|
||||
void Convert2SortedRoot();
|
||||
void Convert2RawRoot();
|
||||
|
||||
void SetRunRange(int rmin, int rmax);
|
||||
void SetWorkDirectory(const std::string& dir);
|
||||
void SetChannelMap(const std::string& name);
|
||||
void SetBoardShiftFile(const std::string& name);
|
||||
void SetSlowCoincidenceWindow(double window);
|
||||
void SetScalerFile(const std::string& fullpath);
|
||||
void SetBufferSize(uint64_t bufsize);
|
||||
|
||||
inline int GetRunMin() const { return m_rmin; }
|
||||
inline int GetRunMax() const { return m_rmax; }
|
||||
inline std::string GetWorkDirectory() const { return m_workspace; }
|
||||
inline double GetSlowCoincidenceWindow() const { return m_SlowWindow; }
|
||||
inline std::string GetBoardShiftFile() const { return m_shiftfile; }
|
||||
inline std::string GetScalerFile() const { return m_scalerfile; }
|
||||
|
||||
void DefaultProgressCallback(int64_t curVal, int64_t totalVal);
|
||||
inline void SetProgressCallbackFunc(const ProgressCallbackFunc& function) { m_progressCallback = function; }
|
||||
inline void SetProgressFraction(double frac) { m_progressFraction = frac; }
|
||||
|
||||
enum Operation
|
||||
{
|
||||
Convert,
|
||||
ConvertSlow,
|
||||
Merge
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
int m_rmin, m_rmax;
|
||||
double m_progressFraction;
|
||||
|
||||
std::string m_workspace;
|
||||
std::string m_shiftfile;
|
||||
std::string m_scalerfile;
|
||||
|
||||
uint64_t m_buffersize;
|
||||
double m_SlowWindow;
|
||||
|
||||
RunCollector grabber;
|
||||
|
||||
ProgressCallbackFunc m_progressCallback;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -1,86 +1,92 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "FlagHandler.h"
|
||||
|
||||
FlagHandler::FlagHandler() :
|
||||
log("./event_log.txt")
|
||||
{
|
||||
}
|
||||
namespace EventBuilder {
|
||||
|
||||
FlagHandler::FlagHandler(const std::string& filename) :
|
||||
log(filename)
|
||||
{
|
||||
}
|
||||
|
||||
FlagHandler::~FlagHandler() {
|
||||
WriteLog();
|
||||
log.close();
|
||||
}
|
||||
|
||||
void FlagHandler::CheckFlag(int board, int channel, int flag) {
|
||||
|
||||
int gchan = channel + board*16;
|
||||
FlagCount& counter = event_count_map[gchan]; //yikes
|
||||
|
||||
counter.total_counts++;
|
||||
|
||||
if(flag & DEAD_TIME) counter.dead_time++;
|
||||
|
||||
if(flag & TIME_ROLLOVER) counter.time_roll++;
|
||||
|
||||
if(flag & TIME_RESET) counter.time_reset++;
|
||||
|
||||
if(flag & FAKE_EVENT) counter.fake_event++;
|
||||
|
||||
if(flag & MEM_FULL) counter.mem_full++;
|
||||
|
||||
if(flag & TRIG_LOST) counter.trig_lost++;
|
||||
|
||||
if(flag & N_TRIG_LOST) counter.n_trig_lost++;
|
||||
|
||||
if(flag & SATURATING_IN_GATE) counter.sat_in_gate++;
|
||||
|
||||
if(flag & TRIG_1024_COUNTED) counter.trig_1024++;;
|
||||
|
||||
if(flag & SATURATING_INPUT) counter.sat_input++;
|
||||
|
||||
if(flag & N_TRIG_COUNTED) counter.n_trig_count++;
|
||||
|
||||
if(flag & EVENT_NOT_MATCHED) counter.event_not_matched++;
|
||||
|
||||
if(flag & PILE_UP) counter.pile_up++;
|
||||
|
||||
if(flag & PLL_LOCK_LOSS) counter.pll_lock_loss++;
|
||||
|
||||
if(flag & OVER_TEMP) counter.over_temp++;
|
||||
|
||||
if(flag & ADC_SHUTDOWN) counter.adc_shutdown++;
|
||||
|
||||
}
|
||||
|
||||
void FlagHandler::WriteLog() {
|
||||
log<<"Event Flag Log"<<std::endl;
|
||||
log<<"-----------------------------"<<std::endl;
|
||||
for(auto& counter : event_count_map) {
|
||||
log<<"-----------------------------"<<std::endl;
|
||||
log<<"GLOBAL CHANNEL No.: "<<counter.first<<std::endl;
|
||||
log<<"Total number of events: "<<counter.second.total_counts<<std::endl;
|
||||
log<<"Dead time incurred (only for V1724): "<<counter.second.dead_time<<std::endl;
|
||||
log<<"Timestamp rollovers: "<<counter.second.time_roll<<std::endl;
|
||||
log<<"Timestamp resets from external: "<<counter.second.time_reset<<std::endl;
|
||||
log<<"Fake events: "<<counter.second.fake_event<<std::endl;
|
||||
log<<"Memory full: "<<counter.second.mem_full<<std::endl;
|
||||
log<<"Triggers lost: "<<counter.second.trig_lost<<std::endl;
|
||||
log<<"N Triggers lost: "<<counter.second.n_trig_lost<<std::endl;
|
||||
log<<"Saturation within the gate: "<<counter.second.sat_in_gate<<std::endl;
|
||||
log<<"1024 Triggers found: "<<counter.second.trig_1024<<std::endl;
|
||||
log<<"Saturation on input: "<<counter.second.sat_input<<std::endl;
|
||||
log<<"N Triggers counted: "<<counter.second.n_trig_count<<std::endl;
|
||||
log<<"Events not matched: "<<counter.second.event_not_matched<<std::endl;
|
||||
log<<"Pile ups: "<<counter.second.pile_up<<std::endl;
|
||||
log<<"PLL lock lost: "<<counter.second.pll_lock_loss<<std::endl;
|
||||
log<<"Over Temperature: "<<counter.second.over_temp<<std::endl;
|
||||
log<<"ADC Shutdown: "<<counter.second.adc_shutdown<<std::endl;
|
||||
log<<"-----------------------------"<<std::endl;
|
||||
FlagHandler::FlagHandler() :
|
||||
log("./event_log.txt")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
FlagHandler::FlagHandler(const std::string& filename) :
|
||||
log(filename)
|
||||
{
|
||||
}
|
||||
|
||||
FlagHandler::~FlagHandler()
|
||||
{
|
||||
WriteLog();
|
||||
log.close();
|
||||
}
|
||||
|
||||
void FlagHandler::CheckFlag(int board, int channel, int flag)
|
||||
{
|
||||
|
||||
int gchan = channel + board*16;
|
||||
FlagCount& counter = event_count_map[gchan]; //yikes
|
||||
|
||||
counter.total_counts++;
|
||||
|
||||
if(flag & DEAD_TIME) counter.dead_time++;
|
||||
|
||||
if(flag & TIME_ROLLOVER) counter.time_roll++;
|
||||
|
||||
if(flag & TIME_RESET) counter.time_reset++;
|
||||
|
||||
if(flag & FAKE_EVENT) counter.fake_event++;
|
||||
|
||||
if(flag & MEM_FULL) counter.mem_full++;
|
||||
|
||||
if(flag & TRIG_LOST) counter.trig_lost++;
|
||||
|
||||
if(flag & N_TRIG_LOST) counter.n_trig_lost++;
|
||||
|
||||
if(flag & SATURATING_IN_GATE) counter.sat_in_gate++;
|
||||
|
||||
if(flag & TRIG_1024_COUNTED) counter.trig_1024++;;
|
||||
|
||||
if(flag & SATURATING_INPUT) counter.sat_input++;
|
||||
|
||||
if(flag & N_TRIG_COUNTED) counter.n_trig_count++;
|
||||
|
||||
if(flag & EVENT_NOT_MATCHED) counter.event_not_matched++;
|
||||
|
||||
if(flag & PILE_UP) counter.pile_up++;
|
||||
|
||||
if(flag & PLL_LOCK_LOSS) counter.pll_lock_loss++;
|
||||
|
||||
if(flag & OVER_TEMP) counter.over_temp++;
|
||||
|
||||
if(flag & ADC_SHUTDOWN) counter.adc_shutdown++;
|
||||
|
||||
}
|
||||
|
||||
void FlagHandler::WriteLog()
|
||||
{
|
||||
log<<"Event Flag Log"<<std::endl;
|
||||
log<<"-----------------------------"<<std::endl;
|
||||
for(auto& counter : event_count_map) {
|
||||
log<<"-----------------------------"<<std::endl;
|
||||
log<<"GLOBAL CHANNEL No.: "<<counter.first<<std::endl;
|
||||
log<<"Total number of events: "<<counter.second.total_counts<<std::endl;
|
||||
log<<"Dead time incurred (only for V1724): "<<counter.second.dead_time<<std::endl;
|
||||
log<<"Timestamp rollovers: "<<counter.second.time_roll<<std::endl;
|
||||
log<<"Timestamp resets from external: "<<counter.second.time_reset<<std::endl;
|
||||
log<<"Fake events: "<<counter.second.fake_event<<std::endl;
|
||||
log<<"Memory full: "<<counter.second.mem_full<<std::endl;
|
||||
log<<"Triggers lost: "<<counter.second.trig_lost<<std::endl;
|
||||
log<<"N Triggers lost: "<<counter.second.n_trig_lost<<std::endl;
|
||||
log<<"Saturation within the gate: "<<counter.second.sat_in_gate<<std::endl;
|
||||
log<<"1024 Triggers found: "<<counter.second.trig_1024<<std::endl;
|
||||
log<<"Saturation on input: "<<counter.second.sat_input<<std::endl;
|
||||
log<<"N Triggers counted: "<<counter.second.n_trig_count<<std::endl;
|
||||
log<<"Events not matched: "<<counter.second.event_not_matched<<std::endl;
|
||||
log<<"Pile ups: "<<counter.second.pile_up<<std::endl;
|
||||
log<<"PLL lock lost: "<<counter.second.pll_lock_loss<<std::endl;
|
||||
log<<"Over Temperature: "<<counter.second.over_temp<<std::endl;
|
||||
log<<"ADC Shutdown: "<<counter.second.adc_shutdown<<std::endl;
|
||||
log<<"-----------------------------"<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
64
src/evb/FlagHandler.h
Normal file
64
src/evb/FlagHandler.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
#ifndef FLAGHANDLER_H
|
||||
#define FLAGHANDLER_H
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
struct FlagCount
|
||||
{
|
||||
int64_t total_counts=0;
|
||||
int64_t dead_time=0;
|
||||
int64_t time_roll=0;
|
||||
int64_t time_reset=0;
|
||||
int64_t fake_event=0;
|
||||
int64_t mem_full=0;
|
||||
int64_t trig_lost=0;
|
||||
int64_t n_trig_lost=0;
|
||||
int64_t sat_in_gate=0;
|
||||
int64_t trig_1024=0;
|
||||
int64_t sat_input=0;
|
||||
int64_t n_trig_count=0;
|
||||
int64_t event_not_matched=0;
|
||||
int64_t fine_time=0;
|
||||
int64_t pile_up=0;
|
||||
int64_t pll_lock_loss=0;
|
||||
int64_t over_temp=0;
|
||||
int64_t adc_shutdown=0;
|
||||
};
|
||||
|
||||
class FlagHandler
|
||||
{
|
||||
public:
|
||||
FlagHandler();
|
||||
FlagHandler(const std::string& filename);
|
||||
~FlagHandler();
|
||||
void CheckFlag(int board, int channel, int flag);
|
||||
|
||||
const int DEAD_TIME = 0x00000001;
|
||||
const int TIME_ROLLOVER = 0x00000002;
|
||||
const int TIME_RESET = 0x00000004;
|
||||
const int FAKE_EVENT = 0x00000008;
|
||||
const int MEM_FULL = 0x00000010;
|
||||
const int TRIG_LOST = 0x00000020;
|
||||
const int N_TRIG_LOST = 0x00000040;
|
||||
const int SATURATING_IN_GATE = 0x00000080;
|
||||
const int TRIG_1024_COUNTED = 0x00000100;
|
||||
const int SATURATING_INPUT = 0x00000400;
|
||||
const int N_TRIG_COUNTED = 0x00000800;
|
||||
const int EVENT_NOT_MATCHED = 0x00001000;
|
||||
const int FINE_TIME = 0x00004000;
|
||||
const int PILE_UP = 0x00008000;
|
||||
const int PLL_LOCK_LOSS = 0x00080000;
|
||||
const int OVER_TEMP = 0x00100000;
|
||||
const int ADC_SHUTDOWN = 0x00200000;
|
||||
|
||||
private:
|
||||
std::ofstream log;
|
||||
std::map<int, FlagCount> event_count_map;
|
||||
|
||||
void WriteLog();
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
GWMEventBuilder.cpp
|
||||
Class which represents the API of the event building environment. Wraps together the core concepts
|
||||
of the event builder, from conversion to plotting. Even intended to be able to archive data.
|
||||
Currently under development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#include "EventBuilder.h"
|
||||
#include <cstdlib>
|
||||
#include "GWMEventBuilder.h"
|
||||
#include "RunCollector.h"
|
||||
#include "CompassRun.h"
|
||||
|
||||
GWMEventBuilder::GWMEventBuilder() :
|
||||
m_rmin(0), m_rmax(0), m_workspace("none"), m_shiftfile("none"), m_SlowWindow(0), m_buffersize(200000), m_pb(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
GWMEventBuilder::~GWMEventBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
bool GWMEventBuilder::ReadConfigFile(const std::string& fullpath) {
|
||||
std::cout<<"Reading in configuration from file: "<<fullpath<<std::endl;
|
||||
std::ifstream input(fullpath);
|
||||
if(!input.is_open()) {
|
||||
std::cout<<"Read failed! Unable to open input file!"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
std::string junk;
|
||||
|
||||
std::getline(input, junk);
|
||||
input>>junk>>m_workspace;
|
||||
input>>junk;
|
||||
std::getline(input, junk);
|
||||
std::getline(input, junk);
|
||||
input>>junk>>m_scalerfile;
|
||||
input>>junk;
|
||||
std::getline(input, junk);
|
||||
std::getline(input, junk);
|
||||
input>>junk>>m_shiftfile;
|
||||
input>>junk>>m_SlowWindow;
|
||||
input>>junk;
|
||||
std::getline(input, junk);
|
||||
std::getline(input, junk);
|
||||
input>>junk>>m_rmin;
|
||||
input>>junk>>m_rmax;
|
||||
input>>junk>>m_buffersize;
|
||||
|
||||
input.close();
|
||||
|
||||
std::cout<<"Completed."<<std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GWMEventBuilder::WriteConfigFile(const std::string& fullpath) {
|
||||
|
||||
std::cout<<"Writing out configuration to file: "<<fullpath<<std::endl;
|
||||
std::ofstream output(fullpath);
|
||||
if(!output.is_open()) {
|
||||
std::cout<<"Write failed! Unable to open output file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
output<<"-------Data Location----------"<<std::endl;
|
||||
output<<"WorkspaceDirectory: "<<m_workspace<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
output<<"------Experimental Inputs------"<<std::endl;
|
||||
output<<"ScalerFile: "<<m_scalerfile<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
output<<"-------Timing Information------"<<std::endl;
|
||||
output<<"BoardOffsetFile: "<<m_shiftfile<<std::endl;
|
||||
output<<"SlowCoincidenceWindow(ps): "<<m_SlowWindow<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
output<<"--------Run Information--------"<<std::endl;
|
||||
output<<"MinRun: "<<m_rmin<<std::endl;
|
||||
output<<"MaxRun: "<<m_rmax<<std::endl;
|
||||
output<<"BufferSize: "<<m_buffersize<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
|
||||
output.close();
|
||||
|
||||
std::cout<<"Completed."<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void GWMEventBuilder::Convert2RawRoot() {
|
||||
std::string rawroot_dir = m_workspace+"/raw_root/";
|
||||
std::string unpack_dir = m_workspace+"/temp_binary/";
|
||||
std::string binary_dir = m_workspace+"/raw_binary/";
|
||||
std::cout<<"-------------GWM Event Builder-------------"<<std::endl;
|
||||
std::cout<<"Converting Binary file Archive to ROOT file"<<std::endl;
|
||||
std::cout<<"Binary Archive Directory: "<<binary_dir<<std::endl;
|
||||
std::cout<<"Temporary Unpack Directory: "<<unpack_dir<<std::endl;
|
||||
std::cout<<"Timestamp Shift File: "<<m_shiftfile<<std::endl;
|
||||
std::cout<<"Min Run: "<<m_rmin<<" Max Run: "<<m_rmax<<std::endl;
|
||||
std::cout<<"Buffer Size in hits: "<<m_buffersize<<std::endl;
|
||||
|
||||
|
||||
grabber.SetSearchParams(binary_dir, "", ".tar.gz",0,1000);
|
||||
|
||||
std::cout<<"Workspace Directory: "<<m_workspace<<std::endl;
|
||||
|
||||
std::string rawfile, binfile;
|
||||
std::string unpack_command, wipe_command;
|
||||
|
||||
CompassRun converter(unpack_dir, m_buffersize);
|
||||
converter.SetShiftMap(m_shiftfile);
|
||||
converter.SetScalerInput(m_scalerfile);
|
||||
if(m_pb) converter.AttachProgressBar(m_pb);
|
||||
|
||||
std::cout<<"Beginning conversion..."<<std::endl;
|
||||
|
||||
for(int i=m_rmin; i<=m_rmax; i++) {
|
||||
binfile = grabber.GrabFile(i);
|
||||
if(binfile == "") continue;
|
||||
converter.SetRunNumber(i);
|
||||
std::cout<<"Converting file: "<<binfile<<std::endl;
|
||||
|
||||
rawfile = rawroot_dir + "compass_run_"+ to_string(i) + ".root";
|
||||
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
|
||||
wipe_command = "rm -r "+unpack_dir+"*.bin";
|
||||
|
||||
system(unpack_command.c_str());
|
||||
converter.Convert2RawRoot(rawfile);
|
||||
system(wipe_command.c_str());
|
||||
|
||||
}
|
||||
std::cout<<std::endl<<"Conversion complete."<<std::endl;
|
||||
std::cout<<"-------------------------------------------"<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void GWMEventBuilder::MergeROOTFiles() {
|
||||
std::string merge_file = m_workspace+"/merged/run_"+to_string(m_rmin)+"_"+to_string(m_rmax)+".root";
|
||||
std::string file_dir = m_workspace+"/analyzed/";
|
||||
std::cout<<"-------------GWM Event Builder-------------"<<std::endl;
|
||||
std::cout<<"Merging ROOT files into single ROOT file"<<std::endl;
|
||||
std::cout<<"Workspace directory: "<<m_workspace<<std::endl;
|
||||
std::cout<<"Min Run: "<<m_rmin<<" Max Run: "<<m_rmax<<std::endl;
|
||||
std::cout<<"Output file: "<<merge_file<<std::endl;
|
||||
std::string prefix = "";
|
||||
std::string suffix = ".root";
|
||||
grabber.SetSearchParams(file_dir, prefix, suffix,m_rmin,m_rmax);
|
||||
std::cout<<"Beginning the merge...";
|
||||
if(!grabber.Merge_TChain(merge_file)) {
|
||||
std::cout<<"Unable to find files at MergeROOTFiles"<<std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout<<" Complete."<<std::endl;
|
||||
std::cout<<"-------------------------------------------"<<std::endl;
|
||||
}
|
||||
|
||||
void GWMEventBuilder::Convert2SortedRoot() {
|
||||
std::string sortroot_dir = m_workspace+"/sorted/";
|
||||
std::string unpack_dir = m_workspace+"/temp_binary/";
|
||||
std::string binary_dir = m_workspace+"/raw_binary/";
|
||||
std::cout<<"-------------GWM Event Builder-------------"<<std::endl;
|
||||
std::cout<<"Converting Binary file Archive to ROOT file"<<std::endl;
|
||||
std::cout<<"Binary Archive Directory: "<<binary_dir<<std::endl;
|
||||
std::cout<<"Temporary Unpack Directory: "<<unpack_dir<<std::endl;
|
||||
std::cout<<"Timestamp Shift File: "<<m_shiftfile<<std::endl;
|
||||
std::cout<<"Slow Coincidence Window(ps): "<<m_SlowWindow<<std::endl;
|
||||
std::cout<<"Min Run: "<<m_rmin<<" Max Run: "<<m_rmax<<std::endl;
|
||||
std::cout<<"Buffer Size in hits: "<<m_buffersize<<std::endl;
|
||||
|
||||
grabber.SetSearchParams(binary_dir,"",".tar.gz",m_rmin,m_rmax);
|
||||
|
||||
std::cout<<"Workspace Directory: "<<m_workspace<<std::endl;
|
||||
|
||||
std::string sortfile, binfile;
|
||||
std::string unpack_command, wipe_command;
|
||||
|
||||
CompassRun converter(unpack_dir, m_buffersize);
|
||||
converter.SetShiftMap(m_shiftfile);
|
||||
converter.SetScalerInput(m_scalerfile);
|
||||
if(m_pb) converter.AttachProgressBar(m_pb);
|
||||
|
||||
std::cout<<"Beginning conversion..."<<std::endl;
|
||||
|
||||
for(int i=m_rmin; i<= m_rmax; i++) {
|
||||
binfile = grabber.GrabFile(i);
|
||||
if(binfile == "") continue;
|
||||
converter.SetRunNumber(i);
|
||||
std::cout<<"Converting file: "<<binfile<<std::endl;
|
||||
|
||||
sortfile = sortroot_dir +"run_"+to_string(i)+ ".root";
|
||||
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
|
||||
wipe_command = "rm -r "+unpack_dir+"*.bin";
|
||||
|
||||
system(unpack_command.c_str());
|
||||
converter.Convert2SortedRoot(sortfile, m_SlowWindow);
|
||||
system(wipe_command.c_str());
|
||||
|
||||
}
|
||||
std::cout<<std::endl<<"Conversion complete."<<std::endl;
|
||||
std::cout<<"-------------------------------------------"<<std::endl;
|
||||
}
|
16
src/evb/Logger.cpp
Normal file
16
src/evb/Logger.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
std::shared_ptr<spdlog::logger> Logger::s_logger;
|
||||
|
||||
void Logger::Init()
|
||||
{
|
||||
spdlog::set_pattern("%^[%T] %n: %v%$");
|
||||
|
||||
s_logger = spdlog::stdout_color_mt("EVB");
|
||||
s_logger->set_level(spdlog::level::trace);
|
||||
}
|
||||
|
||||
}
|
28
src/evb/Logger.h
Normal file
28
src/evb/Logger.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include <memory>
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/fmt/ostr.h"
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
inline static std::shared_ptr<spdlog::logger> GetLogger() { return s_logger; }
|
||||
|
||||
private:
|
||||
static std::shared_ptr<spdlog::logger> s_logger;
|
||||
};
|
||||
|
||||
#define EVB_CRITICAL(...) ::EventBuilder::Logger::GetLogger()->critical(__VA_ARGS__)
|
||||
#define EVB_ERROR(...) ::EventBuilder::Logger::GetLogger()->error(__VA_ARGS__)
|
||||
#define EVB_WARN(...) ::EventBuilder::Logger::GetLogger()->warn(__VA_ARGS__)
|
||||
#define EVB_INFO(...) ::EventBuilder::Logger::GetLogger()->info(__VA_ARGS__)
|
||||
#define EVB_TRACE(...) ::EventBuilder::Logger::GetLogger()->trace(__VA_ARGS__)
|
||||
}
|
||||
|
||||
#endif
|
|
@ -8,30 +8,33 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "OrderChecker.h"
|
||||
|
||||
OrderChecker::OrderChecker() {
|
||||
namespace EventBuilder {
|
||||
|
||||
}
|
||||
OrderChecker::OrderChecker() {}
|
||||
|
||||
OrderChecker::~OrderChecker() {
|
||||
OrderChecker::~OrderChecker() {}
|
||||
|
||||
}
|
||||
bool OrderChecker::IsOrdered(const std::string& filename)
|
||||
{
|
||||
TFile* file = TFile::Open(filename.c_str(), "READ");
|
||||
TTree* tree = (TTree*) file->Get("Data");
|
||||
|
||||
bool OrderChecker::IsOrdered(const std::string& filename) {
|
||||
TFile* file = TFile::Open(filename.c_str(), "READ");
|
||||
TTree* tree = (TTree*) file->Get("Data");
|
||||
uint64_t ts;
|
||||
tree->SetBranchAddress("Timestamp", &ts);
|
||||
uint64_t prevStamp = 0;
|
||||
|
||||
ULong64_t ts;
|
||||
tree->SetBranchAddress("Timestamp", &ts);
|
||||
ULong64_t prevStamp = 0;
|
||||
|
||||
for(Long64_t i=0; i<tree->GetEntries(); i++) {
|
||||
tree->GetEntry();
|
||||
if(prevStamp >= ts) {
|
||||
std::cerr<<"Bad order at entry "<<i<<" out of "<<tree->GetEntries()<<std::endl;
|
||||
return false;
|
||||
for(int64_t i=0; i<tree->GetEntries(); i++)
|
||||
{
|
||||
tree->GetEntry(i);
|
||||
if(prevStamp >= ts)
|
||||
{
|
||||
std::cerr<<"Bad order at entry "<<i<<" out of "<<tree->GetEntries()<<std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
file->Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
file->Close();
|
||||
return true;
|
||||
}
|
|
@ -8,11 +8,15 @@
|
|||
#ifndef ORDERCHECKER_H
|
||||
#define ORDERCHECKER_H
|
||||
|
||||
class OrderChecker {
|
||||
public:
|
||||
OrderChecker();
|
||||
~OrderChecker();
|
||||
bool IsOrdered(const std::string& filename);
|
||||
};
|
||||
namespace EventBuilder {
|
||||
|
||||
class OrderChecker
|
||||
{
|
||||
public:
|
||||
OrderChecker();
|
||||
~OrderChecker();
|
||||
bool IsOrdered(const std::string& filename);
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
14
src/evb/ProgressCallback.h
Normal file
14
src/evb/ProgressCallback.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef PROGRESSCALLBACK_H
|
||||
#define PROGRESSCALLBACK_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#define BIND_PROGRESS_CALLBACK_FUNCTION(func) std::bind(&func, this, std::placeholders::_1, std::placeholders::_2)
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
using ProgressCallbackFunc = std::function<void(long, long)>;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,196 +1,232 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "RunCollector.h"
|
||||
#include <TSystemDirectory.h>
|
||||
#include <TSystemFile.h>
|
||||
#include <TCollection.h>
|
||||
#include <TList.h>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace std;
|
||||
namespace EventBuilder {
|
||||
|
||||
RunCollector::RunCollector():
|
||||
m_initFlag(false), m_directory(""), m_prefix(""), m_suffix(""), m_minRun(0), m_maxRun(0)
|
||||
{
|
||||
}
|
||||
|
||||
RunCollector::RunCollector(const std::string& dirname, const std::string& prefix, const std::string& suffix) :
|
||||
m_initFlag(true), m_directory(dirname), m_prefix(prefix), m_suffix(suffix), m_minRun(0), m_maxRun(0)
|
||||
{
|
||||
}
|
||||
|
||||
RunCollector::RunCollector(const std::string& dirname, const std::string& prefix, const std::string& suffix, int min, int max) :
|
||||
m_initFlag(true), m_directory(dirname), m_prefix(prefix), m_suffix(suffix), m_minRun(min), m_maxRun(max)
|
||||
{
|
||||
}
|
||||
|
||||
RunCollector::~RunCollector() {}
|
||||
|
||||
void RunCollector::SetSearchParams(const std::string& dirname, const std::string& prefix, const std::string& suffix, int min, int max)
|
||||
{
|
||||
m_directory = dirname.c_str();
|
||||
m_prefix = prefix.c_str();
|
||||
m_suffix = suffix.c_str();
|
||||
m_minRun = min; m_maxRun = max;
|
||||
m_initFlag = true;
|
||||
}
|
||||
|
||||
bool RunCollector::GrabAllFiles()
|
||||
{
|
||||
if(!m_initFlag)
|
||||
return false;
|
||||
|
||||
TSystemDirectory sysdir(m_directory.c_str(), m_directory.c_str());
|
||||
TList *flist = sysdir.GetListOfFiles();
|
||||
m_filelist.clear();
|
||||
|
||||
if(!flist) //Make sure list is real. If not, means no directory
|
||||
{
|
||||
EVB_WARN("RunCollector::GrabAllFiles() unable to find any files in directory {0}",m_directory);
|
||||
return false;
|
||||
}
|
||||
|
||||
TSystemFile *file;
|
||||
std::string fname, temp;
|
||||
TIter next_element(flist); //List iterator
|
||||
while((file = (TSystemFile*)next_element()))
|
||||
{
|
||||
temp = file->GetName();
|
||||
if(temp.size() < m_prefix.size() || temp.size() < m_suffix.size())
|
||||
continue;
|
||||
else if(!file->IsDirectory() && !temp.compare(0,m_prefix.size(),m_prefix) &&
|
||||
!temp.compare(temp.size()-m_suffix.size(), m_suffix.size(), m_suffix))
|
||||
{
|
||||
fname = m_directory+temp;
|
||||
m_filelist.push_back(fname);
|
||||
}
|
||||
}
|
||||
|
||||
delete flist;
|
||||
if(m_filelist.size()>0)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
EVB_WARN("RunCollector::GrabAllFiles() unable to find any files in directory {0} which match run pattern",m_directory);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string RunCollector::GrabFile(int runNum) {
|
||||
if(!m_initFlag)
|
||||
return "";
|
||||
TSystemDirectory sysdir(m_directory.c_str(), m_directory.c_str());
|
||||
TList* flist = sysdir.GetListOfFiles();
|
||||
|
||||
if(!flist)
|
||||
return "";
|
||||
|
||||
TSystemFile *file;
|
||||
std::string fname = "", temp;
|
||||
std::string runno = "_"+std::to_string(runNum)+m_suffix;
|
||||
TIter next_element(flist);
|
||||
while((file = (TSystemFile*)next_element()))
|
||||
{
|
||||
temp = file->GetName();
|
||||
if(temp.size() < m_prefix.size() || temp.size() < runno.size())
|
||||
continue;
|
||||
else if(!file->IsDirectory() && !temp.compare(0,m_prefix.size(),m_prefix) &&
|
||||
!temp.compare(temp.size()-runno.size(),runno.size(), runno))
|
||||
{
|
||||
fname = m_directory+temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete flist;
|
||||
return fname;
|
||||
}
|
||||
|
||||
/*Grabs all files within a specified run range*/
|
||||
bool RunCollector::GrabFilesInRange()
|
||||
{
|
||||
if(!m_initFlag)
|
||||
return false;
|
||||
|
||||
TSystemDirectory sysdir(m_directory.c_str(), m_directory.c_str());
|
||||
TList *flist = sysdir.GetListOfFiles();
|
||||
m_filelist.clear();
|
||||
|
||||
if(!flist)
|
||||
{
|
||||
EVB_WARN("RunCollector::GrabFilesInRange() unable to find any files in directory {0}",m_directory);
|
||||
return false;
|
||||
}
|
||||
|
||||
TSystemFile *file;
|
||||
std::string fname, temp;
|
||||
std::string runno;
|
||||
for(int i=m_minRun; i<=m_maxRun; i++) //loop over range
|
||||
{
|
||||
TIter next_element(flist);//list iterator
|
||||
runno = "_"+std::to_string(i) + m_suffix; //suffix is now _#.suffix
|
||||
while((file = (TSystemFile*)next_element())) //look through directory until file found
|
||||
{
|
||||
temp = file->GetName();
|
||||
if(temp.size() < m_prefix.size() || temp.size() < runno.size())
|
||||
continue;
|
||||
else if(!file->IsDirectory() && !temp.compare(0,m_prefix.size(),m_prefix) &&
|
||||
!temp.compare(temp.size()-runno.size(),runno.size(), runno))
|
||||
{
|
||||
fname = m_directory+temp;
|
||||
m_filelist.push_back(fname);
|
||||
break; //if we find the file, break out of iterator loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete flist;
|
||||
if(m_filelist.size()>0)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
EVB_WARN("RunCollector::GrabAllFiles() unable to find any files in directory {0} which match run pattern and were in run range",m_directory);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool RunCollector::Merge_hadd(const std::string& outname)
|
||||
{
|
||||
int sys_return;
|
||||
if(!m_initFlag)
|
||||
return false;
|
||||
|
||||
if(m_maxRun == 0)
|
||||
{
|
||||
if(GrabAllFiles())
|
||||
{
|
||||
std::string clump = "hadd "+outname;
|
||||
for(unsigned int i=0; i<m_filelist.size(); i++)
|
||||
clump += " "+m_filelist[i];
|
||||
sys_return = std::system(clump.c_str());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GrabFilesInRange())
|
||||
{
|
||||
std::string clump = "hadd "+outname;
|
||||
for(unsigned int i=0; i<m_filelist.size(); i++)
|
||||
clump += " "+m_filelist[i];
|
||||
sys_return = std::system(clump.c_str());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!sys_return)
|
||||
EVB_ERROR("How did i even get here?");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RunCollector::Merge_TChain(const std::string& outname)
|
||||
{
|
||||
if(!m_initFlag)
|
||||
return false;
|
||||
TFile *output = new TFile(outname.c_str(), "RECREATE");
|
||||
TChain *chain = new TChain("SPSTree", "SPSTree");
|
||||
|
||||
if(m_maxRun == 0)
|
||||
{
|
||||
if(GrabAllFiles())
|
||||
{
|
||||
for(unsigned int i=0; i<m_filelist.size(); i++)
|
||||
chain->Add(m_filelist[i].c_str());
|
||||
chain->Merge(output,0,"fast");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GrabFilesInRange())
|
||||
{
|
||||
for(unsigned int i=0; i<m_filelist.size(); i++)
|
||||
chain->Add(m_filelist[i].c_str());
|
||||
chain->Merge(output,0,"fast");
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
if(output->IsOpen())
|
||||
output->Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
RunCollector::RunCollector():
|
||||
initFlag(false), dir(""), run(""), end(""), MaxRun(0), MinRun(0)
|
||||
{
|
||||
}
|
||||
|
||||
RunCollector::RunCollector(const string& dirname, const string& prefix, const string& suffix) {
|
||||
dir = dirname.c_str();
|
||||
run = prefix.c_str();
|
||||
end = suffix.c_str();
|
||||
|
||||
MinRun = 0; MaxRun = LITERALMAX;
|
||||
initFlag = true;
|
||||
}
|
||||
|
||||
RunCollector::RunCollector(const string& dirname, const string& prefix, const string& suffix, int min, int max) {
|
||||
dir = dirname.c_str();
|
||||
run = prefix.c_str();
|
||||
end = suffix.c_str();
|
||||
|
||||
MinRun = min; MaxRun = max;
|
||||
initFlag = true;
|
||||
}
|
||||
|
||||
RunCollector::~RunCollector() {}
|
||||
|
||||
void RunCollector::SetSearchParams(const string& dirname, const string& prefix, const string& suffix, int min, int max) {
|
||||
dir = dirname.c_str();
|
||||
run = prefix.c_str();
|
||||
end = suffix.c_str();
|
||||
MinRun = min; MaxRun = max;
|
||||
initFlag = true;
|
||||
}
|
||||
|
||||
int RunCollector::GrabAllFiles() {
|
||||
if(!initFlag) {return 0;}
|
||||
TSystemDirectory sysdir(dir.Data(), dir.Data());
|
||||
TList *flist = sysdir.GetListOfFiles();
|
||||
filelist.clear();
|
||||
int counter = 0;
|
||||
if(flist) { //Make sure list is real. If not, means no directory
|
||||
TSystemFile *file;
|
||||
TString fname, temp;
|
||||
TIter next_element(flist); //List iterator
|
||||
while((file = (TSystemFile*)next_element())) {
|
||||
temp = file->GetName();
|
||||
if(!file->IsDirectory() && temp.BeginsWith(run.Data()) && temp.EndsWith(end.Data())) {
|
||||
counter++;
|
||||
fname = dir+temp;
|
||||
filelist.push_back(fname);
|
||||
}
|
||||
}
|
||||
if(counter>0) {
|
||||
delete flist;
|
||||
return 1;
|
||||
} else {
|
||||
cerr<<"Unable to find files with matching run name in directory; check input.txt"<<endl;
|
||||
delete flist;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
cerr<<"Unable to find any files in directory; check name given to the input.txt"<<endl;
|
||||
delete flist;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string RunCollector::GrabFile(int runNum) {
|
||||
if(!initFlag) return "";
|
||||
TSystemDirectory sysdir(dir.Data(), dir.Data());
|
||||
TList* flist = sysdir.GetListOfFiles();
|
||||
|
||||
if(!flist) return "";
|
||||
|
||||
TSystemFile *file;
|
||||
TString fname = "", temp;
|
||||
string runno = "_"+to_string(runNum)+end.Data();
|
||||
TIter next_element(flist);
|
||||
while((file = (TSystemFile*)next_element())) {
|
||||
temp = file->GetName();
|
||||
if(!file->IsDirectory() && temp.BeginsWith(run.Data()) && temp.EndsWith(runno.c_str())) {
|
||||
fname = dir+temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return fname.Data();
|
||||
}
|
||||
|
||||
/*Grabs all files within a specified run range*/
|
||||
int RunCollector::GrabFilesInRange() {
|
||||
if(!initFlag) {return 0;}
|
||||
TSystemDirectory sysdir(dir.Data(), dir.Data());
|
||||
TList *flist = sysdir.GetListOfFiles();
|
||||
filelist.clear();
|
||||
int counter = 0;
|
||||
if(flist) {
|
||||
TSystemFile *file;
|
||||
TString fname, temp;
|
||||
string runno;
|
||||
for(int i=MinRun; i<=MaxRun; i++) {//loop over range
|
||||
TIter next_element(flist);//list iterator
|
||||
runno = "_"+to_string(i) + end.Data(); //suffix is now _#.endData
|
||||
while((file = (TSystemFile*)next_element())) {//look through directory until file found
|
||||
temp = file->GetName();
|
||||
if(!file->IsDirectory()&&temp.BeginsWith(run.Data())&&temp.EndsWith(runno.c_str())){
|
||||
counter++;
|
||||
fname = dir+temp;
|
||||
filelist.push_back(fname);
|
||||
break; //if we find the file, break out of iterator loop
|
||||
}
|
||||
}
|
||||
}
|
||||
if(counter>0) {
|
||||
delete flist;
|
||||
return 1;
|
||||
} else {
|
||||
cerr<<"Unable to find files with matching run name in directory; check input.txt"<<endl;
|
||||
delete flist;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
cerr<<"Unable to find any files in directory; check name given to input.txt"<<endl;
|
||||
delete flist;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int RunCollector::Merge_hadd(const string& outname) {
|
||||
if(!initFlag) {return 0;}
|
||||
if(MaxRun == LITERALMAX) {
|
||||
if(GrabAllFiles()) {
|
||||
TString clump = "hadd "+outname;
|
||||
for(unsigned int i=0; i<filelist.size(); i++) {
|
||||
clump += " "+filelist[i];
|
||||
}
|
||||
cout<<"Merging runs into single file..."<<endl;
|
||||
system(clump.Data());
|
||||
cout<<"Finished merging"<<endl;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if(GrabFilesInRange()) {
|
||||
TString clump = "hadd "+outname;
|
||||
for(unsigned int i=0; i<filelist.size(); i++) {
|
||||
clump += " "+filelist[i];
|
||||
}
|
||||
cout<<"Merging runs "<<MinRun<<" to "<<MaxRun<<" into a single file..."<<endl;
|
||||
system(clump.Data());
|
||||
cout<<"Finished merging"<<endl;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int RunCollector::Merge_TChain(const string& outname) {
|
||||
if(!initFlag) {return 0;}
|
||||
TFile *output = new TFile(outname.c_str(), "RECREATE");
|
||||
TChain *chain = new TChain("SPSTree", "SPSTree");
|
||||
|
||||
if(MaxRun == LITERALMAX) {
|
||||
if(GrabAllFiles()) {
|
||||
for(unsigned int i=0; i<filelist.size(); i++) {
|
||||
chain->Add(filelist[i].Data());
|
||||
}
|
||||
cout<<"Merging runs into single file..."<<endl;
|
||||
chain->Merge(output,0,"fast");
|
||||
cout<<"Finished merging"<<endl;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if(GrabFilesInRange()) {
|
||||
for(unsigned int i=0; i<filelist.size(); i++) {
|
||||
chain->Add(filelist[i]);
|
||||
}
|
||||
cout<<"Merging runs "<<MinRun<<" to "<<MaxRun<<" into a single file..."<<endl;
|
||||
chain->Merge(output,0,"fast");
|
||||
cout<<"Finished merging"<<endl;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(output->IsOpen()) output->Close();
|
||||
return 0;
|
||||
}
|
47
src/evb/RunCollector.h
Normal file
47
src/evb/RunCollector.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*RunCollector.h
|
||||
*Class that searches through a directory looking for files of a specified format.
|
||||
*Stores all filenames in a vector which can be accessed by other functions/classes for
|
||||
*further use. Can also use Merge() to combine all files using hadd into a single file.
|
||||
*Merge() is NOT RECOMMENDED in the analyzer program.
|
||||
*
|
||||
*Created Jan2020 by GWM
|
||||
*/
|
||||
|
||||
#ifndef RUNCOLLECTOR_H
|
||||
#define RUNCOLLECTOR_H
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
class RunCollector
|
||||
{
|
||||
public:
|
||||
RunCollector();
|
||||
RunCollector(const std::string& dirname, const std::string& prefix, const std::string& suffix);
|
||||
RunCollector(const std::string& dirname, const std::string& prefix, const std::string& suffix, int min, int max);
|
||||
~RunCollector();
|
||||
void SetSearchParams(const std::string& dirname, const std::string& prefix, const std::string& suffix, int min, int max);
|
||||
bool Merge_hadd(const std::string& outname);
|
||||
bool Merge_TChain(const std::string& outname);
|
||||
bool GrabAllFiles();
|
||||
bool GrabFilesInRange();
|
||||
std::string GrabFile(int runNum);
|
||||
inline std::string GetSearchDir() { return m_directory; }
|
||||
inline std::string GetSearchPrefix() { return m_prefix; }
|
||||
inline std::string GetSearchSuffix() { return m_suffix; }
|
||||
inline int GetRunMin() { return m_minRun; }
|
||||
inline int GetRunMax() { return m_maxRun; }
|
||||
inline const std::vector<std::string>& GetFileList() { return m_filelist; }
|
||||
|
||||
private:
|
||||
bool m_initFlag;
|
||||
std::string m_directory;
|
||||
std::string m_prefix;
|
||||
std::string m_suffix;
|
||||
int m_minRun, m_maxRun; //user run limits
|
||||
const int m_maxAllowedRuns = 1000; //class run limit
|
||||
std::vector<std::string> m_filelist;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -12,58 +12,73 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "ShiftMap.h"
|
||||
|
||||
ShiftMap::ShiftMap() :
|
||||
m_filename(""), is_set(false)
|
||||
{
|
||||
}
|
||||
namespace EventBuilder {
|
||||
|
||||
ShiftMap::ShiftMap(const std::string& filename) :
|
||||
m_filename(filename), is_set(false)
|
||||
{
|
||||
ParseFile();
|
||||
}
|
||||
|
||||
ShiftMap::~ShiftMap() {}
|
||||
|
||||
void ShiftMap::SetFile(const std::string& filename) {
|
||||
m_filename = filename;
|
||||
ParseFile();
|
||||
}
|
||||
|
||||
Long64_t ShiftMap::GetShift(int gchan) {
|
||||
if(!is_set) return 0.0;
|
||||
|
||||
auto iter = m_map.find(gchan);
|
||||
if(iter == m_map.end()) {
|
||||
return 0.0;
|
||||
} else return iter->second;
|
||||
}
|
||||
|
||||
void ShiftMap::ParseFile() {
|
||||
std::ifstream input(m_filename);
|
||||
if(!input.is_open()) return;
|
||||
|
||||
int board, channel, gchan;
|
||||
Long64_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;
|
||||
}
|
||||
ShiftMap::ShiftMap() :
|
||||
m_filename(""), is_set(false)
|
||||
{
|
||||
}
|
||||
|
||||
ShiftMap::ShiftMap(const std::string& filename) :
|
||||
m_filename(filename), is_set(false)
|
||||
{
|
||||
ParseFile();
|
||||
}
|
||||
|
||||
ShiftMap::~ShiftMap() {}
|
||||
|
||||
void ShiftMap::SetFile(const std::string& filename)
|
||||
{
|
||||
m_filename = filename;
|
||||
ParseFile();
|
||||
}
|
||||
|
||||
int64_t ShiftMap::GetShift(int gchan)
|
||||
{
|
||||
if(!is_set)
|
||||
return 0.0;
|
||||
|
||||
auto iter = m_map.find(gchan);
|
||||
if(iter == m_map.end())
|
||||
return 0.0;
|
||||
else
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
void ShiftMap::ParseFile()
|
||||
{
|
||||
std::ifstream input(m_filename);
|
||||
if(!input.is_open())
|
||||
return;
|
||||
|
||||
int board, channel, gchan;
|
||||
int64_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;
|
||||
}
|
||||
}
|
||||
|
||||
is_set = true;
|
||||
}
|
||||
|
||||
is_set = true;
|
||||
}
|
|
@ -12,24 +12,27 @@
|
|||
#ifndef SHIFTMAP_H
|
||||
#define SHIFTMAP_H
|
||||
|
||||
class ShiftMap {
|
||||
public:
|
||||
ShiftMap();
|
||||
ShiftMap(const std::string& filename);
|
||||
~ShiftMap();
|
||||
void SetFile(const std::string& filename);
|
||||
inline bool IsSet() { return is_set; };
|
||||
inline std::string GetFilename() { return m_filename; };
|
||||
Long64_t GetShift(int gchan);
|
||||
namespace EventBuilder {
|
||||
|
||||
private:
|
||||
void ParseFile();
|
||||
class ShiftMap
|
||||
{
|
||||
public:
|
||||
ShiftMap();
|
||||
ShiftMap(const std::string& filename);
|
||||
~ShiftMap();
|
||||
void SetFile(const std::string& filename);
|
||||
inline bool IsSet() { return is_set; }
|
||||
inline std::string GetFilename() { return m_filename; }
|
||||
int64_t GetShift(int gchan);
|
||||
|
||||
std::string m_filename;
|
||||
bool is_set;
|
||||
private:
|
||||
void ParseFile();
|
||||
|
||||
std::unordered_map<int, Long64_t> m_map;
|
||||
std::string m_filename;
|
||||
bool is_set;
|
||||
|
||||
};
|
||||
std::unordered_map<int, int64_t> m_map;
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
|
@ -10,78 +10,92 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "SlowSort.h"
|
||||
|
||||
/*Constructor takes input of coincidence window size, and fills sabre channel map*/
|
||||
SlowSort::SlowSort() :
|
||||
coincWindow(-1.0), eventFlag(false)
|
||||
{
|
||||
event_stats = new TH2F("coinc_event_stats","coinc_events_stats;global channel;number of coincident hits;counts",144,0,144,20,0,20);
|
||||
}
|
||||
|
||||
SlowSort::SlowSort(double windowSize) :
|
||||
coincWindow(windowSize), eventFlag(false)
|
||||
{
|
||||
event_stats = new TH2F("coinc_event_stats","coinc_events_stats;global channel;number of coincident hits;counts",144,0,144,20,0,20);
|
||||
}
|
||||
|
||||
SlowSort::~SlowSort() {
|
||||
}
|
||||
|
||||
bool SlowSort::AddHitToEvent(CompassHit& mhit) {
|
||||
DPPChannel curHit;
|
||||
curHit.Timestamp = mhit.timestamp/1.0e3; //convert to ns for easier drawing
|
||||
curHit.Energy = mhit.lgate;
|
||||
curHit.EnergyShort = mhit.sgate;
|
||||
curHit.Channel = mhit.channel;
|
||||
curHit.Board = mhit.board;
|
||||
curHit.Flags = mhit.flags;
|
||||
curHit.Samples = mhit.samples;
|
||||
|
||||
if(hitList.empty()) {
|
||||
startTime = curHit.Timestamp;
|
||||
hitList.push_back(curHit);
|
||||
} else if (curHit.Timestamp < previousHitTime) {
|
||||
return false;
|
||||
} else if ((curHit.Timestamp - startTime) < coincWindow) {
|
||||
hitList.push_back(curHit);
|
||||
} else {
|
||||
ProcessEvent();
|
||||
hitList.clear();
|
||||
startTime = curHit.Timestamp;
|
||||
hitList.push_back(curHit);
|
||||
eventFlag = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SlowSort::FlushHitsToEvent() {
|
||||
if(hitList.empty()) {
|
||||
eventFlag = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessEvent();
|
||||
hitList.clear();
|
||||
eventFlag = true;
|
||||
}
|
||||
|
||||
vector<DPPChannel> SlowSort::GetEvent() {
|
||||
eventFlag = false;
|
||||
return event;
|
||||
}
|
||||
|
||||
/*Function called when a start of a coincidence event is detected*/
|
||||
void SlowSort::StartEvent() {
|
||||
if(hitList.size() != 0) {
|
||||
cerr<<"Attempting to initalize hitList when not cleared!! Check processing order."<<endl;
|
||||
}
|
||||
startTime = hit.Timestamp;
|
||||
hitList.push_back(hit);
|
||||
}
|
||||
|
||||
/*Function called when an event outside the coincidence window is detected
|
||||
*Process all of the hits in the list, and write them to the sorted tree
|
||||
*/
|
||||
void SlowSort::ProcessEvent() {
|
||||
event = hitList;
|
||||
namespace EventBuilder {
|
||||
|
||||
/*Constructor takes input of coincidence window size, and fills sabre channel map*/
|
||||
SlowSort::SlowSort() :
|
||||
coincWindow(-1.0), eventFlag(false)
|
||||
{
|
||||
event_stats = new TH2F("coinc_event_stats","coinc_events_stats;global channel;number of coincident hits;counts",144,0,144,20,0,20);
|
||||
}
|
||||
|
||||
SlowSort::SlowSort(double windowSize) :
|
||||
coincWindow(windowSize), eventFlag(false)
|
||||
{
|
||||
event_stats = new TH2F("coinc_event_stats","coinc_events_stats;global channel;number of coincident hits;counts",144,0,144,20,0,20);
|
||||
}
|
||||
|
||||
SlowSort::~SlowSort() {}
|
||||
|
||||
bool SlowSort::AddHitToEvent(CompassHit& mhit)
|
||||
{
|
||||
DPPChannel curHit;
|
||||
curHit.Timestamp = mhit.timestamp/1.0e3; //convert to ns for easier drawing
|
||||
curHit.Energy = mhit.energy;
|
||||
curHit.EnergyShort = mhit.energyShort;
|
||||
curHit.EnergyCal = mhit.energyCalibrated;
|
||||
curHit.Channel = mhit.channel;
|
||||
curHit.Board = mhit.board;
|
||||
curHit.Flags = mhit.flags;
|
||||
curHit.Samples = mhit.samples;
|
||||
|
||||
if(hitList.empty())
|
||||
{
|
||||
startTime = curHit.Timestamp;
|
||||
hitList.push_back(curHit);
|
||||
}
|
||||
else if (curHit.Timestamp < previousHitTime)
|
||||
return false;
|
||||
else if ((curHit.Timestamp - startTime) < coincWindow)
|
||||
hitList.push_back(curHit);
|
||||
else
|
||||
{
|
||||
ProcessEvent();
|
||||
hitList.clear();
|
||||
startTime = curHit.Timestamp;
|
||||
hitList.push_back(curHit);
|
||||
eventFlag = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SlowSort::FlushHitsToEvent()
|
||||
{
|
||||
if(hitList.empty())
|
||||
{
|
||||
eventFlag = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessEvent();
|
||||
hitList.clear();
|
||||
eventFlag = true;
|
||||
}
|
||||
|
||||
std::vector<DPPChannel> SlowSort::GetEvent()
|
||||
{
|
||||
eventFlag = false;
|
||||
return event;
|
||||
}
|
||||
|
||||
/*Function called when a start of a coincidence event is detected*/
|
||||
void SlowSort::StartEvent()
|
||||
{
|
||||
if(hitList.size() != 0)
|
||||
{
|
||||
EVB_WARN("Attempting to initalize hitList when not cleared!! Check processing order.");
|
||||
}
|
||||
startTime = hit.Timestamp;
|
||||
hitList.push_back(hit);
|
||||
}
|
||||
|
||||
/*Function called when an event outside the coincidence window is detected
|
||||
*Process all of the hits in the list, and write them to the sorted tree
|
||||
*/
|
||||
void SlowSort::ProcessEvent()
|
||||
{
|
||||
event = hitList;
|
||||
}
|
||||
|
||||
}
|
52
src/evb/SlowSort.h
Normal file
52
src/evb/SlowSort.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*SlowSort.h
|
||||
*Class designed to first time-order raw data, and then based on a given coincidence window
|
||||
*sort the raw data into coincidence structures. Utilizes dictionary elements DPPChannel and
|
||||
*CoincEvent. Based on work by S. Balak, K. Macon, and E. Good from LSU.
|
||||
*
|
||||
*Gordon M. Oct. 2019
|
||||
*
|
||||
*Refurbished and updated Jan 2020 GWM
|
||||
*/
|
||||
#ifndef SLOW_SORT_H
|
||||
#define SLOW_SORT_H
|
||||
|
||||
#include "CompassHit.h"
|
||||
#include "evbdict/DataStructs.h"
|
||||
#include <TH2.h>
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
class SlowSort
|
||||
{
|
||||
public:
|
||||
SlowSort();
|
||||
SlowSort(double windowSize);
|
||||
~SlowSort();
|
||||
inline void SetWindowSize(double window) { coincWindow = window; }
|
||||
bool AddHitToEvent(CompassHit& mhit);
|
||||
std::vector<DPPChannel> GetEvent();
|
||||
inline TH2F* GetEventStats() { return event_stats; }
|
||||
void FlushHitsToEvent(); //For use with *last* hit list
|
||||
inline bool IsEventReady() { return eventFlag; }
|
||||
|
||||
private:
|
||||
void InitVariableMaps();
|
||||
void Reset();
|
||||
void StartEvent();
|
||||
void ProcessEvent();
|
||||
|
||||
double coincWindow;
|
||||
std::vector<DPPChannel> hitList;
|
||||
std::vector<DPPChannel> event;
|
||||
bool eventFlag;
|
||||
DPPChannel hit;
|
||||
|
||||
double startTime, previousHitTime;
|
||||
|
||||
TH2F* event_stats;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -8,25 +8,34 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "Stopwatch.h"
|
||||
|
||||
Stopwatch::Stopwatch() {
|
||||
start_time = Clock::now();
|
||||
stop_time = start_time;
|
||||
}
|
||||
namespace EventBuilder {
|
||||
|
||||
Stopwatch::~Stopwatch() {}
|
||||
Stopwatch::Stopwatch()
|
||||
{
|
||||
start_time = Clock::now();
|
||||
stop_time = start_time;
|
||||
}
|
||||
|
||||
void Stopwatch::Start() {
|
||||
start_time = Clock::now();
|
||||
}
|
||||
Stopwatch::~Stopwatch() {}
|
||||
|
||||
void Stopwatch::Stop() {
|
||||
stop_time = Clock::now();
|
||||
}
|
||||
void Stopwatch::Start()
|
||||
{
|
||||
start_time = Clock::now();
|
||||
}
|
||||
|
||||
double Stopwatch::GetElapsedSeconds() {
|
||||
return std::chrono::duration_cast<std::chrono::duration<double>>(stop_time-start_time).count();
|
||||
}
|
||||
void Stopwatch::Stop()
|
||||
{
|
||||
stop_time = Clock::now();
|
||||
}
|
||||
|
||||
double Stopwatch::GetElapsedSeconds()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::duration<double>>(stop_time-start_time).count();
|
||||
}
|
||||
|
||||
double Stopwatch::GetElapsedMilliseconds()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::duration<double>>(stop_time-start_time).count()*1000.0;
|
||||
}
|
||||
|
||||
double Stopwatch::GetElapsedMilliseconds() {
|
||||
return std::chrono::duration_cast<std::chrono::duration<double>>(stop_time-start_time).count()*1000.0;
|
||||
}
|
33
src/evb/Stopwatch.h
Normal file
33
src/evb/Stopwatch.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Stopwatch.h
|
||||
Simple class designed to provide timing info on parts of the process.
|
||||
Only for use in development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#ifndef STOPWATCH_H
|
||||
#define STOPWATCH_H
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace EventBuilder {
|
||||
|
||||
class Stopwatch
|
||||
{
|
||||
public:
|
||||
Stopwatch();
|
||||
~Stopwatch();
|
||||
void Start();
|
||||
void Stop();
|
||||
double GetElapsedSeconds();
|
||||
double GetElapsedMilliseconds();
|
||||
|
||||
private:
|
||||
using Time = std::chrono::high_resolution_clock::time_point;
|
||||
using Clock = std::chrono::high_resolution_clock;
|
||||
|
||||
Time start_time, stop_time;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
17
src/evbdict/CMakeLists.txt
Normal file
17
src/evbdict/CMakeLists.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
add_library(EVBDict SHARED)
|
||||
|
||||
target_include_directories(EVBDict SYSTEM PUBLIC ${ROOT_INCLUDE_DIRS} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
ROOT_GENERATE_DICTIONARY(evbdict DataStructs.h LINKDEF LinkDef_evb.h MODULE EVBDict)
|
||||
|
||||
target_sources(EVBDict PRIVATE
|
||||
DataStructs.h
|
||||
DataStructs.cpp
|
||||
)
|
||||
target_link_libraries(EVBDict ${ROOT_LIBRARIES})
|
||||
set_target_properties(EVBDict PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${EVB_LIBRARY_DIR})
|
||||
|
||||
add_custom_command(TARGET EVBDict POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libEVBDict_rdict.pcm
|
||||
${EVB_LIBRARY_DIR}/libEVBDict_rdict.pcm
|
||||
)
|
3
src/evbdict/DataStructs.cpp
Normal file
3
src/evbdict/DataStructs.cpp
Normal file
|
@ -0,0 +1,3 @@
|
|||
#include "DataStructs.h"
|
||||
|
||||
bool EnforceDictonaryLinked() { return true; }
|
28
src/evbdict/DataStructs.h
Normal file
28
src/evbdict/DataStructs.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*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>
|
||||
#include <cstdint>
|
||||
|
||||
struct DPPChannel
|
||||
{
|
||||
double Timestamp;
|
||||
int Channel, Board, Energy, EnergyShort;
|
||||
int64_t EnergyCal;
|
||||
int Flags;
|
||||
std::vector<uint16_t> Samples;
|
||||
};
|
||||
|
||||
/*
|
||||
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, 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 EnforceDictonaryLinked();
|
||||
|
||||
#endif
|
|
@ -3,6 +3,8 @@
|
|||
#include "EVBMainFrame.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
EventBuilder::Logger::Init();
|
||||
|
||||
TApplication app("app", &argc, argv);
|
||||
UInt_t h = 400;
|
||||
UInt_t w = 400;
|
||||
|
|
23
src/guidict/CMakeLists.txt
Normal file
23
src/guidict/CMakeLists.txt
Normal 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(guidict 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
|
||||
EVBDict
|
||||
EventBuilderCore
|
||||
${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
|
||||
)
|
|
@ -1,4 +1,3 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "EVBMainFrame.h"
|
||||
#include "FileViewFrame.h"
|
||||
#include <TGLabel.h>
|
||||
|
@ -12,6 +11,8 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) :
|
|||
SetCleanup(kDeepCleanup);
|
||||
MAIN_W = w; MAIN_H = h;
|
||||
|
||||
fInfo = new TGFileInfo();
|
||||
|
||||
//Organization hints
|
||||
TGLayoutHints *fchints = new TGLayoutHints(kLHintsExpandX|kLHintsExpandY,5,5,5,5);
|
||||
TGLayoutHints *fhints = new TGLayoutHints(kLHintsExpandX|kLHintsCenterY,5,5,5,5);
|
||||
|
@ -76,9 +77,9 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) :
|
|||
TGLabel *typelabel = new TGLabel(RunFrame, "Operation Type:");
|
||||
fTypeBox = new TGComboBox(RunFrame, TYPEBOX);
|
||||
//Needs modification for new conversion based sorting GWM -- Dec 2020
|
||||
fTypeBox->AddEntry("Convert Slow", GWMEventBuilder::CONVERT_S);
|
||||
fTypeBox->AddEntry("Convert", GWMEventBuilder::CONVERT);
|
||||
fTypeBox->AddEntry("Merge ROOT", GWMEventBuilder::MERGE);
|
||||
fTypeBox->AddEntry("Convert Slow", EventBuilder::EVBApp::Operation::ConvertSlow);
|
||||
fTypeBox->AddEntry("Convert", EventBuilder::EVBApp::Operation::Convert);
|
||||
fTypeBox->AddEntry("Merge ROOT", EventBuilder::EVBApp::Operation::Merge);
|
||||
fTypeBox->Resize(200,20);
|
||||
fTypeBox->Connect("Selected(Int_t, Int_t)","EVBMainFrame",this,"HandleTypeSelection(Int_t,Int_t)");
|
||||
TGLabel *rminlabel = new TGLabel(RunFrame, "Min Run:");
|
||||
|
@ -105,7 +106,6 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) :
|
|||
fProgressBar = new TGHProgressBar(PBFrame, TGProgressBar::kFancy, w);
|
||||
fProgressBar->ShowPosition();
|
||||
fProgressBar->SetBarColor("lightblue");
|
||||
fBuilder.AttachProgressBar(fProgressBar);
|
||||
PBFrame->AddFrame(pbLabel, lhints);
|
||||
PBFrame->AddFrame(fProgressBar, fhints);
|
||||
|
||||
|
@ -121,6 +121,8 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) :
|
|||
AddFrame(InputFrame, fchints);
|
||||
AddFrame(PBFrame, fpbhints);
|
||||
|
||||
fBuilder.SetProgressCallbackFunc(BIND_PROGRESS_CALLBACK_FUNCTION(EVBMainFrame::SetProgressBarPosition));
|
||||
fBuilder.SetProgressFraction(0.01);
|
||||
SetWindowName("GWM Event Builder");
|
||||
MapSubwindows();
|
||||
Resize();
|
||||
|
@ -128,54 +130,77 @@ EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) :
|
|||
|
||||
}
|
||||
|
||||
EVBMainFrame::~EVBMainFrame() {
|
||||
EVBMainFrame::~EVBMainFrame()
|
||||
{
|
||||
Cleanup();
|
||||
delete fInfo;
|
||||
delete this;
|
||||
}
|
||||
|
||||
void EVBMainFrame::CloseWindow() {
|
||||
void EVBMainFrame::CloseWindow()
|
||||
{
|
||||
gApplication->Terminate();
|
||||
}
|
||||
|
||||
void EVBMainFrame::HandleMenuSelection(int id) {
|
||||
if(id == M_SAVE_CONFIG) new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, M_SAVE_CONFIG);
|
||||
else if(id == M_LOAD_CONFIG) new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, M_LOAD_CONFIG);
|
||||
else if(id == M_EXIT) CloseWindow();
|
||||
void EVBMainFrame::HandleMenuSelection(int id)
|
||||
{
|
||||
if(id == M_SAVE_CONFIG)
|
||||
{
|
||||
new TGFileDialog(gClient->GetRoot(), this, kFDOpen, fInfo);
|
||||
if(fInfo->fFilename)
|
||||
SaveConfig(fInfo->fFilename);
|
||||
}
|
||||
else if(id == M_LOAD_CONFIG)
|
||||
{
|
||||
new TGFileDialog(gClient->GetRoot(), this, kFDOpen, fInfo);
|
||||
if(fInfo->fFilename)
|
||||
LoadConfig(fInfo->fFilename);
|
||||
}
|
||||
else if(id == M_EXIT)
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void EVBMainFrame::DoOpenWorkdir() {
|
||||
void EVBMainFrame::DoOpenWorkdir()
|
||||
{
|
||||
new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, WORKDIR);
|
||||
}
|
||||
|
||||
void EVBMainFrame::DoOpenSMapfile() {
|
||||
new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, SMAP);
|
||||
void EVBMainFrame::DoOpenSMapfile()
|
||||
{
|
||||
new TGFileDialog(gClient->GetRoot(), this, kFDOpen, fInfo);
|
||||
if(fInfo->fFilename)
|
||||
DisplaySMap(fInfo->fFilename);
|
||||
}
|
||||
|
||||
void EVBMainFrame::DoOpenScalerfile() {
|
||||
new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, SCALER);
|
||||
void EVBMainFrame::DoOpenScalerfile()
|
||||
{
|
||||
new TGFileDialog(gClient->GetRoot(), this, kFDOpen, fInfo);
|
||||
if(fInfo->fFilename)
|
||||
DisplayScaler(fInfo->fFilename);
|
||||
}
|
||||
|
||||
void EVBMainFrame::DoRun() {
|
||||
void EVBMainFrame::DoRun()
|
||||
{
|
||||
|
||||
DisableAllInput();
|
||||
|
||||
SetParameters();
|
||||
|
||||
int type = fTypeBox->GetSelected();
|
||||
fBuilder.SetAnalysisType(type);
|
||||
|
||||
switch(type) {
|
||||
case GWMEventBuilder::CONVERT :
|
||||
switch(type)
|
||||
{
|
||||
case EventBuilder::EVBApp::Operation::Convert :
|
||||
{
|
||||
fBuilder.Convert2RawRoot();
|
||||
break;
|
||||
}
|
||||
case GWMEventBuilder::MERGE :
|
||||
case EventBuilder::EVBApp::Operation::Merge :
|
||||
{
|
||||
fBuilder.MergeROOTFiles();
|
||||
break;
|
||||
}
|
||||
case GWMEventBuilder::CONVERT_S :
|
||||
case EventBuilder::EVBApp::Operation::ConvertSlow :
|
||||
{
|
||||
fBuilder.Convert2SortedRoot();
|
||||
break;
|
||||
|
@ -185,11 +210,13 @@ void EVBMainFrame::DoRun() {
|
|||
EnableAllInput();
|
||||
}
|
||||
|
||||
void EVBMainFrame::HandleTypeSelection(int box, int entry) {
|
||||
void EVBMainFrame::HandleTypeSelection(int box, int entry)
|
||||
{
|
||||
fRunButton->SetState(kButtonUp);
|
||||
}
|
||||
|
||||
bool EVBMainFrame::SetParameters() {
|
||||
bool EVBMainFrame::SetParameters()
|
||||
{
|
||||
fBuilder.SetRunRange(fRMinField->GetIntNumber(), fRMaxField->GetIntNumber());
|
||||
fBuilder.SetSlowCoincidenceWindow(fSlowWindowField->GetNumber());
|
||||
fBuilder.SetBufferSize(fBufferSizeField->GetNumber());
|
||||
|
@ -200,27 +227,32 @@ bool EVBMainFrame::SetParameters() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void EVBMainFrame::DisplayWorkdir(const char* dir) {
|
||||
void EVBMainFrame::DisplayWorkdir(const char* dir)
|
||||
{
|
||||
fWorkField->SetText(dir);
|
||||
fBuilder.SetWorkDirectory(dir);
|
||||
}
|
||||
|
||||
void EVBMainFrame::DisplaySMap(const char* file) {
|
||||
void EVBMainFrame::DisplaySMap(const char* file)
|
||||
{
|
||||
fSMapField->SetText(file);
|
||||
fBuilder.SetBoardShiftFile(file);
|
||||
}
|
||||
|
||||
void EVBMainFrame::DisplayScaler(const char* file) {
|
||||
void EVBMainFrame::DisplayScaler(const char* file)
|
||||
{
|
||||
fScalerField->SetText(file);
|
||||
fBuilder.SetScalerFile(file);
|
||||
}
|
||||
|
||||
void EVBMainFrame::SaveConfig(const char* file) {
|
||||
void EVBMainFrame::SaveConfig(const char* file)
|
||||
{
|
||||
std::string filename = file;
|
||||
fBuilder.WriteConfigFile(filename);
|
||||
}
|
||||
|
||||
void EVBMainFrame::LoadConfig(const char* file) {
|
||||
void EVBMainFrame::LoadConfig(const char* file)
|
||||
{
|
||||
std::string filename = file;
|
||||
fBuilder.ReadConfigFile(filename);
|
||||
|
||||
|
@ -236,24 +268,26 @@ void EVBMainFrame::LoadConfig(const char* file) {
|
|||
|
||||
}
|
||||
|
||||
void EVBMainFrame::UpdateWorkdir() {
|
||||
void EVBMainFrame::UpdateWorkdir()
|
||||
{
|
||||
const char* dir = fWorkField->GetText();
|
||||
fBuilder.SetWorkDirectory(dir);
|
||||
}
|
||||
|
||||
void EVBMainFrame::UpdateSMap() {
|
||||
void EVBMainFrame::UpdateSMap()
|
||||
{
|
||||
const char* file = fSMapField->GetText();
|
||||
fBuilder.SetBoardShiftFile(file);
|
||||
}
|
||||
|
||||
void EVBMainFrame::UpdateScaler() {
|
||||
void EVBMainFrame::UpdateScaler()
|
||||
{
|
||||
const char* file = fScalerField->GetText();
|
||||
fBuilder.SetScalerFile(file);
|
||||
}
|
||||
|
||||
void EVBMainFrame::RunMerge(const char* file, const char* dir) {}
|
||||
|
||||
void EVBMainFrame::DisableAllInput() {
|
||||
void EVBMainFrame::DisableAllInput()
|
||||
{
|
||||
fRunButton->SetState(kButtonDisabled);
|
||||
fOpenWorkButton->SetState(kButtonDisabled);
|
||||
fOpenSMapButton->SetState(kButtonDisabled);
|
||||
|
@ -272,7 +306,8 @@ void EVBMainFrame::DisableAllInput() {
|
|||
fSlowWindowField->SetState(false);
|
||||
}
|
||||
|
||||
void EVBMainFrame::EnableAllInput() {
|
||||
void EVBMainFrame::EnableAllInput()
|
||||
{
|
||||
fRunButton->SetState(kButtonUp);
|
||||
fOpenWorkButton->SetState(kButtonUp);
|
||||
fOpenSMapButton->SetState(kButtonUp);
|
||||
|
@ -289,5 +324,12 @@ void EVBMainFrame::EnableAllInput() {
|
|||
fRMinField->SetState(true);
|
||||
|
||||
fSlowWindowField->SetState(true);
|
||||
|
||||
}
|
||||
|
||||
void EVBMainFrame::SetProgressBarPosition(uint64_t val, uint64_t total)
|
||||
{
|
||||
fProgressBar->SetMin(0);
|
||||
fProgressBar->SetMax(total);
|
||||
fProgressBar->SetPosition(val);
|
||||
gSystem->ProcessEvents();
|
||||
}
|
|
@ -10,12 +10,14 @@
|
|||
#include <TGMenu.h>
|
||||
#include <TGTextViewStream.h>
|
||||
#include <TGProgressBar.h>
|
||||
#include <TGFileDialog.h>
|
||||
#include <TTimer.h>
|
||||
#include <TGComboBox.h>
|
||||
#include "GWMEventBuilder.h"
|
||||
#include "../evb/EVBApp.h"
|
||||
|
||||
|
||||
class EVBMainFrame : public TGMainFrame {
|
||||
class EVBMainFrame : public TGMainFrame
|
||||
{
|
||||
public:
|
||||
EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h);
|
||||
virtual ~EVBMainFrame();
|
||||
|
@ -38,6 +40,7 @@ public:
|
|||
void RunMerge(const char* dir, const char* file);
|
||||
void DisableAllInput();
|
||||
void EnableAllInput();
|
||||
void SetProgressBarPosition(uint64_t val, uint64_t total);
|
||||
|
||||
|
||||
enum WidgetId {
|
||||
|
@ -70,7 +73,9 @@ private:
|
|||
|
||||
TGPopupMenu *fFileMenu;
|
||||
|
||||
GWMEventBuilder fBuilder;
|
||||
TGFileInfo *fInfo;
|
||||
|
||||
EventBuilder::EVBApp fBuilder;
|
||||
|
||||
int counter;
|
||||
UInt_t MAIN_W, MAIN_H;
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
*/
|
||||
|
||||
#include "EventBuilder.h"
|
||||
#include "FileViewFrame.h"
|
||||
#include <TGTextBuffer.h>
|
||||
#include <TGLabel.h>
|
||||
|
@ -30,7 +29,7 @@ FileViewFrame::FileViewFrame(const TGWindow* p, const TGFrame* main, UInt_t w, U
|
|||
|
||||
/*Layout orgainization hints*/
|
||||
TGLayoutHints *fhints = new TGLayoutHints(kLHintsCenterX|kLHintsCenterY,5,5,5,5);
|
||||
TGLayoutHints *thints = new TGLayoutHints(kLHintsExpandX|kLHintsCenterY,5,5,5,5);
|
||||
TGLayoutHints *thints = new TGLayoutHints(kLHintsExpandX|kLHintsBottom,5,5,5,5);
|
||||
TGLayoutHints *fchints = new TGLayoutHints(kLHintsExpandX|kLHintsExpandY,5,5,5,5);
|
||||
TGLayoutHints *lhints = new TGLayoutHints(kLHintsLeft|kLHintsTop,5,5,5,5);
|
||||
TGLayoutHints *fbhints = new TGLayoutHints(kLHintsCenterX|kLHintsBottom,5,5,5,5);
|
40
src/main.cpp
40
src/main.cpp
|
@ -1,11 +1,14 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "GWMEventBuilder.h"
|
||||
#include "EVBApp.h"
|
||||
#include "Stopwatch.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if(argc != 3) {
|
||||
std::cerr<<"Incorrect number of command line arguments!"<<std::endl;
|
||||
std::cerr<<"Need to specify type of operation (buildSlow, buildFast, etc.) and input file."<<std::endl;
|
||||
|
||||
EventBuilder::Logger::Init();
|
||||
if(argc != 3)
|
||||
{
|
||||
EVB_ERROR("Incorrect number of command line arguments!");
|
||||
EVB_ERROR("Need to specify type of operation (buildSlow, buildFast, etc.) and input file.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -19,27 +22,32 @@ int main(int argc, char** argv) {
|
|||
merge (combine root files)
|
||||
*/
|
||||
|
||||
GWMEventBuilder theBuilder;
|
||||
if(!theBuilder.ReadConfigFile(filename)) {
|
||||
EventBuilder::EVBApp theBuilder;
|
||||
if(!theBuilder.ReadConfigFile(filename))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
Stopwatch timer;
|
||||
EventBuilder::Stopwatch timer;
|
||||
timer.Start();
|
||||
if(operation == "convert") {
|
||||
theBuilder.SetAnalysisType(GWMEventBuilder::CONVERT);
|
||||
if(operation == "convert")
|
||||
{
|
||||
theBuilder.Convert2RawRoot();
|
||||
} else if(operation == "merge") {
|
||||
theBuilder.SetAnalysisType(GWMEventBuilder::MERGE);
|
||||
}
|
||||
else if(operation == "merge")
|
||||
{
|
||||
theBuilder.MergeROOTFiles();
|
||||
} else if (operation == "convertSlow"){
|
||||
theBuilder.SetAnalysisType(GWMEventBuilder::CONVERT_S);
|
||||
}
|
||||
else if (operation == "convertSlow")
|
||||
{
|
||||
theBuilder.Convert2SortedRoot();
|
||||
} else {
|
||||
std::cerr<<"Unidentified type of operation! Check your first argument."<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
EVB_ERROR("Unidentified type of operation! Check your first argument.");
|
||||
return 1;
|
||||
}
|
||||
timer.Stop();
|
||||
std::cout<<"Elapsed time (ms): "<<timer.GetElapsedMilliseconds()<<std::endl;
|
||||
EVB_INFO("Elapsed time (ms): {0}", timer.GetElapsedMilliseconds());
|
||||
|
||||
return 0;
|
||||
}
|
1
vendor/spdlog
vendored
Submodule
1
vendor/spdlog
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 173d06578f4cfecc94de1746b101240c93f8b45b
|
Loading…
Reference in New Issue
Block a user