mirror of
https://github.com/sesps/SPS_SABRE_EventBuilder.git
synced 2024-11-22 10:08:50 -05:00
First commit
This commit is contained in:
commit
e9168bed2a
22
.gitignore
vendored
Normal file
22
.gitignore
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
###directories to ignore###
|
||||
./rootfiles/
|
||||
./pics/
|
||||
./images/
|
||||
./hotfixes/
|
||||
|
||||
###file types to ignore###
|
||||
*.swp
|
||||
*.o
|
||||
*.cxx
|
||||
*.root
|
||||
*.bin
|
||||
*.pcm
|
||||
*.jpg
|
||||
*.png
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
event_log.txt
|
||||
.DS_Store
|
||||
|
||||
###include this###
|
||||
!.gitignore
|
87
README.md
Normal file
87
README.md
Normal file
|
@ -0,0 +1,87 @@
|
|||
# SPS-SABRE Data Analysis Package
|
||||
Version 3
|
||||
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.
|
||||
|
||||
### 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.
|
||||
|
||||
#### Types of Event Building
|
||||
1. Convert: simply sends data from CoMPASS format to ROOT format and time orders the data.
|
||||
2. Slow Events: This perfoms the event building of slow events and then analyzes the slow data. Note that in this option, if there are unresolved multiplicities in data, the analyzer assumes the earliest datum is relevant one.
|
||||
3. Fast Events: This performs the event building of fast events, assuming that slow event data has already been created and EXISTS in the proper directory. The fast event data is then analyzed.
|
||||
4. Analyze Slow Events: This performs analysis of slow event data, without performing any fast sorting.
|
||||
5. Analyze Fast Events: This performs analysis of fast event data.
|
||||
|
||||
#### Slow Sorting
|
||||
The first stage is slow sorting the shifted data by timestamp and orgainizing detector hits into
|
||||
large data events. Events are structures which contain all detector hits that occur within a given coincidence window with physical detector variables. This event data is then written to an output file. The goal of the slow sorting is to be as general as possible; slow sorting should change very little on a data set to data set basis, as this coincidence window is limited mostly be the time difference between an anode hit and the maximum delay line time if the correct shifts are applied to SABRE and the scintillator.
|
||||
|
||||
#### Fast Sorting
|
||||
This is basically a secondary tier of event building, that is more user specific. It breaks down
|
||||
data within the coincidence window into single focal plane events with asscoiated SABRE data. The
|
||||
principle is that the scintillator provides very sharp timing resolution by which we can further
|
||||
refine the built event. Currently, `FastSort` is desinged to take two windows: a coincidence window
|
||||
for SABRE and the scintillator, and a coincidence window for the ion chamber and the scintillator.
|
||||
For the ion chamber, the back anode was chosen to be the representative (it really doesn't matter
|
||||
which part of the ion chamber is chosen). SABRE data is additionally filtered to contain only paired
|
||||
hits (hits that have both a ring and a wedge). Fast sorting is where the user will have to make the
|
||||
most changes to the actual event building. Any new detector or additional changes will require more
|
||||
coincidence definitions and sorting depth.
|
||||
|
||||
#### Analyzing
|
||||
Finally, the sorted event data is then converted into meaningful physical data, and saved to a
|
||||
final analyzed file. This is where the digitizer parameters (charge/energy, time, etc.) are converted
|
||||
into the actual paramters of interest such as focal plane position, SABRE energy, etc. In this way,
|
||||
each raw data file gives four output files from the analysis: a shifted file, a slow sorted file,
|
||||
a fast sorted file, and an analyzed file. The rationale behind the repetative writting is that
|
||||
it helps the user isolate at which stage data issues occur at; this is especially useful for the
|
||||
shifting and sorting stages, where the values for the shifts and coincidence window have to be
|
||||
estimated by the user before running.
|
||||
|
||||
All of the user input is handled through an input file in the program directory named
|
||||
`input.txt`. This file is preformated; all the user needs to do is update the names and
|
||||
values. Everything from input and output directories, to shifts and coincidence windows should
|
||||
be specified in this file. Note that directorires should be explicit fullpaths.
|
||||
|
||||
See the Plotter section for advice on which histograms are useful for choosing the correct shifts
|
||||
and window sizes for the data set.
|
||||
|
||||
### Merging
|
||||
The program is capable of merging several root files together using either `hadd` or the ROOT TChain class. Currently, only the TChain version is implemented in the API, however if you want the other method, it does exist in the RunCollector class.
|
||||
|
||||
### Plotting
|
||||
The plotting is intended to be the final leg of the analysis pipeline. The goal of this program
|
||||
is to take a collection of analyzed files and produce a file containing relevant histograms,
|
||||
graphs, and other such data measures. As it is currently built, this program has no ability to
|
||||
save any data of its own, it merely makes data measures. It is a quick and dirty analysis, and is not intended to be increased beyond merely checking some TCutGs and making some histograms. Cuts can be applied using a cut list. The cut list should contain a name for the cut, the name of the file containing the TCutG ROOT object (named CUTG), and then names for the x and y variables. The x and y variables must be initialized in the variable map. By default x1, x2, xavg, scintLeft, anodeBack, and cathode are all initialized. Any other variables will have to be added by the user by modifiying the CutHandler::InitVariableMap() function.
|
||||
|
||||
#### Determining Shifts and Windows
|
||||
The plotting already provides most of the histograms one would need to determine the shifts and windows
|
||||
for a data set. These, in general, come from plots of the relative time of various components of the
|
||||
detector. The goal of the scintillator and si shifts are to make them occur in coincidence with the
|
||||
anode (pick one of the focal plane anodes, they occur at essentially the same time). Included automatically are plots of the back anode relative to the scintillator (anodeB.Time-scintL.Time, gives scint offset), the is relative to the scint (SABRE fronts and backs... pick higher res one to make offsets and shifts), and maximum delay times relative to scint for both lines.
|
||||
|
||||
The method is the following:
|
||||
|
||||
Using the anode relative to the scint, one can determine the scint offset (center the peak on 0). Then,
|
||||
by looking at the SABRE relative to scint plots one can determine the shift for si and the fast window
|
||||
size (again center the peak on 0, the width of the peak becomes the fast window). Finally, if everything goes according to plan, now the maximum size of the slow coincidence window will be the relative time of the maximum delay line signal. Look at the plot of this and determine where you want to cut off. Run it again and check the results. You should look for, in general, reduced background and noise along with correct centering of the timing peaks.
|
||||
|
||||
### Scaler Support
|
||||
Currently the pipeline supports declaring individual digitizer channels as scalers. These channels will be used a pure counting measures. To make a channel a scaler, put the CoMPASS formated name of the channel and board (check the given etc/ScalerFile.txt for an example) in a text file along with a parameter name for the scaler to be saved as. These files are then processed outside of the event building loop, which can greatly increase the computational speed. Future versions will include scaler rates as well.
|
||||
|
||||
## System Requirements
|
||||
Only tested with `ROOT` 6.14, mileage may vary
|
||||
Uses C++11 standards
|
||||
Only compatible with MacOSX and Linux
|
||||
|
||||
## Compliling and Running
|
||||
To compile use the command `make`
|
||||
To clean run `make clean` and then run `make`
|
||||
For a complete rebuild use `make clean_header` as well as `make clean`.
|
4
bin/.gitignore
vendored
Normal file
4
bin/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
###use this to keep the directory but not any of the contents###
|
||||
*
|
||||
!archivist
|
||||
!.gitignore
|
15
bin/archivist
Executable file
15
bin/archivist
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
RUNNO=$1
|
||||
BINARYDIR=/nvme/27Al_Feb2021/DAQ/run_$RUNNO/UNFILTERED/
|
||||
ARCHIVE=/nvme/WorkingData/raw_binary/run_$RUNNO.tar.gz
|
||||
|
||||
echo "Running archivist for binary data in $BINARYDIR to archive $ARCHIVE..."
|
||||
|
||||
cd $BINARYDIR
|
||||
|
||||
tar -cvzf $ARCHIVE ./*.bin
|
||||
|
||||
cd -
|
||||
|
||||
echo "Complete."
|
146
etc/ChannelMap_Feb2021_SABRE.txt
Normal file
146
etc/ChannelMap_Feb2021_SABRE.txt
Normal file
|
@ -0,0 +1,146 @@
|
|||
Format: global_channel detectorID_number detectorType_identifier detectorPart_identifier
|
||||
NOTE: the focal plane ionchamber is given the UNIQUE detector id of 11. All other detector id ranges should be 0 to nDetectors-1.
|
||||
0 4 SABREWEDGE 0
|
||||
1 4 SABREWEDGE 1
|
||||
2 4 SABREWEDGE 2
|
||||
3 4 SABREWEDGE 3
|
||||
4 4 SABREWEDGE 4
|
||||
5 4 SABREWEDGE 5
|
||||
6 4 SABREWEDGE 6
|
||||
7 4 SABREWEDGE 7
|
||||
8 -1 UNUSED 0
|
||||
9 -1 UNUSED 0
|
||||
10 -1 UNUSED 0
|
||||
11 -1 UNUSED 0
|
||||
12 -1 UNUSED 0
|
||||
13 -1 UNUSED 0
|
||||
14 -1 UNUSED 0
|
||||
15 -1 UNUSED 0
|
||||
16 2 SABREWEDGE 0
|
||||
17 2 SABREWEDGE 1
|
||||
18 2 SABREWEDGE 2
|
||||
19 2 SABREWEDGE 3
|
||||
20 2 SABREWEDGE 4
|
||||
21 2 SABREWEDGE 5
|
||||
22 2 SABREWEDGE 6
|
||||
23 2 SABREWEDGE 7
|
||||
24 3 SABREWEDGE 0
|
||||
25 3 SABREWEDGE 1
|
||||
26 3 SABREWEDGE 2
|
||||
27 3 SABREWEDGE 3
|
||||
28 3 SABREWEDGE 4
|
||||
29 3 SABREWEDGE 5
|
||||
30 3 SABREWEDGE 6
|
||||
31 3 SABREWEDGE 7
|
||||
32 1 SABREWEDGE 0
|
||||
33 1 SABREWEDGE 1
|
||||
34 1 SABREWEDGE 2
|
||||
35 1 SABREWEDGE 3
|
||||
36 1 SABREWEDGE 4
|
||||
37 1 SABREWEDGE 5
|
||||
38 1 SABREWEDGE 6
|
||||
39 1 SABREWEDGE 7
|
||||
40 0 SABREWEDGE 0
|
||||
41 0 SABREWEDGE 1
|
||||
42 0 SABREWEDGE 2
|
||||
43 0 SABREWEDGE 3
|
||||
44 0 SABREWEDGE 4
|
||||
45 0 SABREWEDGE 5
|
||||
46 0 SABREWEDGE 6
|
||||
47 0 SABREWEDGE 7
|
||||
48 4 SABRERING 0
|
||||
49 4 SABRERING 1
|
||||
50 4 SABRERING 2
|
||||
51 4 SABRERING 3
|
||||
52 4 SABRERING 4
|
||||
53 4 SABRERING 5
|
||||
54 4 SABRERING 6
|
||||
55 4 SABRERING 7
|
||||
56 4 SABRERING 8
|
||||
57 4 SABRERING 9
|
||||
58 4 SABRERING 10
|
||||
59 4 SABRERING 11
|
||||
60 4 SABRERING 12
|
||||
61 4 SABRERING 13
|
||||
62 4 SABRERING 14
|
||||
63 4 SABRERING 15
|
||||
64 3 SABRERING 0
|
||||
65 3 SABRERING 1
|
||||
66 3 SABRERING 2
|
||||
67 3 SABRERING 3
|
||||
68 3 SABRERING 4
|
||||
69 3 SABRERING 5
|
||||
70 3 SABRERING 6
|
||||
71 3 SABRERING 7
|
||||
72 3 SABRERING 8
|
||||
73 3 SABRERING 9
|
||||
74 3 SABRERING 10
|
||||
75 3 SABRERING 11
|
||||
76 3 SABRERING 12
|
||||
77 3 SABRERING 13
|
||||
78 3 SABRERING 14
|
||||
79 3 SABRERING 15
|
||||
80 2 SABRERING 0
|
||||
81 2 SABRERING 1
|
||||
82 2 SABRERING 2
|
||||
83 2 SABRERING 3
|
||||
84 2 SABRERING 4
|
||||
85 2 SABRERING 5
|
||||
86 2 SABRERING 6
|
||||
87 2 SABRERING 7
|
||||
88 2 SABRERING 8
|
||||
89 2 SABRERING 9
|
||||
90 2 SABRERING 10
|
||||
91 2 SABRERING 11
|
||||
92 2 SABRERING 12
|
||||
93 2 SABRERING 13
|
||||
94 2 SABRERING 14
|
||||
95 2 SABRERING 15
|
||||
96 1 SABRERING 0
|
||||
97 1 SABRERING 1
|
||||
98 1 SABRERING 2
|
||||
99 1 SABRERING 3
|
||||
100 1 SABRERING 4
|
||||
101 1 SABRERING 5
|
||||
102 1 SABRERING 6
|
||||
103 1 SABRERING 7
|
||||
104 1 SABRERING 8
|
||||
105 1 SABRERING 9
|
||||
106 1 SABRERING 10
|
||||
107 1 SABRERING 11
|
||||
108 1 SABRERING 12
|
||||
109 1 SABRERING 13
|
||||
110 1 SABRERING 14
|
||||
111 1 SABRERING 15
|
||||
112 0 SABRERING 0
|
||||
113 0 SABRERING 1
|
||||
114 0 SABRERING 2
|
||||
115 0 SABRERING 3
|
||||
116 0 SABRERING 4
|
||||
117 0 SABRERING 5
|
||||
118 0 SABRERING 6
|
||||
119 0 SABRERING 7
|
||||
120 0 SABRERING 8
|
||||
121 0 SABRERING 9
|
||||
122 0 SABRERING 10
|
||||
123 0 SABRERING 11
|
||||
124 0 SABRERING 12
|
||||
125 0 SABRERING 13
|
||||
126 0 SABRERING 14
|
||||
127 0 SABRERING 15
|
||||
128 11 FOCALPLANE SCINTRIGHT
|
||||
129 11 FOCALPLANE SCINTLEFT
|
||||
130 -1 UNUSED 0
|
||||
131 -1 UNUSED 0
|
||||
132 -1 UNUSED 0
|
||||
133 -1 UNUSED 0
|
||||
134 -1 UNUSED 0
|
||||
135 11 FOCALPLANE CATHODE
|
||||
136 11 FOCALPLANE DELAYFL
|
||||
137 11 FOCALPLANE DELAYFR
|
||||
138 11 FOCALPLANE DELAYBL
|
||||
139 11 FOCALPLANE DELAYBR
|
||||
140 -1 UNUSED 0
|
||||
141 11 FOCALPLANE ANODEFRONT
|
||||
142 -1 UNUSED 0
|
||||
143 11 FOCALPLANE ANODEBACK
|
146
etc/ChannelMap_March2020_newFormat_092020.txt
Normal file
146
etc/ChannelMap_March2020_newFormat_092020.txt
Normal file
|
@ -0,0 +1,146 @@
|
|||
Format: global_channel detectorID_number detectorType_identifier detectorPart_identifier
|
||||
NOTE: the focal plane ionchamber is given the UNIQUE detector id of 11. All other detector id ranges should be 0 to nDetectors-1.
|
||||
0 4 SABREWEDGE 0
|
||||
1 4 SABREWEDGE 1
|
||||
2 4 SABREWEDGE 2
|
||||
3 4 SABREWEDGE 3
|
||||
4 4 SABREWEDGE 4
|
||||
5 4 SABREWEDGE 5
|
||||
6 4 SABREWEDGE 6
|
||||
7 4 SABREWEDGE 7
|
||||
8 -1 UNUSED 0
|
||||
9 -1 UNUSED 0
|
||||
10 -1 UNUSED 0
|
||||
11 -1 UNUSED 0
|
||||
12 -1 UNUSED 0
|
||||
13 -1 UNUSED 0
|
||||
14 -1 UNUSED 0
|
||||
15 -1 UNUSED 0
|
||||
16 2 SABREWEDGE 0
|
||||
17 2 SABREWEDGE 1
|
||||
18 2 SABREWEDGE 2
|
||||
19 2 SABREWEDGE 3
|
||||
20 2 SABREWEDGE 4
|
||||
21 2 SABREWEDGE 5
|
||||
22 2 SABREWEDGE 6
|
||||
23 2 SABREWEDGE 7
|
||||
24 3 SABREWEDGE 0
|
||||
25 3 SABREWEDGE 1
|
||||
26 3 SABREWEDGE 2
|
||||
27 3 SABREWEDGE 3
|
||||
28 3 SABREWEDGE 4
|
||||
29 3 SABREWEDGE 5
|
||||
30 3 SABREWEDGE 6
|
||||
31 3 SABREWEDGE 7
|
||||
32 1 SABREWEDGE 0
|
||||
33 1 SABREWEDGE 1
|
||||
34 1 SABREWEDGE 2
|
||||
35 1 SABREWEDGE 3
|
||||
36 1 SABREWEDGE 4
|
||||
37 1 SABREWEDGE 5
|
||||
38 1 SABREWEDGE 6
|
||||
39 1 SABREWEDGE 7
|
||||
40 0 SABREWEDGE 0
|
||||
41 0 SABREWEDGE 1
|
||||
42 0 SABREWEDGE 2
|
||||
43 0 SABREWEDGE 3
|
||||
44 0 SABREWEDGE 4
|
||||
45 0 SABREWEDGE 5
|
||||
46 0 SABREWEDGE 6
|
||||
47 0 SABREWEDGE 7
|
||||
48 4 SABRERING 0
|
||||
49 4 SABRERING 1
|
||||
50 4 SABRERING 2
|
||||
51 4 SABRERING 3
|
||||
52 4 SABRERING 4
|
||||
53 4 SABRERING 5
|
||||
54 4 SABRERING 6
|
||||
55 4 SABRERING 7
|
||||
56 4 SABRERING 8
|
||||
57 4 SABRERING 9
|
||||
58 4 SABRERING 10
|
||||
59 4 SABRERING 11
|
||||
60 4 SABRERING 12
|
||||
61 4 SABRERING 13
|
||||
62 4 SABRERING 14
|
||||
63 4 SABRERING 15
|
||||
64 3 SABRERING 0
|
||||
65 3 SABRERING 1
|
||||
66 3 SABRERING 2
|
||||
67 3 SABRERING 3
|
||||
68 3 SABRERING 4
|
||||
69 3 SABRERING 5
|
||||
70 3 SABRERING 6
|
||||
71 3 SABRERING 7
|
||||
72 3 SABRERING 8
|
||||
73 3 SABRERING 9
|
||||
74 3 SABRERING 10
|
||||
75 3 SABRERING 11
|
||||
76 3 SABRERING 12
|
||||
77 3 SABRERING 13
|
||||
78 3 SABRERING 14
|
||||
79 3 SABRERING 15
|
||||
80 2 SABRERING 0
|
||||
81 2 SABRERING 1
|
||||
82 2 SABRERING 2
|
||||
83 2 SABRERING 3
|
||||
84 2 SABRERING 4
|
||||
85 2 SABRERING 5
|
||||
86 2 SABRERING 6
|
||||
87 2 SABRERING 7
|
||||
88 2 SABRERING 8
|
||||
89 2 SABRERING 9
|
||||
90 2 SABRERING 10
|
||||
91 2 SABRERING 11
|
||||
92 2 SABRERING 12
|
||||
93 2 SABRERING 13
|
||||
94 2 SABRERING 14
|
||||
95 2 SABRERING 15
|
||||
96 1 SABRERING 0
|
||||
97 1 SABRERING 1
|
||||
98 1 SABRERING 2
|
||||
99 1 SABRERING 3
|
||||
100 1 SABRERING 4
|
||||
101 1 SABRERING 5
|
||||
102 1 SABRERING 6
|
||||
103 1 SABRERING 7
|
||||
104 1 SABRERING 8
|
||||
105 1 SABRERING 9
|
||||
106 1 SABRERING 10
|
||||
107 1 SABRERING 11
|
||||
108 1 SABRERING 12
|
||||
109 1 SABRERING 13
|
||||
110 1 SABRERING 14
|
||||
111 1 SABRERING 15
|
||||
112 0 SABRERING 0
|
||||
113 0 SABRERING 1
|
||||
114 0 SABRERING 2
|
||||
115 0 SABRERING 3
|
||||
116 0 SABRERING 4
|
||||
117 0 SABRERING 5
|
||||
118 0 SABRERING 6
|
||||
119 0 SABRERING 7
|
||||
120 0 SABRERING 8
|
||||
121 0 SABRERING 9
|
||||
122 0 SABRERING 10
|
||||
123 0 SABRERING 11
|
||||
124 0 SABRERING 12
|
||||
125 0 SABRERING 13
|
||||
126 0 SABRERING 14
|
||||
127 0 SABRERING 15
|
||||
128 11 FOCALPLANE SCINTRIGHT
|
||||
129 11 FOCALPLANE SCINTLEFT
|
||||
130 -1 UNUSED 0
|
||||
131 -1 UNUSED 0
|
||||
132 -1 UNUSED 0
|
||||
133 -1 UNUSED 0
|
||||
134 -1 UNUSED 0
|
||||
135 11 FOCALPLANE CATHODE
|
||||
136 11 FOCALPLANE DELAYFL
|
||||
137 11 FOCALPLANE DELAYFR
|
||||
138 11 FOCALPLANE DELAYBL
|
||||
139 11 FOCALPLANE DELAYBR
|
||||
140 -1 UNUSED 0
|
||||
141 11 FOCALPLANE ANODEFRONT
|
||||
142 -1 UNUSED 0
|
||||
143 11 FOCALPLANE ANODEBACK
|
18
etc/ChannelMap_Nov2020_50Tidp.txt
Normal file
18
etc/ChannelMap_Nov2020_50Tidp.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
Format: global_channel detectorID_number detectorType_identifier detectorPart_identifier
|
||||
NOTE: the focal plane ionchamber is given the UNIQUE detector id of 11. All other detector id ranges should be 0 to nDetectors-1.
|
||||
0 11 FOCALPLANE SCINTRIGHT
|
||||
1 11 FOCALPLANE SCINTLEFT
|
||||
2 -1 UNUSED 0
|
||||
3 11 FOCALPLANE MONITOR
|
||||
4 -1 UNUSED 0
|
||||
5 11 FOCALPLANE BEAMINT
|
||||
6 -1 UNUSED 0
|
||||
7 11 FOCALPLANE CATHODE
|
||||
8 11 FOCALPLANE DELAYFL
|
||||
9 11 FOCALPLANE DELAYFR
|
||||
10 11 FOCALPLANE DELAYBL
|
||||
11 11 FOCALPLANE DELAYBR
|
||||
12 -1 UNUSED 0
|
||||
13 11 FOCALPLANE ANODEFRONT
|
||||
14 -1 UNUSED 0
|
||||
15 11 FOCALPLANE ANODEBACK
|
4
etc/CutList_Feb2021_10B3hea.txt
Normal file
4
etc/CutList_Feb2021_10B3hea.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
E_dE_CutFile: /data1/gwm17/10B3He/Feb2021/cuts/edeCut_Rachel.root
|
||||
dE_position_CutFile: /data1/gwm17/10B3He/Feb2021/cuts/alphaCut_03012021.root
|
||||
E_positon_CutFile: /data1/gwm17/10B3He/Feb2021/cuts/alphaCut_03012021.root
|
||||
x1_x2_CutFile: /data1/gwm17/10B3He/Feb2021/cuts/xxCut_Rachel.root
|
4
etc/CutList_March2020.txt
Normal file
4
etc/CutList_March2020.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
E_dE_CutFile: /Volumes/LaCie/9BMarch2020/cuts/alphaCut_dbr_sl.root
|
||||
dE_position_CutFile: /Volumes/LaCie/9BMarch2020/cuts/delayEXavgCut.root
|
||||
E_positon_CutFile: /Volumes/LaCie/9BMarch2020/cuts/scintXavgCut.root
|
||||
x1_x2_CutFile: /Volumes/LaCie/9BMarch2020/cuts/x1x2Cut.root
|
4
etc/CutList_Nov2020_50Tidp.txt
Normal file
4
etc/CutList_Nov2020_50Tidp.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
E_dE_CutFile: /media/gordon/b6414c35-ec1f-4fc1-83bc-a6b68ca4325a/gwm17/50Tidp/cuts/EdECut_run16.root
|
||||
dE_position_CutFile: /media/gordon/b6414c35-ec1f-4fc1-83bc-a6b68ca4325a/gwm17/50Tidp/cuts/EdECut_run16.root
|
||||
E_positon_CutFile: /media/gordon/b6414c35-ec1f-4fc1-83bc-a6b68ca4325a/gwm17/50Tidp/cuts/EdECut_run16.root
|
||||
x1_x2_CutFile: /media/gordon/b6414c35-ec1f-4fc1-83bc-a6b68ca4325a/gwm17/50Tidp/cuts/x1x2Cut_run16.root
|
93
etc/Plotter.C
Normal file
93
etc/Plotter.C
Normal file
|
@ -0,0 +1,93 @@
|
|||
#include <TROOT.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TFile.h>
|
||||
#include <TCutG.h>
|
||||
#include <TTree.h>
|
||||
#include <iostream>
|
||||
#include "include/DataStructs.h"
|
||||
R__LOAD_LIBRARY(lib/libSPSDict.dylib)
|
||||
|
||||
void Plotter() {
|
||||
TFile* input = TFile::Open("/Volumes/LaCie/9BMarch2020/combined/main_data_carbonCal.root","READ");
|
||||
TTree* intree = (TTree*) input->Get("SPSTree");
|
||||
|
||||
TFile *cutfile = TFile::Open("/Volumes/LaCie/9BMarch2020/maindata_12C_extraTheta.root","READ");
|
||||
TCutG *cut = (TCutG*) cutfile->Get("CUTG");
|
||||
cut->SetName("extraTheta");
|
||||
cut->SetLineColor(kRed);
|
||||
cut->SetVarX("xavg");
|
||||
cut->SetVarY("theta");
|
||||
|
||||
ProcessedEvent *event_address = new ProcessedEvent();
|
||||
intree->SetBranchAddress("event", &event_address);
|
||||
|
||||
TFile *outfile = TFile::Open("/Volumes/LaCie/9BMarch2020/9b_histograms/carbonCal_thetaGating.root","RECREATE");
|
||||
TH2F *xtheta = new TH2F("xtheta","xtheta",600,-300,300,300,0,1.75);
|
||||
TH2F *xde = new TH2F("xde","xde",600,-300,300,512,0,4096);
|
||||
TH2F *xde_thetaCut = new TH2F("xde_thetaCut","xde_thetaCut",600,-300,300,512,0,4096);
|
||||
xde_thetaCut->SetLineColor(kRed);
|
||||
xde_thetaCut->SetMarkerColor(kRed);
|
||||
TH2F *xde_antithetaCut = new TH2F("xde_antithetaCut","xde_antithetaCut",600,-300,300,512,0,4096);
|
||||
xde_antithetaCut->SetLineColor(kBlack);
|
||||
xde_antithetaCut->SetMarkerColor(kBlue);
|
||||
TH1F *anodeRelTime = new TH1F("anodeRelTime","anodeRelTime",1000,-1000,1000);
|
||||
TH1F *anodeRelTime_thetaCut = new TH1F("anodeRelTime_thetaCut","anodeRelTime_thetacut",1000,-1000,1000);
|
||||
anodeRelTime_thetaCut->SetLineColor(kRed);
|
||||
TH1F *anodeRelTime_antithetaCut = new TH1F("anodeRelTime_antithetaCut","anodeRelTime_antithetacut",1000,-1000,1000);
|
||||
anodeRelTime_antithetaCut->SetLineColor(kBlack);
|
||||
|
||||
std::cout<<"Total number of Entries: "<<intree->GetEntries()<<std::endl;
|
||||
for(ULong64_t i=0; i<intree->GetEntries(); i++) {
|
||||
std::cout<<"\rNumber of events processed: "<<i<<std::flush;
|
||||
intree->GetEntry(i);
|
||||
double anodeRT = event_address->anodeBackTime - event_address->scintLeftTime;
|
||||
|
||||
if(anodeRT != 0) {
|
||||
xtheta->Fill(event_address->xavg, event_address->theta);
|
||||
xde->Fill(event_address->xavg, event_address->delayBackRightE);
|
||||
anodeRelTime->Fill(anodeRT);
|
||||
if(cut->IsInside(event_address->xavg, event_address->theta)) {
|
||||
xde_thetaCut->Fill(event_address->xavg, event_address->delayBackRightE);
|
||||
anodeRelTime_thetaCut->Fill(anodeRT);
|
||||
} else {
|
||||
xde_antithetaCut->Fill(event_address->xavg, event_address->delayBackRightE);
|
||||
anodeRelTime_antithetaCut->Fill(anodeRT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TCanvas *c1 = new TCanvas();
|
||||
c1->Divide(2,2);
|
||||
c1->cd(1);
|
||||
xde->Draw("colz");
|
||||
c1->cd(2);
|
||||
xde_antithetaCut->Draw();
|
||||
xde_thetaCut->Draw("same");
|
||||
c1->BuildLegend();
|
||||
c1->cd(3);
|
||||
anodeRelTime->Draw();
|
||||
anodeRelTime_antithetaCut->Draw("same");
|
||||
anodeRelTime_thetaCut->Draw("same");
|
||||
c1->BuildLegend();
|
||||
c1->cd(4);
|
||||
xtheta->Draw();
|
||||
cut->Draw("same");
|
||||
|
||||
input->Close();
|
||||
cutfile->Close();
|
||||
|
||||
outfile->cd();
|
||||
xtheta->Write();
|
||||
xde->Write();
|
||||
xde_thetaCut->Write();
|
||||
xde_antithetaCut->Write();
|
||||
anodeRelTime->Write();
|
||||
anodeRelTime_thetaCut->Write();
|
||||
anodeRelTime_antithetaCut->Write();
|
||||
c1->Write();
|
||||
|
||||
c1->Close();
|
||||
outfile->Close();
|
||||
|
||||
|
||||
}
|
133
etc/SabreSingles.C
Normal file
133
etc/SabreSingles.C
Normal file
|
@ -0,0 +1,133 @@
|
|||
#include <TROOT.h>
|
||||
#include <TFile.h>
|
||||
#include <TTree.h>
|
||||
#include <TH1.h>
|
||||
#include <THashTable.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "include/DataStructs.h"
|
||||
#include "include/CompassHit.h"
|
||||
#include "include/GainMatcher.h"
|
||||
#include "include/SabreMap.h"
|
||||
|
||||
R__LOAD_LIBRARY(lib/libGainMatcher.dylib)
|
||||
R__LOAD_LIBRARY(lib/libSPSDict.dylib)
|
||||
R__LOAD_LIBRARY(lib/libSabreMap.dylib)
|
||||
|
||||
|
||||
void MyFill(THashTable *table, std::string name, int bins, double min, double max, double value) {
|
||||
TH1F *histo = (TH1F*) table->FindObject(name.c_str());
|
||||
if(histo == NULL) {
|
||||
TH1F* h = new TH1F(name.c_str(), name.c_str(), bins, min, max);
|
||||
h->Fill(value);
|
||||
table->Add(h);
|
||||
} else {
|
||||
histo->Fill(value);
|
||||
}
|
||||
}
|
||||
|
||||
void MyFill(THashTable *table, 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 == NULL) {
|
||||
TH2F* h = new TH2F(name.c_str(), name.c_str(), binsx, minx, maxx, binsy, miny, maxy);
|
||||
h->Fill(valuex, valuey);
|
||||
table->Add(h);
|
||||
} else {
|
||||
histo->Fill(valuex, valuey);
|
||||
}
|
||||
}
|
||||
|
||||
void SabreSingles_raw() {
|
||||
|
||||
GainMatcher gains;
|
||||
gains.SetFile("etc/March2020_gainmatch_2.0V_5486Am241.txt");
|
||||
|
||||
std::unordered_map<int, sabrechan> smap;
|
||||
|
||||
FillSabreMap("etc/ChannelMap_March2020_flipping.dat", smap);
|
||||
|
||||
TFile *input = TFile::Open("/Volumes/LaCie/9BMarch2020/raw_root_singles/compass_run_37.root", "READ");
|
||||
TTree *intree = (TTree*) input->Get("Data");
|
||||
|
||||
ULong64_t ts;
|
||||
UShort_t e, c, b, es;
|
||||
UInt_t f;
|
||||
intree->SetBranchAddress("Timestamp", &ts);
|
||||
intree->SetBranchAddress("Channel", &c);
|
||||
intree->SetBranchAddress("Board", &b);
|
||||
intree->SetBranchAddress("Energy", &e);
|
||||
intree->SetBranchAddress("EnergyShort", &es);
|
||||
intree->SetBranchAddress("Flags", &f);
|
||||
intree->SetMaxVirtualSize(4000000000);
|
||||
|
||||
TFile *output = TFile::Open("/Volumes/LaCie/9BMarch2020/analyzed_singles/singles_run37.root","RECREATE");
|
||||
THashTable *hash = new THashTable();
|
||||
|
||||
int gchan;
|
||||
DPPChannel hit;
|
||||
cout<<"Total Number of Entries: "<<intree->GetEntries()<<endl;
|
||||
for(ULong64_t i=0; i<intree->GetEntries(); i++) {
|
||||
intree->GetEntry(i);
|
||||
std::cout<<"\rNumber of entries processed: "<<i<<std::flush;
|
||||
|
||||
hit.Timestamp = ts;
|
||||
hit.Energy = e;
|
||||
hit.Channel = c;
|
||||
hit.Board = b;
|
||||
hit.EnergyShort = es;
|
||||
hit.Flags = f;
|
||||
|
||||
gchan = hit.Channel + hit.Board*16;
|
||||
|
||||
sabrechan& schan = smap[gchan];
|
||||
|
||||
if(schan.side_pos.first == "RING" && hit.Energy>20) {
|
||||
MyFill(hash, Form("detector%i_ring%i_energy",schan.detID,hit.Channel), 280, 0, 28, hit.Energy*gains.GetScaler(gchan));
|
||||
}
|
||||
}
|
||||
|
||||
input->Close();
|
||||
hash->Write();
|
||||
output->Close();
|
||||
}
|
||||
|
||||
void SabreSingles_analyzed() {
|
||||
|
||||
std::unordered_map<int, sabrechan> smap;
|
||||
FillSabreMap("etc/ChannelMap_March2020_flipping.dat", smap);
|
||||
|
||||
TFile *input = TFile::Open("/Volumes/LaCie/9BMarch2020/combined/downscaled_singles.root", "READ");
|
||||
TTree *intree = (TTree*) input->Get("SPSTree");
|
||||
|
||||
ProcessedEvent *event_address = new ProcessedEvent();
|
||||
intree->SetBranchAddress("event", &event_address);
|
||||
intree->SetMaxVirtualSize(4000000000);
|
||||
|
||||
TFile *output = TFile::Open("/Volumes/LaCie/9BMarch2020/analyzed_singles/downscale_histograms.root", "RECREATE");
|
||||
THashTable *hash = new THashTable();
|
||||
|
||||
std::cout<<"Total entries: "<<intree->GetEntries()<<std::endl;
|
||||
for(ULong64_t i=0; i<intree->GetEntries(); i++) {
|
||||
std::cout<<"\rNumber of entries processed: "<<i<<std::flush;
|
||||
intree->GetEntry(i);
|
||||
|
||||
for(int j=0; j<5; j++) {
|
||||
for(unsigned int k=0; k<(event_address->sabreArray[j].rings.size()); k++) {
|
||||
MyFill(hash, Form("detector%i_ring%i_energy",j,event_address->sabreArray[j].rings[k].Ch), 280,0,28, event_address->sabreArray[j].rings[k].Long);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input->Close();
|
||||
hash->Write();
|
||||
output->Close();
|
||||
delete event_address;
|
||||
}
|
||||
|
||||
void SabreSingles() {
|
||||
//SabreSingles_raw();
|
||||
SabreSingles_analyzed();
|
||||
}
|
||||
|
3
etc/ScalerFile.txt
Normal file
3
etc/ScalerFile.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Format: scaler_param_name assoc_binary_file_name_without_runID
|
||||
NOTE: As of this version, scalers are pure counting parameters (the total events will be counted and saved as a TParameter with the data)
|
||||
Data_CH5@V1730_89 beamint
|
5
etc/ScalerFile_Feb2021_SABRE.txt
Normal file
5
etc/ScalerFile_Feb2021_SABRE.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
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
|
||||
CH1@V1730_89_Data t2
|
||||
|
12
etc/ShiftMap_April2020_newFormat_10102020.txt
Normal file
12
etc/ShiftMap_April2020_newFormat_10102020.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
Format: board channel/keyword shift
|
||||
NOTE: Do not delete these lines! If no shift is specified for a channel, no shift is applied. Use keyword 'all' to apply a uniform shift to all channels in a single board. Shifts are in ps.
|
||||
0 all 110000
|
||||
1 all 70000
|
||||
2 all 70000
|
||||
3 all -115000
|
||||
4 all 185000
|
||||
5 all 195000
|
||||
6 all 225000
|
||||
7 all 235000
|
||||
8 0 650000
|
||||
8 1 650000
|
12
etc/ShiftMap_Feb2021_SABRE.txt
Normal file
12
etc/ShiftMap_Feb2021_SABRE.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
Format: board channel/keyword shift
|
||||
NOTE: Do not delete these lines! If no shift is specified for a channel, no shift is applied. Use keyword 'all' to apply a uniform shift to all channels in a single board. Shifts are in ps.
|
||||
0 all 260000
|
||||
1 all 220000
|
||||
2 all 220000
|
||||
3 all 335000
|
||||
4 all 385000
|
||||
5 all 395000
|
||||
6 all 425000
|
||||
7 all 435000
|
||||
8 0 900000
|
||||
8 1 900000
|
4
etc/ShiftMap_Nov2020_50Tidp.txt
Normal file
4
etc/ShiftMap_Nov2020_50Tidp.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
Format: board channel/keyword shift
|
||||
NOTE: Do not delete these lines! If no shift is specified for a channel, no shift is applied. Use keyword 'all' to apply a uniform shift to all channels in a single board. Shifts are in ps.
|
||||
0 0 685000
|
||||
0 1 685000
|
15
etc/default_input.txt
Normal file
15
etc/default_input.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
Ztarget: 6 Atarget: 12 Zproj: 2 Aproj: 3 Zeject: 2 Aeject: 4
|
||||
BeamE(MeV): 24 Angle(deg): 20 Bfield(G): 9500
|
||||
Board_shift_file: ./etc/ShiftMap_April2020.txt
|
||||
Scint_offset(ps): 0.65e6
|
||||
coincidence_window(ps): 1.5e6
|
||||
si_fast_coincidence_window(ps): 0.125e6
|
||||
ion_chamber_fast_coincidence_window(ps): 0.25e6
|
||||
DataDir: /Users/gordonmccann/Desktop/GWM_EventBuilder/example/raw_root/
|
||||
MinRun: -99 MaxRun: 99
|
||||
TimeshiftedDir: /Users/gordonmccann/Desktop/GWM_EventBuilder/example/shifted/
|
||||
SortedDir: /Users/gordonmccann/Desktop/GWM_EventBuilder/example//sorted/
|
||||
FastDir: /Users/gordonmccann/Desktop/GWM_EventBuilder/example/fast/
|
||||
AnalyzedDir: /Users/gordonmccann/Desktop/GWM_EventBuilder/example/analyzed/
|
||||
SABREChannelMapFile: ./etc/ChannelMap_March2020.dat
|
||||
GainMatchingFile: ./etc/March2020_gainmatch_2.0V_5486Am241.txt
|
11
etc/logo.txt
Normal file
11
etc/logo.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
_
|
||||
| |
|
||||
| |
|
||||
___ _ __ ___ ___ ____ _| |__ _ _______
|
||||
/ __|| ' \/ __|/ __| / __ ` | _ \| '__/ __ \
|
||||
\__ \| |\ \__ \\__ \| | | | | | | | | |__| |
|
||||
__) | |/ /__) |__) | |__| | |_| | | | ___/
|
||||
|___/| .__/|___/____/ \____,_|____/|_| \____|
|
||||
| |
|
||||
| |
|
||||
|_|
|
2501
etc/mass.txt
Normal file
2501
etc/mass.txt
Normal file
File diff suppressed because it is too large
Load Diff
3
etc/new_CutList_Feb202110B3hea.txt
Normal file
3
etc/new_CutList_Feb202110B3hea.txt
Normal file
|
@ -0,0 +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
|
146
etc/orig_ChannelMap_Feb2021_SABRE.txt
Normal file
146
etc/orig_ChannelMap_Feb2021_SABRE.txt
Normal file
|
@ -0,0 +1,146 @@
|
|||
Format: global_channel detectorID_number detectorType_identifier detectorPart_identifier
|
||||
NOTE: the focal plane ionchamber is given the UNIQUE detector id of 11. All other detector id ranges should be 0 to nDetectors-1.
|
||||
0 4 SABREWEDGE 0
|
||||
1 4 SABREWEDGE 1
|
||||
2 4 SABREWEDGE 2
|
||||
3 4 SABREWEDGE 3
|
||||
4 4 SABREWEDGE 4
|
||||
5 4 SABREWEDGE 5
|
||||
6 4 SABREWEDGE 6
|
||||
7 4 SABREWEDGE 7
|
||||
8 -1 UNUSED 0
|
||||
9 -1 UNUSED 0
|
||||
10 -1 UNUSED 0
|
||||
11 -1 UNUSED 0
|
||||
12 -1 UNUSED 0
|
||||
13 -1 UNUSED 0
|
||||
14 -1 UNUSED 0
|
||||
15 -1 UNUSED 0
|
||||
16 2 SABREWEDGE 0
|
||||
17 2 SABREWEDGE 1
|
||||
18 2 SABREWEDGE 2
|
||||
19 2 SABREWEDGE 3
|
||||
20 2 SABREWEDGE 4
|
||||
21 2 SABREWEDGE 5
|
||||
22 2 SABREWEDGE 6
|
||||
23 2 SABREWEDGE 7
|
||||
24 3 SABREWEDGE 0
|
||||
25 3 SABREWEDGE 1
|
||||
26 3 SABREWEDGE 2
|
||||
27 3 SABREWEDGE 3
|
||||
28 3 SABREWEDGE 4
|
||||
29 3 SABREWEDGE 5
|
||||
30 3 SABREWEDGE 6
|
||||
31 3 SABREWEDGE 7
|
||||
32 1 SABREWEDGE 0
|
||||
33 1 SABREWEDGE 1
|
||||
34 1 SABREWEDGE 2
|
||||
35 1 SABREWEDGE 3
|
||||
36 1 SABREWEDGE 4
|
||||
37 1 SABREWEDGE 5
|
||||
38 1 SABREWEDGE 6
|
||||
39 1 SABREWEDGE 7
|
||||
40 0 SABREWEDGE 0
|
||||
41 0 SABREWEDGE 1
|
||||
42 0 SABREWEDGE 2
|
||||
43 0 SABREWEDGE 3
|
||||
44 0 SABREWEDGE 4
|
||||
45 0 SABREWEDGE 5
|
||||
46 0 SABREWEDGE 6
|
||||
47 0 SABREWEDGE 7
|
||||
48 4 SABRERING 0
|
||||
49 4 SABRERING 1
|
||||
50 4 SABRERING 2
|
||||
51 4 SABRERING 3
|
||||
52 4 SABRERING 4
|
||||
53 4 SABRERING 5
|
||||
54 4 SABRERING 6
|
||||
55 4 SABRERING 7
|
||||
56 4 SABRERING 8
|
||||
57 4 SABRERING 9
|
||||
58 4 SABRERING 10
|
||||
59 4 SABRERING 11
|
||||
60 4 SABRERING 12
|
||||
61 4 SABRERING 13
|
||||
62 4 SABRERING 14
|
||||
63 4 SABRERING 15
|
||||
64 3 SABRERING 0
|
||||
65 3 SABRERING 1
|
||||
66 3 SABRERING 2
|
||||
67 3 SABRERING 3
|
||||
68 3 SABRERING 4
|
||||
69 3 SABRERING 5
|
||||
70 3 SABRERING 6
|
||||
71 3 SABRERING 7
|
||||
72 3 SABRERING 8
|
||||
73 3 SABRERING 9
|
||||
74 3 SABRERING 10
|
||||
75 3 SABRERING 11
|
||||
76 3 SABRERING 12
|
||||
77 3 SABRERING 13
|
||||
78 3 SABRERING 14
|
||||
79 3 SABRERING 15
|
||||
80 2 SABRERING 0
|
||||
81 2 SABRERING 1
|
||||
82 2 SABRERING 2
|
||||
83 2 SABRERING 3
|
||||
84 2 SABRERING 4
|
||||
85 2 SABRERING 5
|
||||
86 2 SABRERING 6
|
||||
87 2 SABRERING 7
|
||||
88 2 SABRERING 8
|
||||
89 2 SABRERING 9
|
||||
90 2 SABRERING 10
|
||||
91 2 SABRERING 11
|
||||
92 2 SABRERING 12
|
||||
93 2 SABRERING 13
|
||||
94 2 SABRERING 14
|
||||
95 2 SABRERING 15
|
||||
96 1 SABRERING 0
|
||||
97 1 SABRERING 1
|
||||
98 1 SABRERING 2
|
||||
99 1 SABRERING 3
|
||||
100 1 SABRERING 4
|
||||
101 1 SABRERING 5
|
||||
102 1 SABRERING 6
|
||||
103 1 SABRERING 7
|
||||
104 1 SABRERING 8
|
||||
105 1 SABRERING 9
|
||||
106 1 SABRERING 10
|
||||
107 1 SABRERING 11
|
||||
108 1 SABRERING 12
|
||||
109 1 SABRERING 13
|
||||
110 1 SABRERING 14
|
||||
111 1 SABRERING 15
|
||||
112 0 SABRERING 0
|
||||
113 0 SABRERING 1
|
||||
114 0 SABRERING 2
|
||||
115 0 SABRERING 3
|
||||
116 0 SABRERING 4
|
||||
117 0 SABRERING 5
|
||||
118 0 SABRERING 6
|
||||
119 0 SABRERING 7
|
||||
120 0 SABRERING 8
|
||||
121 0 SABRERING 9
|
||||
122 0 SABRERING 10
|
||||
123 0 SABRERING 11
|
||||
124 0 SABRERING 12
|
||||
125 0 SABRERING 13
|
||||
126 0 SABRERING 14
|
||||
127 0 SABRERING 15
|
||||
128 11 FOCALPLANE SCINTRIGHT
|
||||
129 11 FOCALPLANE SCINTLEFT
|
||||
130 -1 UNUSED 0
|
||||
131 -1 UNUSED 0
|
||||
132 -1 UNUSED 0
|
||||
133 -1 UNUSED 0
|
||||
134 -1 UNUSED 0
|
||||
135 11 FOCALPLANE CATHODE
|
||||
136 11 FOCALPLANE DELAYFL
|
||||
137 11 FOCALPLANE DELAYFR
|
||||
138 11 FOCALPLANE DELAYBL
|
||||
139 11 FOCALPLANE DELAYBR
|
||||
140 -1 UNUSED 0
|
||||
141 11 FOCALPLANE ANODEFRONT
|
||||
142 -1 UNUSED 0
|
||||
143 11 FOCALPLANE ANODEBACK
|
3
etc/orig_ScalerFile_Feb2021_SABRE.txt
Normal file
3
etc/orig_ScalerFile_Feb2021_SABRE.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
Format: scaler_param_name assoc_binary_file_name_without_runID
|
||||
NOTE: As of this version, scalers are pure counting parameters (the total events will be counted and saved as a TParameter with the data)
|
||||
CH5@V1730_89_Data beamint
|
12
etc/orig_ShiftMap_Feb2021_SABRE.txt
Normal file
12
etc/orig_ShiftMap_Feb2021_SABRE.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
Format: board channel/keyword shift
|
||||
NOTE: Do not delete these lines! If no shift is specified for a channel, no shift is applied. Use keyword 'all' to apply a uniform shift to all channels in a single board. Shifts are in ps.
|
||||
0 all 110000
|
||||
1 all 70000
|
||||
2 all 70000
|
||||
3 all 135000
|
||||
4 all 185000
|
||||
5 all 195000
|
||||
6 all 225000
|
||||
7 all 235000
|
||||
8 0 650000
|
||||
8 1 650000
|
2
example/.gitignore
vendored
Normal file
2
example/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
###Keep this dir###
|
||||
!.gitignore
|
BIN
example/EventBuilderGuide.pdf
Normal file
BIN
example/EventBuilderGuide.pdf
Normal file
Binary file not shown.
2
example/analyzed/.gitignore
vendored
Normal file
2
example/analyzed/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
###Keep this dir###
|
||||
!.gitignore
|
2
example/cuts/.gitignore
vendored
Normal file
2
example/cuts/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
###Keep this dir###
|
||||
!.gitignore
|
2
example/fast/.gitignore
vendored
Normal file
2
example/fast/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
###Keep this dir###
|
||||
!.gitignore
|
2
example/histograms/.gitignore
vendored
Normal file
2
example/histograms/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
###Keep this dir###
|
||||
!.gitignore
|
2
example/raw_binary/.gitignore
vendored
Normal file
2
example/raw_binary/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
###Keep this dir###
|
||||
!.gitignore
|
BIN
example/raw_binary/run_75.tar.gz
Normal file
BIN
example/raw_binary/run_75.tar.gz
Normal file
Binary file not shown.
2
example/raw_root/.gitignore
vendored
Normal file
2
example/raw_root/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
###Keep this dir###
|
||||
!.gitignore
|
2
example/sorted/.gitignore
vendored
Normal file
2
example/sorted/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
###Keep this dir###
|
||||
!.gitignore
|
2
example/temp_binary/.gitignore
vendored
Normal file
2
example/temp_binary/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
###Keep this dir###
|
||||
!.gitignore
|
5
include/.gitignore
vendored
Normal file
5
include/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
###ignore pch###
|
||||
*.gch
|
||||
|
||||
###include this###
|
||||
!.gitignore
|
57
include/ChannelMap.h
Normal file
57
include/ChannelMap.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
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<int, Channel> Containter;
|
||||
typedef std::unordered_map<int, Channel>::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
|
66
include/CompassFile.h
Normal file
66
include/CompassFile.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
CompassFile.h
|
||||
Wrapper class around a shared pointer to an ifstream. Here the shared pointer is used
|
||||
to overcome limitations of the ifstream class, namely that it is written such that ifstream
|
||||
cannot be modified by move semantics. Contains all information needed to parse a single binary
|
||||
CompassFile. Currently has a class wide defined buffer size; may want to make this user input
|
||||
in the future.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#ifndef COMPASSFILE_H
|
||||
#define COMPASSFILE_H
|
||||
|
||||
#include "CompassHit.h"
|
||||
#include "ShiftMap.h"
|
||||
#include <memory>
|
||||
|
||||
class CompassFile {
|
||||
public:
|
||||
CompassFile();
|
||||
CompassFile(const std::string& filename);
|
||||
CompassFile(const std::string& filename, 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<char>;
|
||||
|
||||
using FilePointer = std::shared_ptr<std::ifstream>; //to make this class copy/movable
|
||||
|
||||
std::string m_filename;
|
||||
Buffer hitBuffer;
|
||||
char* bufferIter;
|
||||
char* bufferEnd;
|
||||
ShiftMap* m_smap; //NOT owned by CompassFile. DO NOT delete
|
||||
bool hitUsedFlag;
|
||||
int bufsize = 200000; //size of the buffer in hits
|
||||
int hitsize = 24; //size of a CompassHit in bytes (without alignment padding)
|
||||
int m_buffersize;
|
||||
CompassHit m_currentHit;
|
||||
FilePointer m_file;
|
||||
bool eofFlag;
|
||||
unsigned int m_size; //size of the file in bytes
|
||||
unsigned int m_nHits; //number of hits in the file (m_size/24)
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
14
include/CompassHit.h
Normal file
14
include/CompassHit.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#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
|
69
include/CompassRun.h
Normal file
69
include/CompassRun.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
CompassRun.h
|
||||
Class designed as abstraction of a collection of binary files that represent the total data in a single
|
||||
Compass data run. It handles the user input (shift maps, file collection etc.) and creates a list of
|
||||
CompassFiles from which to draw data. It then draws data from these files, organizes them in time,
|
||||
and writes to a ROOT file for further processing.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#ifndef COMPASSRUN_H
|
||||
#define COMPASSRUN_H
|
||||
|
||||
#include "CompassFile.h"
|
||||
#include "DataStructs.h"
|
||||
#include "RunCollector.h"
|
||||
#include "ShiftMap.h"
|
||||
#include <TParameter.h>
|
||||
#include <TGProgressBar.h>
|
||||
#include <TSystem.h>
|
||||
|
||||
class CompassRun {
|
||||
public:
|
||||
CompassRun();
|
||||
CompassRun(const std::string& dir);
|
||||
~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<CompassFile> m_datafiles;
|
||||
unsigned int startIndex; //this is the file we start looking at; increases as we finish files.
|
||||
ShiftMap m_smap;
|
||||
std::unordered_map<std::string, TParameter<Long64_t>> m_scaler_map; //maps scaler files to the TParameter to be saved
|
||||
|
||||
//Potential branch variables
|
||||
CompassHit hit;
|
||||
CoincEvent event;
|
||||
ProcessedEvent pevent;
|
||||
|
||||
//what run is this
|
||||
int runNum;
|
||||
unsigned int m_totalHits;
|
||||
|
||||
//Scaler switch
|
||||
bool m_scaler_flag;
|
||||
|
||||
//GUI progress bar, if attached
|
||||
TGProgressBar* m_pb;
|
||||
};
|
||||
|
||||
#endif
|
27
include/CutHandler.h
Normal file
27
include/CutHandler.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#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<TCutG*> GetCuts() { return cut_array; };
|
||||
|
||||
private:
|
||||
void InitVariableMap();
|
||||
|
||||
std::vector<TCutG*> cut_array;
|
||||
std::vector<TFile*> file_array;
|
||||
std::unordered_map<std::string, double*> varmap;
|
||||
bool validFlag;
|
||||
ProcessedEvent m_event;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
69
include/DataStructs.h
Normal file
69
include/DataStructs.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*DataStructs.h
|
||||
*Data structures for analysis. To be implemented as a dictionary for ROOT in LinkDef
|
||||
*Based on: FocalPlane_SABRE.h
|
||||
*Gordon M. Oct. 2019
|
||||
*/
|
||||
#ifndef DATA_STRUCTS_H
|
||||
#define DATA_STRUCTS_H
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct DPPChannel {
|
||||
Double_t Timestamp;
|
||||
Int_t Channel, Board, Energy, EnergyShort;
|
||||
Int_t Flags;
|
||||
};
|
||||
|
||||
struct DetectorHit {
|
||||
Double_t Long=-1, Short=-1, Time=-1;
|
||||
Int_t Ch=-1;
|
||||
};
|
||||
|
||||
struct SabreDetector {
|
||||
vector<DetectorHit> rings;
|
||||
vector<DetectorHit> wedges;
|
||||
};
|
||||
|
||||
struct FPDetector {
|
||||
vector<DetectorHit> delayFL, delayFR, delayBL, delayBR;
|
||||
vector<DetectorHit> anodeF, anodeB, scintL, scintR, cathode;
|
||||
vector<DetectorHit> monitor;
|
||||
};
|
||||
|
||||
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,
|
||||
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_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_t monitorE = -1, monitorShort = -1;
|
||||
Double_t monitorTime = -1;
|
||||
|
||||
|
||||
SabreDetector sabreArray[5]; //index = ChannelMap Id# -1
|
||||
};
|
||||
|
||||
#endif
|
102
include/EVBMainFrame.h
Normal file
102
include/EVBMainFrame.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
#ifndef EVBMAINFRAME_H
|
||||
#define EVBMAINFRAME_H
|
||||
|
||||
#include <TGClient.h>
|
||||
#include <TGWindow.h>
|
||||
#include <TGFrame.h>
|
||||
#include <TGNumberEntry.h>
|
||||
#include <TGTextEntry.h>
|
||||
#include <TGButton.h>
|
||||
#include <TGMenu.h>
|
||||
#include <TGTextViewStream.h>
|
||||
#include <TGProgressBar.h>
|
||||
#include <TTimer.h>
|
||||
#include <TGComboBox.h>
|
||||
#include "GWMEventBuilder.h"
|
||||
|
||||
|
||||
class EVBMainFrame : public TGMainFrame {
|
||||
public:
|
||||
EVBMainFrame(const TGWindow* p, UInt_t w, UInt_t h);
|
||||
virtual ~EVBMainFrame();
|
||||
void CloseWindow();
|
||||
void HandleMenuSelection(int id);
|
||||
void DoOpenWorkdir();
|
||||
void DoOpenCMapfile();
|
||||
void DoOpenSMapfile();
|
||||
void DoOpenScalerfile();
|
||||
void DoOpenCutfile();
|
||||
void DoRun();
|
||||
void HandleTypeSelection(int box, int entry);
|
||||
bool SetParameters();
|
||||
void DisplayWorkdir(const char* dir);
|
||||
void DisplayCMap(const char* file);
|
||||
void DisplaySMap(const char* file);
|
||||
void DisplayScaler(const char* file);
|
||||
void DisplayCut(const char* file);
|
||||
void SaveConfig(const char* file);
|
||||
void LoadConfig(const char* file);
|
||||
void UpdateWorkdir();
|
||||
void UpdateCMap();
|
||||
void UpdateSMap();
|
||||
void UpdateScaler();
|
||||
void UpdateCut();
|
||||
void RunPlot();
|
||||
void RunMerge(const char* dir, const char* file);
|
||||
void DisableAllInput();
|
||||
void EnableAllInput();
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
ClassDef(EVBMainFrame, 0);
|
||||
|
||||
private:
|
||||
TGTextButton *fRunButton, *fOpenWorkButton, *fOpenCMapButton, *fOpenSMapButton, *fOpenScalerButton, *fOpenCutButton;
|
||||
TGTextEntry *fWorkField;
|
||||
TGTextEntry *fCMapField, * fSMapField;
|
||||
TGTextEntry *fScalerField, *fCutField;
|
||||
TGComboBox *fTypeBox;
|
||||
|
||||
TGNumberEntryField *fZTField, *fATField, *fZPField, *fAPField, *fZEField, *fAEField;
|
||||
TGNumberEntryField *fBField, *fBKEField, *fThetaField;
|
||||
TGNumberEntryField *fSlowWindowField, *fFastICField, *fFastSABREField;
|
||||
TGNumberEntryField *fRMinField, *fRMaxField;
|
||||
|
||||
TGHProgressBar* fProgressBar;
|
||||
|
||||
TGPopupMenu *fFileMenu;
|
||||
|
||||
GWMEventBuilder fBuilder;
|
||||
|
||||
int counter;
|
||||
UInt_t MAIN_W, MAIN_H;
|
||||
|
||||
|
||||
};
|
||||
#endif
|
28
include/EventBuilder.h
Normal file
28
include/EventBuilder.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef EVENTBUILDER_H
|
||||
#define EVENTBUILDER_H
|
||||
|
||||
//STD Library
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
//ROOT
|
||||
#include <TROOT.h>
|
||||
#include <TFile.h>
|
||||
#include <TChain.h>
|
||||
#include <TTree.h>
|
||||
#include <TString.h>
|
||||
#include <TMath.h>
|
||||
#include <TH1.h>
|
||||
#include <TH2.h>
|
||||
#include <TCanvas.h>
|
||||
#include <THashTable.h>
|
||||
#include <TCutG.h>
|
||||
|
||||
|
||||
#endif
|
42
include/FP_kinematics.h
Normal file
42
include/FP_kinematics.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
|
||||
Functions for the calculation of the kinematic shift of the FP
|
||||
for the SESPS @ FSU.
|
||||
|
||||
>>> Delta_Z(int...) returns the shift of the FP in the z-direction in
|
||||
cm. A negative (<0) delta-z is defined as a shift towards the
|
||||
magnet.
|
||||
|
||||
Arguments: Delta_Z(int ZT, int AT, int ZP, int AP, int ZE, int AE,
|
||||
double EP, double angle, double B),
|
||||
where Z,A are atomic number and mass number for each particle,
|
||||
EP is the KE of the projectile (i.e. beam energy in MeV),
|
||||
angle is the spectrograph angle (in degrees),
|
||||
B is the field in Gauss.
|
||||
|
||||
|
||||
>>> Wire_Dist() returns the distance (in cm) between the wires for
|
||||
the calculation of relative weights between FP1 and FP2.
|
||||
|
||||
//format: T(P,E)R
|
||||
// i.e., T = target,
|
||||
// P = projectile,
|
||||
// E = ejectile,
|
||||
// R = residual;
|
||||
//expects angle in degs, B in G, masses and KE in MeV
|
||||
|
||||
KGH -- Jul19
|
||||
|
||||
*/
|
||||
|
||||
#ifndef FP_KINEMATICS
|
||||
#define FP_KINEMATICS
|
||||
|
||||
//requires (Z,A) for T, P, and E, as well as energy of P,
|
||||
// spectrograph angle of interest, and field value
|
||||
double Delta_Z(int ZT, int AT, int ZP, int AP, int ZE, int AE,
|
||||
double EP, double angle, double B);
|
||||
|
||||
double Wire_Dist();
|
||||
|
||||
#endif
|
33
include/FastSort.h
Normal file
33
include/FastSort.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
*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 <TH2.h>
|
||||
|
||||
class FastSort {
|
||||
|
||||
public:
|
||||
FastSort(float si_windowSize, float ion_windowSize);
|
||||
~FastSort();
|
||||
std::vector<CoincEvent> 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
|
46
include/FileViewFrame.h
Normal file
46
include/FileViewFrame.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
|
||||
FileViewFrame.h
|
||||
Wrapper class on a TGTransientFrame (temporary frame assoc. with a main frame)
|
||||
Designed to graphically display directories and files for selection. Takes in a type
|
||||
to specify the signal pathing.
|
||||
|
||||
Written by G.W. McCann Sep. 2020
|
||||
|
||||
*/
|
||||
|
||||
#ifndef FILEVIEWFRAME_H
|
||||
#define FILEVIEWFRAME_H
|
||||
|
||||
#include "EVBMainFrame.h"
|
||||
#include <TGTextEntry.h>
|
||||
#include <TGFSContainer.h>
|
||||
#include <TGListView.h>
|
||||
#include <TQObject.h>
|
||||
#include <RQ_OBJECT.h>
|
||||
|
||||
class FileViewFrame {
|
||||
|
||||
RQ_OBJECT("FileViewFrame"); //ROOT wrapping into the gui environment
|
||||
public:
|
||||
FileViewFrame(const TGWindow* p, const TGFrame* main, UInt_t w, UInt_t h, EVBMainFrame *parent, int type);
|
||||
virtual ~FileViewFrame();
|
||||
void CloseWindow();
|
||||
void DoOk();
|
||||
void DoCancel();
|
||||
void DoDoubleClick(TGLVEntry* entry, int id);
|
||||
void DisplayDir(const TString& name);
|
||||
void SendText(const char* text); // *SIGNAL*
|
||||
ClassDef(FileViewFrame, 0); //ROOT requirement
|
||||
|
||||
private:
|
||||
TGTransientFrame *fMain;
|
||||
TGTextButton *fOkButton, *fCancelButton;
|
||||
TGTextEntry *fNameField;
|
||||
TGFileContainer *fContents;
|
||||
TGListView *fViewer;
|
||||
std::string suffix;
|
||||
bool dirFlag;
|
||||
};
|
||||
|
||||
#endif
|
59
include/FlagHandler.h
Normal file
59
include/FlagHandler.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
#ifndef FLAGHANDLER_H
|
||||
#define FLAGHANDLER_H
|
||||
|
||||
#include <map>
|
||||
|
||||
struct FlagCount {
|
||||
long total_counts=0;
|
||||
long dead_time=0;
|
||||
long time_roll=0;
|
||||
long time_reset=0;
|
||||
long fake_event=0;
|
||||
long mem_full=0;
|
||||
long trig_lost=0;
|
||||
long n_trig_lost=0;
|
||||
long sat_in_gate=0;
|
||||
long trig_1024=0;
|
||||
long sat_input=0;
|
||||
long n_trig_count=0;
|
||||
long event_not_matched=0;
|
||||
long fine_time=0;
|
||||
long pile_up=0;
|
||||
long pll_lock_loss=0;
|
||||
long over_temp=0;
|
||||
long adc_shutdown=0;
|
||||
};
|
||||
|
||||
class FlagHandler {
|
||||
public:
|
||||
FlagHandler();
|
||||
FlagHandler(const std::string& filename);
|
||||
~FlagHandler();
|
||||
void CheckFlag(int board, int channel, int flag);
|
||||
|
||||
const int DEAD_TIME = 0x00000001;
|
||||
const int TIME_ROLLOVER = 0x00000002;
|
||||
const int TIME_RESET = 0x00000004;
|
||||
const int FAKE_EVENT = 0x00000008;
|
||||
const int MEM_FULL = 0x00000010;
|
||||
const int TRIG_LOST = 0x00000020;
|
||||
const int N_TRIG_LOST = 0x00000040;
|
||||
const int SATURATING_IN_GATE = 0x00000080;
|
||||
const int TRIG_1024_COUNTED = 0x00000100;
|
||||
const int SATURATING_INPUT = 0x00000400;
|
||||
const int N_TRIG_COUNTED = 0x00000800;
|
||||
const int EVENT_NOT_MATCHED = 0x00001000;
|
||||
const int FINE_TIME = 0x00004000;
|
||||
const int PILE_UP = 0x00008000;
|
||||
const int PLL_LOCK_LOSS = 0x00080000;
|
||||
const int OVER_TEMP = 0x00100000;
|
||||
const int ADC_SHUTDOWN = 0x00200000;
|
||||
|
||||
private:
|
||||
std::ofstream log;
|
||||
std::map<int, FlagCount> event_count_map;
|
||||
|
||||
void WriteLog();
|
||||
};
|
||||
|
||||
#endif
|
102
include/GWMEventBuilder.h
Normal file
102
include/GWMEventBuilder.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
GWMEventBuilder.h
|
||||
Class which represents the API of the event building environment. Wraps together the core concepts
|
||||
of the event builder, from conversion to plotting. Even intended to be able to archive data.
|
||||
Currently under development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#ifndef GWMEVENTBUILDER_H
|
||||
#define GWMEVENTBUILDER_H
|
||||
|
||||
#include "RunCollector.h"
|
||||
#include <TGProgressBar.h>
|
||||
|
||||
class GWMEventBuilder {
|
||||
public:
|
||||
GWMEventBuilder();
|
||||
~GWMEventBuilder();
|
||||
|
||||
bool ReadConfigFile(const std::string& filename);
|
||||
void WriteConfigFile(const std::string& filename);
|
||||
|
||||
void 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
|
7
include/LinkDef_Gui.h
Normal file
7
include/LinkDef_Gui.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifdef __CLING__
|
||||
|
||||
|
||||
#pragma link C++ class EVBMainFrame+;
|
||||
#pragma link C++ class FileViewFrame+;
|
||||
|
||||
#endif
|
11
include/LinkDef_sps.h
Normal file
11
include/LinkDef_sps.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifdef __CLING__
|
||||
|
||||
#pragma link C++ struct DPPChannel+;
|
||||
#pragma link C++ struct DetectorHit+;
|
||||
#pragma link C++ class std::vector<DetectorHit>+;
|
||||
#pragma link C++ struct SabreDetector+;
|
||||
#pragma link C++ struct FPDetector+;
|
||||
#pragma link C++ struct CoincEvent+;
|
||||
#pragma link C++ struct ProcessedEvent+;
|
||||
|
||||
#endif
|
34
include/MassLookup.h
Normal file
34
include/MassLookup.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
|
||||
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<std::string, double> massTable;
|
||||
std::unordered_map<int, std::string> 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
|
18
include/OrderChecker.h
Normal file
18
include/OrderChecker.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
OrderChecker.h
|
||||
Very simple class designed to test whether or not a root file is time ordered.
|
||||
Meant to be used with newly converted from binary data. Only for development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#ifndef ORDERCHECKER_H
|
||||
#define ORDERCHECKER_H
|
||||
|
||||
class OrderChecker {
|
||||
public:
|
||||
OrderChecker();
|
||||
~OrderChecker();
|
||||
bool IsOrdered(const std::string& filename);
|
||||
};
|
||||
|
||||
#endif
|
50
include/RunCollector.h
Normal file
50
include/RunCollector.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*RunCollector.h
|
||||
*Class that searches through a directory looking for files of a specified format.
|
||||
*Stores all filenames in a vector which can be accessed by other functions/classes for
|
||||
*further use. Can also use Merge() to combine all files using hadd into a single file.
|
||||
*Merge() is NOT RECOMMENDED in the analyzer program.
|
||||
*
|
||||
*Created Jan2020 by GWM
|
||||
*/
|
||||
|
||||
#ifndef RUNCOLLECTOR_H
|
||||
#define RUNCOLLECTOR_H
|
||||
|
||||
#include <TSystemDirectory.h>
|
||||
#include <TSystemFile.h>
|
||||
#include <TCollection.h>
|
||||
#include <TList.h>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class RunCollector {
|
||||
public:
|
||||
RunCollector();
|
||||
RunCollector(const string& dirname, const string& prefix, const string& suffix);
|
||||
RunCollector(const string& dirname, const string& prefix, const string& suffix, int min, int max);
|
||||
~RunCollector();
|
||||
void SetSearchParams(const string& dirname, const string& prefix, const string& suffix, int min, int max);
|
||||
int Merge_hadd(const string& outname);
|
||||
int Merge_TChain(const string& outname);
|
||||
int GrabAllFiles();
|
||||
int GrabFilesInRange();
|
||||
std::string GrabFile(int runNum);
|
||||
inline std::string GetSearchDir() {return dir.Data();};
|
||||
inline std::string GetSearchPrefix() {return run.Data();};
|
||||
inline std::string GetSearchSuffix() {return end.Data();};
|
||||
inline int GetRunMin() {return MinRun;};
|
||||
inline int GetRunMax() {return MaxRun;};
|
||||
vector<TString> filelist;
|
||||
|
||||
private:
|
||||
bool initFlag;
|
||||
TString dir;
|
||||
TString run;
|
||||
TString end;
|
||||
Int_t MaxRun, MinRun; //user run limits
|
||||
const Int_t LITERALMAX = 1000; //class run limit
|
||||
};
|
||||
|
||||
#endif
|
46
include/SFPAnalyzer.h
Normal file
46
include/SFPAnalyzer.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*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
|
53
include/SFPPlotter.h
Normal file
53
include/SFPPlotter.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*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 <TGProgressBar.h>
|
||||
|
||||
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<TString> files, const string& output);
|
||||
|
||||
private:
|
||||
void SetProgressBar(long total);
|
||||
void Chain(vector<TString> 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;
|
||||
bool cutFlag;
|
||||
|
||||
TChain *chain;
|
||||
|
||||
TGProgressBar* m_pb; //GUI progress
|
||||
|
||||
};
|
||||
|
||||
#endif
|
35
include/ShiftMap.h
Normal file
35
include/ShiftMap.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
ShiftMap.h
|
||||
New class to act a go-between for timestamp shifts to channels. Takes in a
|
||||
formated file containing data for shifts and then stores them in an unordered_map.
|
||||
Key is a global compass channel (board#*16 + channel). Shifts in ps.
|
||||
|
||||
Note: Timestamps are now shifted in binary conversion. This means that shifts *MUST*
|
||||
be stored as Long64_t types. No decimals!
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#ifndef SHIFTMAP_H
|
||||
#define SHIFTMAP_H
|
||||
|
||||
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);
|
||||
|
||||
private:
|
||||
void ParseFile();
|
||||
|
||||
std::string m_filename;
|
||||
bool is_set;
|
||||
|
||||
std::unordered_map<int, Long64_t> m_map;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
57
include/SlowSort.h
Normal file
57
include/SlowSort.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*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 <TH2.h>
|
||||
|
||||
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<DPPChannel> hitList;
|
||||
bool eventFlag;
|
||||
DPPChannel hit;
|
||||
CoincEvent event;
|
||||
CoincEvent blank;
|
||||
|
||||
double startTime, previousHitTime;
|
||||
unordered_map<int, vector<DetectorHit>*> fpVMap;
|
||||
unordered_map<int, vector<DetectorHit>*> sabreVMap;
|
||||
|
||||
TH2F* event_stats;
|
||||
|
||||
ChannelMap cmap;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
30
include/Stopwatch.h
Normal file
30
include/Stopwatch.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Stopwatch.h
|
||||
Simple class designed to provide timing info on parts of the process.
|
||||
Only for use in development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#ifndef STOPWATCH_H
|
||||
#define STOPWATCH_H
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class Stopwatch {
|
||||
|
||||
public:
|
||||
Stopwatch();
|
||||
~Stopwatch();
|
||||
void Start();
|
||||
void Stop();
|
||||
double GetElapsedSeconds();
|
||||
double GetElapsedMilliseconds();
|
||||
|
||||
private:
|
||||
using Time = std::chrono::high_resolution_clock::time_point;
|
||||
using Clock = std::chrono::high_resolution_clock;
|
||||
|
||||
Time start_time, stop_time;
|
||||
};
|
||||
|
||||
#endif
|
27
input.txt
Normal file
27
input.txt
Normal file
|
@ -0,0 +1,27 @@
|
|||
-------Data Location----------
|
||||
WorkspaceDirectory: /data1/gwm17/10B3He/Feb2021/
|
||||
-------------------------------
|
||||
------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
|
||||
ZT: 5
|
||||
AT: 10
|
||||
ZP: 2
|
||||
AP: 3
|
||||
ZE: 2
|
||||
AE: 4
|
||||
BField(G): 8925
|
||||
BeamKE(MeV): 24
|
||||
Theta(deg): 15
|
||||
-------------------------------
|
||||
-------Timing Information------
|
||||
BoardOffsetFile: /home/gwm17/GWM_EventBuilder/etc/orig_ShiftMap_Feb2021_SABRE.txt
|
||||
SlowCoincidenceWindow(ps): 1.5e+06
|
||||
FastCoincidenceWindow_IonCh(ps): 250000
|
||||
FastCoincidenceWindow_SABRE(ps): 150000
|
||||
-------------------------------
|
||||
--------Run Information--------
|
||||
MinRun: 99
|
||||
MaxRun: 99
|
||||
-------------------------------
|
7
lib/.gitignore
vendored
Normal file
7
lib/.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
###ignore these files####
|
||||
*.dylib
|
||||
*.so
|
||||
*.pcm
|
||||
|
||||
###keep this one###
|
||||
!.gitignore
|
96
makefile
Normal file
96
makefile
Normal file
|
@ -0,0 +1,96 @@
|
|||
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 $^
|
3
objs/.gitignore
vendored
Normal file
3
objs/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
### dont include any files, but include this dir ###
|
||||
*
|
||||
!.gitignore
|
3
src/.gitignore
vendored
Normal file
3
src/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
###ignore the root dictionary generated file###
|
||||
*.cxx
|
||||
!.gitignore
|
72
src/evb/ChannelMap.cpp
Normal file
72
src/evb/ChannelMap.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
ChannelMap.cpp
|
||||
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
|
||||
*/
|
||||
#include "EventBuilder.h"
|
||||
#include "ChannelMap.h"
|
||||
|
||||
ChannelMap::ChannelMap() :
|
||||
is_valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
cmap[gchan] = this_chan;
|
||||
}
|
||||
|
||||
input.close();
|
||||
is_valid = true;
|
||||
return is_valid;
|
||||
}
|
151
src/evb/CompassFile.cpp
Normal file
151
src/evb/CompassFile.cpp
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
CompassFile.cpp
|
||||
Wrapper class around a shared pointer to an ifstream. Here the shared pointer is used
|
||||
to overcome limitations of the ifstream class, namely that it is written such that ifstream
|
||||
cannot be modified by move semantics. Contains all information needed to parse a single binary
|
||||
CompassFile. Currently has a class wide defined buffer size; may want to make this user input
|
||||
in the future.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#include "EventBuilder.h"
|
||||
#include "CompassFile.h"
|
||||
|
||||
CompassFile::CompassFile() :
|
||||
m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_file(std::make_shared<std::ifstream>()), eofFlag(false)
|
||||
{
|
||||
m_buffersize = bufsize*hitsize;
|
||||
hitBuffer.resize(m_buffersize);
|
||||
}
|
||||
|
||||
CompassFile::CompassFile(const std::string& filename) :
|
||||
m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true), m_file(std::make_shared<std::ifstream>()), eofFlag(false)
|
||||
{
|
||||
m_buffersize = bufsize*hitsize;
|
||||
hitBuffer.resize(m_buffersize);
|
||||
Open(filename);
|
||||
}
|
||||
|
||||
CompassFile::CompassFile(const std::string& filename, int bsize) :
|
||||
m_filename(""), bufferIter(nullptr), bufferEnd(nullptr), m_smap(nullptr), hitUsedFlag(true),
|
||||
bufsize(bsize), m_file(std::make_shared<std::ifstream>()), eofFlag(false)
|
||||
{
|
||||
m_buffersize = bufsize*hitsize;
|
||||
hitBuffer.resize(m_buffersize);
|
||||
Open(filename);
|
||||
}
|
||||
|
||||
CompassFile::~CompassFile() {
|
||||
Close();
|
||||
}
|
||||
|
||||
void CompassFile::Open(const std::string& filename) {
|
||||
eofFlag = false;
|
||||
hitUsedFlag = true;
|
||||
m_filename = filename;
|
||||
m_file->open(m_filename, std::ios::binary | std::ios::in);
|
||||
|
||||
m_file->seekg(0, std::ios_base::end);
|
||||
m_size = m_file->tellg();
|
||||
m_nHits = m_size/24;
|
||||
if(m_size == 0) {
|
||||
eofFlag = true;
|
||||
} else {
|
||||
m_file->seekg(0, std::ios_base::beg);
|
||||
}
|
||||
}
|
||||
|
||||
void CompassFile::Close() {
|
||||
if(IsOpen()) {
|
||||
m_file->close();
|
||||
}
|
||||
}
|
||||
|
||||
int CompassFile::GetHitSize() {
|
||||
if(!IsOpen()) {
|
||||
std::cerr<<"Unable to get hit size due to file not being open!"<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* firstHit = new char[24]; //A compass hit by default has 24 bytes (at least in our setup)
|
||||
|
||||
m_file->read(firstHit, 24);
|
||||
|
||||
firstHit += 16;
|
||||
int nsamples = *((uint32_t*) firstHit);
|
||||
|
||||
m_file->seekg(0, std::ios_base::beg);
|
||||
|
||||
delete firstHit;
|
||||
|
||||
return 24 + nsamples*16;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
GetNextHit() is the function which... gets the next hit
|
||||
Has to check if the buffer needs refilled/filled for the first time
|
||||
Upon pulling a hit, sets the UsedFlag to false, letting the next level know
|
||||
that the hit should be free game.
|
||||
|
||||
If the file cannot be opened, signals as though file is EOF
|
||||
*/
|
||||
bool CompassFile::GetNextHit() {
|
||||
if(!IsOpen()) return true;
|
||||
|
||||
if((bufferIter == nullptr || bufferIter == bufferEnd) && !IsEOF()) {
|
||||
GetNextBuffer();
|
||||
}
|
||||
|
||||
if(!IsEOF()) {
|
||||
ParseNextHit();
|
||||
hitUsedFlag = false;
|
||||
}
|
||||
|
||||
return eofFlag;
|
||||
}
|
||||
|
||||
/*
|
||||
GetNextBuffer() ... self-explanatory name
|
||||
Note tht this is where the EOF flag is set. The EOF is only singaled
|
||||
after the LAST buffer is completely read (i.e literally no more data). ifstream sets its eof
|
||||
bit upon pulling the last buffer, but this class waits until that entire
|
||||
last buffer is read to singal EOF (the true end of file).
|
||||
*/
|
||||
void CompassFile::GetNextBuffer() {
|
||||
|
||||
if(m_file->eof()) {
|
||||
eofFlag = true;
|
||||
return;
|
||||
}
|
||||
|
||||
m_file->read(hitBuffer.data(), hitBuffer.size());
|
||||
|
||||
bufferIter = hitBuffer.data();
|
||||
bufferEnd = bufferIter + m_file->gcount(); //one past the last datum
|
||||
|
||||
}
|
||||
|
||||
void CompassFile::ParseNextHit() {
|
||||
|
||||
m_currentHit.board = *((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);
|
||||
}
|
||||
|
||||
}
|
518
src/evb/CompassRun.cpp
Normal file
518
src/evb/CompassRun.cpp
Normal file
|
@ -0,0 +1,518 @@
|
|||
/*
|
||||
CompassRun.cpp
|
||||
Class designed as abstraction of a collection of binary files that represent the total data in a single
|
||||
Compass data run. It handles the user input (shift maps, file collection etc.) and creates a list of
|
||||
CompassFiles from which to draw data. It then draws data from these files, organizes them in time,
|
||||
and writes to a ROOT file for further processing.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
|
||||
Updated to also handle scaler data. -- GWM Oct. 2020
|
||||
*/
|
||||
#include "EventBuilder.h"
|
||||
#include "CompassRun.h"
|
||||
#include "RunCollector.h"
|
||||
#include "SlowSort.h"
|
||||
#include "FastSort.h"
|
||||
#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<Long64_t>(varname.c_str(), init);
|
||||
}
|
||||
input.close();
|
||||
}
|
||||
|
||||
bool CompassRun::GetBinaryFiles() {
|
||||
std::string prefix = "";
|
||||
std::string suffix = ".bin"; //binaries
|
||||
RunCollector grabber(directory, prefix, suffix);
|
||||
grabber.GrabAllFiles();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
if(scalerd) continue;
|
||||
}
|
||||
|
||||
m_datafiles.emplace_back(entry.Data());
|
||||
m_datafiles[m_datafiles.size()-1].AttachShiftMap(&m_smap);
|
||||
//Any time we have a file that fails to be found, we terminate the whole process
|
||||
if(!m_datafiles[m_datafiles.size() - 1].IsOpen()) {
|
||||
return false;
|
||||
}
|
||||
m_totalHits += m_datafiles[m_datafiles.size()-1].GetNumberOfHits();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Pure counting of scalers. Potential upgrade path to something like
|
||||
average count rate etc.
|
||||
*/
|
||||
void CompassRun::ReadScalerData(const std::string& filename) {
|
||||
if(!m_scaler_flag) return;
|
||||
|
||||
Long64_t count;
|
||||
count = 0;
|
||||
CompassFile file(filename);
|
||||
auto& this_param = m_scaler_map[file.GetName()];
|
||||
while(true) {
|
||||
file.GetNextHit();
|
||||
if(file.IsEOF()) break;
|
||||
count++;
|
||||
}
|
||||
this_param.SetVal(count);
|
||||
}
|
||||
|
||||
/*
|
||||
GetHitsFromFiles() is the function which actually retrieves and sorts the data from the individual
|
||||
files. There are several tricks which allow this to happen. First is that, after sorting, it is impossible
|
||||
to determine which file the data originally came from (short of parsing the name of the file against board/channel).
|
||||
However, we need to let the file know that we want it to pull the next hit. To do this, a pointer to the UsedFlag of the file
|
||||
is retrieved along with the data. This flag is flipped so that on the next hit cycle a new hit is pulled. Second is the use
|
||||
of a rolling start index. Once a file has gone EOF, we no longer need it. If this is the first file in the list, we can just skip
|
||||
that index all together. In this way, the loop can go from N times to N-1 times.
|
||||
*/
|
||||
bool CompassRun::GetHitsFromFiles() {
|
||||
|
||||
std::pair<CompassHit, bool*> earliestHit = make_pair(CompassHit(), nullptr);
|
||||
for(unsigned int i=startIndex; i<m_datafiles.size(); i++) {
|
||||
if(m_datafiles[i].CheckHitHasBeenUsed()) {
|
||||
m_datafiles[i].GetNextHit();
|
||||
}
|
||||
|
||||
if(m_datafiles[i].IsEOF()) {
|
||||
if(i == startIndex) startIndex++;
|
||||
continue;
|
||||
} else if(i == startIndex) {
|
||||
earliestHit = make_pair(m_datafiles[i].GetCurrentHit(), m_datafiles[i].GetUsedFlagPtr());
|
||||
} else if(m_datafiles[i].GetCurrentHit().timestamp < earliestHit.first.timestamp) {
|
||||
earliestHit = make_pair(m_datafiles[i].GetCurrentHit(), m_datafiles[i].GetUsedFlagPtr());
|
||||
}
|
||||
}
|
||||
|
||||
if(earliestHit.second == nullptr) return false; //Make sure that there actually was a hit
|
||||
hit = earliestHit.first;
|
||||
*earliestHit.second = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CompassRun::Convert2RawRoot(const std::string& name) {
|
||||
TFile* output = TFile::Open(name.c_str(), "RECREATE");
|
||||
TTree* outtree = new TTree("Data", "Data");
|
||||
|
||||
outtree->Branch("Board", &hit.board);
|
||||
outtree->Branch("Channel", &hit.channel);
|
||||
outtree->Branch("Energy", &hit.lgate);
|
||||
outtree->Branch("EnergyShort", &hit.sgate);
|
||||
outtree->Branch("Timestamp", &hit.timestamp);
|
||||
outtree->Branch("Flags", &hit.flags);
|
||||
|
||||
if(!m_smap.IsSet()) {
|
||||
std::cerr<<"Bad shift map at CompassRun::Convert()."<<std::endl;
|
||||
std::cerr<<"Shifts will be locked to 0"<<std::endl;
|
||||
}
|
||||
|
||||
SetScalers();
|
||||
|
||||
if(!GetBinaryFiles()) {
|
||||
std::cerr<<"Unable to open a file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_pb) SetProgressBar();
|
||||
|
||||
startIndex = 0; //Reset the startIndex
|
||||
unsigned int count = 0, flush = m_totalHits*0.01, flush_count = 0;
|
||||
if(flush == 0) flush = 1;
|
||||
while(true) {
|
||||
count++;
|
||||
if(count == flush) { //Progress Log
|
||||
if(m_pb) {
|
||||
m_pb->Increment(count);
|
||||
gSystem->ProcessEvents();
|
||||
count=0;
|
||||
} else {
|
||||
count = 0;
|
||||
flush_count++;
|
||||
std::cout<<"\rPercent of run built: "<<flush_count*10<<"%"<<std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
if(!GetHitsFromFiles()) break;
|
||||
outtree->Fill();
|
||||
}
|
||||
|
||||
output->cd();
|
||||
outtree->Write(outtree->GetName(), TObject::kOverwrite);
|
||||
for(auto& entry : m_scaler_map) {
|
||||
entry.second.Write();
|
||||
}
|
||||
output->Close();
|
||||
}
|
||||
|
||||
void CompassRun::Convert2SortedRoot(const std::string& name, const std::string& mapfile, double window) {
|
||||
TFile* output = TFile::Open(name.c_str(), "RECREATE");
|
||||
TTree* outtree = new TTree("SortTree", "SortTree");
|
||||
|
||||
outtree->Branch("event", &event);
|
||||
|
||||
if(!m_smap.IsSet()) {
|
||||
std::cerr<<"Bad shift map at CompassRun::Convert()."<<std::endl;
|
||||
std::cerr<<"Shifts will be locked to 0"<<std::endl;
|
||||
}
|
||||
|
||||
SetScalers();
|
||||
|
||||
if(!GetBinaryFiles()) {
|
||||
std::cerr<<"Unable to open a file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_pb) SetProgressBar();
|
||||
|
||||
startIndex = 0;
|
||||
SlowSort coincidizer(window, mapfile);
|
||||
bool killFlag = false;
|
||||
unsigned int count = 0, flush = m_totalHits*0.01, flush_count = 0;
|
||||
if(flush == 0) flush = 1;
|
||||
while(true) {
|
||||
count++;
|
||||
if(count == flush) {
|
||||
if(m_pb) {
|
||||
m_pb->Increment(count);
|
||||
gSystem->ProcessEvents();
|
||||
count=0;
|
||||
} else {
|
||||
count = 0;
|
||||
flush_count++;
|
||||
std::cout<<"\rPercent of run built: "<<flush_count*10<<"%"<<std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
if(!GetHitsFromFiles()) {
|
||||
coincidizer.FlushHitsToEvent();
|
||||
killFlag = true;
|
||||
} else {
|
||||
coincidizer.AddHitToEvent(hit);
|
||||
}
|
||||
|
||||
if(coincidizer.IsEventReady()) {
|
||||
event = coincidizer.GetEvent();
|
||||
outtree->Fill();
|
||||
if(killFlag) break;
|
||||
}
|
||||
}
|
||||
|
||||
output->cd();
|
||||
outtree->Write(outtree->GetName(), TObject::kOverwrite);
|
||||
for(auto& entry : m_scaler_map) {
|
||||
entry.second.Write();
|
||||
}
|
||||
coincidizer.GetEventStats()->Write();
|
||||
output->Close();
|
||||
}
|
||||
|
||||
void CompassRun::Convert2FastSortedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window) {
|
||||
TFile* output = TFile::Open(name.c_str(), "RECREATE");
|
||||
TTree* outtree = new TTree("SortTree", "SortTree");
|
||||
|
||||
outtree->Branch("event", &event);
|
||||
|
||||
if(!m_smap.IsSet()) {
|
||||
std::cerr<<"Bad shift map at CompassRun::Convert()."<<std::endl;
|
||||
std::cerr<<"Shifts will be locked to 0"<<std::endl;
|
||||
}
|
||||
|
||||
SetScalers();
|
||||
|
||||
if(!GetBinaryFiles()) {
|
||||
std::cerr<<"Unable to open a file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_pb) SetProgressBar();
|
||||
|
||||
startIndex = 0;
|
||||
CoincEvent this_event;
|
||||
std::vector<CoincEvent> 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 {
|
||||
count = 0;
|
||||
flush_count++;
|
||||
std::cout<<"\rPercent of run built: "<<flush_count*10<<"%"<<std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
if(!GetHitsFromFiles()) {
|
||||
coincidizer.FlushHitsToEvent();
|
||||
killFlag = true;
|
||||
} else {
|
||||
flagger.CheckFlag(hit.board, hit.channel, hit.flags);
|
||||
coincidizer.AddHitToEvent(hit);
|
||||
}
|
||||
|
||||
if(coincidizer.IsEventReady()) {
|
||||
this_event = coincidizer.GetEvent();
|
||||
|
||||
fast_events = speedyCoincidizer.GetFastEvents(this_event);
|
||||
for(auto& entry : fast_events) {
|
||||
event = entry;
|
||||
outtree->Fill();
|
||||
}
|
||||
if(killFlag) break;
|
||||
}
|
||||
}
|
||||
|
||||
output->cd();
|
||||
outtree->Write(outtree->GetName(), TObject::kOverwrite);
|
||||
for(auto& entry : m_scaler_map) {
|
||||
entry.second.Write();
|
||||
}
|
||||
coincidizer.GetEventStats()->Write();
|
||||
output->Close();
|
||||
}
|
||||
|
||||
|
||||
void CompassRun::Convert2SlowAnalyzedRoot(const std::string& name, const std::string& mapfile, double window,
|
||||
int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta) {
|
||||
|
||||
TFile* output = TFile::Open(name.c_str(), "RECREATE");
|
||||
TTree* outtree = new TTree("SPSTree", "SPSTree");
|
||||
|
||||
outtree->Branch("event", &pevent);
|
||||
|
||||
if(!m_smap.IsSet()) {
|
||||
std::cerr<<"Bad shift map at CompassRun::Convert()."<<std::endl;
|
||||
std::cerr<<"Shifts will be locked to 0"<<std::endl;
|
||||
}
|
||||
|
||||
SetScalers();
|
||||
|
||||
if(!GetBinaryFiles()) {
|
||||
std::cerr<<"Unable to open a file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_pb) SetProgressBar();
|
||||
|
||||
startIndex = 0;
|
||||
CoincEvent this_event;
|
||||
SlowSort coincidizer(window, mapfile);
|
||||
SFPAnalyzer analyzer(zt, at, zp, ap, ze, ae, bke, theta, b);
|
||||
|
||||
vector<TParameter<Double_t>> parvec;
|
||||
parvec.reserve(9);
|
||||
parvec.emplace_back("ZT", zt);
|
||||
parvec.emplace_back("AT", at);
|
||||
parvec.emplace_back("ZP", zp);
|
||||
parvec.emplace_back("AP", ap);
|
||||
parvec.emplace_back("ZE", ze);
|
||||
parvec.emplace_back("AE", ae);
|
||||
parvec.emplace_back("Bfield", b);
|
||||
parvec.emplace_back("BeamKE", bke);
|
||||
parvec.emplace_back("Theta", theta);
|
||||
|
||||
bool killFlag = false;
|
||||
unsigned int count = 0, flush = m_totalHits*0.01, flush_count = 0;
|
||||
if(flush == 0) flush = 1;
|
||||
while(true) {
|
||||
count++;
|
||||
if(count == flush) {
|
||||
if(m_pb) {
|
||||
m_pb->Increment(count);
|
||||
gSystem->ProcessEvents();
|
||||
count=0;
|
||||
} else {
|
||||
count = 0;
|
||||
flush_count++;
|
||||
std::cout<<"\rPercent of run built: "<<flush_count*10<<"%"<<std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
if(!GetHitsFromFiles()) {
|
||||
coincidizer.FlushHitsToEvent();
|
||||
killFlag = true;
|
||||
} else {
|
||||
coincidizer.AddHitToEvent(hit);
|
||||
}
|
||||
|
||||
if(coincidizer.IsEventReady()) {
|
||||
this_event = coincidizer.GetEvent();
|
||||
pevent = analyzer.GetProcessedEvent(this_event);
|
||||
outtree->Fill();
|
||||
if(killFlag) break;
|
||||
}
|
||||
}
|
||||
|
||||
output->cd();
|
||||
outtree->Write(outtree->GetName(), TObject::kOverwrite);
|
||||
for(auto& entry : m_scaler_map) {
|
||||
entry.second.Write();
|
||||
}
|
||||
for(auto& entry : parvec) {
|
||||
entry.Write();
|
||||
}
|
||||
coincidizer.GetEventStats()->Write();
|
||||
analyzer.GetHashTable()->Write();
|
||||
analyzer.ClearHashTable();
|
||||
output->Close();
|
||||
}
|
||||
|
||||
void CompassRun::Convert2FastAnalyzedRoot(const std::string& name, const std::string& mapfile, double window, double fsi_window, double fic_window,
|
||||
int zt, int at, int zp, int ap, int ze, int ae, double bke, double b, double theta) {
|
||||
|
||||
TFile* output = TFile::Open(name.c_str(), "RECREATE");
|
||||
TTree* outtree = new TTree("SPSTree", "SPSTree");
|
||||
|
||||
outtree->Branch("event", &pevent);
|
||||
|
||||
if(!m_smap.IsSet()) {
|
||||
std::cerr<<"Bad shift map at CompassRun::Convert()."<<std::endl;
|
||||
std::cerr<<"Shifts will be locked to 0"<<std::endl;
|
||||
}
|
||||
|
||||
SetScalers();
|
||||
|
||||
if(!GetBinaryFiles()) {
|
||||
std::cerr<<"Unable to open a file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_pb) SetProgressBar();
|
||||
|
||||
startIndex = 0;
|
||||
CoincEvent this_event;
|
||||
std::vector<CoincEvent> fast_events;
|
||||
SlowSort coincidizer(window, mapfile);
|
||||
FastSort speedyCoincidizer(fsi_window, fic_window);
|
||||
SFPAnalyzer analyzer(zt, at, zp, ap, ze, ae, bke, theta, b);
|
||||
|
||||
vector<TParameter<Double_t>> parvec;
|
||||
parvec.reserve(9);
|
||||
parvec.emplace_back("ZT", zt);
|
||||
parvec.emplace_back("AT", at);
|
||||
parvec.emplace_back("ZP", zp);
|
||||
parvec.emplace_back("AP", ap);
|
||||
parvec.emplace_back("ZE", ze);
|
||||
parvec.emplace_back("AE", ae);
|
||||
parvec.emplace_back("Bfield", b);
|
||||
parvec.emplace_back("BeamKE", bke);
|
||||
parvec.emplace_back("Theta", theta);
|
||||
|
||||
FlagHandler flagger;
|
||||
|
||||
bool killFlag = false;
|
||||
unsigned int count = 0, flush = m_totalHits*0.01, flush_count = 0;
|
||||
if(flush == 0) flush = 1;
|
||||
while(true) {
|
||||
count++;
|
||||
if(count == flush) {
|
||||
if(m_pb) {
|
||||
m_pb->Increment(count);
|
||||
gSystem->ProcessEvents();
|
||||
count=0;
|
||||
} else {
|
||||
count = 0;
|
||||
flush_count++;
|
||||
std::cout<<"\rPercent of run built: "<<flush_count*10<<"%"<<std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
if(!GetHitsFromFiles()) {
|
||||
coincidizer.FlushHitsToEvent();
|
||||
killFlag = true;
|
||||
} else {
|
||||
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();
|
||||
}
|
||||
|
||||
void CompassRun::SetProgressBar() {
|
||||
m_pb->SetMax(m_totalHits);
|
||||
m_pb->SetMin(0);
|
||||
m_pb->SetPosition(0);
|
||||
gSystem->ProcessEvents();
|
||||
}
|
90
src/evb/CutHandler.cpp
Normal file
90
src/evb/CutHandler.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
#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; i<file_array.size(); i++) {
|
||||
if(file_array[i]->IsOpen()) file_array[i]->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void CutHandler::SetCuts(const std::string& filename) {
|
||||
std::ifstream cutlist(filename);
|
||||
|
||||
if(!cutlist.is_open()) {
|
||||
validFlag = false;
|
||||
}
|
||||
|
||||
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 {
|
||||
validFlag = false;
|
||||
std::cerr<<"CutHandler has encountered a bad cut at file: "<<file<<"."<<std::endl;
|
||||
std::cerr<<"The file either does not exist or does not contain a TCutG named CUTG"<<std::endl;
|
||||
std::cerr<<"Cuts will not be used."<<std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
validFlag = true;
|
||||
}
|
||||
|
||||
/*
|
||||
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; i<cut_array.size(); i++) {
|
||||
TCutG* cut = cut_array[i];
|
||||
x = cut->GetVarX();
|
||||
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: "<<xentry->first<<" , "<<yentry->first<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!cut->IsInside(*(xentry->second), *(yentry->second))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
103
src/evb/FP_kinematics.cpp
Normal file
103
src/evb/FP_kinematics.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
|
||||
Functions for the calculation of the kinematic shift of the FP
|
||||
for the SESPS @ FSU.
|
||||
|
||||
|
||||
>>> Delta_Z(int...) returns the shift of the FP in the z-direction in
|
||||
cm. A negative (<0) delta-z is defined as a shift towards the
|
||||
magnet.
|
||||
|
||||
Arguments: Delta_Z(int ZT, int AT, int ZP, int AP, int ZE, int AE,
|
||||
double EP, double angle, double B),
|
||||
where Z,A are atomic number and mass number for each particle,
|
||||
EP is the KE of the projectile (i.e. beam energy in MeV),
|
||||
angle is the spectrograph angle (in degrees),
|
||||
B is the field in Gauss.
|
||||
|
||||
>>> Wire_Dist() returns the distance (in cm) between the wires for
|
||||
the calculation of relative weights between FP1 and FP2.
|
||||
|
||||
//format: T(P,E)R
|
||||
// i.e., T = target,
|
||||
// P = projectile,
|
||||
// E = ejectile,
|
||||
// R = residual;
|
||||
//expects angle in degs, B in G, masses and KE in MeV
|
||||
|
||||
KGH -- Jul19
|
||||
|
||||
Small modifications for use with the MassLookup class GWM -- Jan 2021
|
||||
|
||||
*/
|
||||
|
||||
#include "EventBuilder.h"
|
||||
#include <cmath>
|
||||
#include "MassLookup.h"
|
||||
#include "FP_kinematics.h"
|
||||
|
||||
//requires (Z,A) for T, P, and E, as well as energy of P,
|
||||
// spectrograph angle of interest, and field value
|
||||
double Delta_Z(int ZT, int AT, int ZP, int AP, int ZE, int AE,
|
||||
double EP, double angle, double B) {
|
||||
|
||||
/* CONSTANTS */
|
||||
const double UTOMEV = 931.4940954; //MeV per u;
|
||||
const double MEVTOJ = 1.60218E-13; //J per MeV
|
||||
const double RESTMASS_ELECTRON = 0.000548579909; //amu
|
||||
const double UNIT_CHARGE = 1.602E-19; //Coulombs
|
||||
const double C = 2.9979E8; //m/s
|
||||
|
||||
/* SESPS-SPECIFIC */
|
||||
const double DISP = 1.96; //dispersion (x/rho)
|
||||
const double MAG = 0.39; //magnification in x
|
||||
const double DEGTORAD = M_PI/180.;
|
||||
|
||||
int ZR = ZT + ZP - ZE, AR = AT + AP - AE;
|
||||
double EE=0; //ejectile energy
|
||||
|
||||
double MT=0, MP=0, ME=0, MR=0; //masses (MeV)
|
||||
|
||||
B /= 10000; //convert to tesla
|
||||
angle *= DEGTORAD;
|
||||
|
||||
MT = MASS.FindMass(ZT, AT) - ZT*RESTMASS_ELECTRON*UTOMEV;
|
||||
MP = MASS.FindMass(ZP, AP) - ZP*RESTMASS_ELECTRON*UTOMEV;
|
||||
ME = MASS.FindMass(ZE, AE) - ZE*RESTMASS_ELECTRON*UTOMEV;
|
||||
MR = MASS.FindMass(ZR, AR) - ZR*RESTMASS_ELECTRON*UTOMEV;
|
||||
|
||||
if (MT*MP*ME*MR == 0) {
|
||||
std::cerr << "***WARNING: error loading one or more masses; returning 0\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
double Q = MT + MP - ME - MR; //Q-value
|
||||
|
||||
//kinematics a la Iliadis p.590
|
||||
double term1 = sqrt(MP*ME*EP)/(ME + MR)*cos(angle);
|
||||
double term2 = (EP*(MR - MP) + MR*Q)/(ME + MR);
|
||||
|
||||
EE = term1 + sqrt(term1*term1 + term2);
|
||||
EE *= EE;
|
||||
|
||||
//momentum
|
||||
double PE = sqrt(EE*(EE+2*ME));
|
||||
|
||||
//calculate rho from B a la B*rho = (proj. momentum)/(proj. charge)
|
||||
double rho = (PE*MEVTOJ)/(ZE*UNIT_CHARGE*C*B)*100; //in cm
|
||||
|
||||
double K;
|
||||
|
||||
K = sqrt(MP*ME*EP/EE);
|
||||
K *= sin(angle);
|
||||
|
||||
double denom = ME + MR - sqrt(MP*ME*EP/EE)*cos(angle);
|
||||
|
||||
K /= denom;
|
||||
std::cout<<"Delta Z= "<<-1*rho*DISP*MAG*K<<std::endl;
|
||||
return -1*rho*DISP*MAG*K; //delta-Z in cm
|
||||
|
||||
}
|
||||
|
||||
double Wire_Dist() {return 4.28625;} //cm
|
||||
|
116
src/evb/FastSort.cpp
Normal file
116
src/evb/FastSort.cpp
Normal file
|
@ -0,0 +1,116 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "FastSort.h"
|
||||
|
||||
FastSort::FastSort(float si_windowSize, float ion_windowSize) {
|
||||
si_coincWindow = si_windowSize/1.0e3; //given in pico s, want in nano s
|
||||
ion_coincWindow = ion_windowSize/1.0e3;
|
||||
event_address = NULL;
|
||||
}
|
||||
|
||||
FastSort::~FastSort() {
|
||||
delete event_address;
|
||||
}
|
||||
|
||||
void FastSort::ResetSABRE() {
|
||||
for(int i=0; i<5; i++) {
|
||||
fastEvent.sabreArray[i] = sblank;
|
||||
}
|
||||
}
|
||||
|
||||
void FastSort::ResetFocalPlane() {
|
||||
fastEvent.focalPlane = fpblank;
|
||||
}
|
||||
|
||||
/*Assign a set of ion chamber data to the scintillator*/
|
||||
void FastSort::ProcessFocalPlane(unsigned int scint_index, unsigned int ionch_index) {
|
||||
|
||||
/*In order to have a coincidence window, one must choose a portion of the ion chamber to form a requirement.
|
||||
*In this case, I chose one of the anodes. But in principle you could also choose any other part of the ion
|
||||
*chamber
|
||||
*/
|
||||
if(slowEvent.focalPlane.anodeB.size() > 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<DetectorHit> rings;
|
||||
std::vector<DetectorHit> 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<slowEvent.sabreArray[i].rings.size(); j++) {
|
||||
float sabreRelTime = fabs(slowEvent.sabreArray[i].rings[j].Time - slowEvent.focalPlane.scintL[scint_index].Time);
|
||||
if(sabreRelTime < si_coincWindow) {
|
||||
rings.push_back(slowEvent.sabreArray[i].rings[j]);
|
||||
}
|
||||
}
|
||||
for(unsigned int j=0; j<slowEvent.sabreArray[i].wedges.size(); j++) {
|
||||
float sabreRelTime = fabs(slowEvent.sabreArray[i].wedges[j].Time - slowEvent.focalPlane.scintL[scint_index].Time);
|
||||
if(sabreRelTime < si_coincWindow) {
|
||||
wedges.push_back(slowEvent.sabreArray[i].wedges[j]);
|
||||
}
|
||||
}
|
||||
|
||||
fastEvent.sabreArray[i].rings = rings;
|
||||
fastEvent.sabreArray[i].wedges = wedges;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CoincEvent> FastSort::GetFastEvents(CoincEvent& event) {
|
||||
slowEvent = event;
|
||||
std::vector<CoincEvent> 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<slowEvent.focalPlane.scintL.size(); i++) {
|
||||
ResetSABRE();
|
||||
ProcessSABRE(i);
|
||||
//loop over ion chamber
|
||||
//NOTE: as written, this dumps data that does not have an ion chamber hit!
|
||||
//If you want scint/SABRE singles, move the fill outside of this loop
|
||||
for(unsigned int j=0; j<maxSize; j++) {
|
||||
ResetFocalPlane();
|
||||
ProcessFocalPlane(i, j);
|
||||
fast_events.push_back(fastEvent);
|
||||
}
|
||||
}
|
||||
return fast_events;
|
||||
}
|
86
src/evb/FlagHandler.cpp
Normal file
86
src/evb/FlagHandler.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "FlagHandler.h"
|
||||
|
||||
FlagHandler::FlagHandler() :
|
||||
log("./event_log.txt")
|
||||
{
|
||||
}
|
||||
|
||||
FlagHandler::FlagHandler(const std::string& filename) :
|
||||
log(filename)
|
||||
{
|
||||
}
|
||||
|
||||
FlagHandler::~FlagHandler() {
|
||||
WriteLog();
|
||||
log.close();
|
||||
}
|
||||
|
||||
void FlagHandler::CheckFlag(int board, int channel, int flag) {
|
||||
|
||||
int gchan = channel + board*16;
|
||||
FlagCount& counter = event_count_map[gchan]; //yikes
|
||||
|
||||
counter.total_counts++;
|
||||
|
||||
if(flag & DEAD_TIME) counter.dead_time++;
|
||||
|
||||
if(flag & TIME_ROLLOVER) counter.time_roll++;
|
||||
|
||||
if(flag & TIME_RESET) counter.time_reset++;
|
||||
|
||||
if(flag & FAKE_EVENT) counter.fake_event++;
|
||||
|
||||
if(flag & MEM_FULL) counter.mem_full++;
|
||||
|
||||
if(flag & TRIG_LOST) counter.trig_lost++;
|
||||
|
||||
if(flag & N_TRIG_LOST) counter.n_trig_lost++;
|
||||
|
||||
if(flag & SATURATING_IN_GATE) counter.sat_in_gate++;
|
||||
|
||||
if(flag & TRIG_1024_COUNTED) counter.trig_1024++;;
|
||||
|
||||
if(flag & SATURATING_INPUT) counter.sat_input++;
|
||||
|
||||
if(flag & N_TRIG_COUNTED) counter.n_trig_count++;
|
||||
|
||||
if(flag & EVENT_NOT_MATCHED) counter.event_not_matched++;
|
||||
|
||||
if(flag & PILE_UP) counter.pile_up++;
|
||||
|
||||
if(flag & PLL_LOCK_LOSS) counter.pll_lock_loss++;
|
||||
|
||||
if(flag & OVER_TEMP) counter.over_temp++;
|
||||
|
||||
if(flag & ADC_SHUTDOWN) counter.adc_shutdown++;
|
||||
|
||||
}
|
||||
|
||||
void FlagHandler::WriteLog() {
|
||||
log<<"Event Flag Log"<<std::endl;
|
||||
log<<"-----------------------------"<<std::endl;
|
||||
for(auto& counter : event_count_map) {
|
||||
log<<"-----------------------------"<<std::endl;
|
||||
log<<"GLOBAL CHANNEL No.: "<<counter.first<<std::endl;
|
||||
log<<"Total number of events: "<<counter.second.total_counts<<std::endl;
|
||||
log<<"Dead time incurred (only for V1724): "<<counter.second.dead_time<<std::endl;
|
||||
log<<"Timestamp rollovers: "<<counter.second.time_roll<<std::endl;
|
||||
log<<"Timestamp resets from external: "<<counter.second.time_reset<<std::endl;
|
||||
log<<"Fake events: "<<counter.second.fake_event<<std::endl;
|
||||
log<<"Memory full: "<<counter.second.mem_full<<std::endl;
|
||||
log<<"Triggers lost: "<<counter.second.trig_lost<<std::endl;
|
||||
log<<"N Triggers lost: "<<counter.second.n_trig_lost<<std::endl;
|
||||
log<<"Saturation within the gate: "<<counter.second.sat_in_gate<<std::endl;
|
||||
log<<"1024 Triggers found: "<<counter.second.trig_1024<<std::endl;
|
||||
log<<"Saturation on input: "<<counter.second.sat_input<<std::endl;
|
||||
log<<"N Triggers counted: "<<counter.second.n_trig_count<<std::endl;
|
||||
log<<"Events not matched: "<<counter.second.event_not_matched<<std::endl;
|
||||
log<<"Pile ups: "<<counter.second.pile_up<<std::endl;
|
||||
log<<"PLL lock lost: "<<counter.second.pll_lock_loss<<std::endl;
|
||||
log<<"Over Temperature: "<<counter.second.over_temp<<std::endl;
|
||||
log<<"ADC Shutdown: "<<counter.second.adc_shutdown<<std::endl;
|
||||
log<<"-----------------------------"<<std::endl;
|
||||
}
|
||||
}
|
||||
|
405
src/evb/GWMEventBuilder.cpp
Normal file
405
src/evb/GWMEventBuilder.cpp
Normal file
|
@ -0,0 +1,405 @@
|
|||
/*
|
||||
GWMEventBuilder.cpp
|
||||
Class which represents the API of the event building environment. Wraps together the core concepts
|
||||
of the event builder, from conversion to plotting. Even intended to be able to archive data.
|
||||
Currently under development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#include "EventBuilder.h"
|
||||
#include <cstdlib>
|
||||
#include "GWMEventBuilder.h"
|
||||
#include "RunCollector.h"
|
||||
#include "CompassRun.h"
|
||||
#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: "<<fullpath<<std::endl;
|
||||
std::ifstream input(fullpath);
|
||||
if(!input.is_open()) {
|
||||
std::cout<<"Read failed! Unable to open input file!"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
std::string junk;
|
||||
|
||||
std::getline(input, junk);
|
||||
input>>junk>>m_workspace;
|
||||
input>>junk;
|
||||
std::getline(input, junk);
|
||||
std::getline(input, junk);
|
||||
input>>junk>>m_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."<<std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GWMEventBuilder::WriteConfigFile(const std::string& fullpath) {
|
||||
|
||||
std::cout<<"Writing out configuration to file: "<<fullpath<<std::endl;
|
||||
std::ofstream output(fullpath);
|
||||
if(!output.is_open()) {
|
||||
std::cout<<"Write failed! Unable to open output file!"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
output<<"-------Data Location----------"<<std::endl;
|
||||
output<<"WorkspaceDirectory: "<<m_workspace<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
output<<"------Experimental Inputs------"<<std::endl;
|
||||
output<<"ChannelMapFile: "<<m_mapfile<<std::endl;
|
||||
output<<"ScalerFile: "<<m_scalerfile<<std::endl;
|
||||
output<<"CutListFile: "<<m_cutList<<std::endl;
|
||||
output<<"ZT: "<<m_ZT<<std::endl;
|
||||
output<<"AT: "<<m_AT<<std::endl;
|
||||
output<<"ZP: "<<m_ZP<<std::endl;
|
||||
output<<"AP: "<<m_AP<<std::endl;
|
||||
output<<"ZE: "<<m_ZE<<std::endl;
|
||||
output<<"AE: "<<m_AE<<std::endl;
|
||||
output<<"BField(G): "<<m_B<<std::endl;
|
||||
output<<"BeamKE(MeV): "<<m_BKE<<std::endl;
|
||||
output<<"Theta(deg): "<<m_Theta<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
output<<"-------Timing Information------"<<std::endl;
|
||||
output<<"BoardOffsetFile: "<<m_shiftfile<<std::endl;
|
||||
output<<"SlowCoincidenceWindow(ps): "<<m_SlowWindow<<std::endl;
|
||||
output<<"FastCoincidenceWindow_IonCh(ps): "<<m_FastWindowIonCh<<std::endl;
|
||||
output<<"FastCoincidenceWindow_SABRE(ps): "<<m_FastWindowSABRE<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
output<<"--------Run Information--------"<<std::endl;
|
||||
output<<"MinRun: "<<m_rmin<<std::endl;
|
||||
output<<"MaxRun: "<<m_rmax<<std::endl;
|
||||
output<<"-------------------------------"<<std::endl;
|
||||
|
||||
output.close();
|
||||
|
||||
std::cout<<"Completed."<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void GWMEventBuilder::PlotHistograms() {
|
||||
std::string analyze_dir = m_workspace+"/analyzed/";
|
||||
std::string plot_file = m_workspace+"/histograms/run_"+to_string(m_rmin)+"_"+to_string(m_rmax)+".root";
|
||||
SFPPlotter grammer;
|
||||
grammer.ApplyCutlist(m_cutList);
|
||||
std::cout<<"-------------GWM Event Builder-------------"<<std::endl;
|
||||
std::cout<<"Generating a histogram file from analyzed files"<<std::endl;
|
||||
std::cout<<"Analyzed directory: "<<analyze_dir<<std::endl;
|
||||
std::cout<<"Min Run: "<<m_rmin<<" Max Run: "<<m_rmax<<std::endl;
|
||||
std::cout<<"Cut List File: "<<m_cutList<<std::endl;
|
||||
std::cout<<"Histogram File: "<<plot_file<<std::endl;
|
||||
|
||||
if(m_pb) grammer.AttachProgressBar(m_pb);
|
||||
grabber.SetSearchParams(analyze_dir, "", ".root", m_rmin, m_rmax);
|
||||
if(grabber.GrabFilesInRange()) {
|
||||
std::cout<<"Working...";
|
||||
grammer.Run(grabber.filelist, plot_file);
|
||||
std::cout<<" Complete."<<std::endl;
|
||||
} else {
|
||||
std::cout<<"Unable to find files at PlotHistograms"<<std::endl;
|
||||
}
|
||||
std::cout<<"-------------------------------------------"<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void GWMEventBuilder::Convert2RawRoot() {
|
||||
std::string rawroot_dir = m_workspace+"/raw_root/";
|
||||
std::string unpack_dir = m_workspace+"/temp_binary/";
|
||||
std::string binary_dir = m_workspace+"/raw_binary/";
|
||||
std::cout<<"-------------GWM Event Builder-------------"<<std::endl;
|
||||
std::cout<<"Converting Binary file Archive to ROOT file"<<std::endl;
|
||||
std::cout<<"Binary Archive Directory: "<<binary_dir<<std::endl;
|
||||
std::cout<<"Temporary Unpack Directory: "<<unpack_dir<<std::endl;
|
||||
std::cout<<"Timestamp Shift File: "<<m_shiftfile<<std::endl;
|
||||
std::cout<<"Min Run: "<<m_rmin<<" Max Run: "<<m_rmax<<std::endl;
|
||||
|
||||
|
||||
grabber.SetSearchParams(binary_dir, "", ".tar.gz",0,1000);
|
||||
|
||||
std::cout<<"Workspace Directory: "<<m_workspace<<std::endl;
|
||||
|
||||
std::string rawfile, binfile;
|
||||
std::string unpack_command, wipe_command;
|
||||
|
||||
CompassRun converter(unpack_dir);
|
||||
converter.SetShiftMap(m_shiftfile);
|
||||
converter.SetScalerInput(m_scalerfile);
|
||||
if(m_pb) converter.AttachProgressBar(m_pb);
|
||||
|
||||
std::cout<<"Beginning conversion..."<<std::endl;
|
||||
|
||||
for(int i=m_rmin; i<=m_rmax; i++) {
|
||||
binfile = grabber.GrabFile(i);
|
||||
if(binfile == "") continue;
|
||||
converter.SetRunNumber(i);
|
||||
std::cout<<"Converting file: "<<binfile<<std::endl;
|
||||
|
||||
rawfile = rawroot_dir + "compass_run_"+ to_string(i) + ".root";
|
||||
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
|
||||
wipe_command = "rm -r "+unpack_dir+"*.bin";
|
||||
|
||||
system(unpack_command.c_str());
|
||||
converter.Convert2RawRoot(rawfile);
|
||||
system(wipe_command.c_str());
|
||||
|
||||
}
|
||||
std::cout<<std::endl<<"Conversion complete."<<std::endl;
|
||||
std::cout<<"-------------------------------------------"<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void GWMEventBuilder::MergeROOTFiles() {
|
||||
std::string merge_file = m_workspace+"/merged/run_"+to_string(m_rmin)+"_"+to_string(m_rmax)+".root";
|
||||
std::string file_dir = m_workspace+"/analyzed/";
|
||||
std::cout<<"-------------GWM Event Builder-------------"<<std::endl;
|
||||
std::cout<<"Merging ROOT files into single ROOT file"<<std::endl;
|
||||
std::cout<<"Workspace directory: "<<m_workspace<<std::endl;
|
||||
std::cout<<"Min Run: "<<m_rmin<<" Max Run: "<<m_rmax<<std::endl;
|
||||
std::cout<<"Output file: "<<merge_file<<std::endl;
|
||||
std::string prefix = "";
|
||||
std::string suffix = ".root";
|
||||
grabber.SetSearchParams(file_dir, prefix, suffix,m_rmin,m_rmax);
|
||||
std::cout<<"Beginning the merge...";
|
||||
if(!grabber.Merge_TChain(merge_file)) {
|
||||
std::cout<<"Unable to find files at MergeROOTFiles"<<std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout<<" Complete."<<std::endl;
|
||||
std::cout<<"-------------------------------------------"<<std::endl;
|
||||
}
|
||||
|
||||
void GWMEventBuilder::Convert2SortedRoot() {
|
||||
std::string sortroot_dir = m_workspace+"/sorted/";
|
||||
std::string unpack_dir = m_workspace+"/temp_binary/";
|
||||
std::string binary_dir = m_workspace+"/raw_binary/";
|
||||
std::cout<<"-------------GWM Event Builder-------------"<<std::endl;
|
||||
std::cout<<"Converting Binary file Archive to ROOT file"<<std::endl;
|
||||
std::cout<<"Binary Archive Directory: "<<binary_dir<<std::endl;
|
||||
std::cout<<"Temporary Unpack Directory: "<<unpack_dir<<std::endl;
|
||||
std::cout<<"Timestamp Shift File: "<<m_shiftfile<<std::endl;
|
||||
std::cout<<"Channel Map File: "<<m_mapfile<<std::endl;
|
||||
std::cout<<"Slow Coincidence Window(ps): "<<m_SlowWindow<<std::endl;
|
||||
std::cout<<"Min Run: "<<m_rmin<<" Max Run: "<<m_rmax<<std::endl;
|
||||
|
||||
grabber.SetSearchParams(binary_dir,"",".tar.gz",m_rmin,m_rmax);
|
||||
|
||||
std::cout<<"Workspace Directory: "<<m_workspace<<std::endl;
|
||||
|
||||
std::string sortfile, binfile;
|
||||
std::string unpack_command, wipe_command;
|
||||
|
||||
CompassRun converter(unpack_dir);
|
||||
converter.SetShiftMap(m_shiftfile);
|
||||
converter.SetScalerInput(m_scalerfile);
|
||||
if(m_pb) converter.AttachProgressBar(m_pb);
|
||||
|
||||
std::cout<<"Beginning conversion..."<<std::endl;
|
||||
|
||||
for(int i=m_rmin; i<= m_rmax; i++) {
|
||||
binfile = grabber.GrabFile(i);
|
||||
if(binfile == "") continue;
|
||||
converter.SetRunNumber(i);
|
||||
std::cout<<"Converting file: "<<binfile<<std::endl;
|
||||
|
||||
sortfile = sortroot_dir +"run_"+to_string(i)+ ".root";
|
||||
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
|
||||
wipe_command = "rm -r "+unpack_dir+"*.bin";
|
||||
|
||||
system(unpack_command.c_str());
|
||||
converter.Convert2SortedRoot(sortfile, m_mapfile, m_SlowWindow);
|
||||
system(wipe_command.c_str());
|
||||
|
||||
}
|
||||
std::cout<<std::endl<<"Conversion complete."<<std::endl;
|
||||
std::cout<<"-------------------------------------------"<<std::endl;
|
||||
}
|
||||
|
||||
void GWMEventBuilder::Convert2FastSortedRoot() {
|
||||
std::string sortroot_dir = m_workspace+"/fast/";
|
||||
std::string unpack_dir = m_workspace+"/temp_binary/";
|
||||
std::string binary_dir = m_workspace+"/raw_binary/";
|
||||
std::cout<<"-------------GWM Event Builder-------------"<<std::endl;
|
||||
std::cout<<"Converting Binary file Archive to ROOT file"<<std::endl;
|
||||
std::cout<<"Binary Archive Directory: "<<binary_dir<<std::endl;
|
||||
std::cout<<"Temporary Unpack Directory: "<<unpack_dir<<std::endl;
|
||||
std::cout<<"Timestamp Shift File: "<<m_shiftfile<<std::endl;
|
||||
std::cout<<"Channel Map File: "<<m_mapfile<<std::endl;
|
||||
std::cout<<"Slow Coincidence Window(ps): "<<m_SlowWindow<<std::endl;
|
||||
std::cout<<"Min Run: "<<m_rmin<<" Max Run: "<<m_rmax<<std::endl;
|
||||
|
||||
grabber.SetSearchParams(binary_dir,"",".tar.gz",m_rmin,m_rmax);
|
||||
|
||||
std::cout<<"Workspace Directory: "<<m_workspace<<std::endl;
|
||||
|
||||
std::string sortfile, binfile;
|
||||
std::string unpack_command, wipe_command;
|
||||
|
||||
CompassRun converter(unpack_dir);
|
||||
converter.SetShiftMap(m_shiftfile);
|
||||
converter.SetScalerInput(m_scalerfile);
|
||||
if(m_pb) converter.AttachProgressBar(m_pb);
|
||||
|
||||
std::cout<<"Beginning conversion..."<<std::endl;
|
||||
|
||||
for(int i=m_rmin; i<=m_rmax; i++) {
|
||||
binfile = grabber.GrabFile(i);
|
||||
if(binfile == "") continue;
|
||||
converter.SetRunNumber(i);
|
||||
std::cout<<"Converting file: "<<binfile<<std::endl;
|
||||
|
||||
sortfile = sortroot_dir + "run_" + to_string(i) + ".root";
|
||||
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
|
||||
wipe_command = "rm -r "+unpack_dir+"*.bin";
|
||||
|
||||
system(unpack_command.c_str());
|
||||
converter.Convert2FastSortedRoot(sortfile, m_mapfile, m_SlowWindow, m_FastWindowSABRE, m_FastWindowIonCh);
|
||||
system(wipe_command.c_str());
|
||||
|
||||
}
|
||||
std::cout<<std::endl<<"Conversion complete."<<std::endl;
|
||||
std::cout<<"-------------------------------------------"<<std::endl;
|
||||
}
|
||||
|
||||
void GWMEventBuilder::Convert2SlowAnalyzedRoot() {
|
||||
std::string sortroot_dir = m_workspace+"/analyzed/";
|
||||
std::string unpack_dir = m_workspace+"/temp_binary/";
|
||||
std::string binary_dir = m_workspace+"/raw_binary/";
|
||||
std::cout<<"-------------GWM Event Builder-------------"<<std::endl;
|
||||
std::cout<<"Converting Binary file Archive to ROOT file"<<std::endl;
|
||||
std::cout<<"Binary Archive Directory: "<<binary_dir<<std::endl;
|
||||
std::cout<<"Temporary Unpack Directory: "<<unpack_dir<<std::endl;
|
||||
std::cout<<"Timestamp Shift File: "<<m_shiftfile<<std::endl;
|
||||
std::cout<<"Channel Map File: "<<m_mapfile<<std::endl;
|
||||
std::cout<<"Slow Coincidence Window(ps): "<<m_SlowWindow<<std::endl;
|
||||
std::cout<<"Min Run: "<<m_rmin<<" Max Run: "<<m_rmax<<std::endl;
|
||||
|
||||
grabber.SetSearchParams(binary_dir,"",".tar.gz",m_rmin, m_rmax);
|
||||
std::cout<<"Workspace Directory: "<<m_workspace<<std::endl;
|
||||
|
||||
std::string sortfile, binfile;
|
||||
std::string unpack_command, wipe_command;
|
||||
|
||||
CompassRun converter(unpack_dir);
|
||||
converter.SetShiftMap(m_shiftfile);
|
||||
converter.SetScalerInput(m_scalerfile);
|
||||
if(m_pb) converter.AttachProgressBar(m_pb);
|
||||
|
||||
std::cout<<"Beginning conversion..."<<std::endl;
|
||||
|
||||
for(int i=m_rmin; i<=m_rmax; i++) {
|
||||
binfile = grabber.GrabFile(i);
|
||||
if(binfile == "") continue;
|
||||
converter.SetRunNumber(i);
|
||||
std::cout<<"Converting file: "<<binfile<<std::endl;
|
||||
|
||||
sortfile = sortroot_dir + "run_" + to_string(i) + ".root";
|
||||
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
|
||||
wipe_command = "rm -r "+unpack_dir+"*.bin";
|
||||
|
||||
system(unpack_command.c_str());
|
||||
converter.Convert2SlowAnalyzedRoot(sortfile, m_mapfile, m_SlowWindow, m_ZT, m_AT, m_ZP, m_AP, m_ZE, m_AE, m_BKE, m_B, m_Theta);
|
||||
system(wipe_command.c_str());
|
||||
|
||||
}
|
||||
std::cout<<std::endl<<"Conversion complete."<<std::endl;
|
||||
std::cout<<"-------------------------------------------"<<std::endl;
|
||||
}
|
||||
|
||||
void GWMEventBuilder::Convert2FastAnalyzedRoot() {
|
||||
std::string sortroot_dir = m_workspace+"/analyzed/";
|
||||
std::string unpack_dir = m_workspace+"/temp_binary/";
|
||||
std::string binary_dir = m_workspace+"/raw_binary/";
|
||||
std::cout<<"-------------GWM Event Builder-------------"<<std::endl;
|
||||
std::cout<<"Converting Binary file Archive to ROOT file"<<std::endl;
|
||||
std::cout<<"Binary Archive Directory: "<<binary_dir<<std::endl;
|
||||
std::cout<<"Temporary Unpack Directory: "<<unpack_dir<<std::endl;
|
||||
std::cout<<"Timestamp Shift File: "<<m_shiftfile<<std::endl;
|
||||
std::cout<<"Channel Map File: "<<m_mapfile<<std::endl;
|
||||
std::cout<<"Slow Coincidence Window(ps): "<<m_SlowWindow<<std::endl;
|
||||
std::cout<<"Fast Ion Chamber Coincidence Window(ps): "<<m_FastWindowIonCh<<std::endl;
|
||||
std::cout<<"Fast SABRE Coincidence Window(ps): "<<m_FastWindowSABRE<<std::endl;
|
||||
std::cout<<"Min Run: "<<m_rmin<<" Max Run: "<<m_rmax<<std::endl;
|
||||
|
||||
grabber.SetSearchParams(binary_dir,"",".tar.gz",m_rmin,m_rmax);
|
||||
|
||||
std::cout<<"Workspace Directory: "<<m_workspace<<std::endl;
|
||||
|
||||
std::string sortfile, binfile;
|
||||
std::string unpack_command, wipe_command;
|
||||
|
||||
CompassRun converter(unpack_dir);
|
||||
converter.SetShiftMap(m_shiftfile);
|
||||
converter.SetScalerInput(m_scalerfile);
|
||||
if(m_pb) converter.AttachProgressBar(m_pb);
|
||||
|
||||
std::cout<<"Beginning conversion..."<<std::endl;
|
||||
|
||||
for(int i=m_rmin; i<=m_rmax; i++) {
|
||||
binfile = grabber.GrabFile(i);
|
||||
if(binfile == "") continue;
|
||||
converter.SetRunNumber(i);
|
||||
std::cout<<"Converting file: "<<binfile<<std::endl;
|
||||
|
||||
sortfile = sortroot_dir + "run_" + to_string(i) + ".root";
|
||||
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
|
||||
wipe_command = "rm -r "+unpack_dir+"*.bin";
|
||||
|
||||
system(unpack_command.c_str());
|
||||
converter.Convert2FastAnalyzedRoot(sortfile, m_mapfile, m_SlowWindow, m_FastWindowSABRE, m_FastWindowIonCh, m_ZT, m_AT, m_ZP, m_AP, m_ZE, m_AE, m_BKE, m_B, m_Theta);
|
||||
system(wipe_command.c_str());
|
||||
|
||||
}
|
||||
std::cout<<std::endl<<"Conversion complete."<<std::endl;
|
||||
std::cout<<"-------------------------------------------"<<std::endl;
|
||||
}
|
||||
|
||||
bool GWMEventBuilder::SetKinematicParameters(int zt, int at, int zp, int ap, int ze, int ae, double b, double theta, double bke) {
|
||||
|
||||
if((at + ap - ae) < 0 || (zt + zp - ze) < 0) {
|
||||
std::cout<<"Invalid Parameters at SetKinematicParameters"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
m_ZT = zt; m_AT = at; m_ZP = zp; m_AP = ap; m_ZE = ze; m_AE = ae;
|
||||
m_B = b; m_Theta = theta; m_BKE = bke;
|
||||
|
||||
m_ZR = (zt + zp - ze);
|
||||
m_AR = (at + ap - ae);
|
||||
|
||||
return true;
|
||||
}
|
61
src/evb/MassLookup.cpp
Normal file
61
src/evb/MassLookup.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
#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."<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
std::cerr<<"Invaild nucleus at MassLookup! Returning mass of 0"<<std::endl;
|
||||
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()) {
|
||||
std::cerr<<"Invaild nucleus at MassLookup! Returning empty symbol"<<std::endl;
|
||||
return "";
|
||||
}
|
||||
std::string fullsymbol = std::to_string(A) + data->second;
|
||||
return fullsymbol;
|
||||
}
|
37
src/evb/OrderChecker.cpp
Normal file
37
src/evb/OrderChecker.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
OrderChecker.cpp
|
||||
Very simple class designed to test whether or not a root file is time ordered.
|
||||
Meant to be used with newly converted from binary data. Only for development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#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; i<tree->GetEntries(); i++) {
|
||||
tree->GetEntry();
|
||||
if(prevStamp >= ts) {
|
||||
std::cerr<<"Bad order at entry "<<i<<" out of "<<tree->GetEntries()<<std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
file->Close();
|
||||
return true;
|
||||
}
|
196
src/evb/RunCollector.cpp
Normal file
196
src/evb/RunCollector.cpp
Normal file
|
@ -0,0 +1,196 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "RunCollector.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
RunCollector::RunCollector():
|
||||
initFlag(false), dir(""), run(""), end(""), MaxRun(0), MinRun(0)
|
||||
{
|
||||
}
|
||||
|
||||
RunCollector::RunCollector(const string& dirname, const string& prefix, const string& suffix) {
|
||||
dir = dirname.c_str();
|
||||
run = prefix.c_str();
|
||||
end = suffix.c_str();
|
||||
|
||||
MinRun = 0; MaxRun = LITERALMAX;
|
||||
initFlag = true;
|
||||
}
|
||||
|
||||
RunCollector::RunCollector(const string& dirname, const string& prefix, const string& suffix, int min, int max) {
|
||||
dir = dirname.c_str();
|
||||
run = prefix.c_str();
|
||||
end = suffix.c_str();
|
||||
|
||||
MinRun = min; MaxRun = max;
|
||||
initFlag = true;
|
||||
}
|
||||
|
||||
RunCollector::~RunCollector() {}
|
||||
|
||||
void RunCollector::SetSearchParams(const string& dirname, const string& prefix, const string& suffix, int min, int max) {
|
||||
dir = dirname.c_str();
|
||||
run = prefix.c_str();
|
||||
end = suffix.c_str();
|
||||
MinRun = min; MaxRun = max;
|
||||
initFlag = true;
|
||||
}
|
||||
|
||||
int RunCollector::GrabAllFiles() {
|
||||
if(!initFlag) {return 0;}
|
||||
TSystemDirectory sysdir(dir.Data(), dir.Data());
|
||||
TList *flist = sysdir.GetListOfFiles();
|
||||
filelist.clear();
|
||||
int counter = 0;
|
||||
if(flist) { //Make sure list is real. If not, means no directory
|
||||
TSystemFile *file;
|
||||
TString fname, temp;
|
||||
TIter next_element(flist); //List iterator
|
||||
while((file = (TSystemFile*)next_element())) {
|
||||
temp = file->GetName();
|
||||
if(!file->IsDirectory() && temp.BeginsWith(run.Data()) && temp.EndsWith(end.Data())) {
|
||||
counter++;
|
||||
fname = dir+temp;
|
||||
filelist.push_back(fname);
|
||||
}
|
||||
}
|
||||
if(counter>0) {
|
||||
delete flist;
|
||||
return 1;
|
||||
} else {
|
||||
cerr<<"Unable to find files with matching run name in directory; check input.txt"<<endl;
|
||||
delete flist;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
cerr<<"Unable to find any files in directory; check name given to the input.txt"<<endl;
|
||||
delete flist;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string RunCollector::GrabFile(int runNum) {
|
||||
if(!initFlag) return "";
|
||||
TSystemDirectory sysdir(dir.Data(), dir.Data());
|
||||
TList* flist = sysdir.GetListOfFiles();
|
||||
|
||||
if(!flist) return "";
|
||||
|
||||
TSystemFile *file;
|
||||
TString fname = "", temp;
|
||||
string runno = "_"+to_string(runNum)+end.Data();
|
||||
TIter next_element(flist);
|
||||
while((file = (TSystemFile*)next_element())) {
|
||||
temp = file->GetName();
|
||||
if(!file->IsDirectory() && temp.BeginsWith(run.Data()) && temp.EndsWith(runno.c_str())) {
|
||||
fname = dir+temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return fname.Data();
|
||||
}
|
||||
|
||||
/*Grabs all files within a specified run range*/
|
||||
int RunCollector::GrabFilesInRange() {
|
||||
if(!initFlag) {return 0;}
|
||||
TSystemDirectory sysdir(dir.Data(), dir.Data());
|
||||
TList *flist = sysdir.GetListOfFiles();
|
||||
filelist.clear();
|
||||
int counter = 0;
|
||||
if(flist) {
|
||||
TSystemFile *file;
|
||||
TString fname, temp;
|
||||
string runno;
|
||||
for(int i=MinRun; i<=MaxRun; i++) {//loop over range
|
||||
TIter next_element(flist);//list iterator
|
||||
runno = "_"+to_string(i) + end.Data(); //suffix is now _#.endData
|
||||
while((file = (TSystemFile*)next_element())) {//look through directory until file found
|
||||
temp = file->GetName();
|
||||
if(!file->IsDirectory()&&temp.BeginsWith(run.Data())&&temp.EndsWith(runno.c_str())){
|
||||
counter++;
|
||||
fname = dir+temp;
|
||||
filelist.push_back(fname);
|
||||
break; //if we find the file, break out of iterator loop
|
||||
}
|
||||
}
|
||||
}
|
||||
if(counter>0) {
|
||||
delete flist;
|
||||
return 1;
|
||||
} else {
|
||||
cerr<<"Unable to find files with matching run name in directory; check input.txt"<<endl;
|
||||
delete flist;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
cerr<<"Unable to find any files in directory; check name given to input.txt"<<endl;
|
||||
delete flist;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int RunCollector::Merge_hadd(const string& outname) {
|
||||
if(!initFlag) {return 0;}
|
||||
if(MaxRun == LITERALMAX) {
|
||||
if(GrabAllFiles()) {
|
||||
TString clump = "hadd "+outname;
|
||||
for(unsigned int i=0; i<filelist.size(); i++) {
|
||||
clump += " "+filelist[i];
|
||||
}
|
||||
cout<<"Merging runs into single file..."<<endl;
|
||||
system(clump.Data());
|
||||
cout<<"Finished merging"<<endl;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if(GrabFilesInRange()) {
|
||||
TString clump = "hadd "+outname;
|
||||
for(unsigned int i=0; i<filelist.size(); i++) {
|
||||
clump += " "+filelist[i];
|
||||
}
|
||||
cout<<"Merging runs "<<MinRun<<" to "<<MaxRun<<" into a single file..."<<endl;
|
||||
system(clump.Data());
|
||||
cout<<"Finished merging"<<endl;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int RunCollector::Merge_TChain(const string& outname) {
|
||||
if(!initFlag) {return 0;}
|
||||
TFile *output = new TFile(outname.c_str(), "RECREATE");
|
||||
TChain *chain = new TChain("SPSTree", "SPSTree");
|
||||
|
||||
if(MaxRun == LITERALMAX) {
|
||||
if(GrabAllFiles()) {
|
||||
for(unsigned int i=0; i<filelist.size(); i++) {
|
||||
chain->Add(filelist[i].Data());
|
||||
}
|
||||
cout<<"Merging runs into single file..."<<endl;
|
||||
chain->Merge(output,0,"fast");
|
||||
cout<<"Finished merging"<<endl;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if(GrabFilesInRange()) {
|
||||
for(unsigned int i=0; i<filelist.size(); i++) {
|
||||
chain->Add(filelist[i]);
|
||||
}
|
||||
cout<<"Merging runs "<<MinRun<<" to "<<MaxRun<<" into a single file..."<<endl;
|
||||
chain->Merge(output,0,"fast");
|
||||
cout<<"Finished merging"<<endl;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(output->IsOpen()) output->Close();
|
||||
return 0;
|
||||
}
|
183
src/evb/SFPAnalyzer.cpp
Normal file
183
src/evb/SFPAnalyzer.cpp
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*SFPAnalyzer.cpp
|
||||
*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
|
||||
*/
|
||||
#include "EventBuilder.h"
|
||||
#include "SFPAnalyzer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*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;
|
||||
cout<<"w1: "<<w1<<" w2: "<<w2<<endl;
|
||||
}
|
||||
|
||||
/*2D histogram fill wrapper for use with THashTable (faster)*/
|
||||
void SFPAnalyzer::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 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/1.98; //position from time, based on total delay
|
||||
//pevent.x1 = 0.52*pevent.fp1_tdiff - 0.128; //position from time, based on delay chips
|
||||
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/2.10; //position from time, based on total delay
|
||||
//pevent.x2 = 0.48*pevent.fp2_tdiff - 2.365; //position from time, based on delay chips
|
||||
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;
|
||||
}
|
297
src/evb/SFPPlotter.cpp
Normal file
297
src/evb/SFPPlotter.cpp
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*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
|
||||
*/
|
||||
|
||||
#include "EventBuilder.h"
|
||||
#include "SFPPlotter.h"
|
||||
#include <TSystem.h>
|
||||
|
||||
/*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");
|
||||
cutFlag = false;
|
||||
m_pb = NULL;
|
||||
}
|
||||
|
||||
SFPPlotter::~SFPPlotter() {
|
||||
delete event_address;
|
||||
}
|
||||
|
||||
/*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);
|
||||
cutFlag = true;
|
||||
}
|
||||
|
||||
/*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.IsValid()) return;
|
||||
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<TString> 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: "<<blentries<<endl;
|
||||
|
||||
long count=0, flush=blentries*0.01, nflushes=0;
|
||||
if(flush == 0) flush = 1;
|
||||
|
||||
for(long double i=0; i<chain->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: "<<nflushes*10<<"%"<<std::flush;
|
||||
}
|
||||
}
|
||||
chain->GetEntry(i);
|
||||
MakeUncutHistograms(*event_address);
|
||||
if(cutFlag) MakeCutHistograms(*event_address);
|
||||
}
|
||||
cout<<endl;
|
||||
outfile->cd();
|
||||
rootObj->Write();
|
||||
if(cutFlag && cutter.IsValid()) {
|
||||
auto clist = cutter.GetCuts();
|
||||
for(unsigned int i=0; i<clist.size(); i++) {
|
||||
clist[i]->Write();
|
||||
}
|
||||
}
|
||||
delete rootObj;
|
||||
outfile->Close();
|
||||
delete outfile;
|
||||
}
|
||||
|
||||
/*Link all files*/
|
||||
void SFPPlotter::Chain(vector<TString> files) {
|
||||
for(unsigned int i=0; i<files.size(); i++) {
|
||||
chain->Add(files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SFPPlotter::SetProgressBar(long total) {
|
||||
m_pb->SetMax(total);
|
||||
m_pb->SetMin(0);
|
||||
m_pb->SetPosition(0);
|
||||
gSystem->ProcessEvents();
|
||||
}
|
69
src/evb/ShiftMap.cpp
Normal file
69
src/evb/ShiftMap.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
ShiftMap.h
|
||||
New class to act a go-between for timestamp shifts to channels. Takes in a
|
||||
formated file containing data for shifts and then stores them in an unordered_map.
|
||||
Key is a global compass channel (board#*16 + channel). Shifts in ps.
|
||||
|
||||
Note: Timestamps are now shifted in binary conversion. This means that shifts *MUST*
|
||||
be stored as Long64_t types. No decimals!
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#include "EventBuilder.h"
|
||||
#include "ShiftMap.h"
|
||||
|
||||
ShiftMap::ShiftMap() :
|
||||
m_filename(""), is_set(false)
|
||||
{
|
||||
}
|
||||
|
||||
ShiftMap::ShiftMap(const std::string& filename) :
|
||||
m_filename(filename), is_set(false)
|
||||
{
|
||||
ParseFile();
|
||||
}
|
||||
|
||||
ShiftMap::~ShiftMap() {}
|
||||
|
||||
void ShiftMap::SetFile(const std::string& filename) {
|
||||
m_filename = filename;
|
||||
ParseFile();
|
||||
}
|
||||
|
||||
Long64_t ShiftMap::GetShift(int gchan) {
|
||||
if(!is_set) return 0.0;
|
||||
|
||||
auto iter = m_map.find(gchan);
|
||||
if(iter == m_map.end()) {
|
||||
return 0.0;
|
||||
} else return iter->second;
|
||||
}
|
||||
|
||||
void ShiftMap::ParseFile() {
|
||||
std::ifstream input(m_filename);
|
||||
if(!input.is_open()) return;
|
||||
|
||||
int board, channel, gchan;
|
||||
Long64_t shift;
|
||||
std::string junk, temp;
|
||||
|
||||
std::getline(input, junk);
|
||||
std::getline(input, junk);
|
||||
|
||||
while(input>>board) {
|
||||
input>>temp;
|
||||
input>>shift;
|
||||
if(temp == "all") { //keyword to set all channels in this board to same shift
|
||||
for(int i=0; i<16; i++) {
|
||||
gchan = board*16 + i;
|
||||
m_map[gchan] = shift;
|
||||
}
|
||||
} else {
|
||||
channel = stoi(temp);
|
||||
gchan = channel + board*16;
|
||||
m_map[gchan] = shift;
|
||||
}
|
||||
}
|
||||
|
||||
is_set = true;
|
||||
}
|
166
src/evb/SlowSort.cpp
Normal file
166
src/evb/SlowSort.cpp
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*SlowSort.cpp
|
||||
*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
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
|
||||
/*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);
|
||||
}
|
||||
|
||||
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."<<endl;
|
||||
}
|
||||
startTime = hit.Timestamp;
|
||||
hitList.push_back(hit);
|
||||
}
|
||||
|
||||
/*Function called when an event outside the coincidence window is detected
|
||||
*Process all of the hits in the list, and write them to the sorted tree
|
||||
*/
|
||||
void SlowSort::ProcessEvent() {
|
||||
Reset();
|
||||
DetectorHit dhit;
|
||||
int gchan;
|
||||
int size = hitList.size();
|
||||
for(DPPChannel& curHit: 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()) {
|
||||
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<<std::endl;
|
||||
std::cout<<"------Data Assignment Error!-------"<<std::endl;
|
||||
std::cout<<"Channel is present in channel map, but does not have a variable assigned in variable map!"<<std::endl;
|
||||
std::cout<<"global channel number: "<<gchan<<" channel detector type: "<<channel_info->second.detectorType<<std::endl;
|
||||
std::cout<<"Skipping this hit..."<<std::endl;
|
||||
std::cout<<"-----------------------------------"<<std::endl;
|
||||
|
||||
}
|
||||
}
|
||||
//Organize the SABRE data in descending energy order
|
||||
for(int s=0; s<5; s++) {
|
||||
sort(event.sabreArray[s].rings.begin(), event.sabreArray[s].rings.end(), SabreSort);
|
||||
sort(event.sabreArray[s].wedges.begin(), event.sabreArray[s].wedges.end(), SabreSort);
|
||||
}
|
||||
}
|
32
src/evb/Stopwatch.cpp
Normal file
32
src/evb/Stopwatch.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Stopwatch.cpp
|
||||
Simple class designed to provide timing info on parts of the process.
|
||||
Only for use in development.
|
||||
|
||||
Written by G.W. McCann Oct. 2020
|
||||
*/
|
||||
#include "EventBuilder.h"
|
||||
#include "Stopwatch.h"
|
||||
|
||||
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<std::chrono::duration<double>>(stop_time-start_time).count();
|
||||
}
|
||||
|
||||
double Stopwatch::GetElapsedMilliseconds() {
|
||||
return std::chrono::duration_cast<std::chrono::duration<double>>(stop_time-start_time).count()*1000.0;
|
||||
}
|
468
src/gui/EVBMainFrame.cpp
Normal file
468
src/gui/EVBMainFrame.cpp
Normal file
|
@ -0,0 +1,468 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "EVBMainFrame.h"
|
||||
#include "FileViewFrame.h"
|
||||
#include <TGLabel.h>
|
||||
#include <TGTextBuffer.h>
|
||||
#include <TApplication.h>
|
||||
#include <TSystem.h>
|
||||
|
||||
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);
|
||||
|
||||
}
|
166
src/gui/FileViewFrame.cpp
Normal file
166
src/gui/FileViewFrame.cpp
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
|
||||
FileViewFrame.cpp
|
||||
Wrapper class on a TGTransientFrame (temporary frame assoc. with a main frame)
|
||||
Designed to graphically display directories and files for selection. Takes in a type
|
||||
to specify the signal pathing.
|
||||
|
||||
Written by G.W. McCann Sep. 2020
|
||||
|
||||
*/
|
||||
|
||||
#include "EventBuilder.h"
|
||||
#include "FileViewFrame.h"
|
||||
#include <TGTextBuffer.h>
|
||||
#include <TGLabel.h>
|
||||
#include <TTimer.h>
|
||||
|
||||
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
|
||||
|
||||
dirFlag = false;
|
||||
bool rootFlag = false;
|
||||
suffix = ".txt";
|
||||
if(type == EVBMainFrame::WORKDIR) {
|
||||
dirFlag = true;
|
||||
suffix = ".NOTHING";
|
||||
} 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 *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);
|
||||
|
||||
/*Create object for displaying*/
|
||||
fViewer = new TGListView(fMain, w, h*0.5);
|
||||
Pixel_t white;
|
||||
gClient->GetColorByName("white", white);
|
||||
fContents = new TGFileContainer(fViewer, kSunkenFrame, white);
|
||||
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);
|
||||
TGLabel *nameLabel;
|
||||
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());
|
||||
NameFrame->AddFrame(nameLabel, lhints);
|
||||
NameFrame->AddFrame(fNameField, thints);
|
||||
|
||||
/*Buttons for ok and cancel*/
|
||||
TGHorizontalFrame *ButtonFrame = new TGHorizontalFrame(fMain, w, h*0.25);
|
||||
fOkButton = new TGTextButton(ButtonFrame, "Ok");
|
||||
fOkButton->Connect("Clicked()","FileViewFrame",this,"DoOk()");
|
||||
fCancelButton = new TGTextButton(ButtonFrame, "Cancel");
|
||||
fCancelButton->Connect("Clicked()","FileViewFrame",this,"DoCancel()");
|
||||
ButtonFrame->AddFrame(fOkButton, fhints);
|
||||
ButtonFrame->AddFrame(fCancelButton, fhints);
|
||||
|
||||
fMain->AddFrame(fViewer, fchints);
|
||||
fMain->AddFrame(NameFrame, thints);
|
||||
fMain->AddFrame(ButtonFrame, fbhints);
|
||||
|
||||
/*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*)");
|
||||
|
||||
fMain->SetWindowName("Select File");
|
||||
fMain->MapSubwindows();
|
||||
fMain->Resize();
|
||||
fMain->CenterOnParent();
|
||||
fMain->MapWindow();
|
||||
|
||||
fContents->SetDefaultHeaders();
|
||||
if(dirFlag) fContents->SetFilter("*.NOTHING"); //relevant extension
|
||||
else if(rootFlag) fContents->SetFilter("*.root");
|
||||
else fContents->SetFilter("*.txt");
|
||||
fContents->DisplayDirectory();
|
||||
fContents->AddFile(".."); //go back a dir
|
||||
fContents->Resize();
|
||||
fContents->StopRefreshTimer();
|
||||
|
||||
fMain->Resize();
|
||||
}
|
||||
|
||||
FileViewFrame::~FileViewFrame() {
|
||||
fMain->Cleanup(); //delete children
|
||||
fMain->DeleteWindow();
|
||||
}
|
||||
|
||||
void FileViewFrame::CloseWindow() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
void FileViewFrame::DoOk() {
|
||||
/*Prevent user from doing something dumb*/
|
||||
fOkButton->SetState(kButtonDisabled);
|
||||
fCancelButton->SetState(kButtonDisabled);
|
||||
|
||||
TString filename = fNameField->GetText();
|
||||
TString fullpath = TString(fContents->GetDirectory()) + "/" + filename;
|
||||
if(fullpath == "") { //check validity
|
||||
std::cerr<<"Need to give a name!"<<std::endl;
|
||||
fOkButton->SetState(kButtonUp);
|
||||
fCancelButton->SetState(kButtonUp);
|
||||
return;
|
||||
}
|
||||
|
||||
SendText(fullpath.Data()); //signal sent
|
||||
//Destroy this frame after a brief pause (to make sure memory isnt freed too quickly)
|
||||
TTimer::SingleShot(150,"FileViewFrame",this,"CloseWindow()");
|
||||
}
|
||||
|
||||
void FileViewFrame::DoCancel() {
|
||||
/*Prevent user from doing something dumb*/
|
||||
fOkButton->SetState(kButtonDisabled);
|
||||
fCancelButton->SetState(kButtonDisabled);
|
||||
|
||||
//Destroy this frame after a brief pause (to make sure memory isnt freed too quickly)
|
||||
TTimer::SingleShot(150,"FileViewFrame",this,"CloseWindow()");
|
||||
}
|
||||
|
||||
//Handle directory selection
|
||||
void FileViewFrame::DisplayDir(const TString& name) {
|
||||
fContents->SetDefaultHeaders();
|
||||
fContents->ChangeDirectory(name);
|
||||
fContents->DisplayDirectory();
|
||||
fContents->AddFile("..");
|
||||
fMain->Resize();
|
||||
}
|
||||
|
||||
//Handle double click
|
||||
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
|
||||
TString name = entryname;
|
||||
fNameField->SetText(name.Data());
|
||||
} else {
|
||||
DisplayDir(entryname);
|
||||
if(dirFlag) {
|
||||
fNameField->SetText((dirname+"/"+entryname).Data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*SIGNAL*/
|
||||
void FileViewFrame::SendText(const char* text) {
|
||||
Emit("SendText(const char*)", text);
|
||||
}
|
12
src/gui_main.cpp
Normal file
12
src/gui_main.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "EventBuilder.h"
|
||||
#include <TApplication.h>
|
||||
#include "EVBMainFrame.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
TApplication app("app", &argc, argv);
|
||||
UInt_t h = 400;
|
||||
UInt_t w = 400;
|
||||
EVBMainFrame* myEVB = new EVBMainFrame(gClient->GetRoot(), w, h);
|
||||
app.Run();
|
||||
return 0;
|
||||
}
|
61
src/main.cpp
Normal file
61
src/main.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include "EventBuilder.h"
|
||||
#include "GWMEventBuilder.h"
|
||||
#include "Stopwatch.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if(argc != 3) {
|
||||
std::cerr<<"Incorrect number of command line arguments!"<<std::endl;
|
||||
std::cerr<<"Need to specify type of operation (buildSlow, buildFast, etc.) and input file."<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string filename = argv[2];
|
||||
std::string operation = argv[1];
|
||||
|
||||
|
||||
/* DEFAULT Operation Types:
|
||||
convert (convert binary archive to root data)
|
||||
convertSlow (convert binary arhcive to event slow data)
|
||||
convertFast (convert binary archive to event fast data)
|
||||
convertSlowA (convert binary archive to analyzed slow event data)
|
||||
convertFastA (convert binary archive to analyzed fast event data)
|
||||
merge (combine root files)
|
||||
plot (generate a default histogram file from analyzed data)
|
||||
*/
|
||||
|
||||
GWMEventBuilder theBuilder;
|
||||
if(!theBuilder.ReadConfigFile(filename)) {
|
||||
return 1;
|
||||
}
|
||||
Stopwatch timer;
|
||||
timer.Start();
|
||||
if(operation == "convert") {
|
||||
theBuilder.SetAnalysisType(GWMEventBuilder::CONVERT);
|
||||
theBuilder.Convert2RawRoot();
|
||||
} else if(operation == "merge") {
|
||||
theBuilder.SetAnalysisType(GWMEventBuilder::MERGE);
|
||||
theBuilder.MergeROOTFiles();
|
||||
} else if(operation == "plot") {
|
||||
theBuilder.SetAnalysisType(GWMEventBuilder::PLOT);
|
||||
theBuilder.PlotHistograms();
|
||||
} else if (operation == "convertSlow"){
|
||||
theBuilder.SetAnalysisType(GWMEventBuilder::CONVERT_S);
|
||||
theBuilder.Convert2SortedRoot();
|
||||
} else if (operation == "convertFast"){
|
||||
theBuilder.SetAnalysisType(GWMEventBuilder::CONVERT_F);
|
||||
theBuilder.Convert2FastSortedRoot();
|
||||
} else if (operation == "convertSlowA"){
|
||||
theBuilder.SetAnalysisType(GWMEventBuilder::CONVERT_SA);
|
||||
theBuilder.Convert2SlowAnalyzedRoot();
|
||||
} else if (operation == "convertFastA"){
|
||||
theBuilder.SetAnalysisType(GWMEventBuilder::CONVERT_FA);
|
||||
theBuilder.Convert2FastAnalyzedRoot();
|
||||
} else {
|
||||
std::cerr<<"Unidentified type of operation! Check your first argument."<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
timer.Stop();
|
||||
std::cout<<"Elapsed time (ms): "<<timer.GetElapsedMilliseconds()<<std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user