diff --git a/.gitignore b/.gitignore index 699d1e2..09f7d8d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,14 @@ ###directories to ignore### -./rootfiles/ -./pics/ -./images/ -./hotfixes/ +pics/ +images/ +build/ +objs/ ###file types to ignore### *.swp *.o +*.a +*.so *.cxx *.root *.bin @@ -15,6 +17,8 @@ *.png *.sublime-project *.sublime-workspace +*.make +Makefile event_log.txt .DS_Store diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..18a8e2a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vendor/spdlog"] + path = vendor/spdlog + url = https://github.com/gabime/spdlog.git diff --git a/README.md b/README.md index 47d1c4c..c3d2f05 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,25 @@ # SPS-SABRE Data Analysis Package -Version 3 +Version 4 This is a software package designed to help experimenters analyze data from SPS-SABRE at FSU. It can convert CoMPASS data to ROOT, sort the data in time, build events, perform preliminary analysis and provide basic plots. Programs are built using make, and a make file is included. Simply using the command make will build all programs. WHEN TESTING, RUN WITH WIDE WINDOWS -## 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. +## Installation +To install the event builder, the Premake build system is used. To install Premake, simply go to the [Premake](https://premake.github.io/) site and Download the right prebuilt binary for your system (there's no need to try and build from source). Place the binary in a location on your path so that you can call it on the commandline by simply typing `premake5`. + +To clone the repository use `git clone --recursive https://github.com/sesps/SPS_SABRE_EventBuilder.git`. If you're using the devel branch be sure to specify this with the `--branch` flag. The recursive flag is important; this tells github to pull all submodules associated with the repository. + +Once the repository is cloned, go into the event builder directory and locate the file `premake5.lua`. This is the file which contains the build rules for this project. You will need to specify the location of your `ROOT` install so that we can properly find headers and libraries using the parameters ROOTIncludeDir and ROOTLibDir (lines 8 and 9 of premake5.lua). On unix style systems these paths can be found easily using the `root-config` tool. Simply run `root-config --cflags` and copy the path after the `-I` to ROOTIncludeDir and run `root-config --glibs` and copy the path after the `-L` to ROOTLibDir. Once the `ROOT` paths are set, run the command `premake5 gmake2` on Linux or Mac for a Makefile style build, or `premake5 Xcode4` to build an XCode project on Mac. Then the program can be built using the standard methods of the chosen build type (i.e. `make` or XCode Build). + +The binaries are installed to the `bin` directory of the event builder, and should be run from the event builder directory (i.e. `./bin/EventBuilderGui`). + +In general, one should only build for Release (this is the default), for maximum optimization. However, it can be useful to run in Debug (in make do `make config=debug`) when testing new features. + +Note: On Mac, if you have XCode installed, it is best to build through XCode. Results when linking can be unreliable otherwise. + +## EventBuilder vs. EventBuilderGui +There are two programs provided. They are `EventBuilderGui` and `EventBuilder`. The first is a full GUI version of the event builder. The GUI supports all conversion methods and the plotting tool. ### 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. @@ -79,9 +92,4 @@ Currently the pipeline supports declaring individual digitizer channels as scale ## 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`. +Only compatible with MacOSX and Linux \ No newline at end of file diff --git a/etc/CutList_Feb2021_10B3hea.txt b/etc/CutList_Feb2021_10B3hea.txt index d476893..abf8217 100644 --- a/etc/CutList_Feb2021_10B3hea.txt +++ b/etc/CutList_Feb2021_10B3hea.txt @@ -1,3 +1,3 @@ Name File VarX VarY -edeAlphas /data1/gwm17/10B3He/Feb2021/cuts/alphaCut_03012021.root scintLeft cathode -x1x2 /data1/gwm17/10B3He/Feb2021/cuts/xxCut_03012021.root x1 x2 \ No newline at end of file +edeAlphas /media/gordon/GordonData/gwm17/9BFeb2021/cuts/alphaCut_03012021.root scintLeft cathode +x1x2 /media/gordon/GordonData/gwm17/9BFeb2021/cuts/xxCut_03012021.root x1 x2 \ No newline at end of file diff --git a/etc/ScalerFile_Feb2021_SABRE.txt b/etc/ScalerFile_Feb2021_SABRE.txt index 88c1a8f..a2f4e92 100644 --- a/etc/ScalerFile_Feb2021_SABRE.txt +++ b/etc/ScalerFile_Feb2021_SABRE.txt @@ -1,4 +1,4 @@ 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) CH0@V1730_89_Data t1 - +CH5@V1730_89_Data t2 \ No newline at end of file diff --git a/include/ChannelMap.h b/include/ChannelMap.h deleted file mode 100644 index ca8be59..0000000 --- a/include/ChannelMap.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - ChannelMap.h - Class which acts as the go between for global compass channels (board#*16 + channel) and - physical detector information. Used in the event builder to assign compass data to real values - in a simple way. Takes in a definition file and parses it into an unordered_map container. - - Written by G.W. McCann Oct. 2020 -*/ -#ifndef CHANNELMAP_H -#define CHANNELMAP_H - -struct Channel { - int detectorType; //What kind of detector we're looking at - int detectorID; //Which specific detector we're looking at - int detectorPart; //Which specific part we're looking at -}; - -//Detector part/type identifiers for use in the code -enum DetAttribute { - FOCALPLANE, - SCINTLEFT, - SCINTRIGHT, - ANODEFRONT, - ANODEBACK, - DELAYFR, - DELAYFL, - DELAYBR, - DELAYBL, - CATHODE, - MONITOR, - SABRERING = 88, //These are offset to avoid interference at the variable mapping phase - SABREWEDGE = 99 //Just don't add any new attributes with values greater than 88 -}; - - -class ChannelMap { - -public: - typedef std::unordered_map Containter; - typedef std::unordered_map::iterator Iterator; - - ChannelMap(); - ChannelMap(const std::string& filename); - ~ChannelMap(); - bool FillMap(const std::string& filename); - inline const Containter* GetCMap() { return &cmap; }; - inline Iterator FindChannel(int key) { return cmap.find(key); }; - inline Iterator End() { return cmap.end(); }; - inline bool IsValid() { return is_valid; }; - -private: - Containter cmap; - bool is_valid; -}; - - -#endif diff --git a/include/CompassFile.h b/include/CompassFile.h deleted file mode 100644 index 5b00007..0000000 --- a/include/CompassFile.h +++ /dev/null @@ -1,66 +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 - -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(); - 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: - int GetHitSize(); - void ParseNextHit(); - void GetNextBuffer(); - - using Buffer = std::vector; - - using FilePointer = std::shared_ptr; //to make this class copy/movable - - std::string m_filename; - Buffer hitBuffer; - char* bufferIter; - char* bufferEnd; - ShiftMap* m_smap; //NOT owned by CompassFile. DO NOT delete - bool hitUsedFlag; - int bufsize = 200000; //size of the buffer in hits - int hitsize = 24; //size of a CompassHit in bytes (without alignment padding) - int m_buffersize; - CompassHit m_currentHit; - FilePointer m_file; - bool eofFlag; - unsigned int m_size; //size of the file in bytes - unsigned int m_nHits; //number of hits in the file (m_size/24) - -}; - - -#endif diff --git a/include/CompassHit.h b/include/CompassHit.h deleted file mode 100644 index 45eda7f..0000000 --- a/include/CompassHit.h +++ /dev/null @@ -1,14 +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; -}; - -#endif diff --git a/include/CompassRun.h b/include/CompassRun.h deleted file mode 100644 index 7684972..0000000 --- a/include/CompassRun.h +++ /dev/null @@ -1,69 +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 -#include -#include - -class CompassRun { -public: - CompassRun(); - CompassRun(const std::string& dir); - ~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, const std::string& mapfile, double window); - void Convert2FastSortedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window); - void Convert2SlowAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, - int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta); - void Convert2FastAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window, - int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta); - - inline void 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 m_datafiles; - unsigned int startIndex; //this is the file we start looking at; increases as we finish files. - ShiftMap m_smap; - std::unordered_map> m_scaler_map; //maps scaler files to the TParameter to be saved - - //Potential branch variables - CompassHit hit; - CoincEvent event; - ProcessedEvent pevent; - - //what run is this - int runNum; - unsigned int m_totalHits; - - //Scaler switch - bool m_scaler_flag; - - //GUI progress bar, if attached - TGProgressBar* m_pb; -}; - -#endif diff --git a/include/CutHandler.h b/include/CutHandler.h deleted file mode 100644 index 430b783..0000000 --- a/include/CutHandler.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef CUTHANDLER_H -#define CUTHANDLER_H - -#include "DataStructs.h" - -class CutHandler { -public: - CutHandler(); - CutHandler(const std::string& filename); - ~CutHandler(); - void SetCuts(const std::string& filename); - bool IsValid() { return validFlag; }; - bool IsInside(ProcessedEvent* eaddress); - std::vector GetCuts() { return cut_array; }; - -private: - void InitVariableMap(); - - std::vector cut_array; - std::vector file_array; - std::unordered_map varmap; - bool validFlag; - ProcessedEvent m_event; - -}; - -#endif \ No newline at end of file diff --git a/include/DataStructs.h b/include/DataStructs.h index de97aef..d57fb39 100644 --- a/include/DataStructs.h +++ b/include/DataStructs.h @@ -6,64 +6,77 @@ #ifndef DATA_STRUCTS_H #define DATA_STRUCTS_H -using namespace std; +#include -struct DPPChannel { - Double_t Timestamp; - Int_t Channel, Board, Energy, EnergyShort; - Int_t Flags; +struct DPPChannel +{ + double Timestamp; + int Channel, Board, Energy, EnergyShort; + int Flags; }; -struct DetectorHit { - Double_t Long=-1, Short=-1, Time=-1; - Int_t Ch=-1; +struct DetectorHit +{ + double Long=-1, Short=-1, Time=-1; + int Ch=-1; }; -struct SabreDetector { - vector rings; - vector wedges; +struct SabreDetector +{ + std::vector rings; + std::vector wedges; }; -struct FPDetector { - vector delayFL, delayFR, delayBL, delayBR; - vector anodeF, anodeB, scintL, scintR, cathode; - vector monitor; +struct FPDetector +{ + std::vector delayFL, delayFR, delayBL, delayBR; + std::vector anodeF, anodeB, scintL, scintR, cathode; + std::vector monitor; }; -struct CoincEvent { +struct CoincEvent +{ FPDetector focalPlane; SabreDetector sabreArray[5]; //index = ChannelMap Id# -1 }; -struct ProcessedEvent { - Double_t fp1_tdiff = -1e6, fp2_tdiff = -1e6, fp1_tsum = -1, fp2_tsum = -1, +struct ProcessedEvent +{ + double fp1_tdiff = -1e6, fp2_tdiff = -1e6, fp1_tsum = -1, fp2_tsum = -1, fp1_tcheck = -1, fp2_tcheck = -1; - Double_t fp1_y=-1, fp2_y=-1; - Double_t anodeFront = -1, anodeBack = -1, scintRight = -1, scintLeft = -1; - Double_t scintRightShort = -1, scintLeftShort = -1; - Double_t cathode = -1; - Double_t xavg = -1e6, x1 = -1e6, x2 = -1e6; - Double_t theta = -1e6; - Double_t sabreRingE[5] = {-1,-1,-1,-1,-1}, sabreWedgeE[5] = {-1,-1,-1,-1,-1}; - Double_t sabreRingChannel[5] = {-1,-1,-1,-1,-1}, sabreWedgeChannel[5] = {-1,-1,-1,-1,-1}; - Double_t sabreRingTime[5] = {-1,-1,-1,-1,-1}, sabreWedgeTime[5] = {-1,-1,-1,-1,-1}; + double fp1_y=-1, fp2_y=-1; + double anodeFront = -1, anodeBack = -1, scintRight = -1, scintLeft = -1; + double scintRightShort = -1, scintLeftShort = -1; + double cathode = -1; + double xavg = -1e6, x1 = -1e6, x2 = -1e6; + double theta = -1e6; + double sabreRingE[5] = {-1,-1,-1,-1,-1}, sabreWedgeE[5] = {-1,-1,-1,-1,-1}; + double sabreRingChannel[5] = {-1,-1,-1,-1,-1}, sabreWedgeChannel[5] = {-1,-1,-1,-1,-1}; + double sabreRingTime[5] = {-1,-1,-1,-1,-1}, sabreWedgeTime[5] = {-1,-1,-1,-1,-1}; - Double_t delayFrontRightE = -1, delayFrontLeftE = -1; - Double_t delayBackRightE = -1, delayBackLeftE = -1; - Double_t delayFrontRightShort = -1, delayFrontLeftShort = -1; - Double_t delayBackRightShort = -1, delayBackLeftShort = -1; - Double_t anodeFrontTime = -1, anodeBackTime = -1; - Double_t scintRightTime = -1, scintLeftTime = -1; - Double_t delayFrontMaxTime = -1, delayBackMaxTime = -1; - Double_t delayFrontLeftTime = -1, delayFrontRightTime = -1; - Double_t delayBackLeftTime = -1, delayBackRightTime = -1; - Double_t cathodeTime = -1; + double delayFrontRightE = -1, delayFrontLeftE = -1; + double delayBackRightE = -1, delayBackLeftE = -1; + double delayFrontRightShort = -1, delayFrontLeftShort = -1; + double delayBackRightShort = -1, delayBackLeftShort = -1; + double anodeFrontTime = -1, anodeBackTime = -1; + double scintRightTime = -1, scintLeftTime = -1; + double delayFrontMaxTime = -1, delayBackMaxTime = -1; + double delayFrontLeftTime = -1, delayFrontRightTime = -1; + double delayBackLeftTime = -1, delayBackRightTime = -1; + double cathodeTime = -1; - Double_t monitorE = -1, monitorShort = -1; - Double_t monitorTime = -1; + double monitorE = -1, monitorShort = -1; + double monitorTime = -1; SabreDetector sabreArray[5]; //index = ChannelMap Id# -1 }; +/* + ROOT does a bad job of ensuring that header-only type dictionaries (the only type they explicity accept) + are linked when compiled as shared libraries (the recommended method). As a work around, as a dummy function that + ensures the library is linked (better than no-as-needed which I dont think is in general supported across platforms) +*/ +bool EnforceDictionaryLinked(); + #endif diff --git a/include/FastSort.h b/include/FastSort.h deleted file mode 100644 index 6c44be8..0000000 --- a/include/FastSort.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - *Goal is to provide a fast coinc window for rejecting si. - *And a way to orgainize focal plane data within slow cw. - * - */ -#ifndef FASTSORT_H -#define FASTSORT_H - -#include "DataStructs.h" -#include - -class FastSort { - - public: - FastSort(float si_windowSize, float ion_windowSize); - ~FastSort(); - std::vector GetFastEvents(CoincEvent& event); - - private: - void ResetSABRE(); - void ResetFocalPlane(); - void ProcessSABRE(unsigned int scint_index); - void ProcessFocalPlane(unsigned int scint_index, unsigned int ionch_index); - - float si_coincWindow, ion_coincWindow; - CoincEvent *event_address, slowEvent; - CoincEvent fastEvent, blank; - SabreDetector sblank; - FPDetector fpblank; - -}; - -#endif diff --git a/include/FlagHandler.h b/include/FlagHandler.h deleted file mode 100644 index bbce132..0000000 --- a/include/FlagHandler.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef FLAGHANDLER_H -#define FLAGHANDLER_H - -#include - -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 event_count_map; - - void WriteLog(); -}; - -#endif diff --git a/include/GWMEventBuilder.h b/include/GWMEventBuilder.h deleted file mode 100644 index f4f5b8c..0000000 --- a/include/GWMEventBuilder.h +++ /dev/null @@ -1,102 +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 - -class GWMEventBuilder { -public: - GWMEventBuilder(); - ~GWMEventBuilder(); - - bool ReadConfigFile(const std::string& filename); - void WriteConfigFile(const std::string& filename); - - void PlotHistograms(); - void MergeROOTFiles(); - void Convert2SortedRoot(); - void Convert2FastSortedRoot(); - void Convert2RawRoot(); - void Convert2SlowAnalyzedRoot(); - void Convert2FastAnalyzedRoot(); - - 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 SetChannelMap(const std::string& name) { m_mapfile = name; }; - inline void SetBoardShiftFile(const std::string& name) { m_shiftfile = name; }; - inline void SetSlowCoincidenceWindow(double window) { m_SlowWindow = window; }; - inline void SetFastWindowIonChamber(double window) { m_FastWindowIonCh = window; }; - inline void SetFastWindowSABRE(double window) { m_FastWindowSABRE = window; }; - inline void SetCutList(const std::string& name) { m_cutList = name; }; - inline void SetScalerFile(const std::string& fullpath) { m_scalerfile = fullpath; }; - bool SetKinematicParameters(int zt, int at, int zp, int ap, int ze, int ae, double b, double theta, double bke); - - inline int GetRunMin() {return m_rmin;}; - inline int GetRunMax() {return m_rmax;}; - inline std::string GetWorkDirectory() {return m_workspace;}; - inline int GetTargetZ() {return m_ZT;}; - inline int GetTargetA() {return m_AT;}; - inline int GetProjectileZ() {return m_ZP;}; - inline int GetProjectileA() {return m_AP;}; - inline int GetEjectileZ() {return m_ZE;}; - inline int GetEjectileA() {return m_AE;}; - inline int GetResidualZ() {return m_ZR;}; - inline int GetResidualA() {return m_AR;}; - inline double GetBField() {return m_B;}; - inline double GetBeamKE() {return m_BKE;}; - inline double GetTheta() {return m_Theta;}; - inline double GetSlowCoincidenceWindow() { return m_SlowWindow; }; - inline double GetFastWindowIonChamber() { return m_FastWindowIonCh; }; - inline double GetFastWindowSABRE() { return m_FastWindowSABRE; }; - inline std::string GetChannelMap() { return m_mapfile; }; - inline std::string GetBoardShiftFile() { return m_shiftfile; }; - inline std::string GetCutList() { return m_cutList; }; - inline std::string GetScalerFile() { return m_scalerfile; }; - - inline void AttachProgressBar(TGProgressBar* pb) { m_pb = pb; }; - - enum BuildType { - CONVERT, - CONVERT_S, - CONVERT_SA, - CONVERT_F, - CONVERT_FA, - MERGE, - PLOT - }; - -private: - - int m_rmin, m_rmax; - int m_ZT, m_AT, m_ZP, m_AP, m_ZE, m_AE, m_ZR, m_AR; - double m_B, m_Theta, m_BKE; - - std::string m_workspace; - std::string m_mapfile, m_shiftfile; - std::string m_cutList; - std::string m_scalerfile; - - double m_SlowWindow; - double m_FastWindowIonCh; - double m_FastWindowSABRE; - - int m_analysisType; - - RunCollector grabber; - - TGProgressBar* m_pb; - -}; - -#endif diff --git a/include/MassLookup.h b/include/MassLookup.h deleted file mode 100644 index 1e431ea..0000000 --- a/include/MassLookup.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - -MassLookup.h -Generates a map for isotopic masses using AMDC data; subtracts away -electron mass from the atomic mass by default. Creates a static global instance -of this map (MASS) for use throughout code it is included into. - -Written by G.W. McCann Aug. 2020 - -*/ -#ifndef MASS_LOOKUP_H -#define MASS_LOOKUP_H - -class MassLookup { - - public: - MassLookup(); - ~MassLookup(); - double FindMass(int Z, int A); - std::string FindSymbol(int Z, int A); - - private: - std::unordered_map massTable; - std::unordered_map elementTable; - - //constants - static constexpr double u_to_mev = 931.4940954; - static constexpr double electron_mass = 0.000548579909; - -}; - -//static instance for use throught program -static MassLookup MASS; -#endif diff --git a/include/RunCollector.h b/include/RunCollector.h deleted file mode 100644 index fa9a63c..0000000 --- a/include/RunCollector.h +++ /dev/null @@ -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 -#include -#include -#include -#include -#include - -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 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 diff --git a/include/SFPAnalyzer.h b/include/SFPAnalyzer.h deleted file mode 100644 index fee950f..0000000 --- a/include/SFPAnalyzer.h +++ /dev/null @@ -1,46 +0,0 @@ -/*SFPAnalyzer.h - *Class designed to analyze coincidence events. Currently only implemented for focal plane - *data. Additional changes for SABRE would include this file and the sructure ProcessedEvent - *in DataStructs.h. Based on code written by S. Balak, K. Macon, and E. Good. - * - *Gordon M. Oct. 2019 - * - *Refurbished and updated Jan 2020 by GWM. Now uses both focal plane and SABRE data - */ -#ifndef SFPANALYZER_H -#define SFPANALYZER_H - -#include "DataStructs.h" -#include "FP_kinematics.h" - -using namespace std; - -class SFPAnalyzer { - - public: - SFPAnalyzer(int zt, int at, int zp, int ap, int ze, int ae, double ep, double angle, - double b); - ~SFPAnalyzer(); - ProcessedEvent GetProcessedEvent(CoincEvent& event); - inline void ClearHashTable() { rootObj->Clear(); }; - inline THashTable* GetHashTable() { return rootObj; }; - - private: - void Reset(); //Sets ouput structure back to "zero" - void GetWeights(); //weights for xavg - void AnalyzeEvent(CoincEvent& event); - - /*Fill wrappers for use with THashTable*/ - void MyFill(const string& name, int binsx, double minx, double maxx, double valuex, - int binsy, double miny, double maxy, double valuey); - void MyFill(const string& name, int binsx, double minx, double maxx, double valuex); - - CoincEvent *event_address; //Input branch address - ProcessedEvent pevent, blank; //output branch and reset - - Double_t w1, w2, zfp; - - THashTable *rootObj; //root storage -}; - -#endif diff --git a/include/SFPPlotter.h b/include/SFPPlotter.h deleted file mode 100644 index a1d2860..0000000 --- a/include/SFPPlotter.h +++ /dev/null @@ -1,52 +0,0 @@ -/*SFPPlotter.h - *Class for generating histogram files for SPS-SABRE data - *Intended use case is generating a TChain of multiple analyzed files and making - *histograms of the larger data set. - * - *Created Jan 2020 by GWM - */ - -#ifndef SFPCLEANER_H -#define SFPCLEANER_H - -#include "DataStructs.h" -#include "CutHandler.h" -#include - -using namespace std; - -class SFPPlotter { - public: - SFPPlotter(); - SFPPlotter(bool tf); - ~SFPPlotter(); - inline void AttachProgressBar(TGProgressBar* pb) { m_pb = pb; }; - void ApplyCutlist(const string& listname); - void Run(vector files, const string& output); - - private: - void SetProgressBar(long total); - void Chain(vector files); //Form TChain - void MakeUncutHistograms(ProcessedEvent ev); - void MakeCutHistograms(ProcessedEvent ev); - - /*Histogram fill wrapper functions*/ - void MyFill(const string& name, int binsx, double minx, double maxx, double valuex, - int binsy, double miny, double maxy, double valuey); - void MyFill(const string& name, int binsx, double minx, double maxx, double valuex); - - ProcessedEvent *event_address; - - /*ROOT Storage*/ - THashTable *rootObj; - - /*Cuts*/ - CutHandler cutter; - - TChain *chain; - - TGProgressBar* m_pb; //GUI progress - -}; - -#endif diff --git a/include/SlowSort.h b/include/SlowSort.h deleted file mode 100644 index 7655b61..0000000 --- a/include/SlowSort.h +++ /dev/null @@ -1,57 +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 "ChannelMap.h" -#include - -using namespace std; - -class SlowSort { - - public: - SlowSort(); - SlowSort(double windowSize, const string& mapfile); - ~SlowSort(); - inline void SetWindowSize(double window) { coincWindow = window; }; - inline bool SetMapFile(const std::string& mapfile) { return cmap.FillMap(mapfile); }; - bool AddHitToEvent(CompassHit& mhit); - CoincEvent 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 hitList; - bool eventFlag; - DPPChannel hit; - CoincEvent event; - CoincEvent blank; - - double startTime, previousHitTime; - unordered_map*> fpVMap; - unordered_map*> sabreVMap; - - TH2F* event_stats; - - ChannelMap cmap; - -}; - -#endif diff --git a/include/Stopwatch.h b/include/Stopwatch.h deleted file mode 100644 index af217c1..0000000 --- a/include/Stopwatch.h +++ /dev/null @@ -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 - -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 \ No newline at end of file diff --git a/input.txt b/input.txt index b5f7a71..d73fd22 100644 --- a/input.txt +++ b/input.txt @@ -1,10 +1,10 @@ -------Data Location---------- -WorkspaceDirectory: /data1/gwm17/10B3He/Feb2021/ +WorkspaceDirectory: /media/gordon/GordonData/gwm17/9BFeb2021 ------------------------------- ------Experimental Inputs------ -ChannelMapFile: /home/gwm17/GWM_EventBuilder/etc/orig_ChannelMap_Feb2021_SABRE.txt -ScalerFile: /home/gwm17/GWM_EventBuilder/etc/orig_ScalerFile_Feb2021_SABRE.txt -CutListFile: /home/gwm17/GWM_EventBuilder/etc/new_CutList_Feb202110B3hea.txt +ChannelMapFile: /home/gordon/SPS_SABRE_EventBuilder/etc/ChannelMap_Feb2021_SABRE.txt +ScalerFile: /home/gordon/SPS_SABRE_EventBuilder/etc/ScalerFile_Feb2021_SABRE.txt +CutListFile: /home/gordon/SPS_SABRE_EventBuilder/etc/CutList_Feb2021_10B3hea.txt ZT: 5 AT: 10 ZP: 2 @@ -16,7 +16,7 @@ BeamKE(MeV): 24 Theta(deg): 15 ------------------------------- -------Timing Information------ -BoardOffsetFile: /home/gwm17/GWM_EventBuilder/etc/orig_ShiftMap_Feb2021_SABRE.txt +BoardOffsetFile: /home/gordon/SPS_SABRE_EventBuilder/etc/ShiftMap_Feb2021_SABRE.txt SlowCoincidenceWindow(ps): 1.5e+06 FastCoincidenceWindow_IonCh(ps): 250000 FastCoincidenceWindow_SABRE(ps): 150000 diff --git a/makefile b/makefile deleted file mode 100644 index a40e267..0000000 --- a/makefile +++ /dev/null @@ -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_sps.h -DICT=$(SRCDIR)/sps_dict.cxx -DICTOBJ=$(OBJDIR)/sps_dict.o -DICTLIB=$(LIBDIR)/libSPSDict - -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 $^ diff --git a/objs/.gitignore b/objs/.gitignore deleted file mode 100644 index 1ce6034..0000000 --- a/objs/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -### dont include any files, but include this dir ### -* -!.gitignore diff --git a/premake5.lua b/premake5.lua new file mode 100644 index 0000000..0481183 --- /dev/null +++ b/premake5.lua @@ -0,0 +1,217 @@ +workspace "EVB" + architecture "x64" + configurations { + "Release", + "Debug" + } + +ROOTIncludeDir = "/home/gordon/cern/root-6.22.02/root-install/include" +ROOTLibDir = "/home/gordon/cern/root-6.22.02/root-install/lib" + +project "SPSDict" + kind "SharedLib" + language "C++" + cppdialect "c++11" + targetdir "./lib/" + objdir "./objs/" + + prebuildcommands { + "rootcint -f src/spsdict/sps_dict.cxx src/spsdict/DataStructs.h src/spsdict/LinkDef_sps.h", + "{COPY} src/spsdict/*.pcm ./lib/" + } + + postbuildcommands { + "{COPY} src/spsdict/DataStructs.h ./include/" + } + + files { + "src/spsdict/DataStructs.h", + "src/spsdict/*.cpp", + "src/spsdict/*.cxx" + } + + includedirs { + "./", + "src/spsdict", + } + + sysincludedirs { + ROOTIncludeDir + } + + libdirs { + ROOTLibDir + } + + links { + "Gui", "Core", "Imt", "RIO", "Net", "Hist", + "Graf", "Graf3d", "Gpad", "ROOTDataFrame", "ROOTVecOps", + "Tree", "TreePlayer", "Rint", "Postscript", "Matrix", + "Physics", "MathCore", "Thread", "MultiProc", "m", "dl" + } + + filter "system:macosx or linux" + linkoptions { + "-pthread", + "-rdynamic" + } + + filter "configurations:Debug" + symbols "On" + + filter "configurations:Release" + optimize "On" + +project "EventBuilderCore" + kind "StaticLib" + language "C++" + cppdialect "c++11" + targetdir "./lib/" + objdir "./objs/" + pchheader "EventBuilder.h" + pchsource "./src/EventBuilder.cpp" + + files { + "src/spsdict/DataStructs.h", + "src/evb/*.cpp", + "src/evb/*.h" + } + + defines "ETC_DIR_PATH=\"./etc/\"" + + includedirs { + "./", + "src/", + "vendor/spdlog/include", + "src/evb", + "src/spsdict", + "src/guidict" + } + + sysincludedirs { + ROOTIncludeDir + } + + libdirs { + ROOTLibDir, + } + + links { + "SPSDict", "Gui", "Core", "Imt", "RIO", "Net", "Hist", + "Graf", "Graf3d", "Gpad", "ROOTDataFrame", "ROOTVecOps", + "Tree", "TreePlayer", "Rint", "Postscript", "Matrix", + "Physics", "MathCore", "Thread", "MultiProc", "m", "dl" + } + + filter "system:macosx or linux" + linkoptions { + "-pthread", + "-rdynamic" + } + + filter "configurations:Debug" + symbols "On" + + filter "configurations:Release" + optimize "On" + +project "EventBuilderGui" + kind "ConsoleApp" + language "C++" + cppdialect "c++11" + targetdir "./bin/" + objdir "./objs/" + + prebuildcommands { + "rootcint -f src/guidict/gui_dict.cxx src/guidict/EVBMainFrame.h src/guidict/FileViewFrame.h src/guidict/LinkDef_Gui.h", + "{COPY} src/guidict/*.pcm ./bin/" + } + + files { + "src/guidict/FileViewFrame.h", + "src/guidict/EVBMainFrame.h", + "src/guidict/*.cpp", + "src/guidict/gui_dict.cxx", + "src/gui_main.cpp" + } + + includedirs { + "./", + "vendor/spdlog/include", + "src/evb", + "src/spsdict", + "src/guidict" + } + + sysincludedirs { + ROOTIncludeDir + } + + libdirs { + ROOTLibDir, + } + + links { + "EventBuilderCore", "SPSDict", "Gui", "Core", "Imt", "RIO", "Net", "Hist", + "Graf", "Graf3d", "Gpad", "ROOTDataFrame", "ROOTVecOps", + "Tree", "TreePlayer", "Rint", "Postscript", "Matrix", + "Physics", "MathCore", "Thread", "MultiProc", "m", "dl" + } + + filter "system:macosx or linux" + linkoptions { + "-pthread", + "-rdynamic" + } + + filter "configurations:Debug" + symbols "On" + + filter "configurations:Release" + optimize "On" + +project "EventBuilder" + kind "ConsoleApp" + language "C++" + cppdialect "c++11" + targetdir "./bin/" + objdir "./objs/" + + files { + "src/main.cpp" + } + + includedirs { + "src/", + "vendor/spdlog/include", + "src/evb", + "src/spsdict", + "src/guidict" + } + + sysincludedirs { + ROOTIncludeDir + } + + libdirs { + ROOTLibDir, + } + + links { + "EventBuilderCore", "SPSDict", "Gui", "Core", "Imt", "RIO", "Net", "Hist", + "Graf", "Graf3d", "Gpad", "ROOTDataFrame", "ROOTVecOps", + "Tree", "TreePlayer", "Rint", "Postscript", "Matrix", + "Physics", "MathCore", "Thread", "MultiProc", "m", "dl" + } + + filter "system:macosx or linux" + linkoptions { + "-pthread", + "-rdynamic" + } + + filter "configurations:Debug" + symbols "On" + + filter "configurations:Release" + optimize "On" \ No newline at end of file diff --git a/src/EventBuilder.cpp b/src/EventBuilder.cpp new file mode 100644 index 0000000..9b9e67c --- /dev/null +++ b/src/EventBuilder.cpp @@ -0,0 +1,3 @@ +//For MSVC pch + +#include "EventBuilder.h" \ No newline at end of file diff --git a/include/EventBuilder.h b/src/EventBuilder.h similarity index 90% rename from include/EventBuilder.h rename to src/EventBuilder.h index 4c41c9b..30379c7 100644 --- a/include/EventBuilder.h +++ b/src/EventBuilder.h @@ -9,6 +9,7 @@ #include #include #include +#include //ROOT @@ -24,5 +25,8 @@ #include #include +//Mine +#include "Logger.h" + #endif diff --git a/src/evb/ChannelMap.cpp b/src/evb/ChannelMap.cpp index 620edc7..fcbdc8d 100644 --- a/src/evb/ChannelMap.cpp +++ b/src/evb/ChannelMap.cpp @@ -9,64 +9,89 @@ #include "EventBuilder.h" #include "ChannelMap.h" -ChannelMap::ChannelMap() : - is_valid(false) -{ -} +namespace EventBuilder { -ChannelMap::ChannelMap(const std::string& name) : - is_valid(false) -{ - FillMap(name); -} - -ChannelMap::~ChannelMap() {} - -bool ChannelMap::FillMap(const std::string& name) { - std::ifstream input(name); - if(!input.is_open()) { - is_valid = false; - return is_valid; + ChannelMap::ChannelMap() : + m_validFlag(false) + { } - std::string junk, type, partname; - int gchan, id; - - std::getline(input, junk); - std::getline(input, junk); - Channel this_chan; - while(input>>gchan) { - //Set default values - this_chan.detectorType = -1; - this_chan.detectorID = -1; - this_chan.detectorPart = -1; - input>>id>>type>>partname; - if(type == "SABRERING") { - this_chan.detectorType = SABRERING; - this_chan.detectorID = id; - this_chan.detectorPart = std::stoi(partname); - } else if(type == "SABREWEDGE") { - this_chan.detectorType = SABREWEDGE; - this_chan.detectorID = id; - this_chan.detectorPart = std::stoi(partname); - } else if (type == "FOCALPLANE") { - this_chan.detectorType = FOCALPLANE; - this_chan.detectorID = id; - if(partname == "SCINTRIGHT") this_chan.detectorPart = SCINTRIGHT; - else if(partname == "SCINTLEFT") this_chan.detectorPart = SCINTLEFT; - else if(partname == "DELAYFR") this_chan.detectorPart = DELAYFR; - else if(partname == "DELAYFL") this_chan.detectorPart = DELAYFL; - else if(partname == "DELAYBR") this_chan.detectorPart = DELAYBR; - else if(partname == "DELAYBL") this_chan.detectorPart = DELAYBL; - else if(partname == "CATHODE") this_chan.detectorPart = CATHODE; - else if(partname == "ANODEFRONT") this_chan.detectorPart = ANODEFRONT; - else if(partname == "ANODEBACK") this_chan.detectorPart = ANODEBACK; - else if(partname == "MONITOR") this_chan.detectorPart = MONITOR; + + ChannelMap::ChannelMap(const std::string& name) : + m_validFlag(false) + { + FillMap(name); + } + + ChannelMap::~ChannelMap() {} + + bool ChannelMap::FillMap(const std::string& name) + { + std::ifstream input(name); + if(!input.is_open()) + { + m_validFlag = false; + return m_validFlag; } - - cmap[gchan] = this_chan; + std::string junk, type, partname; + int gchan, id; + + std::getline(input, junk); + std::getline(input, junk); + Channel this_chan; + while(input>>gchan) + { + //Set default values + this_chan.type = DetType::NoneType; + this_chan.local_channel = -1; + this_chan.attribute = DetAttribute::NoneAttr; + input>>id>>type>>partname; + if(type == "SABRERING") + { + this_chan.type = DetType::Sabre; + switch(id) + { + case 0: this_chan.attribute = DetAttribute::SabreRing0; break; + case 1: this_chan.attribute = DetAttribute::SabreRing1; break; + case 2: this_chan.attribute = DetAttribute::SabreRing2; break; + case 3: this_chan.attribute = DetAttribute::SabreRing3; break; + case 4: this_chan.attribute = DetAttribute::SabreRing4; break; + } + this_chan.local_channel = std::stoi(partname); + } + else if(type == "SABREWEDGE") + { + this_chan.type = DetType::Sabre; + switch(id) + { + case 0: this_chan.attribute = DetAttribute::SabreWedge0; break; + case 1: this_chan.attribute = DetAttribute::SabreWedge1; break; + case 2: this_chan.attribute = DetAttribute::SabreWedge2; break; + case 3: this_chan.attribute = DetAttribute::SabreWedge3; break; + case 4: this_chan.attribute = DetAttribute::SabreWedge4; break; + } + this_chan.local_channel = std::stoi(partname); + } + else if (type == "FOCALPLANE") + { + this_chan.type = DetType::FocalPlane; + this_chan.local_channel = id; + if(partname == "SCINTRIGHT") this_chan.attribute = DetAttribute::ScintRight; + else if(partname == "SCINTLEFT") this_chan.attribute = DetAttribute::ScintLeft; + else if(partname == "DELAYFR") this_chan.attribute = DetAttribute::DelayFR; + else if(partname == "DELAYFL") this_chan.attribute = DetAttribute::DelayFL; + else if(partname == "DELAYBR") this_chan.attribute = DetAttribute::DelayBR; + else if(partname == "DELAYBL") this_chan.attribute = DetAttribute::DelayBL; + else if(partname == "CATHODE") this_chan.attribute = DetAttribute::Cathode; + else if(partname == "ANODEFRONT") this_chan.attribute = DetAttribute::AnodeFront; + else if(partname == "ANODEBACK") this_chan.attribute = DetAttribute::AnodeBack; + else if(partname == "MONITOR") this_chan.attribute = DetAttribute::Monitor; + } + + m_cmap[gchan] = this_chan; + } + + input.close(); + m_validFlag = true; + return m_validFlag; } - - input.close(); - is_valid = true; - return is_valid; -} +} \ No newline at end of file diff --git a/src/evb/ChannelMap.h b/src/evb/ChannelMap.h new file mode 100644 index 0000000..1a19cab --- /dev/null +++ b/src/evb/ChannelMap.h @@ -0,0 +1,75 @@ +/* + ChannelMap.h + Class which acts as the go between for global compass channels (board#*16 + channel) and + physical detector information. Used in the event builder to assign compass data to real values + in a simple way. Takes in a definition file and parses it into an unordered_map container. + + Written by G.W. McCann Oct. 2020 +*/ +#ifndef CHANNELMAP_H +#define CHANNELMAP_H + +namespace EventBuilder { + //Detector part/type identifiers for use in the code + enum DetType + { + Sabre, + FocalPlane, + NoneType + }; + + enum DetAttribute + { + ScintLeft, + ScintRight, + AnodeFront, + AnodeBack, + DelayFR, + DelayFL, + DelayBR, + DelayBL, + Cathode, + Monitor, + SabreRing0, + SabreRing1, + SabreRing2, + SabreRing3, + SabreRing4, + SabreWedge0, + SabreWedge1, + SabreWedge2, + SabreWedge3, + SabreWedge4, + NoneAttr + }; + + struct Channel + { + DetType type; + DetAttribute attribute; //What kind of detector we're looking at + int local_channel; //Which specific piece of detector we're looking at + }; + + class ChannelMap + { + + public: + typedef std::unordered_map Containter; + typedef std::unordered_map::iterator Iterator; + + ChannelMap(); + ChannelMap(const std::string& filename); + ~ChannelMap(); + bool FillMap(const std::string& filename); + inline const Containter* GetCMap() { return &m_cmap; }; + inline Iterator FindChannel(int key) { return m_cmap.find(key); }; + inline Iterator End() { return m_cmap.end(); }; + inline bool IsValid() { return m_validFlag; }; + + private: + Containter m_cmap; + bool m_validFlag; + }; +} + +#endif diff --git a/src/evb/CompassFile.cpp b/src/evb/CompassFile.cpp index 2d0b55f..5012da3 100644 --- a/src/evb/CompassFile.cpp +++ b/src/evb/CompassFile.cpp @@ -11,141 +11,161 @@ #include "EventBuilder.h" #include "CompassFile.h" -CompassFile::CompassFile() : - m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_file(std::make_shared()), eofFlag(false) -{ - m_buffersize = bufsize*hitsize; - hitBuffer.resize(m_buffersize); -} +namespace EventBuilder { -CompassFile::CompassFile(const std::string& filename) : - m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_file(std::make_shared()), eofFlag(false) -{ - m_buffersize = bufsize*hitsize; - hitBuffer.resize(m_buffersize); - Open(filename); -} - -CompassFile::CompassFile(const std::string& filename, int bsize) : - m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), - bufsize(bsize), m_file(std::make_shared()), eofFlag(false) -{ - m_buffersize = bufsize*hitsize; - hitBuffer.resize(m_buffersize); - Open(filename); -} - -CompassFile::~CompassFile() { - Close(); -} - -void CompassFile::Open(const std::string& filename) { - eofFlag = false; - hitUsedFlag = true; - m_filename = filename; - m_file->open(m_filename, std::ios::binary | std::ios::in); - - m_file->seekg(0, std::ios_base::end); - m_size = m_file->tellg(); - m_nHits = m_size/24; - if(m_size == 0) { - eofFlag = true; - } else { + CompassFile::CompassFile() : + m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_file(std::make_shared()), eofFlag(false) + { + m_buffersize = bufsize*hitsize; + hitBuffer.resize(m_buffersize); + } + + CompassFile::CompassFile(const std::string& filename) : + m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_file(std::make_shared()), eofFlag(false) + { + m_buffersize = bufsize*hitsize; + hitBuffer.resize(m_buffersize); + Open(filename); + } + + CompassFile::CompassFile(const std::string& filename, int bsize) : + m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), + bufsize(bsize), m_file(std::make_shared()), eofFlag(false) + { + m_buffersize = bufsize*hitsize; + hitBuffer.resize(m_buffersize); + Open(filename); + } + + CompassFile::~CompassFile() + { + Close(); + } + + void CompassFile::Open(const std::string& filename) + { + eofFlag = false; + hitUsedFlag = true; + m_filename = filename; + m_file->open(m_filename, std::ios::binary | std::ios::in); + + m_file->seekg(0, std::ios_base::end); + m_size = m_file->tellg(); + m_nHits = m_size/24; + if(m_size == 0) + { + eofFlag = true; + } + else + { + m_file->seekg(0, std::ios_base::beg); + } + } + + void CompassFile::Close() + { + if(IsOpen()) + { + m_file->close(); + } + } + + int CompassFile::GetHitSize() + { + if(!IsOpen()) + { + EVB_WARN("Unable to get hit size from file {0}, sending invalid value.", m_filename); + return 0; + } + + char* firstHit = new char[24]; //A compass hit by default has 24 bytes (at least in our setup) + + m_file->read(firstHit, 24); + + firstHit += 16; + int nsamples = *((uint32_t*) firstHit); + m_file->seekg(0, std::ios_base::beg); + + delete[] firstHit; + + return 24 + nsamples*16; + } -} - -void CompassFile::Close() { - if(IsOpen()) { - m_file->close(); + + /* + GetNextHit() is the function which... gets the next hit + Has to check if the buffer needs refilled/filled for the first time + Upon pulling a hit, sets the UsedFlag to false, letting the next level know + that the hit should be free game. + + If the file cannot be opened, signals as though file is EOF + */ + bool CompassFile::GetNextHit() + { + if(!IsOpen()) return true; + + if((bufferIter == nullptr || bufferIter == bufferEnd) && !IsEOF()) + { + GetNextBuffer(); + } + + if(!IsEOF()) + { + ParseNextHit(); + hitUsedFlag = false; + } + + return eofFlag; } -} - -int CompassFile::GetHitSize() { - if(!IsOpen()) { - std::cerr<<"Unable to get hit size due to file not being open!"<eof()) + { + eofFlag = true; + return; + } + + m_file->read(hitBuffer.data(), hitBuffer.size()); + + bufferIter = hitBuffer.data(); + bufferEnd = bufferIter + m_file->gcount(); //one past the last datum + + } + + void CompassFile::ParseNextHit() + { + + m_currentHit.board = *((uint16_t*)bufferIter); + bufferIter += 2; + m_currentHit.channel = *((uint16_t*)bufferIter); + bufferIter += 2; + m_currentHit.timestamp = *((uint64_t*)bufferIter); + bufferIter += 8; + m_currentHit.lgate = *((uint16_t*)bufferIter); + bufferIter += 2; + m_currentHit.sgate = *((uint16_t*)bufferIter); + bufferIter += 2; + m_currentHit.flags = *((uint32_t*)bufferIter); + bufferIter += 4; + m_currentHit.Ns = *((uint32_t*)bufferIter); + bufferIter += 4; + + if(m_smap != nullptr) + { //memory safety + int gchan = m_currentHit.channel + m_currentHit.board*16; + m_currentHit.timestamp += m_smap->GetShift(gchan); + } + } - char* firstHit = new char[24]; //A compass hit by default has 24 bytes (at least in our setup) - - m_file->read(firstHit, 24); - - firstHit += 16; - int nsamples = *((uint32_t*) firstHit); - - m_file->seekg(0, std::ios_base::beg); - - delete firstHit; - - return 24 + nsamples*16; - -} - -/* - GetNextHit() is the function which... gets the next hit - Has to check if the buffer needs refilled/filled for the first time - Upon pulling a hit, sets the UsedFlag to false, letting the next level know - that the hit should be free game. - - If the file cannot be opened, signals as though file is EOF -*/ -bool CompassFile::GetNextHit() { - if(!IsOpen()) return true; - - if((bufferIter == nullptr || bufferIter == bufferEnd) && !IsEOF()) { - GetNextBuffer(); - } - - if(!IsEOF()) { - ParseNextHit(); - hitUsedFlag = false; - } - - return eofFlag; -} - -/* - GetNextBuffer() ... self-explanatory name - Note tht this is where the EOF flag is set. The EOF is only singaled - after the LAST buffer is completely read (i.e literally no more data). ifstream sets its eof - bit upon pulling the last buffer, but this class waits until that entire - last buffer is read to singal EOF (the true end of file). -*/ -void CompassFile::GetNextBuffer() { - - if(m_file->eof()) { - eofFlag = true; - return; - } - - m_file->read(hitBuffer.data(), hitBuffer.size()); - - bufferIter = hitBuffer.data(); - bufferEnd = bufferIter + m_file->gcount(); //one past the last datum - -} - -void CompassFile::ParseNextHit() { - - m_currentHit.board = *((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; - - if(m_smap != nullptr) { //memory safety - int gchan = m_currentHit.channel + m_currentHit.board*16; - m_currentHit.timestamp += m_smap->GetShift(gchan); - } - -} +} \ No newline at end of file diff --git a/src/evb/CompassFile.h b/src/evb/CompassFile.h new file mode 100644 index 0000000..c39c5f0 --- /dev/null +++ b/src/evb/CompassFile.h @@ -0,0 +1,74 @@ +/* + 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 + +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 hitUsedFlag; } //query to find out if we've used the current hit + inline void SetHitHasBeenUsed() { hitUsedFlag = true; } //flip the flag to indicate the current hit has been used + inline bool IsEOF() const { return eofFlag; } //see if we've read all available data + inline bool* GetUsedFlagPtr() { return &hitUsedFlag; } + inline void AttachShiftMap(ShiftMap* map) { m_smap = map; } + inline unsigned int GetSize() const { return m_size; } + inline unsigned int GetNumberOfHits() const { return m_nHits; } + + + private: + int GetHitSize(); + void ParseNextHit(); + void GetNextBuffer(); + + using Buffer = std::vector; + + using FilePointer = std::shared_ptr; //to make this class copy/movable + + std::string m_filename; + Buffer hitBuffer; + char* bufferIter; + char* bufferEnd; + ShiftMap* m_smap; //NOT owned by CompassFile. DO NOT delete + + bool hitUsedFlag; + int bufsize = 200000; //size of the buffer in hits + int hitsize = 24; //size of a CompassHit in bytes (without alignment padding) + int m_buffersize; + + CompassHit m_currentHit; + FilePointer m_file; + bool eofFlag; + unsigned int m_size; //size of the file in bytes + unsigned int m_nHits; //number of hits in the file (m_size/24) + + }; + +} + +#endif diff --git a/src/evb/CompassHit.h b/src/evb/CompassHit.h new file mode 100644 index 0000000..fd5c02f --- /dev/null +++ b/src/evb/CompassHit.h @@ -0,0 +1,19 @@ +#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 lgate = 0; + uint16_t sgate = 0; + uint32_t flags = 0; + uint32_t Ns = 0; + }; + +} + +#endif diff --git a/src/evb/CompassRun.cpp b/src/evb/CompassRun.cpp index 65e2c4c..2ef9a52 100644 --- a/src/evb/CompassRun.cpp +++ b/src/evb/CompassRun.cpp @@ -17,502 +17,527 @@ #include "SFPAnalyzer.h" #include "FlagHandler.h" -CompassRun::CompassRun() : - directory(""), m_scalerinput(""), runNum(0), m_scaler_flag(false), m_pb(nullptr) -{ - -} - -CompassRun::CompassRun(const std::string& dir) : - directory(dir), m_scalerinput(""), runNum(0), 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(varname.c_str(), init); +namespace EventBuilder { + + CompassRun::CompassRun() : + m_directory(""), m_scalerinput(""), m_runNum(0), m_scaler_flag(false), m_progressFraction(0.1) + { } - 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.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(const std::string& dir) : + m_directory(dir), m_scalerinput(""), m_runNum(0), m_scaler_flag(false), m_progressFraction(0.1) + { + + } + + CompassRun::~CompassRun() {} + + + /*Load em into a map*/ + void CompassRun::SetScalers() + { + std::ifstream input(m_scalerinput); + if(!input.is_open()) + return; + + m_scaler_flag = true; + std::string junk, filename, varname; + Long64_t init = 0; + std::getline(input, junk); + std::getline(input, junk); + m_scaler_map.clear(); + while(input>>filename) + { + input>>varname; + filename = m_directory+filename+"_run_"+std::to_string(m_runNum)+".bin"; + m_scaler_map[filename] = TParameter(varname.c_str(), init); + } + input.close(); + } + + bool CompassRun::GetBinaryFiles() + { + std::string prefix = ""; + std::string suffix = ".bin"; //binaries + RunCollector grabber(m_directory, prefix, suffix); + grabber.GrabAllFiles(); + + m_datafiles.clear(); //so that the CompassRun can be reused + m_datafiles.reserve(grabber.GetFileList().size()); + bool scalerd; + m_totalHits = 0; //reset total run size + + for(auto& entry : grabber.GetFileList()) + { + //Handle scaler files, if they exist + if(m_scaler_flag) + { + scalerd = false; + for(auto& scaler_pair : m_scaler_map) + { + if(entry == scaler_pair.first) + { + ReadScalerData(entry); + scalerd = true; + break; + } } + if(scalerd) + continue; } - if(scalerd) continue; + + m_datafiles.emplace_back(entry); + m_datafiles[m_datafiles.size()-1].AttachShiftMap(&m_smap); + //Any time we have a file that fails to be found, we terminate the whole process + if(!m_datafiles[m_datafiles.size() - 1].IsOpen()) + return false; + + m_totalHits += m_datafiles[m_datafiles.size()-1].GetNumberOfHits(); } - - 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; + + 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++; } - m_totalHits += m_datafiles[m_datafiles.size()-1].GetNumberOfHits(); + this_param.SetVal(count); } - - return true; -} - -/* - Pure counting of scalers. Potential upgrade path to something like - average count rate etc. -*/ -void CompassRun::ReadScalerData(const std::string& filename) { - if(!m_scaler_flag) return; - - Long64_t count; - count = 0; - CompassFile file(filename); - auto& this_param = m_scaler_map[file.GetName()]; - while(true) { - file.GetNextHit(); - if(file.IsEOF()) break; - count++; - } - this_param.SetVal(count); -} - -/* - GetHitsFromFiles() is the function which actually retrieves and sorts the data from the individual - files. There are several tricks which allow this to happen. First is that, after sorting, it is impossible - to determine which file the data originally came from (short of parsing the name of the file against board/channel). - However, we need to let the file know that we want it to pull the next hit. To do this, a pointer to the UsedFlag of the file - is retrieved along with the data. This flag is flipped so that on the next hit cycle a new hit is pulled. Second is the use - of a rolling start index. Once a file has gone EOF, we no longer need it. If this is the first file in the list, we can just skip - that index all together. In this way, the loop can go from N times to N-1 times. -*/ -bool CompassRun::GetHitsFromFiles() { - - std::pair earliestHit = make_pair(CompassHit(), nullptr); - for(unsigned int i=startIndex; iBranch("Board", &hit.board); - outtree->Branch("Channel", &hit.channel); - outtree->Branch("Energy", &hit.lgate); - outtree->Branch("EnergyShort", &hit.sgate); - outtree->Branch("Timestamp", &hit.timestamp); - outtree->Branch("Flags", &hit.flags); - - if(!m_smap.IsSet()) { - std::cerr<<"Bad shift map at CompassRun::Convert()."<Increment(count); - gSystem->ProcessEvents(); - count=0; - } else { - count = 0; - flush_count++; - std::cout<<"\rPercent of run built: "<Fill(); - } - - output->cd(); - outtree->Write(outtree->GetName(), TObject::kOverwrite); - for(auto& entry : m_scaler_map) { - entry.second.Write(); - } - output->Close(); -} - -void CompassRun::Convert2SortedRoot(const std::string& name, const std::string& mapfile, double window) { - TFile* output = TFile::Open(name.c_str(), "RECREATE"); - TTree* outtree = new TTree("SortTree", "SortTree"); - - outtree->Branch("event", &event); - - if(!m_smap.IsSet()) { - std::cerr<<"Bad shift map at CompassRun::Convert()."<Increment(count); - gSystem->ProcessEvents(); - count=0; - } else { - count = 0; - flush_count++; - std::cout<<"\rPercent of run built: "< earliestHit = std::make_pair(CompassHit(), nullptr); + for(unsigned int i=startIndex; iBranch("Board", &hit.board); + outtree->Branch("Channel", &hit.channel); + outtree->Branch("Energy", &hit.lgate); + outtree->Branch("EnergyShort", &hit.sgate); + outtree->Branch("Timestamp", &hit.timestamp); + outtree->Branch("Flags", &hit.flags); + + if(!m_smap.IsValid()) + { + EVB_WARN("Bad shift map ({0}) at CompassRun::Convert(), shifts all set to 0.", m_smap.GetFilename()); } - - if(coincidizer.IsEventReady()) { - event = coincidizer.GetEvent(); + + SetScalers(); + + if(!GetBinaryFiles()) + { + EVB_ERROR("Unable to find binary files at CompassRun::Convert(), exiting!"); + return; + } + + unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0; + + startIndex = 0; //Reset the startIndex + if(flush == 0) + flush = 1; + while(true) + { + count++; + if(count == flush) + { //Progress Log + count = 0; + flush_count++; + m_progressCallback(flush_count*flush, m_totalHits); + } + + if(!GetHitsFromFiles()) + break; outtree->Fill(); - 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::Convert2FastSortedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window) { - TFile* output = TFile::Open(name.c_str(), "RECREATE"); - TTree* outtree = new TTree("SortTree", "SortTree"); - - outtree->Branch("event", &event); - - if(!m_smap.IsSet()) { - std::cerr<<"Bad shift map at CompassRun::Convert()."< fast_events; - SlowSort coincidizer(window, mapfile); - FastSort speedyCoincidizer(fsi_window, fic_window); - - FlagHandler flagger; - - 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 { + + void CompassRun::Convert2SortedRoot(const std::string& name, const std::string& mapfile, double window) + { + TFile* output = TFile::Open(name.c_str(), "RECREATE"); + TTree* outtree = new TTree("SortTree", "SortTree"); + + outtree->Branch("event", &event); + + if(!m_smap.IsValid()) + { + EVB_WARN("Bad shift map ({0}) at CompassRun::Convert2SortedRoot(), shifts all set to 0.", m_smap.GetFilename()); + } + + SetScalers(); + + if(!GetBinaryFiles()) + { + EVB_ERROR("Unable to find binary files at CompassRun::Convert2SortedRoot(), exiting!"); + return; + } + + unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0; + + startIndex = 0; + SlowSort coincidizer(window, mapfile); + bool killFlag = false; + if(flush == 0) + flush = 1; + while(true) + { + count++; + if(count == flush) + { count = 0; flush_count++; - std::cout<<"\rPercent of run built: "<Fill(); + if(killFlag) break; } } + + output->cd(); + outtree->Write(outtree->GetName(), TObject::kOverwrite); + for(auto& entry : m_scaler_map) + entry.second.Write(); + + coincidizer.GetEventStats()->Write(); + output->Close(); + } + + void CompassRun::Convert2FastSortedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window) + { + TFile* output = TFile::Open(name.c_str(), "RECREATE"); + TTree* outtree = new TTree("SortTree", "SortTree"); + + outtree->Branch("event", &event); + + if(!m_smap.IsValid()) + { + EVB_WARN("Bad shift map ({0}) at CompassRun::Convert2FastSortedRoot(), shifts all set to 0.", m_smap.GetFilename()); + } + + SetScalers(); + + if(!GetBinaryFiles()) + { + EVB_ERROR("Unable to find binary files at CompassRun::Convert2FastSortedRoot(), exiting!"); + return; + } + + unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0; + + startIndex = 0; + CoincEvent this_event; + std::vector fast_events; + SlowSort coincidizer(window, mapfile); + FastSort speedyCoincidizer(fsi_window, fic_window); + + FlagHandler flagger; + + bool killFlag = false; + if(flush == 0) + flush = 1; + while(true) + { + count++; + if(count == flush) + { + count = 0; + flush_count++; + m_progressCallback(flush_count*flush, m_totalHits); + } + + if(!GetHitsFromFiles()) + { + coincidizer.FlushHitsToEvent(); + killFlag = true; + } + else + { + flagger.CheckFlag(hit.board, hit.channel, hit.flags); + coincidizer.AddHitToEvent(hit); + } + + if(coincidizer.IsEventReady()) + { + this_event = coincidizer.GetEvent(); + + fast_events = speedyCoincidizer.GetFastEvents(this_event); + for(auto& entry : fast_events) + { + event = entry; + outtree->Fill(); + } + if(killFlag) + break; + } + } + + output->cd(); + outtree->Write(outtree->GetName(), TObject::kOverwrite); + for(auto& entry : m_scaler_map) + entry.second.Write(); - if(!GetHitsFromFiles()) { - coincidizer.FlushHitsToEvent(); - killFlag = true; - } else { - flagger.CheckFlag(hit.board, hit.channel, hit.flags); - coincidizer.AddHitToEvent(hit); + coincidizer.GetEventStats()->Write(); + output->Close(); + } + + + void CompassRun::Convert2SlowAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, + int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta) + { + + TFile* output = TFile::Open(name.c_str(), "RECREATE"); + TTree* outtree = new TTree("SPSTree", "SPSTree"); + + outtree->Branch("event", &pevent); + + if(!m_smap.IsValid()) + { + EVB_WARN("Bad shift map ({0}) at CompassRun::Convert2SlowAnalyzedRoot(), shifts all set to 0.", m_smap.GetFilename()); } - - if(coincidizer.IsEventReady()) { - this_event = coincidizer.GetEvent(); - - fast_events = speedyCoincidizer.GetFastEvents(this_event); - for(auto& entry : fast_events) { - event = entry; - outtree->Fill(); - } - if(killFlag) break; + + SetScalers(); + + if(!GetBinaryFiles()) + { + EVB_ERROR("Unable to find binary files at CompassRun::Convert2SlowAnalyzedRoot(), exiting!"); + return; } - } - - output->cd(); - outtree->Write(outtree->GetName(), TObject::kOverwrite); - for(auto& entry : m_scaler_map) { - entry.second.Write(); - } - coincidizer.GetEventStats()->Write(); - output->Close(); -} - - -void CompassRun::Convert2SlowAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, - int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta) { - - TFile* output = TFile::Open(name.c_str(), "RECREATE"); - TTree* outtree = new TTree("SPSTree", "SPSTree"); - - outtree->Branch("event", &pevent); - - if(!m_smap.IsSet()) { - std::cerr<<"Bad shift map at CompassRun::Convert()."<> parvec; - parvec.reserve(9); - parvec.emplace_back("ZT", zt); - parvec.emplace_back("AT", at); - parvec.emplace_back("ZP", zp); - parvec.emplace_back("AP", ap); - parvec.emplace_back("ZE", ze); - parvec.emplace_back("AE", ae); - parvec.emplace_back("Bfield", b); - parvec.emplace_back("BeamKE", bke); - parvec.emplace_back("Theta", theta); - - bool killFlag = false; - 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 { + + unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0; + + startIndex = 0; + CoincEvent this_event; + SlowSort coincidizer(window, mapfile); + SFPAnalyzer analyzer(zt, at, zp, ap, ze, ae, bke, theta, b); + + std::vector> parvec; + parvec.reserve(9); + parvec.emplace_back("ZT", zt); + parvec.emplace_back("AT", at); + parvec.emplace_back("ZP", zp); + parvec.emplace_back("AP", ap); + parvec.emplace_back("ZE", ze); + parvec.emplace_back("AE", ae); + parvec.emplace_back("Bfield", b); + parvec.emplace_back("BeamKE", bke); + parvec.emplace_back("Theta", theta); + + bool killFlag = false; + if(flush == 0) + flush = 1; + while(true) + { + count++; + if(count == flush) + { count = 0; flush_count++; - std::cout<<"\rPercent of run built: "<Fill(); + if(killFlag) + break; } } - - if(!GetHitsFromFiles()) { - coincidizer.FlushHitsToEvent(); - killFlag = true; - } else { - coincidizer.AddHitToEvent(hit); + + output->cd(); + outtree->Write(outtree->GetName(), TObject::kOverwrite); + for(auto& entry : m_scaler_map) + entry.second.Write(); + + for(auto& entry : parvec) + entry.Write(); + + coincidizer.GetEventStats()->Write(); + analyzer.GetHashTable()->Write(); + analyzer.ClearHashTable(); + output->Close(); + } + + void CompassRun::Convert2FastAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window, + int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta) + { + + TFile* output = TFile::Open(name.c_str(), "RECREATE"); + TTree* outtree = new TTree("SPSTree", "SPSTree"); + + outtree->Branch("event", &pevent); + + if(!m_smap.IsValid()) + { + EVB_WARN("Bad shift map ({0}) at CompassRun::Convert2FastAnalyzedRoot(), shifts all set to 0.", m_smap.GetFilename()); } - - if(coincidizer.IsEventReady()) { - this_event = coincidizer.GetEvent(); - pevent = analyzer.GetProcessedEvent(this_event); - outtree->Fill(); - if(killFlag) break; + + SetScalers(); + + if(!GetBinaryFiles()) + { + EVB_ERROR("Unable to find binary files at CompassRun::Convert2FastAnalyzedRoot(), exiting!"); + return; } - } - - output->cd(); - outtree->Write(outtree->GetName(), TObject::kOverwrite); - for(auto& entry : m_scaler_map) { - entry.second.Write(); - } - for(auto& entry : parvec) { - entry.Write(); - } - coincidizer.GetEventStats()->Write(); - analyzer.GetHashTable()->Write(); - analyzer.ClearHashTable(); - output->Close(); -} - -void CompassRun::Convert2FastAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window, - int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta) { - - TFile* output = TFile::Open(name.c_str(), "RECREATE"); - TTree* outtree = new TTree("SPSTree", "SPSTree"); - - outtree->Branch("event", &pevent); - - if(!m_smap.IsSet()) { - std::cerr<<"Bad shift map at CompassRun::Convert()."< fast_events; - SlowSort coincidizer(window, mapfile); - FastSort speedyCoincidizer(fsi_window, fic_window); - SFPAnalyzer analyzer(zt, at, zp, ap, ze, ae, bke, theta, b); - - vector> parvec; - parvec.reserve(9); - parvec.emplace_back("ZT", zt); - parvec.emplace_back("AT", at); - parvec.emplace_back("ZP", zp); - parvec.emplace_back("AP", ap); - parvec.emplace_back("ZE", ze); - parvec.emplace_back("AE", ae); - parvec.emplace_back("Bfield", b); - parvec.emplace_back("BeamKE", bke); - parvec.emplace_back("Theta", theta); - - FlagHandler flagger; - - bool killFlag = false; - 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 { + + unsigned int count = 0, flush = m_totalHits*m_progressFraction, flush_count = 0; + + startIndex = 0; + CoincEvent this_event; + std::vector fast_events; + SlowSort coincidizer(window, mapfile); + FastSort speedyCoincidizer(fsi_window, fic_window); + SFPAnalyzer analyzer(zt, at, zp, ap, ze, ae, bke, theta, b); + + std::vector> parvec; + parvec.reserve(9); + parvec.emplace_back("ZT", zt); + parvec.emplace_back("AT", at); + parvec.emplace_back("ZP", zp); + parvec.emplace_back("AP", ap); + parvec.emplace_back("ZE", ze); + parvec.emplace_back("AE", ae); + parvec.emplace_back("Bfield", b); + parvec.emplace_back("BeamKE", bke); + parvec.emplace_back("Theta", theta); + + FlagHandler flagger; + + bool killFlag = false; + if(flush == 0) + flush = 1; + while(true) + { + count++; + if(count == flush) + { count = 0; flush_count++; - std::cout<<"\rPercent of run built: "<Fill(); + } + if(killFlag) + break; } } - - if(!GetHitsFromFiles()) { - coincidizer.FlushHitsToEvent(); - killFlag = true; - } else { - flagger.CheckFlag(hit.board, hit.channel, hit.flags); - coincidizer.AddHitToEvent(hit); - } - - if(coincidizer.IsEventReady()) { - this_event = coincidizer.GetEvent(); - - fast_events = speedyCoincidizer.GetFastEvents(this_event); - for(auto& entry : fast_events) { - pevent = analyzer.GetProcessedEvent(entry); - outtree->Fill(); - } - if(killFlag) break; - } + + output->cd(); + outtree->Write(outtree->GetName(), TObject::kOverwrite); + for(auto& entry : m_scaler_map) + entry.second.Write(); + + for(auto& entry : parvec) + entry.Write(); + + coincidizer.GetEventStats()->Write(); + analyzer.GetHashTable()->Write(); + analyzer.ClearHashTable(); + output->Close(); } - - output->cd(); - outtree->Write(outtree->GetName(), TObject::kOverwrite); - for(auto& entry : m_scaler_map) { - entry.second.Write(); - } - for(auto& entry : parvec) { - entry.Write(); - } - coincidizer.GetEventStats()->Write(); - analyzer.GetHashTable()->Write(); - analyzer.ClearHashTable(); - output->Close(); -} - -void CompassRun::SetProgressBar() { - m_pb->SetMax(m_totalHits); - m_pb->SetMin(0); - m_pb->SetPosition(0); - gSystem->ProcessEvents(); -} +} \ No newline at end of file diff --git a/src/evb/CompassRun.h b/src/evb/CompassRun.h new file mode 100644 index 0000000..8651e4e --- /dev/null +++ b/src/evb/CompassRun.h @@ -0,0 +1,74 @@ +/* + CompassRun.h + Class designed as abstraction of a collection of binary files that represent the total data in a single + Compass data run. It handles the user input (shift maps, file collection etc.) and creates a list of + CompassFiles from which to draw data. It then draws data from these files, organizes them in time, + and writes to a ROOT file for further processing. + + Written by G.W. McCann Oct. 2020 +*/ +#ifndef COMPASSRUN_H +#define COMPASSRUN_H + +#include "CompassFile.h" +#include "DataStructs.h" +#include "RunCollector.h" +#include "ShiftMap.h" +#include "ProgressCallback.h" +#include + +namespace EventBuilder { + + class CompassRun + { + + public: + CompassRun(); + CompassRun(const std::string& dir); + ~CompassRun(); + inline void SetDirectory(const std::string& dir) { m_directory = dir; } + inline void SetScalerInput(const std::string& filename) { m_scalerinput = filename; } + inline void SetRunNumber(int n) { m_runNum = n; } + inline void SetShiftMap(const std::string& filename) { m_smap.SetFile(filename); } + void Convert2RawRoot(const std::string& name); + void Convert2SortedRoot(const std::string& name, const std::string& mapfile, double window); + void Convert2FastSortedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window); + void Convert2SlowAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, + int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta); + void Convert2FastAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window, + int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta); + + inline void SetProgressCallbackFunc(const ProgressCallbackFunc& function) { m_progressCallback = function; } + inline void SetProgressFraction(double frac) { m_progressFraction = frac; } + + private: + bool GetBinaryFiles(); + bool GetHitsFromFiles(); + void SetScalers(); + void ReadScalerData(const std::string& filename); + + std::string m_directory, m_scalerinput; + std::vector m_datafiles; + unsigned int startIndex; //this is the file we start looking at; increases as we finish files. + ShiftMap m_smap; + std::unordered_map> m_scaler_map; //maps scaler files to the TParameter to be saved + + //Potential branch variables + CompassHit hit; + CoincEvent event; + ProcessedEvent pevent; + + //what run is this + int m_runNum; + unsigned int m_totalHits; + + //Scaler switch + bool m_scaler_flag; + + ProgressCallbackFunc m_progressCallback; + double m_progressFraction; + }; + +} + +#endif diff --git a/src/evb/CutHandler.cpp b/src/evb/CutHandler.cpp index da6ef8d..520f98f 100644 --- a/src/evb/CutHandler.cpp +++ b/src/evb/CutHandler.cpp @@ -1,94 +1,106 @@ #include "EventBuilder.h" #include "CutHandler.h" -CutHandler::CutHandler() : - validFlag(false) - { - InitVariableMap(); - } - -CutHandler::CutHandler(const std::string& filename) : - validFlag(false) -{ - SetCuts(filename); - InitVariableMap(); -} - -CutHandler::~CutHandler() { - for(unsigned int i=0; iIsOpen()) file_array[i]->Close(); +namespace EventBuilder { + + CutHandler::CutHandler() : + validFlag(false) + { + InitVariableMap(); + } + + CutHandler::CutHandler(const std::string& filename) : + validFlag(false) + { + SetCuts(filename); + InitVariableMap(); } -} - -void CutHandler::SetCuts(const std::string& filename) { - std::ifstream cutlist(filename); - - if(!cutlist.is_open()) { - validFlag = false; + + CutHandler::~CutHandler() + { + for(unsigned int i=0; iIsOpen()) + file_array[i]->Close(); } - - std::string junk, name, fname, varx, vary; - cutlist>>junk>>junk>>junk>>junk; - - cut_array.clear(); - file_array.clear(); - - while(cutlist>>name) { - cutlist>>fname>>varx>>vary; - TFile* file = TFile::Open(fname.c_str(), "READ"); - TCutG* cut = (TCutG*) file->Get("CUTG"); - if(cut) { - cut->SetVarX(varx.c_str()); - cut->SetVarY(vary.c_str()); - cut->SetName(name.c_str()); - cut_array.push_back(cut); - file_array.push_back(file); - } else { + + void CutHandler::SetCuts(const std::string& filename) + { + std::ifstream cutlist(filename); + + if(!cutlist.is_open()) + { validFlag = false; - std::cerr<<"CutHandler has encountered a bad cut at file: "<>junk>>junk>>junk>>junk; + + cut_array.clear(); + file_array.clear(); + + while(cutlist>>name) + { + cutlist>>fname>>varx>>vary; + TFile* file = TFile::Open(fname.c_str(), "READ"); + TCutG* cut = (TCutG*) file->Get("CUTG"); + if(cut) + { + cut->SetVarX(varx.c_str()); + cut->SetVarY(vary.c_str()); + cut->SetName(name.c_str()); + cut_array.push_back(cut); + file_array.push_back(file); + } + else + { + validFlag = false; + EVB_WARN("CutHandler::SetCuts has encountered a bad file ({0}). The file either does not exist or doesn't contain a TCutG CUTG. Cuts ignored.", fname); + return; + } + } + + if(cut_array.size() > 0) + validFlag = true; + else + validFlag = false; + } + + /* + ADD MORE VARIABLES HERE! + */ + void CutHandler::InitVariableMap() + { + varmap["x1"] = &m_event.x1; + varmap["x2"] = &m_event.x2; + varmap["xavg"] = &m_event.xavg; + varmap["scintLeft"] = &m_event.scintLeft; + varmap["anodeBack"] = &m_event.anodeBack; + varmap["cathode"] = &m_event.cathode; + } + + bool CutHandler::IsInside(const ProcessedEvent* eaddress) + { + m_event = *eaddress; + std::string x, y; + for(unsigned int i=0; iGetVarX(); + y = cut->GetVarY(); + auto xentry = varmap.find(x); + auto yentry = varmap.find(y); + if(xentry == varmap.end() || yentry == varmap.end()) + { + EVB_WARN("Unmapped variable names at CutHandler::IsInside() (x:{0}, y:{1})! Cut not applied.", xentry->first, yentry->first); + return false; + } + + if(!cut->IsInside(*(xentry->second), *(yentry->second))) + return false; + + } + + return true; } - if(cut_array.size() > 0) { - validFlag = true; - } else { - validFlag = false; - } -} - -/* - ADD MORE VARIABLES HERE! -*/ -void CutHandler::InitVariableMap() { - varmap["x1"] = &m_event.x1; - varmap["x2"] = &m_event.x2; - varmap["xavg"] = &m_event.xavg; - varmap["scintLeft"] = &m_event.scintLeft; - varmap["anodeBack"] = &m_event.anodeBack; - varmap["cathode"] = &m_event.cathode; -} - -bool CutHandler::IsInside(ProcessedEvent* eaddress) { - m_event = *eaddress; - std::string x, y; - for(unsigned int i=0; iGetVarX(); - y = cut->GetVarY(); - auto xentry = varmap.find(x); - auto yentry = varmap.find(y); - if(xentry == varmap.end() || yentry == varmap.end()) { - std::cerr<<"Unmapped variable called in CutHandler::IsInside()! Var names: "<first<<" , "<first<IsInside(*(xentry->second), *(yentry->second))) { - return false; - } - } - - return true; -} +} \ No newline at end of file diff --git a/src/evb/CutHandler.h b/src/evb/CutHandler.h new file mode 100644 index 0000000..55d3970 --- /dev/null +++ b/src/evb/CutHandler.h @@ -0,0 +1,30 @@ +#ifndef CUTHANDLER_H +#define CUTHANDLER_H + +#include "../spsdict/DataStructs.h" + +namespace EventBuilder { + + class CutHandler { + public: + CutHandler(); + CutHandler(const std::string& filename); + ~CutHandler(); + void SetCuts(const std::string& filename); + bool IsValid() { return validFlag; } + bool IsInside(const ProcessedEvent* eaddress); + std::vector GetCuts() { return cut_array; } + + private: + void InitVariableMap(); + + std::vector cut_array; + std::vector file_array; + std::unordered_map varmap; + bool validFlag; + ProcessedEvent m_event; + }; + +} + +#endif \ No newline at end of file diff --git a/src/evb/EVBApp.cpp b/src/evb/EVBApp.cpp new file mode 100644 index 0000000..bd55ef1 --- /dev/null +++ b/src/evb/EVBApp.cpp @@ -0,0 +1,414 @@ +/* + 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 +#include "EVBApp.h" +#include "RunCollector.h" +#include "CompassRun.h" +#include "SlowSort.h" +#include "FastSort.h" +#include "SFPAnalyzer.h" +#include "SFPPlotter.h" + +namespace EventBuilder { + + EVBApp::EVBApp() : + m_rmin(0), m_rmax(0), m_ZT(0), m_AT(0), m_ZP(0), m_AP(0), m_ZE(0), m_AE(0), m_ZR(0), m_AR(0), + m_B(0), m_Theta(0), m_BKE(0), m_progressFraction(0.1), m_workspace("none"), m_mapfile("none"), m_shiftfile("none"), + m_cutList("none"), m_scalerfile("none"), m_SlowWindow(0), m_FastWindowIonCh(0), m_FastWindowSABRE(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_mapfile; + input>>junk>>m_scalerfile; + input>>junk>>m_cutList; + input>>junk>>m_ZT>>junk>>m_AT; + input>>junk>>m_ZP>>junk>>m_AP; + input>>junk>>m_ZE>>junk>>m_AE; + input>>junk>>m_B; + input>>junk>>m_BKE; + input>>junk>>m_Theta; + input>>junk; + std::getline(input, junk); + std::getline(input, junk); + input>>junk>>m_shiftfile; + input>>junk>>m_SlowWindow; + input>>junk>>m_FastWindowIonCh; + input>>junk>>m_FastWindowSABRE; + input>>junk; + std::getline(input, junk); + std::getline(input, junk); + input>>junk>>m_rmin; + input>>junk>>m_rmax; + + 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----------"< ionch_index) + { //Back anode required to move on` + + float anodeRelTime = fabs(slowEvent.focalPlane.anodeB[ionch_index].Time - slowEvent.focalPlane.scintL[scint_index].Time); + if(anodeRelTime > ion_coincWindow) + return; //Window check + + fastEvent.focalPlane.anodeB.push_back(slowEvent.focalPlane.anodeB[ionch_index]); + fastEvent.focalPlane.scintL.push_back(slowEvent.focalPlane.scintL[scint_index]); + if(slowEvent.focalPlane.delayFL.size() > ionch_index) + fastEvent.focalPlane.delayFL.push_back(slowEvent.focalPlane.delayFL[ionch_index]); + + if(slowEvent.focalPlane.delayFR.size() > ionch_index) + fastEvent.focalPlane.delayFR.push_back(slowEvent.focalPlane.delayFR[ionch_index]); + + if(slowEvent.focalPlane.delayBR.size() > ionch_index) + fastEvent.focalPlane.delayBR.push_back(slowEvent.focalPlane.delayBR[ionch_index]); + + if(slowEvent.focalPlane.delayBL.size() > ionch_index) + fastEvent.focalPlane.delayBL.push_back(slowEvent.focalPlane.delayBL[ionch_index]); + + if(slowEvent.focalPlane.scintR.size() > ionch_index) + fastEvent.focalPlane.scintR.push_back(slowEvent.focalPlane.scintR[ionch_index]); + + if(slowEvent.focalPlane.anodeF.size() > ionch_index) + fastEvent.focalPlane.anodeF.push_back(slowEvent.focalPlane.anodeF[ionch_index]); + + if(slowEvent.focalPlane.cathode.size() > ionch_index) + fastEvent.focalPlane.cathode.push_back(slowEvent.focalPlane.cathode[ionch_index]); + } + } + + /*Assign a set of SABRE data that falls within the coincidence window*/ + void FastSort::ProcessSABRE(unsigned int scint_index) + { + for(int i=0; i<5; i++) + { //loop over SABRE silicons + std::vector rings; + std::vector wedges; + + if(slowEvent.sabreArray[i].rings.size() == 0 || slowEvent.sabreArray[i].wedges.size() == 0) + continue; //save some time on empties + + /*Dump sabre data that doesnt fall within the fast coincidence window with the scint*/ + for(unsigned int j=0; j FastSort::GetFastEvents(CoincEvent& event) + { + slowEvent = event; + std::vector fast_events; + + unsigned int sizeArray[7]; + sizeArray[0] = slowEvent.focalPlane.delayFL.size(); + sizeArray[1] = slowEvent.focalPlane.delayFR.size(); + sizeArray[2] = slowEvent.focalPlane.delayBL.size(); + sizeArray[3] = slowEvent.focalPlane.delayBR.size(); + sizeArray[4] = slowEvent.focalPlane.anodeF.size(); + sizeArray[5] = slowEvent.focalPlane.anodeB.size(); + sizeArray[6] = slowEvent.focalPlane.cathode.size(); + unsigned int maxSize = *std::max_element(sizeArray, sizeArray+7); + //loop over scints + for(unsigned int i=0; i ionch_index) { //Back anode required to move on` - - float anodeRelTime = fabs(slowEvent.focalPlane.anodeB[ionch_index].Time - slowEvent.focalPlane.scintL[scint_index].Time); - if(anodeRelTime > ion_coincWindow) return; //Window check - - fastEvent.focalPlane.anodeB.push_back(slowEvent.focalPlane.anodeB[ionch_index]); - fastEvent.focalPlane.scintL.push_back(slowEvent.focalPlane.scintL[scint_index]); - if(slowEvent.focalPlane.delayFL.size() > ionch_index) { - fastEvent.focalPlane.delayFL.push_back(slowEvent.focalPlane.delayFL[ionch_index]); - } - if(slowEvent.focalPlane.delayFR.size() > ionch_index) { - fastEvent.focalPlane.delayFR.push_back(slowEvent.focalPlane.delayFR[ionch_index]); - } - if(slowEvent.focalPlane.delayBR.size() > ionch_index) { - fastEvent.focalPlane.delayBR.push_back(slowEvent.focalPlane.delayBR[ionch_index]); - } - if(slowEvent.focalPlane.delayBL.size() > ionch_index) { - fastEvent.focalPlane.delayBL.push_back(slowEvent.focalPlane.delayBL[ionch_index]); - } - if(slowEvent.focalPlane.scintR.size() > ionch_index) { - fastEvent.focalPlane.scintR.push_back(slowEvent.focalPlane.scintR[ionch_index]); - } - if(slowEvent.focalPlane.anodeF.size() > ionch_index) { - fastEvent.focalPlane.anodeF.push_back(slowEvent.focalPlane.anodeF[ionch_index]); - } - if(slowEvent.focalPlane.cathode.size() > ionch_index) { - fastEvent.focalPlane.cathode.push_back(slowEvent.focalPlane.cathode[ionch_index]); - } - } -} - -/*Assign a set of SABRE data that falls within the coincidence window*/ -void FastSort::ProcessSABRE(unsigned int scint_index) { - for(int i=0; i<5; i++) { //loop over SABRE silicons - std::vector rings; - std::vector wedges; - - if(slowEvent.sabreArray[i].rings.size() == 0 || slowEvent.sabreArray[i].wedges.size() == 0) continue; //save some time on empties - - /*Dump sabre data that doesnt fall within the fast coincidence window with the scint*/ - for(unsigned int j=0; j FastSort::GetFastEvents(CoincEvent& event) { - slowEvent = event; - std::vector fast_events; - - unsigned int sizeArray[7]; - sizeArray[0] = slowEvent.focalPlane.delayFL.size(); - sizeArray[1] = slowEvent.focalPlane.delayFR.size(); - sizeArray[2] = slowEvent.focalPlane.delayBL.size(); - sizeArray[3] = slowEvent.focalPlane.delayBR.size(); - sizeArray[4] = slowEvent.focalPlane.anodeF.size(); - sizeArray[5] = slowEvent.focalPlane.anodeB.size(); - sizeArray[6] = slowEvent.focalPlane.cathode.size(); - unsigned int maxSize = *max_element(sizeArray, sizeArray+7); - //loop over scints - for(unsigned int i=0; i + +namespace EventBuilder { + + class FastSort + { + + public: + FastSort(float si_windowSize, float ion_windowSize); + ~FastSort(); + std::vector GetFastEvents(CoincEvent& event); + + private: + void ResetSABRE(); + void ResetFocalPlane(); + void ProcessSABRE(unsigned int scint_index); + void ProcessFocalPlane(unsigned int scint_index, unsigned int ionch_index); + + float si_coincWindow, ion_coincWindow; + CoincEvent *event_address, slowEvent; + CoincEvent fastEvent, blank; + SabreDetector sblank; + FPDetector fpblank; + + }; + +} +#endif diff --git a/src/evb/FlagHandler.cpp b/src/evb/FlagHandler.cpp index 4df5001..52b0cb0 100644 --- a/src/evb/FlagHandler.cpp +++ b/src/evb/FlagHandler.cpp @@ -1,86 +1,108 @@ #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"< + +namespace EventBuilder { + + 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 DeadTime = 0x00000001; + const int TimeRollover = 0x00000002; + const int TimeReset = 0x00000004; + const int FakeEvent = 0x00000008; + const int MemFull = 0x00000010; + const int TrigLost = 0x00000020; + const int NTrigLost = 0x00000040; + const int SaturatingInGate = 0x00000080; + const int Trig1024Counted = 0x00000100; + const int SaturatingInput = 0x00000400; + const int NTrigCounted = 0x00000800; + const int EventNotMatched = 0x00001000; + const int FineTime = 0x00004000; + const int PileUp = 0x00008000; + const int PLLLockLoss = 0x00080000; + const int OverTemp = 0x00100000; + const int ADCShutdown = 0x00200000; + + private: + std::ofstream log; + std::map event_count_map; + + void WriteLog(); + }; + +} +#endif diff --git a/src/evb/GWMEventBuilder.cpp b/src/evb/GWMEventBuilder.cpp deleted file mode 100644 index 1de7f07..0000000 --- a/src/evb/GWMEventBuilder.cpp +++ /dev/null @@ -1,405 +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 -#include "GWMEventBuilder.h" -#include "RunCollector.h" -#include "CompassRun.h" -#include "SlowSort.h" -#include "FastSort.h" -#include "SFPAnalyzer.h" -#include "SFPPlotter.h" - -GWMEventBuilder::GWMEventBuilder() : - m_rmin(0), m_rmax(0), m_ZT(0), m_AT(0), m_ZP(0), m_AP(0), m_ZE(0), m_AE(0), m_ZR(0), m_AR(0), - m_B(0), m_Theta(0), m_BKE(0), m_workspace("none"), m_mapfile("none"), m_shiftfile("none"), - m_cutList("none"), m_SlowWindow(0), m_FastWindowIonCh(0), m_FastWindowSABRE(0), m_pb(nullptr) -{ -} - -GWMEventBuilder::~GWMEventBuilder() -{ -} - -bool GWMEventBuilder::ReadConfigFile(const std::string& fullpath) { - std::cout<<"Reading in configuration from file: "<>junk>>m_workspace; - input>>junk; - std::getline(input, junk); - std::getline(input, junk); - input>>junk>>m_mapfile; - input>>junk>>m_scalerfile; - input>>junk>>m_cutList; - input>>junk>>m_ZT>>junk>>m_AT; - input>>junk>>m_ZP>>junk>>m_AP; - input>>junk>>m_ZE>>junk>>m_AE; - input>>junk>>m_B; - input>>junk>>m_BKE; - input>>junk>>m_Theta; - input>>junk; - std::getline(input, junk); - std::getline(input, junk); - input>>junk>>m_shiftfile; - input>>junk>>m_SlowWindow; - input>>junk>>m_FastWindowIonCh; - input>>junk>>m_FastWindowSABRE; - input>>junk; - std::getline(input, junk); - std::getline(input, junk); - input>>junk>>m_rmin; - input>>junk>>m_rmax; - - input.close(); - - std::cout<<"Completed."< 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); + } + +} \ No newline at end of file diff --git a/src/evb/Logger.h b/src/evb/Logger.h new file mode 100644 index 0000000..105baa8 --- /dev/null +++ b/src/evb/Logger.h @@ -0,0 +1,28 @@ +#ifndef LOGGER_H +#define LOGGER_H + +#include +#include "spdlog/spdlog.h" +#include "spdlog/fmt/ostr.h" + +namespace EventBuilder { + + class Logger + { + public: + static void Init(); + + inline static std::shared_ptr GetLogger() { return s_logger; } + + private: + static std::shared_ptr 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 \ No newline at end of file diff --git a/src/evb/MassLookup.cpp b/src/evb/MassLookup.cpp index 99e9c6c..4352589 100644 --- a/src/evb/MassLookup.cpp +++ b/src/evb/MassLookup.cpp @@ -11,51 +11,67 @@ Written by G.W. McCann Aug. 2020 #include "EventBuilder.h" #include "MassLookup.h" - -/* - Read in AMDC mass file, preformated to remove excess info. Here assumes that by default - the file is in a local directory etc/ -*/ -MassLookup::MassLookup() { - std::ifstream massfile("./etc/mass.txt"); - if(massfile.is_open()) { - std::string junk, A, element; - int Z; - double atomicMassBig, atomicMassSmall, isotopicMass; - getline(massfile,junk); - getline(massfile,junk); - while(massfile>>junk) { - massfile>>Z>>A>>element>>atomicMassBig>>atomicMassSmall; - isotopicMass = (atomicMassBig + atomicMassSmall*1e-6 - Z*electron_mass)*u_to_mev; - std::string key = "("+std::to_string(Z)+","+A+")"; - massTable[key] = isotopicMass; - elementTable[Z] = element; - } - } else { - std::cerr<<"Unable to open mass.txt at MassLookup! Prepare for errors."<second; -} - -//returns element symbol -std::string MassLookup::FindSymbol(int Z, int A) { - auto data = elementTable.find(Z); - if(data == elementTable.end()) { - std::cerr<<"Invaild nucleus at MassLookup! Returning empty symbol"<second; - return fullsymbol; -} +namespace EventBuilder { + + /* + Read in AMDC mass file, preformated to remove excess info. Here assumes that by default + the file is in a local directory etc/ + */ + MassLookup::MassLookup() + { + std::string filepath; + #ifdef ETC_DIR_PATH + filepath = ETC_DIR_PATH; + filepath += "mass.txt"; + #else + filepath = "./etc/mass.txt"; + #endif + std::ifstream massfile(filepath); + if(massfile.is_open()) + { + int Z,A; + std::string junk, element, key; + double atomicMassBig, atomicMassSmall, isotopicMass; + std::getline(massfile,junk); + std::getline(massfile,junk); + while(massfile>>junk) + { + massfile>>Z>>A>>element>>atomicMassBig>>atomicMassSmall; + isotopicMass = (atomicMassBig + atomicMassSmall*1e-6 - Z*electron_mass)*u_to_mev; + key = "("+std::to_string(Z)+","+A+")"; + massTable[key] = isotopicMass; + elementTable[Z] = element; + } + } + else + EVB_ERROR("Mass file could not be loaded ({0}). Crashing inbound.",filepath); + } + + MassLookup::~MassLookup() {} + + //Returns nuclear mass in MeV + double MassLookup::FindMass(int Z, int A) + { + std::string key = "("+std::to_string(Z)+","+std::to_string(A)+")"; + auto data = massTable.find(key); + if(data == massTable.end()) + { + EVB_WARN("Invalid nucleus (Z,A) ({0},{1}) at MassLookup::FindMass; returning zero.",Z,A); + return 0; + } + return data->second; + } + + //returns element symbol + std::string MassLookup::FindSymbol(int Z, int A) + { + auto data = elementTable.find(Z); + if(data == elementTable.end()) + { + EVB_WARN("Invalid nucleus (Z,A) ({0},{1}) at MassLookup::FindSymbol; returning empty string.",Z,A); + return ""; + } + std::string fullsymbol = std::to_string(A) + data->second; + return fullsymbol; + } +} \ No newline at end of file diff --git a/src/evb/MassLookup.h b/src/evb/MassLookup.h new file mode 100644 index 0000000..e6a0dc5 --- /dev/null +++ b/src/evb/MassLookup.h @@ -0,0 +1,39 @@ +/* + +MassLookup.h +Generates a map for isotopic masses using AMDC data; subtracts away +electron mass from the atomic mass by default. Creates a static global instance +of this map (MASS) for use throughout code it is included into. + +Written by G.W. McCann Aug. 2020 + +*/ +#ifndef MASS_LOOKUP_H +#define MASS_LOOKUP_H + +namespace EventBuilder { + + class MassLookup + { + + public: + MassLookup(); + ~MassLookup(); + double FindMass(int Z, int A); + std::string FindSymbol(int Z, int A); + + private: + std::unordered_map massTable; + std::unordered_map elementTable; + + //constants + static constexpr double u_to_mev = 931.4940954; + static constexpr double electron_mass = 0.000548579909; + + }; + + //static instance for use throught program + static MassLookup MASS; + +} +#endif diff --git a/src/evb/OrderChecker.cpp b/src/evb/OrderChecker.cpp index f8b22e0..55db24b 100644 --- a/src/evb/OrderChecker.cpp +++ b/src/evb/OrderChecker.cpp @@ -8,30 +8,37 @@ #include "EventBuilder.h" #include "OrderChecker.h" -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"); - - ULong64_t ts; - tree->SetBranchAddress("Timestamp", &ts); - ULong64_t prevStamp = 0; - - for(Long64_t i=0; iGetEntries(); i++) { - tree->GetEntry(); - if(prevStamp >= ts) { - std::cerr<<"Bad order at entry "<GetEntries()<Get("Data"); + + uint64_t ts; + tree->SetBranchAddress("Timestamp", &ts); + uint64_t prevStamp = 0; + + for(Long64_t i=0; iGetEntries(); i++) + { + tree->GetEntry(); + if(prevStamp >= ts) + { + EVB_WARN("Bad order at entry {0} out of {1}",i,tree->GetEntries()); + return false; + } } + + file->Close(); + return true; } - file->Close(); - return true; -} +} \ No newline at end of file diff --git a/include/OrderChecker.h b/src/evb/OrderChecker.h similarity index 64% rename from include/OrderChecker.h rename to src/evb/OrderChecker.h index 9f4b360..e36d4c5 100644 --- a/include/OrderChecker.h +++ b/src/evb/OrderChecker.h @@ -8,11 +8,16 @@ #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 diff --git a/src/evb/ProgressCallback.h b/src/evb/ProgressCallback.h new file mode 100644 index 0000000..daa4977 --- /dev/null +++ b/src/evb/ProgressCallback.h @@ -0,0 +1,14 @@ +#ifndef PROGRESSCALLBACK_H +#define PROGRESSCALLBACK_H + +#include + +#define BIND_PROGRESS_CALLBACK_FUNCTION(func) std::bind(&func, this, std::placeholders::_1, std::placeholders::_2) + +namespace EventBuilder { + + using ProgressCallbackFunc = std::function; + +} + +#endif \ No newline at end of file diff --git a/src/evb/RunCollector.cpp b/src/evb/RunCollector.cpp index 0074170..3c983e1 100644 --- a/src/evb/RunCollector.cpp +++ b/src/evb/RunCollector.cpp @@ -1,196 +1,232 @@ #include "EventBuilder.h" #include "RunCollector.h" +#include +#include +#include +#include +#include +#include -using namespace std; +namespace EventBuilder { -RunCollector::RunCollector(): - initFlag(false), dir(""), run(""), end(""), MaxRun(0), MinRun(0) -{ -} + 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; iAdd(m_filelist[i].c_str()); + chain->Merge(output,0,"fast"); + return true; + } + else + return false; + } + else + { + if(GrabFilesInRange()) + { + for(unsigned int i=0; iAdd(m_filelist[i].c_str()); + chain->Merge(output,0,"fast"); + return true; + } else + return false; + } + + if(output->IsOpen()) + output->Close(); + return false; + } - 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"<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"<Add(filelist[i].Data()); - } - cout<<"Merging runs into single file..."<Merge(output,0,"fast"); - cout<<"Finished merging"<Add(filelist[i]); - } - cout<<"Merging runs "<Merge(output,0,"fast"); - cout<<"Finished merging"<IsOpen()) output->Close(); - return 0; -} +} \ No newline at end of file diff --git a/src/evb/RunCollector.h b/src/evb/RunCollector.h new file mode 100644 index 0000000..02822db --- /dev/null +++ b/src/evb/RunCollector.h @@ -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& 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 m_filelist; + + }; + +} +#endif diff --git a/src/evb/SFPAnalyzer.cpp b/src/evb/SFPAnalyzer.cpp index 10d1941..a4524bc 100644 --- a/src/evb/SFPAnalyzer.cpp +++ b/src/evb/SFPAnalyzer.cpp @@ -12,172 +12,197 @@ #include "EventBuilder.h" #include "SFPAnalyzer.h" -using namespace std; +namespace EventBuilder { -/*Constructor takes in kinematic parameters for generating focal plane weights*/ -SFPAnalyzer::SFPAnalyzer(int zt, int at, int zp, int ap, int ze, int ae, double ep, - double angle, double b) { - zfp = Delta_Z(zt, at, zp, ap, ze, ae, ep, angle, b); - event_address = new CoincEvent(); - rootObj = new THashTable(); - GetWeights(); -} + /*Constructor takes in kinematic parameters for generating focal plane weights*/ + SFPAnalyzer::SFPAnalyzer(int zt, int at, int zp, int ap, int ze, int ae, double ep, + double angle, double b) + { + zfp = Delta_Z(zt, at, zp, ap, ze, ae, ep, angle, b); + event_address = new CoincEvent(); + rootObj = new THashTable(); + GetWeights(); + } + + SFPAnalyzer::~SFPAnalyzer() + { + rootObj->Clear(); + delete rootObj; + delete event_address; + } + + void SFPAnalyzer::Reset() + { + pevent = blank; //set output back to blank + } + + /*Use functions from FP_kinematics to calculate weights for xavg + *While this seems kind of funny, it is mathematically equivalent to making a line + *from the two focal plane points and finding the intersection with + *the kinematic focal plane + */ + void SFPAnalyzer::GetWeights() + { + w1 = (Wire_Dist()/2.0-zfp)/Wire_Dist(); + w2 = 1.0-w1; + EVB_INFO("Calculated X-Avg weights of w1={0} and w2={1}",w1,w2); + } + + /*2D histogram fill wrapper for use with THashTable (faster)*/ + void SFPAnalyzer::MyFill(const std::string& name, int binsx, double minx, double maxx, double valuex, + int binsy, double miny, double maxy, double valuey) + { + TH2F *histo = (TH2F*) rootObj->FindObject(name.c_str()); + if(histo != nullptr) + histo->Fill(valuex, valuey); + else + { + TH2F *h = new TH2F(name.c_str(), name.c_str(), binsx, minx, maxx, binsy, miny, maxy); + h->Fill(valuex, valuey); + rootObj->Add(h); + } + } + + /*1D histogram fill wrapper for use with THashTable (faster)*/ + void SFPAnalyzer::MyFill(const std::string& name, int binsx, double minx, double maxx, double valuex) + { + TH1F *histo = (TH1F*) rootObj->FindObject(name.c_str()); + if(histo != nullptr) + histo->Fill(valuex); + else + { + TH1F *h = new TH1F(name.c_str(), name.c_str(), binsx, minx, maxx); + h->Fill(valuex); + rootObj->Add(h); + } + } + + void SFPAnalyzer::AnalyzeEvent(CoincEvent& event) + { + Reset(); + if(!event.focalPlane.anodeF.empty()) + { + pevent.anodeFront = event.focalPlane.anodeF[0].Long; + pevent.anodeFrontTime = event.focalPlane.anodeF[0].Time; + } + if(!event.focalPlane.anodeB.empty()) + { + pevent.anodeBack = event.focalPlane.anodeB[0].Long; + pevent.anodeBackTime = event.focalPlane.anodeB[0].Time; + } + if(!event.focalPlane.scintL.empty()) + { + pevent.scintLeft = event.focalPlane.scintL[0].Long; + pevent.scintLeftShort = event.focalPlane.scintL[0].Short; + pevent.scintLeftTime = event.focalPlane.scintL[0].Time; + } + if(!event.focalPlane.scintR.empty()) + { + pevent.scintRight = event.focalPlane.scintR[0].Long; + pevent.scintRightShort = event.focalPlane.scintR[0].Short; + pevent.scintRightTime = event.focalPlane.scintR[0].Time; + } + if(!event.focalPlane.cathode.empty()) + { + pevent.cathode = event.focalPlane.cathode[0].Long; + pevent.cathodeTime = event.focalPlane.cathode[0].Time; + } + if(!event.focalPlane.monitor.empty()) + { + pevent.monitorE = event.focalPlane.monitor[0].Long; + pevent.monitorShort = event.focalPlane.monitor[0].Short; + pevent.monitorTime = event.focalPlane.monitor[0].Time; + } + + /*Delay lines and all that*/ + if(!event.focalPlane.delayFR.empty()) + { + pevent.delayFrontRightE = event.focalPlane.delayFR[0].Long; + pevent.delayFrontRightTime = event.focalPlane.delayFR[0].Time; + pevent.delayFrontRightShort = event.focalPlane.delayFR[0].Short; + } + if(!event.focalPlane.delayFL.empty()) + { + pevent.delayFrontLeftE = event.focalPlane.delayFL[0].Long; + pevent.delayFrontLeftTime = event.focalPlane.delayFL[0].Time; + pevent.delayFrontLeftShort = event.focalPlane.delayFL[0].Short; + } + if(!event.focalPlane.delayBR.empty()) + { + pevent.delayBackRightE = event.focalPlane.delayBR[0].Long; + pevent.delayBackRightTime = event.focalPlane.delayBR[0].Time; + pevent.delayBackRightShort = event.focalPlane.delayBR[0].Short; + } + if(!event.focalPlane.delayBL.empty()) + { + pevent.delayBackLeftE = event.focalPlane.delayBL[0].Long; + pevent.delayBackLeftTime = event.focalPlane.delayBL[0].Time; + pevent.delayBackLeftShort = event.focalPlane.delayBL[0].Short; + } + if(!event.focalPlane.delayFL.empty() && !event.focalPlane.delayFR.empty()) + { + pevent.fp1_tdiff = (event.focalPlane.delayFL[0].Time-event.focalPlane.delayFR[0].Time)*0.5; + pevent.fp1_tsum = (event.focalPlane.delayFL[0].Time+event.focalPlane.delayFR[0].Time); + pevent.fp1_tcheck = (pevent.fp1_tsum)/2.0-pevent.anodeFrontTime; + pevent.delayFrontMaxTime = std::max(event.focalPlane.delayFL[0].Time, event.focalPlane.delayFR[0].Time); + pevent.x1 = pevent.fp1_tdiff*1.0/2.10; //position from time, based on total delay + MyFill("x1",1200,-300,300,pevent.x1); + MyFill("x1 vs anodeBack",600,-300,300,pevent.x1,512,0,4096,pevent.anodeBack); + } + if(!event.focalPlane.delayBL.empty() && !event.focalPlane.delayBR.empty()) + { + pevent.fp2_tdiff = (event.focalPlane.delayBL[0].Time-event.focalPlane.delayBR[0].Time)*0.5; + pevent.fp2_tsum = (event.focalPlane.delayBL[0].Time+event.focalPlane.delayBR[0].Time); + pevent.fp2_tcheck = (pevent.fp2_tsum)/2.0-pevent.anodeBackTime; + pevent.delayBackMaxTime = std::max(event.focalPlane.delayBL[0].Time, event.focalPlane.delayBR[0].Time); + pevent.x2 = pevent.fp2_tdiff*1.0/1.98; //position from time, based on total delay + MyFill("x2",1200,-300,300,pevent.x2); + MyFill("x2 vs anodeBack",600,-300,300,pevent.x2,512,0,4096,pevent.anodeBack); + } + /*SABRE data*/ + for(int j=0; j<5; j++) + { + if(!event.sabreArray[j].rings.empty()) + { + pevent.sabreRingE[j] = event.sabreArray[j].rings[0].Long; + pevent.sabreRingChannel[j] = event.sabreArray[j].rings[0].Ch; + pevent.sabreRingTime[j] = event.sabreArray[j].rings[0].Time; + } + if(!event.sabreArray[j].wedges.empty()) + { + pevent.sabreWedgeE[j] = event.sabreArray[j].wedges[0].Long; + pevent.sabreWedgeChannel[j] = event.sabreArray[j].wedges[0].Ch; + pevent.sabreWedgeTime[j] = event.sabreArray[j].wedges[0].Time; + } + /*Aaaand passes on all of the rest. 4/24/20 GWM*/ + pevent.sabreArray[j] = event.sabreArray[j]; + } + + /*Make some histograms and xavg*/ + MyFill("anodeBack vs scintLeft",512,0,4096,pevent.scintLeft,512,0,4096,pevent.anodeBack); + if(pevent.x1 != -1e6 && pevent.x2 != -1e6) + { + pevent.xavg = pevent.x1*w1+pevent.x2*w2; + MyFill("xavg",1200,-300,300,pevent.xavg); + if((pevent.x2-pevent.x1) > 0) + pevent.theta = std::atan((pevent.x2-pevent.x1)/36.0); + else if((pevent.x2-pevent.x1) < 0) + pevent.theta = TMath::Pi() + std::atan((pevent.x2-pevent.x1)/36.0); + else + pevent.theta = TMath::Pi()/2.0; + MyFill("xavg vs theta",600,-300,300,pevent.xavg,314,0,3.14,pevent.theta); + MyFill("x1 vs x2",600,-300,300,pevent.x1,600,-300,300,pevent.x2); + } + if(pevent.anodeFrontTime != -1 && pevent.scintRightTime != -1) + pevent.fp1_y = pevent.anodeFrontTime-pevent.scintRightTime; + if(pevent.anodeBackTime != -1 && pevent.scintRightTime != -1) + pevent.fp2_y = pevent.anodeBackTime-pevent.scintRightTime; + } + + ProcessedEvent SFPAnalyzer::GetProcessedEvent(CoincEvent& event) + { + AnalyzeEvent(event); + return pevent; + } -SFPAnalyzer::~SFPAnalyzer() { - rootObj->Clear(); - delete rootObj; - delete event_address; -} - -void SFPAnalyzer::Reset() { - pevent = blank; //set output back to blank -} - -/*Use functions from FP_kinematics to calculate weights for xavg - *While this seems kind of funny, it is mathematically equivalent to making a line - *from the two focal plane points and finding the intersection with - *the kinematic focal plane - */ -void SFPAnalyzer::GetWeights() { - w1 = (Wire_Dist()/2.0-zfp)/Wire_Dist(); - w2 = 1.0-w1; - cout<<"w1: "<FindObject(name.c_str()); - if(histo != NULL) { - histo->Fill(valuex, valuey); - } else { - TH2F *h = new TH2F(name.c_str(), name.c_str(), binsx, minx, maxx, binsy, miny, maxy); - h->Fill(valuex, valuey); - rootObj->Add(h); - } -} - -/*1D histogram fill wrapper for use with THashTable (faster)*/ -void SFPAnalyzer::MyFill(const string& name, int binsx, double minx, double maxx, double valuex) { - TH1F *histo = (TH1F*) rootObj->FindObject(name.c_str()); - if(histo != NULL) { - histo->Fill(valuex); - } else { - TH1F *h = new TH1F(name.c_str(), name.c_str(), binsx, minx, maxx); - h->Fill(valuex); - rootObj->Add(h); - } -} - -void SFPAnalyzer::AnalyzeEvent(CoincEvent& event) { - Reset(); - if(!event.focalPlane.anodeF.empty()) { - pevent.anodeFront = event.focalPlane.anodeF[0].Long; - pevent.anodeFrontTime = event.focalPlane.anodeF[0].Time; - } - if(!event.focalPlane.anodeB.empty()) { - pevent.anodeBack = event.focalPlane.anodeB[0].Long; - pevent.anodeBackTime = event.focalPlane.anodeB[0].Time; - } - if(!event.focalPlane.scintL.empty()) { - pevent.scintLeft = event.focalPlane.scintL[0].Long; - pevent.scintLeftShort = event.focalPlane.scintL[0].Short; - pevent.scintLeftTime = event.focalPlane.scintL[0].Time; - } - if(!event.focalPlane.scintR.empty()) { - pevent.scintRight = event.focalPlane.scintR[0].Long; - pevent.scintRightShort = event.focalPlane.scintR[0].Short; - pevent.scintRightTime = event.focalPlane.scintR[0].Time; - } - if(!event.focalPlane.cathode.empty()) { - pevent.cathode = event.focalPlane.cathode[0].Long; - pevent.cathodeTime = event.focalPlane.cathode[0].Time; - } - if(!event.focalPlane.monitor.empty()) { - pevent.monitorE = event.focalPlane.monitor[0].Long; - pevent.monitorShort = event.focalPlane.monitor[0].Short; - pevent.monitorTime = event.focalPlane.monitor[0].Time; - } - - /*Delay lines and all that*/ - if(!event.focalPlane.delayFR.empty()) { - pevent.delayFrontRightE = event.focalPlane.delayFR[0].Long; - pevent.delayFrontRightTime = event.focalPlane.delayFR[0].Time; - pevent.delayFrontRightShort = event.focalPlane.delayFR[0].Short; - } - if(!event.focalPlane.delayFL.empty()) { - pevent.delayFrontLeftE = event.focalPlane.delayFL[0].Long; - pevent.delayFrontLeftTime = event.focalPlane.delayFL[0].Time; - pevent.delayFrontLeftShort = event.focalPlane.delayFL[0].Short; - } - if(!event.focalPlane.delayBR.empty()) { - pevent.delayBackRightE = event.focalPlane.delayBR[0].Long; - pevent.delayBackRightTime = event.focalPlane.delayBR[0].Time; - pevent.delayBackRightShort = event.focalPlane.delayBR[0].Short; - } - if(!event.focalPlane.delayBL.empty()) { - pevent.delayBackLeftE = event.focalPlane.delayBL[0].Long; - pevent.delayBackLeftTime = event.focalPlane.delayBL[0].Time; - pevent.delayBackLeftShort = event.focalPlane.delayBL[0].Short; - } - if(!event.focalPlane.delayFL.empty() && !event.focalPlane.delayFR.empty()) { - pevent.fp1_tdiff = (event.focalPlane.delayFL[0].Time-event.focalPlane.delayFR[0].Time)*0.5; - pevent.fp1_tsum = (event.focalPlane.delayFL[0].Time+event.focalPlane.delayFR[0].Time); - pevent.fp1_tcheck = (pevent.fp1_tsum)/2.0-pevent.anodeFrontTime; - pevent.delayFrontMaxTime = max(event.focalPlane.delayFL[0].Time, event.focalPlane.delayFR[0].Time); - pevent.x1 = pevent.fp1_tdiff*1.0/2.10; //position from time, based on total delay - MyFill("x1",1200,-300,300,pevent.x1); - MyFill("x1 vs anodeBack",600,-300,300,pevent.x1,512,0,4096,pevent.anodeBack); - } - if(!event.focalPlane.delayBL.empty() && !event.focalPlane.delayBR.empty()) { - pevent.fp2_tdiff = (event.focalPlane.delayBL[0].Time-event.focalPlane.delayBR[0].Time)*0.5; - pevent.fp2_tsum = (event.focalPlane.delayBL[0].Time+event.focalPlane.delayBR[0].Time); - pevent.fp2_tcheck = (pevent.fp2_tsum)/2.0-pevent.anodeBackTime; - pevent.delayBackMaxTime = max(event.focalPlane.delayBL[0].Time, event.focalPlane.delayBR[0].Time); - pevent.x2 = pevent.fp2_tdiff*1.0/1.98; //position from time, based on total delay - MyFill("x2",1200,-300,300,pevent.x2); - MyFill("x2 vs anodeBack",600,-300,300,pevent.x2,512,0,4096,pevent.anodeBack); - } - /*SABRE data*/ - for(int j=0; j<5; j++) { - if(!event.sabreArray[j].rings.empty()) { - pevent.sabreRingE[j] = event.sabreArray[j].rings[0].Long; - pevent.sabreRingChannel[j] = event.sabreArray[j].rings[0].Ch; - pevent.sabreRingTime[j] = event.sabreArray[j].rings[0].Time; - } - if(!event.sabreArray[j].wedges.empty()) { - pevent.sabreWedgeE[j] = event.sabreArray[j].wedges[0].Long; - pevent.sabreWedgeChannel[j] = event.sabreArray[j].wedges[0].Ch; - pevent.sabreWedgeTime[j] = event.sabreArray[j].wedges[0].Time; - } - /*Aaaand passes on all of the rest. 4/24/20 GWM*/ - pevent.sabreArray[j] = event.sabreArray[j]; - } - - /*Make some histograms and xavg*/ - MyFill("anodeBack vs scintLeft",512,0,4096,pevent.scintLeft,512,0,4096,pevent.anodeBack); - if(pevent.x1 != -1e6 && pevent.x2 != -1e6) { - pevent.xavg = pevent.x1*w1+pevent.x2*w2; - MyFill("xavg",1200,-300,300,pevent.xavg); - if((pevent.x2-pevent.x1) > 0) { - pevent.theta = atan((pevent.x2-pevent.x1)/36.0); - } else if((pevent.x2-pevent.x1) < 0) { - pevent.theta = TMath::Pi() + atan((pevent.x2-pevent.x1)/36.0); - } else { - pevent.theta = TMath::Pi()/2.0; - } - MyFill("xavg vs theta",600,-300,300,pevent.xavg,314,0,3.14,pevent.theta); - MyFill("x1 vs x2",600,-300,300,pevent.x1,600,-300,300,pevent.x2); - } - if(pevent.anodeFrontTime != -1 && pevent.scintRightTime != -1) { - pevent.fp1_y = pevent.anodeFrontTime-pevent.scintRightTime; - } - if(pevent.anodeBackTime != -1 && pevent.scintRightTime != -1) { - pevent.fp2_y = pevent.anodeBackTime-pevent.scintRightTime; - } -} - -ProcessedEvent SFPAnalyzer::GetProcessedEvent(CoincEvent& event) { - AnalyzeEvent(event); - return pevent; -} +} \ No newline at end of file diff --git a/src/evb/SFPAnalyzer.h b/src/evb/SFPAnalyzer.h new file mode 100644 index 0000000..d70d3d4 --- /dev/null +++ b/src/evb/SFPAnalyzer.h @@ -0,0 +1,48 @@ +/*SFPAnalyzer.h + *Class designed to analyze coincidence events. Currently only implemented for focal plane + *data. Additional changes for SABRE would include this file and the sructure ProcessedEvent + *in DataStructs.h. Based on code written by S. Balak, K. Macon, and E. Good. + * + *Gordon M. Oct. 2019 + * + *Refurbished and updated Jan 2020 by GWM. Now uses both focal plane and SABRE data + */ +#ifndef SFPANALYZER_H +#define SFPANALYZER_H + +#include "DataStructs.h" +#include "FP_kinematics.h" + +namespace EventBuilder { + + class SFPAnalyzer + { + public: + SFPAnalyzer(int zt, int at, int zp, int ap, int ze, int ae, double ep, double angle, + double b); + ~SFPAnalyzer(); + ProcessedEvent GetProcessedEvent(CoincEvent& event); + inline void ClearHashTable() { rootObj->Clear(); } + inline THashTable* GetHashTable() { return rootObj; } + + private: + void Reset(); //Sets ouput structure back to "zero" + void GetWeights(); //weights for xavg + void AnalyzeEvent(CoincEvent& event); + + /*Fill wrappers for use with THashTable*/ + void MyFill(const std::string& name, int binsx, double minx, double maxx, double valuex, + int binsy, double miny, double maxy, double valuey); + void MyFill(const std::string& name, int binsx, double minx, double maxx, double valuex); + + CoincEvent *event_address; //Input branch address + ProcessedEvent pevent, blank; //output branch and reset + + double w1, w2, zfp; + + THashTable *rootObj; //root storage + }; + +} + +#endif diff --git a/src/evb/SFPPlotter.cpp b/src/evb/SFPPlotter.cpp index b79b686..8aa7205 100644 --- a/src/evb/SFPPlotter.cpp +++ b/src/evb/SFPPlotter.cpp @@ -10,285 +10,271 @@ #include "SFPPlotter.h" #include -/*Generates storage and initializes pointers*/ -SFPPlotter::SFPPlotter() { - rootObj = new THashTable(); - rootObj->SetOwner(false);//THashTable doesnt own members; avoid double delete - event_address = new ProcessedEvent(); - chain = new TChain("SPSTree"); - m_pb = NULL; -} +namespace EventBuilder { -SFPPlotter::~SFPPlotter() { - delete event_address; -} + /*Generates storage and initializes pointers*/ + SFPPlotter::SFPPlotter() : + event_address(new ProcessedEvent()), m_progressFraction(0.1) + { + } + + SFPPlotter::~SFPPlotter() + { + delete event_address; + } + + /*2D histogram fill wrapper*/ + void SFPPlotter::MyFill(THashTable* table, const std::string& name, int binsx, double minx, double maxx, double valuex, + int binsy, double miny, double maxy, double valuey) + { + TH2F *histo = (TH2F*) table->FindObject(name.c_str()); + if(histo != nullptr) + histo->Fill(valuex, valuey); + else + { + TH2F *h = new TH2F(name.c_str(), name.c_str(), binsx, minx, maxx, binsy, miny, maxy); + h->Fill(valuex, valuey); + table->Add(h); + } + } + + /*1D histogram fill wrapper*/ + void SFPPlotter::MyFill(THashTable* table, const std::string& name, int binsx, double minx, double maxx, double valuex) + { + TH1F *histo = (TH1F*) table->FindObject(name.c_str()); + if(histo != nullptr) + histo->Fill(valuex); + else + { + TH1F *h = new TH1F(name.c_str(), name.c_str(), binsx, minx, maxx); + h->Fill(valuex); + table->Add(h); + } + } + + /*Makes histograms where only rejection is unset data*/ + void SFPPlotter::MakeUncutHistograms(const ProcessedEvent& ev, THashTable* table) + { + MyFill(table,"x1NoCuts_bothplanes",600,-300,300,ev.x2); + MyFill(table,"x2NoCuts_bothplanes",600,-300,300,ev.x2); + MyFill(table,"xavgNoCuts_bothplanes",600,-300,300,ev.xavg); + MyFill(table,"xavgNoCuts_theta_bothplanes",600,-300,300,ev.xavg,100,0,TMath::Pi()/2.,ev.theta); + + MyFill(table,"x1_delayBackRightE_NoCuts",600,-300,300,ev.x1,512,0,4096,ev.delayBackRightE); + MyFill(table,"x2_delayBackRightE_NoCuts",600,-300,300,ev.x2,512,0,4096,ev.delayBackRightE); + MyFill(table,"xavg_delayBackRightE_NoCuts",600,-300,300,ev.xavg,512,0,4096,ev.delayBackRightE); + MyFill(table,"x1_x2_NoCuts",600,-300,300,ev.x1,600,-300,300,ev.x2); + + Double_t delayBackAvgE = (ev.delayBackRightE+ev.delayBackLeftE)/2.0; + MyFill(table,"x1_delayBackAvgE_NoCuts",600,-300,300,ev.x1,512,0,4096,delayBackAvgE); + MyFill(table,"x2_delayBackAvgE_NoCuts",600,-300,300,ev.x2,512,0,4096,delayBackAvgE); + MyFill(table,"xavg_delayBackAvgE_NoCuts",600,-300,300,ev.xavg,512,0,4096,delayBackAvgE); + Double_t delayFrontAvgE = (ev.delayFrontRightE+ev.delayFrontLeftE)/2.0; + MyFill(table,"x1_delayFrontAvgE_NoCuts",600,-300,300,ev.x1,512,0,4096,delayFrontAvgE); + MyFill(table,"x2_delayFrontAvgE_NoCuts",600,-300,300,ev.x2,512,0,4096,delayFrontAvgE); + MyFill(table,"xavg_delayFrontAvgE_NoCuts",600,-300,300,ev.xavg,512,0,4096,delayFrontAvgE); + + MyFill(table,"scintLeft_anodeBack_NoCuts",512,0,4096,ev.scintLeft,512,0,4096,ev.anodeBack); + MyFill(table,"scintLeft_anodeFront_NoCuts",512,0,4096,ev.scintLeft,512,0,4096,ev.anodeFront); + MyFill(table,"scintLeft_cathode_NoCuts",512,0,4096,ev.scintLeft,512,0,4096,ev.cathode); + + MyFill(table,"x1_scintLeft_NoCuts",600,-300,300,ev.x1,512,0,4096,ev.scintLeft); + MyFill(table,"x2_scintLeft_NoCuts",600,-300,300,ev.x2,512,0,4096,ev.scintLeft); + MyFill(table,"xavg_scintLeft_NoCuts",600,-300,300,ev.xavg,512,0,4096,ev.scintLeft); + + MyFill(table,"x1_anodeBack_NoCuts",600,-300,300,ev.x1,512,0,4096,ev.anodeBack); + MyFill(table,"x2_anodeBack_NoCuts",600,-300,300,ev.x2,512,0,4096,ev.anodeBack); + MyFill(table,"xavg_anodeBack_NoCuts",600,-300,300,ev.xavg,512,0,4096,ev.anodeBack); + + MyFill(table,"x1_anodeFront_NoCuts",600,-300,300,ev.x1,512,0,4096,ev.anodeFront); + MyFill(table,"x2_anodeFront_NoCuts",600,-300,300,ev.x2,512,0,4096,ev.anodeFront); + MyFill(table,"xavg_anodeFront_NoCuts",600,-300,300,ev.xavg,512,0,4096,ev.anodeFront); + + MyFill(table,"x1_cathode_NoCuts",600,-300,300,ev.x1,512,0,4096,ev.cathode); + MyFill(table,"x2_cathode_NoCuts",600,-300,300,ev.x2,512,0,4096,ev.cathode); + MyFill(table,"xavg_cathode_NoCuts",600,-300,300,ev.xavg,512,0,4096,ev.cathode); + + /****Timing relative to back anode****/ + if(ev.anodeBackTime != -1 && ev.scintLeftTime != -1) + { + Double_t anodeRelFT = ev.anodeFrontTime - ev.anodeBackTime; + Double_t delayRelFT = ev.delayFrontMaxTime - ev.anodeBackTime; + Double_t delayRelBT = ev.delayBackMaxTime - ev.anodeBackTime; + Double_t anodeRelBT = ev.anodeBackTime - ev.scintLeftTime; + Double_t delayRelFT_toScint = ev.delayFrontMaxTime - ev.scintLeftTime; + Double_t delayRelBT_toScint = ev.delayBackMaxTime - ev.scintLeftTime; + MyFill(table,"anodeRelFrontTime_NoCuts",1000,-3000,3500, anodeRelFT); + MyFill(table,"delayRelFrontTime_NoCuts",1000,-3000,-3500,delayRelFT); + MyFill(table,"delayRelBackTime_NoCuts",1000,-3000,-3500,delayRelBT); + for(int i=0; i<5; i++) + { + if(ev.sabreRingE[i] != -1) + { + Double_t sabreRelRT = ev.sabreRingTime[i] - ev.anodeBackTime; + Double_t sabreRelWT = ev.sabreWedgeTime[i] - ev.anodeBackTime; + Double_t sabreRelRT_toScint = ev.sabreRingTime[i] - ev.scintLeftTime; + Double_t sabreRelWT_toScint = ev.sabreWedgeTime[i] - ev.scintLeftTime; + MyFill(table,"xavg_sabrefcoinc_NoCuts",600,-300,300, ev.xavg); + MyFill(table,"sabreRelRingTime_NoCuts",1000,-3000,3500, sabreRelRT); + MyFill(table,"sabreRelWedgeTime_NoCuts",1000,-3000,3500, sabreRelWT); + MyFill(table,"sabreRelRingTime_toScint",1000,-3000,3500,sabreRelRT_toScint); + MyFill(table,"sabreRelWedgeTime_toScint",1000,-3000,3500,sabreRelWT_toScint); + MyFill(table,"sabreRelRTScint_sabreRelRTAnode",500,-3000,3500,sabreRelRT_toScint,500,-3000,3500,sabreRelRT); + MyFill(table,"sabreRelRTScint_sabreRingChannel",500,-3000,3500,sabreRelRT_toScint,144,0,144,ev.sabreRingChannel[i]); + MyFill(table,"sabreRelRTAnode_sabreRingChannel",500,-3000,3500,sabreRelRT,144,0,144,ev.sabreRingChannel[i]); + MyFill(table,"sabreRelWTScint_sabreWedgeChannel",500,-3000,3500,sabreRelWT_toScint,144,0,144,ev.sabreWedgeChannel[i]); + MyFill(table,"sabreRelRT_sabreRelWT",500,-3000,3500,sabreRelRT,500,-3000,3500,sabreRelWT); + MyFill(table,"sabreRelRT_sabreRelWT_scint",500,-3000,3500,sabreRelRT_toScint,500,-3000,3500,sabreRelWT_toScint); + MyFill(table,"sabreRelRTScint_anodeRelT",500,-3000,3500,sabreRelRT_toScint,500,-3000,3500,anodeRelBT); + } + } + MyFill(table,"anodeBackRelTime_toScint",1000,-3000,3500,anodeRelBT); + MyFill(table,"delayRelBackTime_toScint",1000,-3000,3500,delayRelBT_toScint); + MyFill(table,"delayRelFrontTime_toScint",1000,-3000,3500,delayRelFT_toScint); + } + else + MyFill(table,"noscinttime_counter_NoCuts",2,0,1,1); + + for(int i=0; i<5; i++) + { + if(ev.sabreRingE[i] != -1) //Again, at this point front&back are required + { + MyFill(table,"sabreRingE_NoCuts",2000,0,20,ev.sabreRingE[i]); + MyFill(table,"sabreRingChannel_sabreRingE_NoCuts",144,0,144,ev.sabreRingChannel[i],200,0,20,ev.sabreRingE[i]); + MyFill(table,"sabreWedgeE_NoCuts",2000,0,20,ev.sabreWedgeE[i]); + MyFill(table,"sabreWedgeChannel_sabreWedgeE_NoCuts",144,0,144,ev.sabreWedgeChannel[i],200,0,20,ev.sabreWedgeE[i]); + } + } + + if(ev.x1 != -1e6 && ev.x2 == -1e6) + MyFill(table,"x1NoCuts_only1plane",600,-300,300,ev.x1); + else if(ev.x2 != -1e6 && ev.x1 == -1e6) + MyFill(table,"x2NoCuts_only1plane",600,-300,300,ev.x2); + else if(ev.x1 == -1e6 && ev.x2 == -1e6) + MyFill(table,"nopos_counter",2,0,1,1); + } + + /*Makes histograms with cuts & gates implemented*/ + void SFPPlotter::MakeCutHistograms(const ProcessedEvent& ev, THashTable* table) + { + if(!cutter.IsInside(&ev)) + return; + + MyFill(table,"x1_bothplanes_Cut",600,-300,300,ev.x1); + MyFill(table,"x2_bothplanes_Cut",600,-300,300,ev.x2); + MyFill(table,"xavg_bothplanes_Cut",600,-300,300,ev.xavg); + MyFill(table,"x1_x2_Cut",600,-300,300,ev.x1, 600,-300,300,ev.x2); + MyFill(table,"xavg_theta_Cut_bothplanes",600,-300,300,ev.xavg,100,0,TMath::Pi()/2.,ev.theta); + + MyFill(table,"x1_delayBackRightE_Cut",600,-300,300,ev.x1,512,0,4096,ev.delayBackRightE); + MyFill(table,"x2_delayBackRightE_Cut",600,-300,300,ev.x2,512,0,4096,ev.delayBackRightE); + MyFill(table,"xavg_delayBackRightE_Cut",600,-300,300,ev.xavg,512,0,4096,ev.delayBackRightE); + + Double_t delayBackAvgE = (ev.delayBackRightE+ev.delayBackLeftE)/2.0; + MyFill(table,"x1_delayBackAvgE_Cut",600,-300,300,ev.x1,512,0,4096,delayBackAvgE); + MyFill(table,"x2_delayBackAvgE_Cut",600,-300,300,ev.x2,512,0,4096,delayBackAvgE); + MyFill(table,"xavg_delayBackAvgE_Cut",600,-300,300,ev.xavg,512,0,4096,delayBackAvgE); + Double_t delayFrontAvgE = (ev.delayFrontRightE+ev.delayFrontLeftE)/2.0; + MyFill(table,"x1_delayFrontAvgE_Cut",600,-300,300,ev.x1,512,0,4096,delayFrontAvgE); + MyFill(table,"x2_delayFrontAvgE_Cut",600,-300,300,ev.x2,512,0,4096,delayFrontAvgE); + MyFill(table,"xavg_delayFrontAvgE_Cut",600,-300,300,ev.xavg,512,0,4096,delayFrontAvgE); + + MyFill(table,"scintLeft_anodeBack_Cut",512,0,4096,ev.scintLeft,512,0,4096,ev.anodeBack); + MyFill(table,"scintLeft_anodeFront_Cut",512,0,4096,ev.scintLeft,512,0,4096,ev.anodeFront); + MyFill(table,"scintLeft_cathode_Cut",512,0,4096,ev.scintLeft,512,0,4096,ev.cathode); + + MyFill(table,"x1_scintLeft_Cut",600,-300,300,ev.x1,512,0,4096,ev.scintLeft); + MyFill(table,"x2_scintLeft_Cut",600,-300,300,ev.x2,512,0,4096,ev.scintLeft); + MyFill(table,"xavg_scintLeft_Cut",600,-300,300,ev.xavg,512,0,4096,ev.scintLeft); + + MyFill(table,"x1_anodeBack_Cut",600,-300,300,ev.x1,512,0,4096,ev.anodeBack); + MyFill(table,"x2_anodeBack_Cut",600,-300,300,ev.x2,512,0,4096,ev.anodeBack); + MyFill(table,"xavg_anodeBack_Cut",600,-300,300,ev.xavg,512,0,4096,ev.anodeBack); + + MyFill(table,"x1_anodeFront_Cut",600,-300,300,ev.x1,512,0,4096,ev.anodeFront); + MyFill(table,"x2_anodeFront_Cut",600,-300,300,ev.x2,512,0,4096,ev.anodeFront); + MyFill(table,"xavg_anodeFront_Cut",600,-300,300,ev.xavg,512,0,4096,ev.anodeFront); + + MyFill(table,"x1_cathode_Cut",600,-300,300,ev.x1,512,0,4096,ev.cathode); + MyFill(table,"x2_cathode_Cut",600,-300,300,ev.x2,512,0,4096,ev.cathode); + MyFill(table,"xavg_cathode_Cut",600,-300,300,ev.xavg,512,0,4096,ev.cathode); + + /****Timing relative to back anode****/ + if(ev.anodeBackTime != -1 && ev.scintLeftTime != -1) + { + Double_t anodeRelFT = ev.anodeFrontTime - ev.anodeBackTime; + Double_t anodeRelBT = ev.anodeBackTime - ev.anodeBackTime; + Double_t anodeRelFT_toScint = ev.anodeFrontTime-ev.scintLeftTime; + MyFill(table,"anodeRelBackTime_Cut",1000,-3000,3500, anodeRelBT); + MyFill(table,"anodeRelFrontTime_Cut",1000,-3000,3500, anodeRelFT); + MyFill(table,"anodeRelTime_toScint_Cut",1000,-3000,3500,anodeRelFT_toScint); + for(int i=0; i<5; i++) + { + if(ev.sabreRingE[i] != -1) + { + Double_t sabreRelRT = ev.sabreRingTime[i] - ev.anodeBackTime; + Double_t sabreRelWT = ev.sabreWedgeTime[i] - ev.anodeBackTime; + MyFill(table,"sabreRelRingTime_Cut",1000,-3000,3500, sabreRelRT); + MyFill(table,"sabreRelWedgeTime_Cut",1000,-3000,3500, sabreRelWT); + } + } + } + else + { + MyFill(table,"noscinttime_counter_Cut",2,0,1,1); + } + + for(int i=0; i<5; i++) + { + if(ev.sabreRingE[i] != -1) + { + MyFill(table,"sabreRingE_Cut",2000,0,20,ev.sabreRingE[i]); + MyFill(table,"xavg_Cut_sabrefcoinc",600,-300,300,ev.xavg); + MyFill(table,"xavg_sabreRingE_Cut",600,-300,300,ev.xavg,200,0,20,ev.sabreRingE[i]); + MyFill(table,"sabreWedgeE_Cut",2000,0,20,ev.sabreWedgeE[i]); + MyFill(table,"xavg_sabreWedgeE_Cut",600,-300,300,ev.xavg,200,0,20,ev.sabreWedgeE[i]); + } + } + } + + /*Runs a list of files given from a RunCollector class*/ + void SFPPlotter::Run(const std::vector& files, const std::string& output) + { + TFile *outfile = TFile::Open(output.c_str(), "RECREATE"); + TChain* chain = new TChain("SPSTree"); + for(unsigned int i=0; iAdd(files[i].c_str()); + chain->SetBranchAddress("event", &event_address); + THashTable* table = new THashTable(); + + long blentries = chain->GetEntries(); + long count=0, flush_val=blentries*m_progressFraction, flush_count=0; + + + for(long i=0; iGetEntries(); i++) + { + count++; + if(count == flush_val) + { + flush_count++; + count=0; + m_progressCallback(flush_count*flush_val, blentries); + } + chain->GetEntry(i); + MakeUncutHistograms(*event_address, table); + if(cutter.IsValid()) MakeCutHistograms(*event_address, table); + } + outfile->cd(); + table->Write(); + if(cutter.IsValid()) + { + auto clist = cutter.GetCuts(); + for(unsigned int i=0; iWrite(); + } + delete table; + outfile->Close(); + delete outfile; + } -/*2D histogram fill wrapper*/ -void SFPPlotter::MyFill(const string& name, int binsx, double minx, double maxx, double valuex, - int binsy, double miny, double maxy, double valuey) { - TH2F *histo = (TH2F*) rootObj->FindObject(name.c_str()); - if(histo != NULL) { - histo->Fill(valuex, valuey); - } else { - TH2F *h = new TH2F(name.c_str(), name.c_str(), binsx, minx, maxx, binsy, miny, maxy); - h->Fill(valuex, valuey); - rootObj->Add(h); - } -} - -/*1D histogram fill wrapper*/ -void SFPPlotter::MyFill(const string& name, int binsx, double minx, double maxx, double valuex) { - TH1F *histo = (TH1F*) rootObj->FindObject(name.c_str()); - if(histo != NULL) { - histo->Fill(valuex); - } else { - TH1F *h = new TH1F(name.c_str(), name.c_str(), binsx, minx, maxx); - h->Fill(valuex); - rootObj->Add(h); - } -} - -void SFPPlotter::ApplyCutlist(const string& listname) { - cutter.SetCuts(listname); -} - -/*Makes histograms where only rejection is unset data*/ -void SFPPlotter::MakeUncutHistograms(ProcessedEvent ev) { - MyFill("x1NoCuts_bothplanes",600,-300,300,ev.x2); - MyFill("x2NoCuts_bothplanes",600,-300,300,ev.x2); - MyFill("xavgNoCuts_bothplanes",600,-300,300,ev.xavg); - MyFill("xavgNoCuts_theta_bothplanes",600,-300,300,ev.xavg,100,0,TMath::Pi()/2.,ev.theta); - - MyFill("x1_delayBackRightE_NoCuts",600,-300,300,ev.x1,512,0,4096,ev.delayBackRightE); - MyFill("x2_delayBackRightE_NoCuts",600,-300,300,ev.x2,512,0,4096,ev.delayBackRightE); - MyFill("xavg_delayBackRightE_NoCuts",600,-300,300,ev.xavg,512,0,4096,ev.delayBackRightE); - MyFill("x1_x2_NoCuts",600,-300,300,ev.x1,600,-300,300,ev.x2); - - Double_t delayBackAvgE = (ev.delayBackRightE+ev.delayBackLeftE)/2.0; - MyFill("x1_delayBackAvgE_NoCuts",600,-300,300,ev.x1,512,0,4096,delayBackAvgE); - MyFill("x2_delayBackAvgE_NoCuts",600,-300,300,ev.x2,512,0,4096,delayBackAvgE); - MyFill("xavg_delayBackAvgE_NoCuts",600,-300,300,ev.xavg,512,0,4096,delayBackAvgE); - Double_t delayFrontAvgE = (ev.delayFrontRightE+ev.delayFrontLeftE)/2.0; - MyFill("x1_delayFrontAvgE_NoCuts",600,-300,300,ev.x1,512,0,4096,delayFrontAvgE); - MyFill("x2_delayFrontAvgE_NoCuts",600,-300,300,ev.x2,512,0,4096,delayFrontAvgE); - MyFill("xavg_delayFrontAvgE_NoCuts",600,-300,300,ev.xavg,512,0,4096,delayFrontAvgE); - - MyFill("scintLeft_anodeBack_NoCuts",512,0,4096,ev.scintLeft,512,0,4096,ev.anodeBack); - MyFill("scintLeft_anodeFront_NoCuts",512,0,4096,ev.scintLeft,512,0,4096,ev.anodeFront); - MyFill("scintLeft_cathode_NoCuts",512,0,4096,ev.scintLeft,512,0,4096,ev.cathode); - - MyFill("x1_scintLeft_NoCuts",600,-300,300,ev.x1,512,0,4096,ev.scintLeft); - MyFill("x2_scintLeft_NoCuts",600,-300,300,ev.x2,512,0,4096,ev.scintLeft); - MyFill("xavg_scintLeft_NoCuts",600,-300,300,ev.xavg,512,0,4096,ev.scintLeft); - - MyFill("x1_anodeBack_NoCuts",600,-300,300,ev.x1,512,0,4096,ev.anodeBack); - MyFill("x2_anodeBack_NoCuts",600,-300,300,ev.x2,512,0,4096,ev.anodeBack); - MyFill("xavg_anodeBack_NoCuts",600,-300,300,ev.xavg,512,0,4096,ev.anodeBack); - - MyFill("x1_anodeFront_NoCuts",600,-300,300,ev.x1,512,0,4096,ev.anodeFront); - MyFill("x2_anodeFront_NoCuts",600,-300,300,ev.x2,512,0,4096,ev.anodeFront); - MyFill("xavg_anodeFront_NoCuts",600,-300,300,ev.xavg,512,0,4096,ev.anodeFront); - - MyFill("x1_cathode_NoCuts",600,-300,300,ev.x1,512,0,4096,ev.cathode); - MyFill("x2_cathode_NoCuts",600,-300,300,ev.x2,512,0,4096,ev.cathode); - MyFill("xavg_cathode_NoCuts",600,-300,300,ev.xavg,512,0,4096,ev.cathode); - - /****Timing relative to back anode****/ - if(ev.anodeBackTime != -1 && ev.scintLeftTime != -1) { - Double_t anodeRelFT = ev.anodeFrontTime - ev.anodeBackTime; - Double_t delayRelFT = ev.delayFrontMaxTime - ev.anodeBackTime; - Double_t delayRelBT = ev.delayBackMaxTime - ev.anodeBackTime; - Double_t anodeRelBT = ev.anodeBackTime - ev.scintLeftTime; - Double_t delayRelFT_toScint = ev.delayFrontMaxTime - ev.scintLeftTime; - Double_t delayRelBT_toScint = ev.delayBackMaxTime - ev.scintLeftTime; - MyFill("anodeRelFrontTime_NoCuts",1000,-3000,3500, anodeRelFT); - MyFill("delayRelFrontTime_NoCuts",1000,-3000,-3500,delayRelFT); - MyFill("delayRelBackTime_NoCuts",1000,-3000,-3500,delayRelBT); - for(int i=0; i<5; i++) { - if(ev.sabreRingE[i] != -1) { - Double_t sabreRelRT = ev.sabreRingTime[i] - ev.anodeBackTime; - Double_t sabreRelWT = ev.sabreWedgeTime[i] - ev.anodeBackTime; - Double_t sabreRelRT_toScint = ev.sabreRingTime[i] - ev.scintLeftTime; - Double_t sabreRelWT_toScint = ev.sabreWedgeTime[i] - ev.scintLeftTime; - MyFill("xavg_sabrefcoinc_NoCuts",600,-300,300, ev.xavg); - MyFill("sabreRelRingTime_NoCuts",1000,-3000,3500, sabreRelRT); - MyFill("sabreRelWedgeTime_NoCuts",1000,-3000,3500, sabreRelWT); - MyFill("sabreRelRingTime_toScint",1000,-3000,3500,sabreRelRT_toScint); - MyFill("sabreRelWedgeTime_toScint",1000,-3000,3500,sabreRelWT_toScint); - MyFill("sabreRelRTScint_sabreRelRTAnode",500,-3000,3500,sabreRelRT_toScint,500,-3000,3500,sabreRelRT); - MyFill("sabreRelRTScint_sabreRingChannel",500,-3000,3500,sabreRelRT_toScint,144,0,144,ev.sabreRingChannel[i]); - MyFill("sabreRelRTAnode_sabreRingChannel",500,-3000,3500,sabreRelRT,144,0,144,ev.sabreRingChannel[i]); - MyFill("sabreRelWTScint_sabreWedgeChannel",500,-3000,3500,sabreRelWT_toScint,144,0,144,ev.sabreWedgeChannel[i]); - MyFill("sabreRelRT_sabreRelWT",500,-3000,3500,sabreRelRT,500,-3000,3500,sabreRelWT); - MyFill("sabreRelRT_sabreRelWT_scint",500,-3000,3500,sabreRelRT_toScint,500,-3000,3500,sabreRelWT_toScint); - MyFill("sabreRelRTScint_anodeRelT",500,-3000,3500,sabreRelRT_toScint,500,-3000,3500,anodeRelBT); - } - } - MyFill("anodeBackRelTime_toScint",1000,-3000,3500,anodeRelBT); - MyFill("delayRelBackTime_toScint",1000,-3000,3500,delayRelBT_toScint); - MyFill("delayRelFrontTime_toScint",1000,-3000,3500,delayRelFT_toScint); - } else { - MyFill("noscinttime_counter_NoCuts",2,0,1,1); - } - - int count = 0; - for(int i=0; i<5; i++) { - if(ev.sabreRingE[i] != -1) { //Again, at this point front&back are required - MyFill("sabreRingE_NoCuts",2000,0,20,ev.sabreRingE[i]); - MyFill("sabreRingChannel_sabreRingE_NoCuts",144,0,144,ev.sabreRingChannel[i],200,0,20,ev.sabreRingE[i]); - MyFill("sabreWedgeE_NoCuts",2000,0,20,ev.sabreWedgeE[i]); - MyFill("sabreWedgeChannel_sabreWedgeE_NoCuts",144,0,144,ev.sabreWedgeChannel[i],200,0,20,ev.sabreWedgeE[i]); - } else { - count++; - } - } - if(count == 80) { - MyFill("xavg_bothplanes_sabreanticoinc_NoCuts",600,-300,300,ev.xavg); - } - if(ev.x1 != -1e6 && ev.x2 == -1e6) { - MyFill("x1NoCuts_only1plane",600,-300,300,ev.x1); - } else if(ev.x2 != -1e6 && ev.x1 == -1e6) { - MyFill("x2NoCuts_only1plane",600,-300,300,ev.x2); - } else if(ev.x1 == -1e6 && ev.x2 == -1e6) { - MyFill("nopos_counter",2,0,1,1); - } -} - -/*Makes histograms with cuts & gates implemented*/ -void SFPPlotter::MakeCutHistograms(ProcessedEvent ev) { - if(cutter.IsInside(&ev)) { - MyFill("x1_bothplanes_Cut",600,-300,300,ev.x1); - MyFill("x2_bothplanes_Cut",600,-300,300,ev.x2); - MyFill("xavg_bothplanes_Cut",600,-300,300,ev.xavg); - MyFill("x1_x2_Cut",600,-300,300,ev.x1, 600,-300,300,ev.x2); - MyFill("xavg_theta_Cut_bothplanes",600,-300,300,ev.xavg,100,0,TMath::Pi()/2.,ev.theta); - - MyFill("x1_delayBackRightE_Cut",600,-300,300,ev.x1,512,0,4096,ev.delayBackRightE); - MyFill("x2_delayBackRightE_Cut",600,-300,300,ev.x2,512,0,4096,ev.delayBackRightE); - MyFill("xavg_delayBackRightE_Cut",600,-300,300,ev.xavg,512,0,4096,ev.delayBackRightE); - - Double_t delayBackAvgE = (ev.delayBackRightE+ev.delayBackLeftE)/2.0; - MyFill("x1_delayBackAvgE_Cut",600,-300,300,ev.x1,512,0,4096,delayBackAvgE); - MyFill("x2_delayBackAvgE_Cut",600,-300,300,ev.x2,512,0,4096,delayBackAvgE); - MyFill("xavg_delayBackAvgE_Cut",600,-300,300,ev.xavg,512,0,4096,delayBackAvgE); - Double_t delayFrontAvgE = (ev.delayFrontRightE+ev.delayFrontLeftE)/2.0; - MyFill("x1_delayFrontAvgE_Cut",600,-300,300,ev.x1,512,0,4096,delayFrontAvgE); - MyFill("x2_delayFrontAvgE_Cut",600,-300,300,ev.x2,512,0,4096,delayFrontAvgE); - MyFill("xavg_delayFrontAvgE_Cut",600,-300,300,ev.xavg,512,0,4096,delayFrontAvgE); - - MyFill("scintLeft_anodeBack_Cut",512,0,4096,ev.scintLeft,512,0,4096,ev.anodeBack); - MyFill("scintLeft_anodeFront_Cut",512,0,4096,ev.scintLeft,512,0,4096,ev.anodeFront); - MyFill("scintLeft_cathode_Cut",512,0,4096,ev.scintLeft,512,0,4096,ev.cathode); - - MyFill("x1_scintLeft_Cut",600,-300,300,ev.x1,512,0,4096,ev.scintLeft); - MyFill("x2_scintLeft_Cut",600,-300,300,ev.x2,512,0,4096,ev.scintLeft); - MyFill("xavg_scintLeft_Cut",600,-300,300,ev.xavg,512,0,4096,ev.scintLeft); - - MyFill("x1_anodeBack_Cut",600,-300,300,ev.x1,512,0,4096,ev.anodeBack); - MyFill("x2_anodeBack_Cut",600,-300,300,ev.x2,512,0,4096,ev.anodeBack); - MyFill("xavg_anodeBack_Cut",600,-300,300,ev.xavg,512,0,4096,ev.anodeBack); - - MyFill("x1_anodeFront_Cut",600,-300,300,ev.x1,512,0,4096,ev.anodeFront); - MyFill("x2_anodeFront_Cut",600,-300,300,ev.x2,512,0,4096,ev.anodeFront); - MyFill("xavg_anodeFront_Cut",600,-300,300,ev.xavg,512,0,4096,ev.anodeFront); - - MyFill("x1_cathode_Cut",600,-300,300,ev.x1,512,0,4096,ev.cathode); - MyFill("x2_cathode_Cut",600,-300,300,ev.x2,512,0,4096,ev.cathode); - MyFill("xavg_cathode_Cut",600,-300,300,ev.xavg,512,0,4096,ev.cathode); - - /****Timing relative to back anode****/ - if(ev.anodeBackTime != -1 && ev.scintLeftTime != -1) { - Double_t anodeRelFT = ev.anodeFrontTime - ev.anodeBackTime; - Double_t anodeRelBT = ev.anodeBackTime - ev.anodeBackTime; - Double_t anodeRelFT_toScint = ev.anodeFrontTime-ev.scintLeftTime; - MyFill("anodeRelBackTime_Cut",1000,-3000,3500, anodeRelBT); - MyFill("anodeRelFrontTime_Cut",1000,-3000,3500, anodeRelFT); - MyFill("anodeRelTime_toScint_Cut",1000,-3000,3500,anodeRelFT_toScint); - for(int i=0; i<5; i++) { - if(ev.sabreRingE[i] != -1) { - Double_t sabreRelRT = ev.sabreRingTime[i] - ev.anodeBackTime; - Double_t sabreRelWT = ev.sabreWedgeTime[i] - ev.anodeBackTime; - MyFill("sabreRelRingTime_Cut",1000,-3000,3500, sabreRelRT); - MyFill("sabreRelWedgeTime_Cut",1000,-3000,3500, sabreRelWT); - } - } - } else { - MyFill("noscinttime_counter_Cut",2,0,1,1); - } - - int count = 0; - for(int i=0; i<5; i++) { - if(ev.sabreRingE[i] != -1) { - MyFill("sabreRingE_Cut",2000,0,20,ev.sabreRingE[i]); - MyFill("xavg_Cut_sabrefcoinc",600,-300,300,ev.xavg); - MyFill("xavg_sabreRingE_Cut",600,-300,300,ev.xavg,200,0,20,ev.sabreRingE[i]); - MyFill("sabreWedgeE_Cut",2000,0,20,ev.sabreWedgeE[i]); - MyFill("xavg_sabreWedgeE_Cut",600,-300,300,ev.xavg,200,0,20,ev.sabreWedgeE[i]); - } else { - count++; - } - } - if(count == 80) { - MyFill("xavg_bothplanes_sabreanticoinc_Cut",600,-300,300,ev.xavg); - } - } -} - -/*Runs a list of files given from a RunMusher/Collector class*/ -void SFPPlotter::Run(vector files, const string& output) { - Chain(files); - chain->SetBranchAddress("event", &event_address); - TFile *outfile = new TFile(output.c_str(), "RECREATE"); - - long blentries = chain->GetEntries(); - if(m_pb) SetProgressBar(blentries); - cout<<"Total number of events: "<GetEntries(); i++) { - count++; - if(count == flush) { - if(m_pb) { - m_pb->Increment(count); - gSystem->ProcessEvents(); - count = 0; - } else { - nflushes++; - count=0; - std::cout<<"\rPercent of data processed: "<GetEntry(i); - MakeUncutHistograms(*event_address); - if(cutter.IsValid()) MakeCutHistograms(*event_address); - } - cout<cd(); - rootObj->Write(); - if(cutter.IsValid()) { - auto clist = cutter.GetCuts(); - for(unsigned int i=0; iWrite(); - } - } - delete rootObj; - outfile->Close(); - delete outfile; -} - -/*Link all files*/ -void SFPPlotter::Chain(vector files) { - for(unsigned int i=0; iAdd(files[i]); - } -} - - -void SFPPlotter::SetProgressBar(long total) { - m_pb->SetMax(total); - m_pb->SetMin(0); - m_pb->SetPosition(0); - gSystem->ProcessEvents(); -} +} \ No newline at end of file diff --git a/src/evb/SFPPlotter.h b/src/evb/SFPPlotter.h new file mode 100644 index 0000000..a62e85c --- /dev/null +++ b/src/evb/SFPPlotter.h @@ -0,0 +1,50 @@ +/*SFPPlotter.h + *Class for generating histogram files for SPS-SABRE data + *Intended use case is generating a TChain of multiple analyzed files and making + *histograms of the larger data set. + * + *Created Jan 2020 by GWM + */ + +#ifndef SFPCLEANER_H +#define SFPCLEANER_H + +#include "DataStructs.h" +#include "ProgressCallback.h" +#include "CutHandler.h" + +namespace EventBuilder { + + class SFPPlotter + { + public: + SFPPlotter(); + ~SFPPlotter(); + inline void ApplyCutlist(const std::string& listname) { cutter.SetCuts(listname); } + void Run(const std::vector& files, const std::string& output); + inline void SetProgressCallbackFunc(const ProgressCallbackFunc& function) { m_progressCallback = function; } + inline void SetProgressFraction(double frac) { m_progressFraction = frac; } + + private: + void Chain(const std::vector& files); //Form TChain + void MakeUncutHistograms(const ProcessedEvent& ev, THashTable* table); + void MakeCutHistograms(const ProcessedEvent& ev, THashTable* table); + + /*Histogram fill wrapper functions*/ + void MyFill(THashTable* table, const std::string& name, int binsx, double minx, double maxx, double valuex, + int binsy, double miny, double maxy, double valuey); + void MyFill(THashTable* table, const std::string& name, int binsx, double minx, double maxx, double valuex); + + ProcessedEvent *event_address; + + /*Cuts*/ + CutHandler cutter; + + ProgressCallbackFunc m_progressCallback; + double m_progressFraction; + + }; + +} + +#endif diff --git a/src/evb/ShiftMap.cpp b/src/evb/ShiftMap.cpp index 4a412e8..91b8eda 100644 --- a/src/evb/ShiftMap.cpp +++ b/src/evb/ShiftMap.cpp @@ -12,58 +12,74 @@ #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; + ShiftMap::ShiftMap() : + m_filename(""), m_validFlag(false) + { + } - 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; + ShiftMap::ShiftMap(const std::string& filename) : + m_filename(filename), m_validFlag(false) + { + ParseFile(); + } + + ShiftMap::~ShiftMap() {} + + void ShiftMap::SetFile(const std::string& filename) + { + m_filename = filename; + ParseFile(); + } + + uint64_t ShiftMap::GetShift(int gchan) + { + if(!m_validFlag) + return 0; + + auto iter = m_map.find(gchan); + if(iter == m_map.end()) + return 0; + else + return iter->second; + } + + void ShiftMap::ParseFile() + { + m_validFlag = false; + std::ifstream input(m_filename); + if(!input.is_open()) + return; + + int board, channel, gchan; + uint64_t shift; + std::string junk, temp; + + std::getline(input, junk); + std::getline(input, junk); + + while(input>>board) + { + input>>temp; + input>>shift; + if(temp == "all") //keyword to set all channels in this board to same shift + { + for(int i=0; i<16; i++) + { + gchan = board*16 + i; + m_map[gchan] = shift; + } + } + else + { + channel = stoi(temp); + gchan = channel + board*16; m_map[gchan] = shift; } - } else { - channel = stoi(temp); - gchan = channel + board*16; - m_map[gchan] = shift; } + + m_validFlag = true; } - is_set = true; -} +} \ No newline at end of file diff --git a/include/ShiftMap.h b/src/evb/ShiftMap.h similarity index 51% rename from include/ShiftMap.h rename to src/evb/ShiftMap.h index 64eea5e..b13dfb5 100644 --- a/include/ShiftMap.h +++ b/src/evb/ShiftMap.h @@ -12,24 +12,29 @@ #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 IsValid() { return m_validFlag; } + inline std::string GetFilename() { return m_filename; } + uint64_t GetShift(int gchan); + + private: + void ParseFile(); + + std::string m_filename; + bool m_validFlag; + + std::unordered_map m_map; + + }; - std::string m_filename; - bool is_set; - - std::unordered_map m_map; - -}; +} #endif diff --git a/src/evb/SlowSort.cpp b/src/evb/SlowSort.cpp index 8daefa7..85edd47 100644 --- a/src/evb/SlowSort.cpp +++ b/src/evb/SlowSort.cpp @@ -10,157 +10,167 @@ #include "EventBuilder.h" #include "SlowSort.h" -/*Sort the Sabre Data in order of descending energy*/ -bool SabreSort(DetectorHit i, DetectorHit j) { - return (i.Long>j.Long); -} +namespace EventBuilder { -/*Constructor takes input of coincidence window size, and fills sabre channel map*/ -SlowSort::SlowSort() : - coincWindow(-1.0), eventFlag(false), event(), cmap() -{ - event_stats = new TH2F("coinc_event_stats","coinc_events_stats;global channel;number of coincident hits;counts",144,0,144,20,0,20); -} + /*Sort the Sabre Data in order of descending energy*/ + bool SabreSort(const DetectorHit& i, const DetectorHit& j) { + return (i.Long>j.Long); + } + + /*Constructor takes input of coincidence window size, and fills sabre channel map*/ + SlowSort::SlowSort() : + m_coincWindow(-1.0), m_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, const std::string& mapfile) : + m_coincWindow(windowSize), m_eventFlag(false), m_event(), cmap(mapfile) + { + event_stats = new TH2F("coinc_event_stats","coinc_events_stats;global channel;number of coincident hits;counts",144,0,144,20,0,20); + InitVariableMaps(); + } + + SlowSort::~SlowSort() {} + + /**EXPERIMENT MODS go here**/ + void SlowSort::InitVariableMaps() + { + + /*For SABRE: Each SABRE det has ring&wedge, so add the detID to the + SABRERING/WEDGE attribute to differentiate*/ + varMap[DetAttribute::SabreRing0] = &m_event.sabreArray[0].rings; + varMap[DetAttribute::SabreRing1] = &m_event.sabreArray[1].rings; + varMap[DetAttribute::SabreRing2] = &m_event.sabreArray[2].rings; + varMap[DetAttribute::SabreRing3] = &m_event.sabreArray[3].rings; + varMap[DetAttribute::SabreRing4] = &m_event.sabreArray[4].rings; + varMap[DetAttribute::SabreWedge0] = &m_event.sabreArray[0].wedges; + varMap[DetAttribute::SabreWedge1] = &m_event.sabreArray[1].wedges; + varMap[DetAttribute::SabreWedge2] = &m_event.sabreArray[2].wedges; + varMap[DetAttribute::SabreWedge3] = &m_event.sabreArray[3].wedges; + varMap[DetAttribute::SabreWedge4] = &m_event.sabreArray[4].wedges; + + /*For focal plane: Only one focal plane, so each variable is uniquely + identified by its attribute + */ + varMap[DetAttribute::ScintLeft] = &m_event.focalPlane.scintL; + varMap[DetAttribute::ScintRight] = &m_event.focalPlane.scintR; + varMap[DetAttribute::Cathode] = &m_event.focalPlane.cathode; + varMap[DetAttribute::DelayFR] = &m_event.focalPlane.delayFR; + varMap[DetAttribute::DelayFL] = &m_event.focalPlane.delayFL; + varMap[DetAttribute::DelayBL] = &m_event.focalPlane.delayBL; + varMap[DetAttribute::DelayBR] = &m_event.focalPlane.delayBR; + varMap[DetAttribute::AnodeFront] = &m_event.focalPlane.anodeF; + varMap[DetAttribute::AnodeBack] = &m_event.focalPlane.anodeB; + varMap[DetAttribute::Monitor] = &m_event.focalPlane.monitor; + + } + + /*Reset output structure to blank*/ + void SlowSort::Reset() + { + m_event = m_blank; + } + + bool SlowSort::AddHitToEvent(CompassHit& mhit) + { + DPPChannel curHit; + curHit.Timestamp = mhit.timestamp; + curHit.Energy = mhit.lgate; + curHit.EnergyShort = mhit.sgate; + curHit.Channel = mhit.channel; + curHit.Board = mhit.board; + curHit.Flags = mhit.flags; + + if(m_hitList.empty()) + { + startTime = curHit.Timestamp; + m_hitList.push_back(curHit); + } + else if (curHit.Timestamp < previousHitTime) + return false; + else if ((curHit.Timestamp - startTime) < m_coincWindow) + m_hitList.push_back(curHit); + else + { + ProcessEvent(); + m_hitList.clear(); + startTime = curHit.Timestamp; + m_hitList.push_back(curHit); + m_eventFlag = true; + } + + return true; + } + + void SlowSort::FlushHitsToEvent() + { + if(m_hitList.empty()) + { + m_eventFlag = false; + return; + } + + ProcessEvent(); + m_hitList.clear(); + m_eventFlag = true; + } + + const CoincEvent& SlowSort::GetEvent() + { + m_eventFlag = false; + return m_event; + } + + /*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() + { + Reset(); + DetectorHit dhit; + int gchan; + int size = m_hitList.size(); + for(DPPChannel& curHit: m_hitList) + { + gchan = curHit.Channel + curHit.Board*16; //global channel + event_stats->Fill(gchan, size); + dhit.Time = curHit.Timestamp/1.0e3; + dhit.Ch = gchan; + dhit.Long = curHit.Energy; + dhit.Short = curHit.EnergyShort; + auto channel_info = cmap.FindChannel(gchan); + + if(channel_info == cmap.End()) + { + EVB_WARN("At SlowSort::ProcessEvent() -- Data Assignment Error! Global channel {0} found but not assigned in ChannelMap! Skipping data.",gchan); + continue; + } + + if(channel_info->second.type == DetType::FocalPlane) + { + auto variable = varMap.find(channel_info->second.attribute); + if(variable != varMap.end()) + variable->second->push_back(dhit); + } + else if(channel_info->second.type == DetType::Sabre) + { + auto variable = varMap.find(channel_info->second.attribute); + if(variable != varMap.end()) + variable->second->push_back(dhit); + } + else + { + EVB_WARN("At SlowSort::ProcessEvent() -- Data Assignment Error! Channel ({0}, {1}, {2}) exists in ChannelMap, but does not have an assigned variable! Skipping data.", + gchan, channel_info->second.type, channel_info->second.attribute); + } + } + //Organize the SABRE data in descending energy order + for(int s=0; s<5; s++) + { + sort(m_event.sabreArray[s].rings.begin(), m_event.sabreArray[s].rings.end(), SabreSort); + sort(m_event.sabreArray[s].wedges.begin(), m_event.sabreArray[s].wedges.end(), SabreSort); + } + } -SlowSort::SlowSort(double windowSize, const string& mapfile) : - coincWindow(windowSize), eventFlag(false), event(), cmap(mapfile) -{ - event_stats = new TH2F("coinc_event_stats","coinc_events_stats;global channel;number of coincident hits;counts",144,0,144,20,0,20); - InitVariableMaps(); -} - -SlowSort::~SlowSort() { -} - -/**EXPERIMENT MODS go here**/ -void SlowSort::InitVariableMaps() { - - /*For SABRE: Each SABRE det has ring&wedge, so add the detID to the - SABRERING/WEDGE attribute to differentiate*/ - for(int i=0; i<5; i++) { - sabreVMap[SABRERING + i] = &event.sabreArray[i].rings; - sabreVMap[SABREWEDGE + i] = &event.sabreArray[i].wedges; - } - - /*For focal plane: Only one focal plane, so each variable is uniquely - identified by its attribute - */ - fpVMap[SCINTLEFT] = &event.focalPlane.scintL; - fpVMap[SCINTRIGHT] = &event.focalPlane.scintR; - fpVMap[CATHODE] = &event.focalPlane.cathode; - fpVMap[DELAYFR] = &event.focalPlane.delayFR; - fpVMap[DELAYFL] = &event.focalPlane.delayFL; - fpVMap[DELAYBL] = &event.focalPlane.delayBL; - fpVMap[DELAYBR] = &event.focalPlane.delayBR; - fpVMap[ANODEFRONT] = &event.focalPlane.anodeF; - fpVMap[ANODEBACK] = &event.focalPlane.anodeB; - fpVMap[MONITOR] = &event.focalPlane.monitor; - -} - -/*Reset output structure to blank*/ -void SlowSort::Reset() { - event = blank; -} - -bool SlowSort::AddHitToEvent(CompassHit& mhit) { - DPPChannel curHit; - curHit.Timestamp = mhit.timestamp; - curHit.Energy = mhit.lgate; - curHit.EnergyShort = mhit.sgate; - curHit.Channel = mhit.channel; - curHit.Board = mhit.board; - curHit.Flags = mhit.flags; - - 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; -} - -CoincEvent 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."<Fill(gchan, size); - dhit.Time = curHit.Timestamp/1.0e3; - dhit.Ch = gchan; - dhit.Long = curHit.Energy; - dhit.Short = curHit.EnergyShort; - auto channel_info = cmap.FindChannel(gchan); - if(channel_info == cmap.End()) { - continue; - } - if(channel_info->second.detectorType == SABRERING || channel_info->second.detectorType == SABREWEDGE) { - - auto variable = sabreVMap.find(channel_info->second.detectorType + channel_info->second.detectorID); - if(variable != sabreVMap.end()) { - variable->second->push_back(dhit); - } - - } else if(channel_info->second.detectorType == FOCALPLANE) { - - auto variable = fpVMap.find(channel_info->second.detectorPart); - if(variable != fpVMap.end()) { - variable->second->push_back(dhit); - } - - } else { - std::cout<second.detectorType< +#include + +namespace EventBuilder { + + class SlowSort + { + + public: + SlowSort(); + SlowSort(double windowSize, const std::string& mapfile); + ~SlowSort(); + inline void SetWindowSize(double window) { m_coincWindow = window; } + inline bool SetMapFile(const std::string& mapfile) { return cmap.FillMap(mapfile); } + bool AddHitToEvent(CompassHit& mhit); + const CoincEvent& GetEvent(); + inline TH2F* GetEventStats() { return event_stats; } + void FlushHitsToEvent(); //For use with *last* hit list + inline bool IsEventReady() { return m_eventFlag; } + + private: + void InitVariableMaps(); + void Reset(); + void ProcessEvent(); + + double m_coincWindow; + std::vector m_hitList; + bool m_eventFlag; + CoincEvent m_event; + CoincEvent m_blank; + + double startTime, previousHitTime; + std::unordered_map*> varMap; + + TH2F* event_stats; + + ChannelMap cmap; + + }; + +} + +#endif diff --git a/src/evb/Stopwatch.cpp b/src/evb/Stopwatch.cpp index e607529..95feb6e 100644 --- a/src/evb/Stopwatch.cpp +++ b/src/evb/Stopwatch.cpp @@ -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; + } + + Stopwatch::~Stopwatch() {} + + void Stopwatch::Start() + { + start_time = Clock::now(); + } + + void Stopwatch::Stop() + { + stop_time = Clock::now(); + } + + double Stopwatch::GetElapsedSeconds() + { + return std::chrono::duration_cast>(stop_time-start_time).count(); + } + + double Stopwatch::GetElapsedMilliseconds() + { + return std::chrono::duration_cast>(stop_time-start_time).count()*1000.0; + } -void Stopwatch::Start() { - start_time = Clock::now(); -} - -void Stopwatch::Stop() { - stop_time = Clock::now(); -} - -double Stopwatch::GetElapsedSeconds() { - return std::chrono::duration_cast>(stop_time-start_time).count(); -} - -double Stopwatch::GetElapsedMilliseconds() { - return std::chrono::duration_cast>(stop_time-start_time).count()*1000.0; } \ No newline at end of file diff --git a/src/evb/Stopwatch.h b/src/evb/Stopwatch.h new file mode 100644 index 0000000..1242e46 --- /dev/null +++ b/src/evb/Stopwatch.h @@ -0,0 +1,34 @@ +/* + 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 + +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 \ No newline at end of file diff --git a/src/gui/EVBMainFrame.cpp b/src/gui/EVBMainFrame.cpp deleted file mode 100644 index 3da6d35..0000000 --- a/src/gui/EVBMainFrame.cpp +++ /dev/null @@ -1,468 +0,0 @@ -#include "EventBuilder.h" -#include "EVBMainFrame.h" -#include "FileViewFrame.h" -#include -#include -#include -#include - -EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) : - TGMainFrame(p, w, h, kVerticalFrame) -{ - SetCleanup(kDeepCleanup); - MAIN_W = w; MAIN_H = h; - - //Organization hints - TGLayoutHints *fchints = new TGLayoutHints(kLHintsExpandX|kLHintsExpandY,5,5,5,5); - TGLayoutHints *fhints = new TGLayoutHints(kLHintsExpandX|kLHintsCenterY,5,5,5,5); - TGLayoutHints *lhints = new TGLayoutHints(kLHintsCenterY|kLHintsLeft,5,5,5,5); - TGLayoutHints *bhints = new TGLayoutHints(kLHintsLeft|kLHintsCenterY,5,5,5,5); - TGLayoutHints *fpbhints = new TGLayoutHints(kLHintsExpandX|kLHintsBottom,5,5,5,5); - TGLayoutHints *mhints = new TGLayoutHints(kLHintsTop|kLHintsLeft,0,4,0,0); - - //Make the containers and link up all signals/slots - - TGVerticalFrame *InputFrame = new TGVerticalFrame(this, w, h*0.9); - - TGVerticalFrame *NameFrame = new TGVerticalFrame(InputFrame, w, h*0.4); - - TGHorizontalFrame *WorkFrame = new TGHorizontalFrame(NameFrame, w, h*0.1); - TGLabel* workLabel = new TGLabel(WorkFrame, "Workspace Directory:"); - fWorkField = new TGTextEntry(WorkFrame, new TGTextBuffer(120), WORKDIR); - fWorkField->Resize(w*0.25, fWorkField->GetDefaultHeight()); - fWorkField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateWorkdir()"); - fOpenWorkButton = new TGTextButton(WorkFrame, "Open"); - fOpenWorkButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenWorkdir()"); - WorkFrame->AddFrame(workLabel, lhints); - WorkFrame->AddFrame(fWorkField, fhints); - WorkFrame->AddFrame(fOpenWorkButton, bhints); - - TGHorizontalFrame *CMapFrame = new TGHorizontalFrame(NameFrame, w, h*0.1); - TGLabel* cmaplabel = new TGLabel(CMapFrame, "Channel Map File:"); - fCMapField = new TGTextEntry(CMapFrame, new TGTextBuffer(120), CMAP); - fCMapField->Resize(w*0.25, fCMapField->GetDefaultHeight()); - fCMapField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateCMap()"); - fOpenCMapButton = new TGTextButton(CMapFrame, "Open"); - fOpenCMapButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenCMapfile()"); - CMapFrame->AddFrame(cmaplabel, lhints); - CMapFrame->AddFrame(fCMapField, fhints); - CMapFrame->AddFrame(fOpenCMapButton, bhints); - - TGHorizontalFrame *SMapFrame = new TGHorizontalFrame(NameFrame, w, h*0.1); - TGLabel* smaplabel = new TGLabel(SMapFrame, "Board Shift File:"); - fSMapField = new TGTextEntry(SMapFrame, new TGTextBuffer(120), SMAP); - fSMapField->Resize(w*0.25, fSMapField->GetDefaultHeight()); - fSMapField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateSMap()"); - fOpenSMapButton = new TGTextButton(SMapFrame, "Open"); - fOpenSMapButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenSMapfile()"); - SMapFrame->AddFrame(smaplabel, lhints); - SMapFrame->AddFrame(fSMapField, fhints); - SMapFrame->AddFrame(fOpenSMapButton, bhints); - - TGHorizontalFrame *ScalerFrame = new TGHorizontalFrame(NameFrame, w, h*0.1); - TGLabel* sclabel = new TGLabel(ScalerFrame, "Scaler File: "); - fScalerField = new TGTextEntry(ScalerFrame, new TGTextBuffer(120), SCALER); - fScalerField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateScaler()"); - fOpenScalerButton = new TGTextButton(ScalerFrame, "Open"); - fOpenScalerButton->Connect("Clicked()","EVBMainFrame", this, "DoOpenScalerfile()"); - ScalerFrame->AddFrame(sclabel, lhints); - ScalerFrame->AddFrame(fScalerField, fhints); - ScalerFrame->AddFrame(fOpenScalerButton, bhints); - - TGHorizontalFrame *CutFrame = new TGHorizontalFrame(NameFrame, w, h*0.1); - TGLabel* clabel = new TGLabel(CutFrame, "Cut List: "); - fCutField = new TGTextEntry(CutFrame, new TGTextBuffer(120), CUT); - fCutField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateCut()"); - fOpenCutButton = new TGTextButton(CutFrame, "Open"); - fOpenCutButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenCutfile()"); - CutFrame->AddFrame(clabel, lhints); - CutFrame->AddFrame(fCutField, fhints); - CutFrame->AddFrame(fOpenCutButton, bhints); - - NameFrame->AddFrame(WorkFrame, fhints); - NameFrame->AddFrame(CMapFrame, fhints); - NameFrame->AddFrame(SMapFrame, fhints); - NameFrame->AddFrame(ScalerFrame, fhints); - NameFrame->AddFrame(CutFrame, fhints); - - - TGHorizontalFrame *ParamFrame = new TGHorizontalFrame(InputFrame, w, h*0.1); - TGLabel *bkelabel = new TGLabel(ParamFrame, "Beam KE (MeV):"); - fBKEField = new TGNumberEntryField(ParamFrame, BKE, 0, TGNumberEntry::kNESRealFour, TGNumberEntry::kNEANonNegative); - TGLabel *bfieldlabel = new TGLabel(ParamFrame, "B-Field (G):"); - fBField = new TGNumberEntryField(ParamFrame, BFIELD, 0, TGNumberEntry::kNESRealFour, TGNumberEntry::kNEANonNegative); - TGLabel *thetalabel = new TGLabel(ParamFrame, "Angle (deg):"); - fThetaField = new TGNumberEntryField(ParamFrame, THETA, 0, TGNumberEntry::kNESRealFour, TGNumberEntry::kNEANonNegative); - TGLabel *ztlabel = new TGLabel(ParamFrame, "ZT:"); - fZTField = new TGNumberEntryField(ParamFrame, ZT, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); - TGLabel *atlabel = new TGLabel(ParamFrame, "AT:"); - fATField = new TGNumberEntryField(ParamFrame, AT, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); - TGLabel *zplabel = new TGLabel(ParamFrame, "ZP:"); - fZPField = new TGNumberEntryField(ParamFrame, ZP, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); - TGLabel *aplabel = new TGLabel(ParamFrame, "AP:"); - fAPField = new TGNumberEntryField(ParamFrame, AP, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); - TGLabel *zelabel = new TGLabel(ParamFrame, "ZE:"); - fZEField = new TGNumberEntryField(ParamFrame, ZE, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); - TGLabel *aelabel = new TGLabel(ParamFrame, "AE:"); - fAEField = new TGNumberEntryField(ParamFrame, AE, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); - ParamFrame->AddFrame(bkelabel, lhints); - ParamFrame->AddFrame(fBKEField, fhints); - ParamFrame->AddFrame(bfieldlabel, lhints); - ParamFrame->AddFrame(fBField, fhints); - ParamFrame->AddFrame(thetalabel, lhints); - ParamFrame->AddFrame(fThetaField, fhints); - ParamFrame->AddFrame(ztlabel, lhints); - ParamFrame->AddFrame(fZTField, fhints); - ParamFrame->AddFrame(atlabel, lhints); - ParamFrame->AddFrame(fATField, fhints); - ParamFrame->AddFrame(zplabel, lhints); - ParamFrame->AddFrame(fZPField, fhints); - ParamFrame->AddFrame(aplabel, lhints); - ParamFrame->AddFrame(fAPField, fhints); - ParamFrame->AddFrame(zelabel, lhints); - ParamFrame->AddFrame(fZEField, fhints); - ParamFrame->AddFrame(aelabel, lhints); - ParamFrame->AddFrame(fAEField, fhints); - - TGHorizontalFrame *WindowFrame = new TGHorizontalFrame(InputFrame, w, h*0.1); - TGLabel *slowlabel = new TGLabel(WindowFrame, "Slow Coincidence Window (ps):"); - fSlowWindowField = new TGNumberEntryField(WindowFrame, SLOWWIND, 0, TGNumberEntry::kNESReal, TGNumberEntry::kNEANonNegative); - TGLabel *fasticlabel = new TGLabel(WindowFrame, "Fast Coincidence Window IC (ps):"); - fFastICField = new TGNumberEntryField(WindowFrame, FASTWIND_IC, 0, TGNumberEntry::kNESReal, TGNumberEntry::kNEANonNegative); - TGLabel *fastsabrelabel = new TGLabel(WindowFrame, "Fast Coincidence Window SABRE (ps):"); - fFastSABREField = new TGNumberEntryField(WindowFrame, FASTWIND_SABRE, 0, TGNumberEntry::kNESReal, TGNumberEntry::kNEANonNegative); - WindowFrame->AddFrame(slowlabel, lhints); - WindowFrame->AddFrame(fSlowWindowField, fhints); - WindowFrame->AddFrame(fasticlabel, lhints); - WindowFrame->AddFrame(fFastICField, fhints); - WindowFrame->AddFrame(fastsabrelabel, lhints); - WindowFrame->AddFrame(fFastSABREField, fhints); - - TGHorizontalFrame *RunFrame = new TGHorizontalFrame(InputFrame, w, h*0.1); - 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 Fast", GWMEventBuilder::CONVERT_F); - fTypeBox->AddEntry("Convert SlowA", GWMEventBuilder::CONVERT_SA); - fTypeBox->AddEntry("Convert FastA", GWMEventBuilder::CONVERT_FA); - fTypeBox->AddEntry("Convert", GWMEventBuilder::CONVERT); - fTypeBox->AddEntry("Merge ROOT", GWMEventBuilder::MERGE); - fTypeBox->AddEntry("Plot", GWMEventBuilder::PLOT); - 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:"); - fRMinField = new TGNumberEntryField(RunFrame, RMIN, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); - TGLabel *rmaxlabel = new TGLabel(RunFrame, "Max Run:"); - fRMaxField = new TGNumberEntryField(RunFrame, RMAX, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); - fRunButton = new TGTextButton(RunFrame, "Run!"); - fRunButton->SetState(kButtonDisabled); - fRunButton->Connect("Clicked()","EVBMainFrame",this,"DoRun()"); - RunFrame->AddFrame(typelabel, lhints); - RunFrame->AddFrame(fTypeBox, fhints); - RunFrame->AddFrame(rminlabel, lhints); - RunFrame->AddFrame(fRMinField, fhints); - RunFrame->AddFrame(rmaxlabel, lhints); - RunFrame->AddFrame(fRMaxField, fhints); - RunFrame->AddFrame(fRunButton, bhints); - - InputFrame->AddFrame(NameFrame, fhints); - InputFrame->AddFrame(ParamFrame, fhints); - InputFrame->AddFrame(WindowFrame, fhints); - InputFrame->AddFrame(RunFrame, fhints); - - TGVerticalFrame *PBFrame = new TGVerticalFrame(this, w, h*0.1); - TGLabel *pbLabel = new TGLabel(PBFrame, "Build Progress"); - fProgressBar = new TGHProgressBar(PBFrame, TGProgressBar::kFancy, w); - fProgressBar->ShowPosition(); - fProgressBar->SetBarColor("lightblue"); - fBuilder.AttachProgressBar(fProgressBar); - PBFrame->AddFrame(pbLabel, lhints); - PBFrame->AddFrame(fProgressBar, fhints); - - TGMenuBar* menuBar = new TGMenuBar(this, w, h*0.1); - fFileMenu = new TGPopupMenu(gClient->GetRoot()); - fFileMenu->AddEntry("Load...", M_LOAD_CONFIG); - fFileMenu->AddEntry("Save...", M_SAVE_CONFIG); - fFileMenu->AddEntry("Exit", M_EXIT); - fFileMenu->Connect("Activated(Int_t)","EVBMainFrame", this, "HandleMenuSelection(Int_t)"); - menuBar->AddPopup("File", fFileMenu, mhints); - - AddFrame(menuBar, new TGLayoutHints(kLHintsTop|kLHintsLeft,0,0,0,0)); - AddFrame(InputFrame, fchints); - AddFrame(PBFrame, fpbhints); - - SetWindowName("GWM Event Builder"); - MapSubwindows(); - Resize(); - MapWindow(); - -} - -EVBMainFrame::~EVBMainFrame() { - Cleanup(); - delete this; -} - -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::DoOpenWorkdir() { - new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, WORKDIR); -} - -void EVBMainFrame::DoOpenCMapfile() { - new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, CMAP); -} - -void EVBMainFrame::DoOpenSMapfile() { - new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, SMAP); -} - -void EVBMainFrame::DoOpenScalerfile() { - new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, SCALER); -} - -void EVBMainFrame::DoOpenCutfile() { - new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H*0.25, this, CUT); -} - -void EVBMainFrame::DoRun() { - - DisableAllInput(); - - SetParameters(); - - int type = fTypeBox->GetSelected(); - fBuilder.SetAnalysisType(type); - - switch(type) { - case GWMEventBuilder::PLOT : - { - RunPlot(); - break; - } - case GWMEventBuilder::CONVERT : - { - fBuilder.Convert2RawRoot(); - break; - } - case GWMEventBuilder::MERGE : - { - fBuilder.MergeROOTFiles(); - break; - } - case GWMEventBuilder::CONVERT_S : - { - fBuilder.Convert2SortedRoot(); - break; - } - case GWMEventBuilder::CONVERT_F : - { - fBuilder.Convert2FastSortedRoot(); - break; - } - case GWMEventBuilder::CONVERT_SA : - { - fBuilder.Convert2SlowAnalyzedRoot(); - break; - } - case GWMEventBuilder::CONVERT_FA : - { - fBuilder.Convert2FastAnalyzedRoot(); - break; - } - } - - EnableAllInput(); -} - -void EVBMainFrame::HandleTypeSelection(int box, int entry) { - fRunButton->SetState(kButtonUp); -} - -bool EVBMainFrame::SetParameters() { - fBuilder.SetRunRange(fRMinField->GetIntNumber(), fRMaxField->GetIntNumber()); - fBuilder.SetSlowCoincidenceWindow(fSlowWindowField->GetNumber()); - fBuilder.SetFastWindowIonChamber(fFastICField->GetNumber()); - fBuilder.SetFastWindowSABRE(fFastSABREField->GetNumber()); - UpdateWorkdir(); - UpdateSMap(); - UpdateCMap(); - UpdateScaler(); - UpdateCut(); - bool test = fBuilder.SetKinematicParameters(fZTField->GetIntNumber(), fATField->GetIntNumber(), - fZPField->GetIntNumber(), fAPField->GetIntNumber(), - fZEField->GetIntNumber(), fAEField->GetIntNumber(), - fBField->GetNumber(), fThetaField->GetNumber(), - fBKEField->GetNumber()); - return test; -} - -void EVBMainFrame::DisplayWorkdir(const char* dir) { - fWorkField->SetText(dir); - fBuilder.SetWorkDirectory(dir); -} - -void EVBMainFrame::DisplayCMap(const char* file) { - fCMapField->SetText(file); - fBuilder.SetChannelMap(file); -} - -void EVBMainFrame::DisplaySMap(const char* file) { - fSMapField->SetText(file); - fBuilder.SetBoardShiftFile(file); -} - -void EVBMainFrame::DisplayScaler(const char* file) { - fScalerField->SetText(file); - fBuilder.SetScalerFile(file); -} - -void EVBMainFrame::DisplayCut(const char* file) { - fCutField->SetText(file); - fBuilder.SetCutList(file); -} - -void EVBMainFrame::SaveConfig(const char* file) { - std::string filename = file; - fBuilder.WriteConfigFile(filename); -} - -void EVBMainFrame::LoadConfig(const char* file) { - std::string filename = file; - fBuilder.ReadConfigFile(filename); - - fWorkField->SetText(fBuilder.GetWorkDirectory().c_str()); - fCMapField->SetText(fBuilder.GetChannelMap().c_str()); - fSMapField->SetText(fBuilder.GetBoardShiftFile().c_str()); - fCutField->SetText(fBuilder.GetCutList().c_str()); - fScalerField->SetText(fBuilder.GetScalerFile().c_str()); - - fZTField->SetIntNumber(fBuilder.GetTargetZ()); - fATField->SetIntNumber(fBuilder.GetTargetA()); - fZPField->SetIntNumber(fBuilder.GetProjectileZ()); - fAPField->SetIntNumber(fBuilder.GetProjectileA()); - fZEField->SetIntNumber(fBuilder.GetEjectileZ()); - fAEField->SetIntNumber(fBuilder.GetEjectileA()); - fBKEField->SetNumber(fBuilder.GetBeamKE()); - fBField->SetNumber(fBuilder.GetBField()); - fThetaField->SetNumber(fBuilder.GetTheta()); - - fSlowWindowField->SetNumber(fBuilder.GetSlowCoincidenceWindow()); - fFastSABREField->SetNumber(fBuilder.GetFastWindowSABRE()); - fFastICField->SetNumber(fBuilder.GetFastWindowIonChamber()); - - fRMaxField->SetIntNumber(fBuilder.GetRunMax()); - fRMinField->SetIntNumber(fBuilder.GetRunMin()); - -} - -void EVBMainFrame::UpdateWorkdir() { - const char* dir = fWorkField->GetText(); - fBuilder.SetWorkDirectory(dir); -} - -void EVBMainFrame::UpdateSMap() { - const char* file = fSMapField->GetText(); - fBuilder.SetBoardShiftFile(file); -} - -void EVBMainFrame::UpdateCMap() { - const char* file = fCMapField->GetText(); - fBuilder.SetChannelMap(file); -} - -void EVBMainFrame::UpdateScaler() { - const char* file = fScalerField->GetText(); - fBuilder.SetScalerFile(file); -} - -void EVBMainFrame::UpdateCut() { - const char* file = fCutField->GetText(); - fBuilder.SetCutList(file); -} - -void EVBMainFrame::RunPlot() { - fBuilder.PlotHistograms(); -} - -void EVBMainFrame::RunMerge(const char* file, const char* dir) {} - -void EVBMainFrame::DisableAllInput() { - fRunButton->SetState(kButtonDisabled); - fOpenWorkButton->SetState(kButtonDisabled); - fOpenCMapButton->SetState(kButtonDisabled); - fOpenSMapButton->SetState(kButtonDisabled); - fOpenScalerButton->SetState(kButtonDisabled); - fOpenCutButton->SetState(kButtonDisabled); - - fWorkField->SetState(false); - fCMapField->SetState(false); - fSMapField->SetState(false); - fScalerField->SetState(false); - fCutField->SetState(false); - - fTypeBox->SetEnabled(false); - - fZTField->SetState(false); - fATField->SetState(false); - fZPField->SetState(false); - fAPField->SetState(false); - fZEField->SetState(false); - fAEField->SetState(false); - - fBField->SetState(false); - fBKEField->SetState(false); - fThetaField->SetState(false); - - fRMaxField->SetState(false); - fRMinField->SetState(false); - - fSlowWindowField->SetState(false); - fFastICField->SetState(false); - fFastSABREField->SetState(false); -} - -void EVBMainFrame::EnableAllInput() { - fRunButton->SetState(kButtonUp); - fOpenWorkButton->SetState(kButtonUp); - fOpenCMapButton->SetState(kButtonUp); - fOpenSMapButton->SetState(kButtonUp); - fOpenScalerButton->SetState(kButtonUp); - fOpenCutButton->SetState(kButtonUp); - - fWorkField->SetState(true); - fCMapField->SetState(true); - fSMapField->SetState(true); - fScalerField->SetState(true); - fCutField->SetState(true); - - fTypeBox->SetEnabled(true); - - fZTField->SetState(true); - fATField->SetState(true); - fZPField->SetState(true); - fAPField->SetState(true); - fZEField->SetState(true); - fAEField->SetState(true); - - fBField->SetState(true); - fBKEField->SetState(true); - fThetaField->SetState(true); - - fRMaxField->SetState(true); - fRMinField->SetState(true); - - fSlowWindowField->SetState(true); - fFastICField->SetState(true); - fFastSABREField->SetState(true); - -} diff --git a/src/gui_main.cpp b/src/gui_main.cpp index be2cb82..601a322 100644 --- a/src/gui_main.cpp +++ b/src/gui_main.cpp @@ -1,8 +1,12 @@ -#include "EventBuilder.h" +#include "evb/Logger.h" +#include "spsdict/DataStructs.h" #include -#include "EVBMainFrame.h" +#include "guidict/EVBMainFrame.h" -int main(int argc, char** argv) { +int main(int argc, char** argv) +{ + EventBuilder::Logger::Init(); + EnforceDictionaryLinked(); TApplication app("app", &argc, argv); UInt_t h = 400; UInt_t w = 400; diff --git a/src/guidict/EVBMainFrame.cpp b/src/guidict/EVBMainFrame.cpp new file mode 100644 index 0000000..1e5203f --- /dev/null +++ b/src/guidict/EVBMainFrame.cpp @@ -0,0 +1,582 @@ +#include "EVBMainFrame.h" +#include "FileViewFrame.h" +#include +#include +#include +#include + +EVBMainFrame::EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h) : + TGMainFrame(p, w, h, kVerticalFrame) +{ + 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); + TGLayoutHints *lhints = new TGLayoutHints(kLHintsCenterY|kLHintsLeft,5,5,5,5); + TGLayoutHints *bhints = new TGLayoutHints(kLHintsLeft|kLHintsCenterY,5,5,5,5); + TGLayoutHints *fpbhints = new TGLayoutHints(kLHintsExpandX|kLHintsBottom,5,5,5,5); + TGLayoutHints *mhints = new TGLayoutHints(kLHintsTop|kLHintsLeft,0,4,0,0); + + //Make the containers and link up all signals/slots + + TGGroupFrame* pathGroup = new TGGroupFrame(this, "Working Paths"); + TGVerticalFrame *NameFrame = new TGVerticalFrame(pathGroup, w, h*0.3); + + TGHorizontalFrame *WorkFrame = new TGHorizontalFrame(NameFrame, w, h*0.06); + TGLabel* workLabel = new TGLabel(WorkFrame, "Workspace Directory:"); + fWorkField = new TGTextEntry(WorkFrame, new TGTextBuffer(120), WorkDir); + fWorkField->Resize(w*0.25, fWorkField->GetDefaultHeight()); + fWorkField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateWorkdir()"); + fOpenWorkButton = new TGTextButton(WorkFrame, "Open"); + fOpenWorkButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenWorkdir()"); + WorkFrame->AddFrame(workLabel, lhints); + WorkFrame->AddFrame(fWorkField, fhints); + WorkFrame->AddFrame(fOpenWorkButton, bhints); + + TGHorizontalFrame *CMapFrame = new TGHorizontalFrame(NameFrame, w, h*0.06); + TGLabel* cmaplabel = new TGLabel(CMapFrame, "Channel Map File:"); + fCMapField = new TGTextEntry(CMapFrame, new TGTextBuffer(120), Cmap); + fCMapField->Resize(w*0.25, fCMapField->GetDefaultHeight()); + fCMapField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateCMap()"); + fOpenCMapButton = new TGTextButton(CMapFrame, "Open"); + fOpenCMapButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenCMapfile()"); + CMapFrame->AddFrame(cmaplabel, lhints); + CMapFrame->AddFrame(fCMapField, fhints); + CMapFrame->AddFrame(fOpenCMapButton, bhints); + + TGHorizontalFrame *SMapFrame = new TGHorizontalFrame(NameFrame, w, h*0.06); + TGLabel* smaplabel = new TGLabel(SMapFrame, "Board Shift File:"); + fSMapField = new TGTextEntry(SMapFrame, new TGTextBuffer(120), Smap); + fSMapField->Resize(w*0.25, fSMapField->GetDefaultHeight()); + fSMapField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateSMap()"); + fOpenSMapButton = new TGTextButton(SMapFrame, "Open"); + fOpenSMapButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenSMapfile()"); + SMapFrame->AddFrame(smaplabel, lhints); + SMapFrame->AddFrame(fSMapField, fhints); + SMapFrame->AddFrame(fOpenSMapButton, bhints); + + TGHorizontalFrame *ScalerFrame = new TGHorizontalFrame(NameFrame, w, h*0.06); + TGLabel* sclabel = new TGLabel(ScalerFrame, "Scaler File: "); + fScalerField = new TGTextEntry(ScalerFrame, new TGTextBuffer(120), Scaler); + fScalerField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateScaler()"); + fOpenScalerButton = new TGTextButton(ScalerFrame, "Open"); + fOpenScalerButton->Connect("Clicked()","EVBMainFrame", this, "DoOpenScalerfile()"); + ScalerFrame->AddFrame(sclabel, lhints); + ScalerFrame->AddFrame(fScalerField, fhints); + ScalerFrame->AddFrame(fOpenScalerButton, bhints); + + TGHorizontalFrame *CutFrame = new TGHorizontalFrame(NameFrame, w, h*0.06); + TGLabel* clabel = new TGLabel(CutFrame, "Cut List: "); + fCutField = new TGTextEntry(CutFrame, new TGTextBuffer(120), Cut); + fCutField->Connect("ReturnPressed()","EVBMainFrame",this,"UpdateCut()"); + fOpenCutButton = new TGTextButton(CutFrame, "Open"); + fOpenCutButton->Connect("Clicked()","EVBMainFrame",this,"DoOpenCutfile()"); + CutFrame->AddFrame(clabel, lhints); + CutFrame->AddFrame(fCutField, fhints); + CutFrame->AddFrame(fOpenCutButton, bhints); + + NameFrame->AddFrame(WorkFrame, fhints); + NameFrame->AddFrame(CMapFrame, fhints); + NameFrame->AddFrame(SMapFrame, fhints); + NameFrame->AddFrame(ScalerFrame, fhints); + NameFrame->AddFrame(CutFrame, fhints); + + pathGroup->AddFrame(NameFrame, fhints); + + + TGHorizontalFrame *ParamFrame = new TGHorizontalFrame(this, w, h*0.4); + + TGGroupFrame* reactionGroup = new TGGroupFrame(ParamFrame, "Reaction Inputs"); + TGHorizontalFrame* reactionFrame = new TGHorizontalFrame(reactionGroup, w*0.7, h*0.5); + + TGVerticalFrame* targFrame = new TGVerticalFrame(reactionFrame, w*0.175, h*0.5); + TGHorizontalFrame* zTargFrame = new TGHorizontalFrame(targFrame, w*0.3, h*0.2); + TGLabel *ztlabel = new TGLabel(zTargFrame, "ZT:"); + fZTField = new TGNumberEntryField(zTargFrame, ZT, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); + zTargFrame->AddFrame(ztlabel, lhints); + zTargFrame->AddFrame(fZTField, fhints); + TGHorizontalFrame* aTargFrame = new TGHorizontalFrame(targFrame, w*0.175, h*0.2); + TGLabel *atlabel = new TGLabel(aTargFrame, "AT:"); + fATField = new TGNumberEntryField(aTargFrame, AT, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); + aTargFrame->AddFrame(atlabel, lhints); + aTargFrame->AddFrame(fATField, fhints); + targFrame->AddFrame(zTargFrame, fhints); + targFrame->AddFrame(aTargFrame, fhints); + + TGVerticalFrame* projFrame = new TGVerticalFrame(reactionFrame, w*0.175, h*0.4); + TGHorizontalFrame* zProjFrame = new TGHorizontalFrame(projFrame, w*0.175, h*0.2); + TGLabel *zplabel = new TGLabel(zProjFrame, "ZP:"); + fZPField = new TGNumberEntryField(zProjFrame, ZP, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); + zProjFrame->AddFrame(zplabel, lhints); + zProjFrame->AddFrame(fZPField, fhints); + TGHorizontalFrame* aProjFrame = new TGHorizontalFrame(projFrame, w*0.175, h*0.2); + TGLabel *aplabel = new TGLabel(aProjFrame, "AP:"); + fAPField = new TGNumberEntryField(aProjFrame, AP, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); + aProjFrame->AddFrame(aplabel, lhints); + aProjFrame->AddFrame(fAPField, fhints); + projFrame->AddFrame(zProjFrame, fhints); + projFrame->AddFrame(aProjFrame, fhints); + + TGVerticalFrame* ejectFrame = new TGVerticalFrame(reactionFrame, w*0.175, h*0.4); + TGHorizontalFrame* zEjectFrame = new TGHorizontalFrame(ejectFrame, w*0.175, h*0.2); + TGLabel *zelabel = new TGLabel(zEjectFrame, "ZE:"); + fZEField = new TGNumberEntryField(zEjectFrame, ZE, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); + zEjectFrame->AddFrame(zelabel, lhints); + zEjectFrame->AddFrame(fZEField, fhints); + TGHorizontalFrame* aEjectFrame = new TGHorizontalFrame(ejectFrame, w*0.175, h*0.2); + TGLabel *aelabel = new TGLabel(aEjectFrame, "AE:"); + fAEField = new TGNumberEntryField(aEjectFrame, AE, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); + aEjectFrame->AddFrame(aelabel, lhints); + aEjectFrame->AddFrame(fAEField, fhints); + ejectFrame->AddFrame(zEjectFrame, fhints); + ejectFrame->AddFrame(aEjectFrame, fhints); + + TGVerticalFrame* extraFrame = new TGVerticalFrame(reactionFrame, w*0.175, h*0.4); + TGHorizontalFrame* beamFrame = new TGHorizontalFrame(extraFrame, w*0.175, h*0.15); + TGLabel *bkelabel = new TGLabel(beamFrame, "Beam KE (MeV):"); + fBKEField = new TGNumberEntryField(beamFrame, Bke, 0, TGNumberEntry::kNESRealFour, TGNumberEntry::kNEANonNegative); + beamFrame->AddFrame(bkelabel, lhints); + beamFrame->AddFrame(fBKEField, fhints); + TGHorizontalFrame* bfFrame = new TGHorizontalFrame(extraFrame, w*0.175, h*0.15); + TGLabel *bfieldlabel = new TGLabel(bfFrame, "B-Field (G):"); + fBField = new TGNumberEntryField(bfFrame, BField, 0, TGNumberEntry::kNESRealFour, TGNumberEntry::kNEANonNegative); + bfFrame->AddFrame(bfieldlabel, lhints); + bfFrame->AddFrame(fBField, fhints); + TGHorizontalFrame* thetaFrame = new TGHorizontalFrame(extraFrame, w*0.175, h*0.15); + TGLabel *thetalabel = new TGLabel(thetaFrame, "Angle (deg):"); + fThetaField = new TGNumberEntryField(thetaFrame, Theta, 0, TGNumberEntry::kNESRealFour, TGNumberEntry::kNEANonNegative); + thetaFrame->AddFrame(thetalabel, lhints); + thetaFrame->AddFrame(fThetaField, fhints); + extraFrame->AddFrame(beamFrame, fhints); + extraFrame->AddFrame(bfFrame, fhints); + extraFrame->AddFrame(thetaFrame, fhints); + + reactionFrame->AddFrame(targFrame, fhints); + reactionFrame->AddFrame(projFrame, fhints); + reactionFrame->AddFrame(ejectFrame, fhints); + reactionFrame->AddFrame(extraFrame, fhints); + + reactionGroup->AddFrame(reactionFrame, fhints); + + + TGGroupFrame* eventGroup = new TGGroupFrame(ParamFrame, "Event Inputs"); + TGVerticalFrame* eventFrame = new TGVerticalFrame(eventGroup, w*0.3, h*0.5); + + TGHorizontalFrame *slowFrame = new TGHorizontalFrame(eventFrame, w*0.4, h*0.1); + TGLabel *slowlabel = new TGLabel(slowFrame, "Slow Coincidence Window (ps):"); + fSlowWindowField = new TGNumberEntryField(slowFrame, SlowWind, 0, TGNumberEntry::kNESReal, TGNumberEntry::kNEANonNegative); + slowFrame->AddFrame(slowlabel, lhints); + slowFrame->AddFrame(fSlowWindowField, fhints); + + TGHorizontalFrame* fastICFrame = new TGHorizontalFrame(eventFrame, w*0.3, h*0.1); + TGLabel *fasticlabel = new TGLabel(fastICFrame, "Fast Coincidence Window IC (ps):"); + fFastICField = new TGNumberEntryField(fastICFrame, FastWind_IC, 0, TGNumberEntry::kNESReal, TGNumberEntry::kNEANonNegative); + fastICFrame->AddFrame(fasticlabel, lhints); + fastICFrame->AddFrame(fFastICField, fhints); + + TGHorizontalFrame* fastSABREFrame = new TGHorizontalFrame(eventFrame, w*0.3, h*0.1); + TGLabel *fastsabrelabel = new TGLabel(fastSABREFrame, "Fast Coincidence Window SABRE (ps):"); + fFastSABREField = new TGNumberEntryField(fastSABREFrame, FastWind_Sabre, 0, TGNumberEntry::kNESReal, TGNumberEntry::kNEANonNegative); + fastSABREFrame->AddFrame(fastsabrelabel, lhints); + fastSABREFrame->AddFrame(fFastSABREField, fhints); + + TGHorizontalFrame *opFrame = new TGHorizontalFrame(eventFrame, w*0.3, h*0.1); + TGLabel *typelabel = new TGLabel(opFrame, "Operation Type:"); + fTypeBox = new TGComboBox(opFrame, TypeBox); + //Needs modification for new conversion based sorting GWM -- Dec 2020 + fTypeBox->AddEntry("Convert Slow", EventBuilder::EVBApp::Operation::ConvertSlow); + fTypeBox->AddEntry("Convert Fast", EventBuilder::EVBApp::Operation::ConvertFast); + fTypeBox->AddEntry("Convert SlowA", EventBuilder::EVBApp::Operation::ConvertSlowA); + fTypeBox->AddEntry("Convert FastA", EventBuilder::EVBApp::Operation::ConvertFastA); + fTypeBox->AddEntry("Convert", EventBuilder::EVBApp::Operation::Convert); + fTypeBox->AddEntry("Merge ROOT", EventBuilder::EVBApp::Operation::Merge); + fTypeBox->AddEntry("Plot", EventBuilder::EVBApp::Operation::Plot); + fTypeBox->Resize(200,20); + fTypeBox->Connect("Selected(Int_t, Int_t)","EVBMainFrame",this,"HandleTypeSelection(Int_t,Int_t)"); + opFrame->AddFrame(typelabel, lhints); + opFrame->AddFrame(fTypeBox, fhints); + + TGHorizontalFrame* rminFrame = new TGHorizontalFrame(eventFrame, w*0.3, h*0.1); + TGLabel *rminlabel = new TGLabel(rminFrame, "Min Run:"); + fRMinField = new TGNumberEntryField(rminFrame, RMin, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); + rminFrame->AddFrame(rminlabel, lhints); + rminFrame->AddFrame(fRMinField, fhints); + + TGHorizontalFrame* rmaxFrame = new TGHorizontalFrame(eventFrame, w*0.3, h*0.1); + TGLabel *rmaxlabel = new TGLabel(rmaxFrame, "Max Run:"); + fRMaxField = new TGNumberEntryField(rmaxFrame, RMax, 0, TGNumberEntry::kNESInteger, TGNumberEntry::kNEANonNegative); + rmaxFrame->AddFrame(rmaxlabel, lhints); + rmaxFrame->AddFrame(fRMaxField, fhints); + + fRunButton = new TGTextButton(eventFrame, "Run!"); + fRunButton->SetState(kButtonDisabled); + fRunButton->Connect("Clicked()","EVBMainFrame",this,"DoRun()"); + + eventFrame->AddFrame(slowFrame, fhints); + eventFrame->AddFrame(fastICFrame, fhints); + eventFrame->AddFrame(fastSABREFrame, fhints); + eventFrame->AddFrame(opFrame, fhints); + eventFrame->AddFrame(rminFrame, fhints); + eventFrame->AddFrame(rmaxFrame, fhints); + eventFrame->AddFrame(fRunButton, bhints); + + eventGroup->AddFrame(eventFrame,fhints); + + ParamFrame->AddFrame(reactionGroup, fhints); + ParamFrame->AddFrame(eventGroup, new TGLayoutHints(kLHintsExpandY|kLHintsLeft,5,5,5,5)); + + TGVerticalFrame *PBFrame = new TGVerticalFrame(this, w, h*0.1); + TGLabel *pbLabel = new TGLabel(PBFrame, "Build Progress"); + fProgressBar = new TGHProgressBar(PBFrame, TGProgressBar::kFancy, w); + fProgressBar->ShowPosition(); + fProgressBar->SetBarColor("lightblue"); + //fBuilder.AttachProgressBar(fProgressBar); + PBFrame->AddFrame(pbLabel, lhints); + PBFrame->AddFrame(fProgressBar, fhints); + + TGMenuBar* menuBar = new TGMenuBar(this, w, h*0.1); + fFileMenu = new TGPopupMenu(gClient->GetRoot()); + fFileMenu->AddEntry("Load...", M_Load_Config); + fFileMenu->AddEntry("Save...", M_Save_Config); + fFileMenu->AddEntry("Exit", M_Exit); + fFileMenu->Connect("Activated(Int_t)","EVBMainFrame", this, "HandleMenuSelection(Int_t)"); + menuBar->AddPopup("File", fFileMenu, mhints); + + AddFrame(menuBar, new TGLayoutHints(kLHintsTop|kLHintsLeft,0,0,0,0)); + AddFrame(pathGroup, new TGLayoutHints(kLHintsTop|kLHintsExpandX,5,5,5,5)); + AddFrame(ParamFrame, new TGLayoutHints(kLHintsCenterX|kLHintsExpandY,5,5,5,5)); + AddFrame(PBFrame, fpbhints); + + fBuilder.SetProgressCallbackFunc(BIND_PROGRESS_CALLBACK_FUNCTION(EVBMainFrame::SetProgressBarPosition)); + fBuilder.SetProgressFraction(0.01); + SetWindowName("GWM Event Builder"); + MapSubwindows(); + Resize(); + MapWindow(); + +} + +EVBMainFrame::~EVBMainFrame() +{ + Cleanup(); + delete fInfo; + delete this; +} + +void EVBMainFrame::CloseWindow() +{ + gApplication->Terminate(); +} + +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() +{ + new FileViewFrame(gClient->GetRoot(), this, MAIN_W*0.5, MAIN_H, this, WorkDir); +} + +void EVBMainFrame::DoOpenCMapfile() +{ + new TGFileDialog(gClient->GetRoot(), this, kFDOpen, fInfo); + if(fInfo->fFilename) + DisplayCMap(fInfo->fFilename); +} + +void EVBMainFrame::DoOpenSMapfile() +{ + new TGFileDialog(gClient->GetRoot(), this, kFDOpen, fInfo); + if(fInfo->fFilename) + DisplaySMap(fInfo->fFilename); +} + +void EVBMainFrame::DoOpenScalerfile() +{ + new TGFileDialog(gClient->GetRoot(), this, kFDOpen, fInfo); + if(fInfo->fFilename) + DisplayScaler(fInfo->fFilename); +} + +void EVBMainFrame::DoOpenCutfile() +{ + new TGFileDialog(gClient->GetRoot(), this, kFDOpen, fInfo); + if(fInfo->fFilename) + DisplayCut(fInfo->fFilename); +} + +void EVBMainFrame::DoRun() +{ + + DisableAllInput(); + + SetParameters(); + + int type = fTypeBox->GetSelected(); + + switch(type) + { + case EventBuilder::EVBApp::Operation::Plot : + { + RunPlot(); + break; + } + case EventBuilder::EVBApp::Operation::Convert : + { + fBuilder.Convert2RawRoot(); + break; + } + case EventBuilder::EVBApp::Operation::Merge : + { + fBuilder.MergeROOTFiles(); + break; + } + case EventBuilder::EVBApp::Operation::ConvertSlow : + { + fBuilder.Convert2SortedRoot(); + break; + } + case EventBuilder::EVBApp::Operation::ConvertFast : + { + fBuilder.Convert2FastSortedRoot(); + break; + } + case EventBuilder::EVBApp::Operation::ConvertSlowA : + { + fBuilder.Convert2SlowAnalyzedRoot(); + break; + } + case EventBuilder::EVBApp::Operation::ConvertFastA : + { + fBuilder.Convert2FastAnalyzedRoot(); + break; + } + } + + EnableAllInput(); +} + +void EVBMainFrame::HandleTypeSelection(int box, int entry) +{ + fRunButton->SetState(kButtonUp); +} + +bool EVBMainFrame::SetParameters() +{ + fBuilder.SetRunRange(fRMinField->GetIntNumber(), fRMaxField->GetIntNumber()); + fBuilder.SetSlowCoincidenceWindow(fSlowWindowField->GetNumber()); + fBuilder.SetFastWindowIonChamber(fFastICField->GetNumber()); + fBuilder.SetFastWindowSABRE(fFastSABREField->GetNumber()); + UpdateWorkdir(); + UpdateSMap(); + UpdateCMap(); + UpdateScaler(); + UpdateCut(); + bool test = fBuilder.SetKinematicParameters(fZTField->GetIntNumber(), fATField->GetIntNumber(), + fZPField->GetIntNumber(), fAPField->GetIntNumber(), + fZEField->GetIntNumber(), fAEField->GetIntNumber(), + fBField->GetNumber(), fThetaField->GetNumber(), + fBKEField->GetNumber()); + return test; +} + +void EVBMainFrame::DisplayWorkdir(const char* dir) +{ + fWorkField->SetText(dir); + fBuilder.SetWorkDirectory(dir); +} + +void EVBMainFrame::DisplayCMap(const char* file) +{ + fCMapField->SetText(file); + fBuilder.SetChannelMap(file); +} + +void EVBMainFrame::DisplaySMap(const char* file) +{ + fSMapField->SetText(file); + fBuilder.SetBoardShiftFile(file); +} + +void EVBMainFrame::DisplayScaler(const char* file) +{ + fScalerField->SetText(file); + fBuilder.SetScalerFile(file); +} + +void EVBMainFrame::DisplayCut(const char* file) +{ + fCutField->SetText(file); + fBuilder.SetCutList(file); +} + +void EVBMainFrame::SaveConfig(const char* file) +{ + std::string filename = file; + fBuilder.WriteConfigFile(filename); +} + +void EVBMainFrame::LoadConfig(const char* file) +{ + std::string filename = file; + fBuilder.ReadConfigFile(filename); + + fWorkField->SetText(fBuilder.GetWorkDirectory().c_str()); + fCMapField->SetText(fBuilder.GetChannelMap().c_str()); + fSMapField->SetText(fBuilder.GetBoardShiftFile().c_str()); + fCutField->SetText(fBuilder.GetCutList().c_str()); + fScalerField->SetText(fBuilder.GetScalerFile().c_str()); + + fZTField->SetIntNumber(fBuilder.GetTargetZ()); + fATField->SetIntNumber(fBuilder.GetTargetA()); + fZPField->SetIntNumber(fBuilder.GetProjectileZ()); + fAPField->SetIntNumber(fBuilder.GetProjectileA()); + fZEField->SetIntNumber(fBuilder.GetEjectileZ()); + fAEField->SetIntNumber(fBuilder.GetEjectileA()); + fBKEField->SetNumber(fBuilder.GetBeamKE()); + fBField->SetNumber(fBuilder.GetBField()); + fThetaField->SetNumber(fBuilder.GetTheta()); + + fSlowWindowField->SetNumber(fBuilder.GetSlowCoincidenceWindow()); + fFastSABREField->SetNumber(fBuilder.GetFastWindowSABRE()); + fFastICField->SetNumber(fBuilder.GetFastWindowIonChamber()); + + fRMaxField->SetIntNumber(fBuilder.GetRunMax()); + fRMinField->SetIntNumber(fBuilder.GetRunMin()); + +} + +void EVBMainFrame::UpdateWorkdir() +{ + const char* dir = fWorkField->GetText(); + fBuilder.SetWorkDirectory(dir); +} + +void EVBMainFrame::UpdateSMap() +{ + const char* file = fSMapField->GetText(); + fBuilder.SetBoardShiftFile(file); +} + +void EVBMainFrame::UpdateCMap() +{ + const char* file = fCMapField->GetText(); + fBuilder.SetChannelMap(file); +} + +void EVBMainFrame::UpdateScaler() +{ + const char* file = fScalerField->GetText(); + fBuilder.SetScalerFile(file); +} + +void EVBMainFrame::UpdateCut() +{ + const char* file = fCutField->GetText(); + fBuilder.SetCutList(file); +} + +void EVBMainFrame::RunPlot() +{ + fBuilder.PlotHistograms(); +} + +void EVBMainFrame::RunMerge(const char* file, const char* dir) {} + +void EVBMainFrame::DisableAllInput() +{ + fRunButton->SetState(kButtonDisabled); + fOpenWorkButton->SetState(kButtonDisabled); + fOpenCMapButton->SetState(kButtonDisabled); + fOpenSMapButton->SetState(kButtonDisabled); + fOpenScalerButton->SetState(kButtonDisabled); + fOpenCutButton->SetState(kButtonDisabled); + + fWorkField->SetState(false); + fCMapField->SetState(false); + fSMapField->SetState(false); + fScalerField->SetState(false); + fCutField->SetState(false); + + fTypeBox->SetEnabled(false); + + fZTField->SetState(false); + fATField->SetState(false); + fZPField->SetState(false); + fAPField->SetState(false); + fZEField->SetState(false); + fAEField->SetState(false); + + fBField->SetState(false); + fBKEField->SetState(false); + fThetaField->SetState(false); + + fRMaxField->SetState(false); + fRMinField->SetState(false); + + fSlowWindowField->SetState(false); + fFastICField->SetState(false); + fFastSABREField->SetState(false); +} + +void EVBMainFrame::EnableAllInput() +{ + fRunButton->SetState(kButtonUp); + fOpenWorkButton->SetState(kButtonUp); + fOpenCMapButton->SetState(kButtonUp); + fOpenSMapButton->SetState(kButtonUp); + fOpenScalerButton->SetState(kButtonUp); + fOpenCutButton->SetState(kButtonUp); + + fWorkField->SetState(true); + fCMapField->SetState(true); + fSMapField->SetState(true); + fScalerField->SetState(true); + fCutField->SetState(true); + + fTypeBox->SetEnabled(true); + + fZTField->SetState(true); + fATField->SetState(true); + fZPField->SetState(true); + fAPField->SetState(true); + fZEField->SetState(true); + fAEField->SetState(true); + + fBField->SetState(true); + fBKEField->SetState(true); + fThetaField->SetState(true); + + fRMaxField->SetState(true); + fRMinField->SetState(true); + + fSlowWindowField->SetState(true); + fFastICField->SetState(true); + fFastSABREField->SetState(true); + +} + +void EVBMainFrame::SetProgressBarPosition(long val, long total) +{ + fProgressBar->SetMin(0); + fProgressBar->SetMax(total); + fProgressBar->SetPosition(val); + gSystem->ProcessEvents(); +} \ No newline at end of file diff --git a/include/EVBMainFrame.h b/src/guidict/EVBMainFrame.h similarity index 81% rename from include/EVBMainFrame.h rename to src/guidict/EVBMainFrame.h index f600c1d..0afb519 100644 --- a/include/EVBMainFrame.h +++ b/src/guidict/EVBMainFrame.h @@ -11,11 +11,13 @@ #include #include #include +#include #include -#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(); @@ -45,33 +47,35 @@ public: void RunMerge(const char* dir, const char* file); void DisableAllInput(); void EnableAllInput(); + void SetProgressBarPosition(long value, long total); - enum WidgetId { - WORKDIR, - CMAP, - SMAP, - SCALER, - CUT, - PLOTF, - BFIELD, - BKE, - THETA, + enum WidgetId + { + WorkDir, + Cmap, + Smap, + Scaler, + Cut, + PlotF, + BField, + Bke, + Theta, ZT, AT, ZP, AP, ZE, AE, - SLOWWIND, - FASTWIND_IC, - FASTWIND_SABRE, - TYPEBOX, - RMIN, - RMAX, - M_LOAD_CONFIG, - M_SAVE_CONFIG, - M_EXIT + SlowWind, + FastWind_IC, + FastWind_Sabre, + TypeBox, + RMin, + RMax, + M_Load_Config, + M_Save_Config, + M_Exit }; ClassDef(EVBMainFrame, 0); @@ -92,7 +96,9 @@ private: TGPopupMenu *fFileMenu; - GWMEventBuilder fBuilder; + TGFileInfo* fInfo; + + EventBuilder::EVBApp fBuilder; int counter; UInt_t MAIN_W, MAIN_H; diff --git a/src/gui/FileViewFrame.cpp b/src/guidict/FileViewFrame.cpp similarity index 69% rename from src/gui/FileViewFrame.cpp rename to src/guidict/FileViewFrame.cpp index 0565f34..a18e872 100644 --- a/src/gui/FileViewFrame.cpp +++ b/src/guidict/FileViewFrame.cpp @@ -9,13 +9,13 @@ */ -#include "EventBuilder.h" #include "FileViewFrame.h" #include #include #include -FileViewFrame::FileViewFrame(const TGWindow* p, const TGFrame* main, UInt_t w, UInt_t h, EVBMainFrame *parent, int type) { +FileViewFrame::FileViewFrame(const TGWindow* p, const TGFrame* main, UInt_t w, UInt_t h, EVBMainFrame *parent, int type) +{ fMain = new TGTransientFrame(p,main,w,h); fMain->SetCleanup(kDeepCleanup); //delete all child frames fMain->DontCallClose(); //Close button on window disabled @@ -23,17 +23,20 @@ FileViewFrame::FileViewFrame(const TGWindow* p, const TGFrame* main, UInt_t w, U dirFlag = false; bool rootFlag = false; suffix = ".txt"; - if(type == EVBMainFrame::WORKDIR) { + if(type == EVBMainFrame::WorkDir) + { dirFlag = true; suffix = ".NOTHING"; - } else if(type == EVBMainFrame::PLOTF) { + } + else if(type == EVBMainFrame::PlotF) + { rootFlag = true; suffix = ".root"; } /*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); @@ -46,10 +49,12 @@ FileViewFrame::FileViewFrame(const TGWindow* p, const TGFrame* main, UInt_t w, U fContents->Connect("DoubleClicked(TGFrame*,Int_t)","FileViewFrame",this,"DoDoubleClick(TGLVEntry*,Int_t)"); /*Add in text options*/ - TGVerticalFrame *NameFrame = new TGVerticalFrame(fMain, w, h*0.25); + TGHorizontalFrame *NameFrame = new TGHorizontalFrame(fMain, w, h*0.25); TGLabel *nameLabel; - if(dirFlag) nameLabel = new TGLabel(NameFrame, "Dir:"); - else nameLabel = new TGLabel(NameFrame, "File:"); + if(dirFlag) + nameLabel = new TGLabel(NameFrame, "Dir:"); + else + nameLabel = new TGLabel(NameFrame, "File:"); TGTextBuffer* fNameBuffer; fNameField = new TGTextEntry(NameFrame, fNameBuffer = new TGTextBuffer(50)); fNameField->Resize(w*0.5, fNameField->GetDefaultHeight()); @@ -66,20 +71,31 @@ FileViewFrame::FileViewFrame(const TGWindow* p, const TGFrame* main, UInt_t w, U ButtonFrame->AddFrame(fCancelButton, fhints); fMain->AddFrame(fViewer, fchints); - fMain->AddFrame(NameFrame, thints); fMain->AddFrame(ButtonFrame, fbhints); + fMain->AddFrame(NameFrame, thints); /*Send signal to appropriate location*/ - if(type == EVBMainFrame::WORKDIR) Connect("SendText(const char*)","EVBMainFrame",parent,"DisplayWorkdir(const char*)"); - else if(type == EVBMainFrame::CMAP) Connect("SendText(const char*)","EVBMainFrame",parent,"DisplayCMap(const char*)"); - else if(type == EVBMainFrame::SMAP) Connect("SendText(const char*)","EVBMainFrame",parent,"DisplaySMap(const char*)"); - else if(type == EVBMainFrame::SCALER) Connect("SendText(const char*)","EVBMainFrame",parent,"DisplayScaler(const char*)"); - else if(type == EVBMainFrame::CUT) Connect("SendText(const char*)","EVBMainFrame",parent,"DisplayCut(const char*)"); - else if(type == EVBMainFrame::M_LOAD_CONFIG) Connect("SendText(const char*)","EVBMainFrame",parent,"LoadConfig(const char*)"); - else if(type == EVBMainFrame::M_SAVE_CONFIG) Connect("SendText(const char*)","EVBMainFrame",parent,"SaveConfig(const char*)"); - else if(type == EVBMainFrame::PLOTF) Connect("SendText(const char*)","EVBMainFrame",parent,"RunPlot(const char*)"); + if(type == EVBMainFrame::WorkDir) + Connect("SendText(const char*)","EVBMainFrame",parent,"DisplayWorkdir(const char*)"); + else if(type == EVBMainFrame::Cmap) + Connect("SendText(const char*)","EVBMainFrame",parent,"DisplayCMap(const char*)"); + else if(type == EVBMainFrame::Smap) + Connect("SendText(const char*)","EVBMainFrame",parent,"DisplaySMap(const char*)"); + else if(type == EVBMainFrame::Scaler) + Connect("SendText(const char*)","EVBMainFrame",parent,"DisplayScaler(const char*)"); + else if(type == EVBMainFrame::Cut) + Connect("SendText(const char*)","EVBMainFrame",parent,"DisplayCut(const char*)"); + else if(type == EVBMainFrame::M_Load_Config) + Connect("SendText(const char*)","EVBMainFrame",parent,"LoadConfig(const char*)"); + else if(type == EVBMainFrame::M_Save_Config) + Connect("SendText(const char*)","EVBMainFrame",parent,"SaveConfig(const char*)"); + else if(type == EVBMainFrame::PlotF) + Connect("SendText(const char*)","EVBMainFrame",parent,"RunPlot(const char*)"); - fMain->SetWindowName("Select File"); + if(dirFlag) + fMain->SetWindowName("Select Directory"); + else + fMain->SetWindowName("Select File"); fMain->MapSubwindows(); fMain->Resize(); fMain->CenterOnParent(); @@ -97,16 +113,19 @@ FileViewFrame::FileViewFrame(const TGWindow* p, const TGFrame* main, UInt_t w, U fMain->Resize(); } -FileViewFrame::~FileViewFrame() { +FileViewFrame::~FileViewFrame() +{ fMain->Cleanup(); //delete children fMain->DeleteWindow(); } -void FileViewFrame::CloseWindow() { +void FileViewFrame::CloseWindow() +{ delete this; } -void FileViewFrame::DoOk() { +void FileViewFrame::DoOk() +{ /*Prevent user from doing something dumb*/ fOkButton->SetState(kButtonDisabled); fCancelButton->SetState(kButtonDisabled); @@ -115,7 +134,8 @@ void FileViewFrame::DoOk() { TString fullpath; if(!dirFlag) fullpath = TString(fContents->GetDirectory()) + "/" + filename; else fullpath = filename; - if(fullpath == "") { //check validity + if(fullpath == "") //check validity + { std::cerr<<"Need to give a name!"<SetState(kButtonUp); fCancelButton->SetState(kButtonUp); @@ -127,7 +147,8 @@ void FileViewFrame::DoOk() { TTimer::SingleShot(150,"FileViewFrame",this,"CloseWindow()"); } -void FileViewFrame::DoCancel() { +void FileViewFrame::DoCancel() +{ /*Prevent user from doing something dumb*/ fOkButton->SetState(kButtonDisabled); fCancelButton->SetState(kButtonDisabled); @@ -137,7 +158,8 @@ void FileViewFrame::DoCancel() { } //Handle directory selection -void FileViewFrame::DisplayDir(const TString& name) { +void FileViewFrame::DisplayDir(const TString& name) +{ fContents->SetDefaultHeaders(); fContents->ChangeDirectory(name); fContents->DisplayDirectory(); @@ -146,23 +168,28 @@ void FileViewFrame::DisplayDir(const TString& name) { } //Handle double click -void FileViewFrame::DoDoubleClick(TGLVEntry *entry, int id) { - if( id != kButton1) return; +void FileViewFrame::DoDoubleClick(TGLVEntry *entry, int id) +{ + if( id != kButton1) + return; TString dirname(fContents->GetDirectory()); TString entryname(entry->GetTitle()); - if(entryname.EndsWith(suffix.c_str())) { //check if its a file + if(entryname.EndsWith(suffix.c_str())) //check if its a file + { TString name = entryname; fNameField->SetText(name.Data()); - } else { + } + else + { DisplayDir(entryname); - if(dirFlag) { + if(dirFlag) fNameField->SetText((dirname+"/"+entryname).Data()); - } } } /*SIGNAL*/ -void FileViewFrame::SendText(const char* text) { +void FileViewFrame::SendText(const char* text) +{ Emit("SendText(const char*)", text); } diff --git a/include/FileViewFrame.h b/src/guidict/FileViewFrame.h similarity index 100% rename from include/FileViewFrame.h rename to src/guidict/FileViewFrame.h diff --git a/include/LinkDef_Gui.h b/src/guidict/LinkDef_Gui.h similarity index 100% rename from include/LinkDef_Gui.h rename to src/guidict/LinkDef_Gui.h diff --git a/src/main.cpp b/src/main.cpp index a98e11b..43f5b63 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,15 @@ -#include "EventBuilder.h" -#include "GWMEventBuilder.h" -#include "Stopwatch.h" +#include "evb/Logger.h" +#include "spsdict/DataStructs.h" +#include "evb/EVBApp.h" +#include "evb/Stopwatch.h" -int main(int argc, char** argv) { - if(argc != 3) { - std::cerr<<"Incorrect number of command line arguments!"< + +struct DPPChannel +{ + double Timestamp; + int Channel, Board, Energy, EnergyShort; + int Flags; +}; + +struct DetectorHit +{ + double Long=-1, Short=-1, Time=-1; + int Ch=-1; +}; + +struct SabreDetector +{ + std::vector rings; + std::vector wedges; +}; + +struct FPDetector +{ + std::vector delayFL, delayFR, delayBL, delayBR; + std::vector anodeF, anodeB, scintL, scintR, cathode; + std::vector monitor; +}; + +struct CoincEvent +{ + FPDetector focalPlane; + SabreDetector sabreArray[5]; //index = ChannelMap Id# -1 +}; + +struct ProcessedEvent +{ + double fp1_tdiff = -1e6, fp2_tdiff = -1e6, fp1_tsum = -1, fp2_tsum = -1, + fp1_tcheck = -1, fp2_tcheck = -1; + double fp1_y=-1, fp2_y=-1; + double anodeFront = -1, anodeBack = -1, scintRight = -1, scintLeft = -1; + double scintRightShort = -1, scintLeftShort = -1; + double cathode = -1; + double xavg = -1e6, x1 = -1e6, x2 = -1e6; + double theta = -1e6; + double sabreRingE[5] = {-1,-1,-1,-1,-1}, sabreWedgeE[5] = {-1,-1,-1,-1,-1}; + double sabreRingChannel[5] = {-1,-1,-1,-1,-1}, sabreWedgeChannel[5] = {-1,-1,-1,-1,-1}; + double sabreRingTime[5] = {-1,-1,-1,-1,-1}, sabreWedgeTime[5] = {-1,-1,-1,-1,-1}; + + double delayFrontRightE = -1, delayFrontLeftE = -1; + double delayBackRightE = -1, delayBackLeftE = -1; + double delayFrontRightShort = -1, delayFrontLeftShort = -1; + double delayBackRightShort = -1, delayBackLeftShort = -1; + double anodeFrontTime = -1, anodeBackTime = -1; + double scintRightTime = -1, scintLeftTime = -1; + double delayFrontMaxTime = -1, delayBackMaxTime = -1; + double delayFrontLeftTime = -1, delayFrontRightTime = -1; + double delayBackLeftTime = -1, delayBackRightTime = -1; + double cathodeTime = -1; + + double monitorE = -1, monitorShort = -1; + double monitorTime = -1; + + + SabreDetector sabreArray[5]; //index = ChannelMap Id# -1 +}; + +/* + ROOT does a bad job of ensuring that header-only type dictionaries (the only type they explicity accept) + are linked when compiled as shared libraries (the recommended method). As a work around, as a dummy function that + ensures the library is linked (better than no-as-needed which I dont think is in general supported across platforms) +*/ +bool EnforceDictionaryLinked(); + +#endif diff --git a/include/LinkDef_sps.h b/src/spsdict/LinkDef_sps.h similarity index 100% rename from include/LinkDef_sps.h rename to src/spsdict/LinkDef_sps.h diff --git a/vendor/spdlog b/vendor/spdlog new file mode 160000 index 0000000..3f49f0f --- /dev/null +++ b/vendor/spdlog @@ -0,0 +1 @@ +Subproject commit 3f49f0f247067830d744b82381ddc41dac9711a1