1
0
Fork 0
mirror of https://github.com/gwm17/Mask.git synced 2024-11-22 10:18:50 -05:00

Added Python plotting tools using matplotlib and pickle. Updated ANASEN geometry to better reflect the actual detector setup.

This commit is contained in:
Gordon McCann 2021-10-08 10:56:57 -04:00
parent 51b64e0c97
commit 6c21c214b4
15 changed files with 455 additions and 16 deletions

1
.gitignore vendored
View File

@ -12,6 +12,7 @@
.DS_Store
Makefile
*.make
__pycache__
###Keep this file###

2
bin/.gitignore vendored
View File

@ -1,3 +1,5 @@
###keep only the directory, not the contents###
*
!.gitignore
!PyPlotter
!PyPlotViewer

5
bin/PyPlotViewer Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
FileName=$1;
./src/Plotters/Python/ViewPyPlots.py ${FileName}

6
bin/PyPlotter Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
InputFile=$1;
OutputFile=$2;
./src/Plotters/Python/PyPlotter.py ${InputFile} ${OutputFile}

View File

@ -2498,4 +2498,3 @@
158 108 266 Hs 266 130045.252
159 110 269 Ds 269 144751.021
160 110 270 Ds 270 144583.090

View File

@ -43,14 +43,15 @@ private:
const int n_qqq = 4;
const double sx3_length = 0.075;
const double sx3_width = 0.04;
const double barrel_gap = 0.013 + 0.049; //0.049 is base gap due to frames
const double ring1_z = sx3_length/2.0 + barrel_gap/2.0;
//const double ring2_z = -0.124 + sx3_length/2.0 + 0.0245 - barrel_gap/2.0;
const double qqq_nom_z = 0.025 + sx3_length + 0.0245 + barrel_gap/2.0;
const double barrel_gap = 0.0254;
const double sx3_frame = 0.049; //0.049 is base gap due to frames
const double ring1_z = sx3_length/2.0 + sx3_frame + barrel_gap/2.0;
const double ring2_z = (-1.0)*(barrel_gap/2.0 + sx3_length/2.0);
const double qqq_nom_z = 0.0125 + sx3_length + sx3_frame + barrel_gap/2.0;
const double qqq_rinner = 0.0501;
const double qqq_router = 0.0990;
const double qqq_deltaphi = 1.52119;
const double qqq_z[4] = {qqq_nom_z, qqq_nom_z - 0.00828, qqq_nom_z, qqq_nom_z};
const double qqq_z[4] = {qqq_nom_z, qqq_nom_z, qqq_nom_z, qqq_nom_z};
const double qqq_phi[4] = {5.49779, 0.785398, 2.35619, 3.92699};
const double ring_rho[12] = {0.0890601, 0.0889871, 0.0890354, 0.0890247, 0.0890354, 0.0890354, 0.0890247, 0.0890354, 0.0890354, 0.0890247, 0.0890354, 0.0890354};
const double ring_phi[12] = {0.785795, 0.262014, 6.02132, 5.49779, 4.97426, 4.45052, 3.92699, 3.40346, 2.87972, 2.35619, 1.83266, 1.30893};

View File

@ -1,13 +1,14 @@
----------Data Information----------
OutputFile: /data1/gwm17/mask_tests/7Be12C_870keV_beam_50CD2.mask
OutputFile: /media/gordon/ANASENData/MaskData/Kinematics/7Bedp_870keV_beam_50CD2.mask
SaveTree: yes
SavePlots: yes
----------Reaction Information----------
ReactionType: 1
ReactionType: 2
Z A (order is target, projectile, ejectile, break1, break3(if pure decay is target, ejectile))
6 12
4 7
1 2
4 7
1 1
2 4
----------Target Information----------
Name: test_targ
Layers: 1

View File

@ -44,8 +44,8 @@ project "RootPlot"
}
--User specified path to ROOT CERN libraries--
ROOTIncludepath = "/usr/include/root"
ROOTLibpath = "/usr/lib64/root"
ROOTIncludepath = "/home/gordon/cern/root-6.22.02/root-install/include"
ROOTLibpath = "/home/gordon/cern/root-6.22.02/root-install/lib"
includedirs {
"include"

View File

@ -9,7 +9,7 @@ AnasenEfficiency::AnasenEfficiency() :
for(int i=0; i<n_sx3_per_ring; i++) {
m_Ring1.emplace_back(4, sx3_length, sx3_width, ring_phi[i], ring1_z, ring_rho[i]);
m_Ring1[i].TurnOnRandomizedCoordinates();
m_Ring2.emplace_back(4, sx3_length, sx3_width, ring_phi[i], -1.0*ring1_z, ring_rho[i]);
m_Ring2.emplace_back(4, sx3_length, sx3_width, ring_phi[i], ring2_z, ring_rho[i]);
m_Ring2[i].TurnOnRandomizedCoordinates();
}
for(int i=0; i<n_qqq; i++) {
@ -113,11 +113,9 @@ void AnasenEfficiency::DrawDetectorSystem(const std::string& filename) {
}
output<<"ANASEN Geometry File -- Coordinates for Detectors"<<std::endl;
output<<"Edges: x y z"<<std::endl;
for(unsigned int i=0; i<x.size(); i++) {
output<<x[i]<<" "<<y[i]<<" "<<z[i]<<std::endl;
}
output<<"Centers: x y z"<<std::endl;
for(unsigned int i=0; i<cx.size(); i++) {
output<<cx[i]<<" "<<cy[i]<<" "<<cz[i]<<std::endl;
}

3
src/Plotters/Python/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
__pycache__
!.gitignore

80
src/Plotters/Python/MaskFile.py Executable file
View File

@ -0,0 +1,80 @@
#!/usr/bin/env python3
import numpy as np
import struct
class MaskFileData :
def __init__(self, n):
self.Z = np.zeros(n, dtype=int)
self.A = np.zeros(n, dtype=int)
self.dFlag = np.zeros(n, dtype=bool)
self.E = np.zeros(n)
self.KE = np.zeros(n)
self.p = np.zeros(n)
self.theta = np.zeros(n)
self.phi = np.zeros(n)
class MaskFile:
int_size = 4
double_size = 8
bool_size = 1
def __init__(self, filename=""):
self.eofFlag = False
self.openFlag = False
if filename != "" :
self.Open(filename)
def Open(self, filename):
self.filename = filename
self.file = open(self.filename, mode="rb")
if self.file.closed :
self.openFlag = False
else:
self.openFlag = True
def ReadHeader(self):
data = self.file.read(2*self.int_size)
(self.nsamples, self.rxntype) = struct.unpack("ii", data)
self.datasize = (5*self.double_size+2*self.int_size+self.bool_size)
self.datastr = "=ii?ddddd"
if self.rxntype == 0:
self.N_nuclei = 3
elif self.rxntype == 1:
self.N_nuclei = 4
elif self.rxntype == 2:
self.N_nuclei = 6
elif self.rxntype == 3:
self.N_nuclei = 8
def ReadData(self):
data = MaskFileData(self.N_nuclei)
for i in range(self.N_nuclei):
buffer = self.file.read(self.datasize)
(data.Z[i], data.A[i], data.dFlag[i], data.E[i], data.KE[i], data.p[i], data.theta[i], data.phi[i]) = struct.unpack(self.datastr, buffer)
if buffer == "":
self.eofFlag = True
return data
def Close(self):
self.file.close()
def main() :
file = MaskFile(filename="/data1/gwm17/mask_tests/7Bedp_870keV_beam_50CD2.mask")
file.ReadHeader()
print("samples: ", file.nsamples, "rxntype:", file.rxntype, "datasize:", file.datasize)
count=0
for i in range(file.nsamples):
file.ReadData()
count += 1
print("count:",count)
print("eofFlag:",file.eofFlag)
file.Close()
if __name__ == '__main__':
main()

70
src/Plotters/Python/NucData.py Executable file
View File

@ -0,0 +1,70 @@
#!/usr/bin/env python3
import numpy as np
import requests
import lxml.html as xhtml
class MassTable:
def __init__(self):
file = open("./etc/mass.txt","r")
self.mtable = {}
u2mev = 931.4940954
me = 0.000548579909 #amu
self.etable = {}
line = file.readline()
line = file.readline()
for line in file:
entries = line.split()
n = entries[0]
z = entries[1]
a = entries[2]
element = entries[3]
massBig = float(entries[4])
massSmall = float(entries[5])
key = '('+z+','+a+')'
value = ((massBig+massSmall*1e-6) - float(z)*me)*u2mev
self.mtable[key] = value
self.etable[key] = element
file.close()
def GetMass(self, z, a):
key = '('+str(z)+','+str(a)+')'
if key in self.mtable:
return self.mtable[key]
else:
return 0
def GetSymbol(self, z, a):
key = '('+str(z)+','+str(a)+')'
if key in self.etable:
return str(a)+self.etable[key]
else:
return 'none'
Masses = MassTable()
def GetExcitations(symbol):
levels = np.array(np.empty(0))
text = ''
site = requests.get("https://www.nndc.bnl.gov/nudat2/getdatasetClassic.jsp?nucleus="+symbol+"&unc=nds")
contents = xhtml.fromstring(site.content)
tables = contents.xpath("//table")
rows = tables[2].xpath("./tr")
for row in rows[1:-2]:
entries = row.xpath("./td")
if len(entries) != 0:
entry = entries[0]
data = entry.xpath("./a")
if len(data) == 0:
text = entry.text
else:
text = data[0].text
text = text.replace('?', '')
text = text.replace('\xa0\xa0','')
levels = np.append(levels, float(text)/1000.0)
return levels

106
src/Plotters/Python/Nucleus.py Executable file
View File

@ -0,0 +1,106 @@
#!/usr/bin/env python3
import numpy as np
from NucData import Masses
class Nucleus:
deg2rad = np.pi/180.0
def __init__(self, Z=0, A=0):
self.Z = Z
self.A = A
if Z != 0 and A != 0:
self.gsMass = Masses.GetMass(self.Z, self.A)
self.vec4 = np.zeros(4)
self.symbol = Masses.GetSymbol(self.Z, self.A)
self.vec4[3] = self.gsMass
def SetIsotope(self, Z, A):
self.gsMass = Masses.GetMass(Z, A)
self.symbol = Masses.GetSymbol(Z, A)
self.Z = Z
self.A = A
self.vec4 = np.zeros(4)
self.vec4[3] = self.gsMass
def SetVectorCart(self, px, py, pz, E):
self.vec4[0] = px
self.vec4[1] = py
self.vec4[2] = pz
self.vec4[3] = E
def SetVectorSpher(self, theta, phi, p, E):
self.vec4[0] = p*np.sin(theta)*np.cos(phi)
self.vec4[1] = p*np.sin(theta)*np.sin(phi)
self.vec4[2] = p*np.cos(theta)
self.vec4[3] = E
def __add__(self, other):
vec4 = self.vec4 + other.vec4
newNuc = Nucleus(self.Z + other.Z, self.A + other.A)
newNuc.SetVectorCart(vec4[0], vec4[1], vec4[2], vec4[3])
return newNuc
def __sub__(self, other):
vec4 = self.vec4 - other.vec4
newNuc = Nucleus(self.Z - other.Z, self.A - other.A)
newNuc.SetVectorCart(vec4[0], vec4[1], vec4[2], vec4[3])
return newNuc
def __str__(self):
return "Nucleus({0},{1}) with 4-vector({2})".format(self.Z, self.A, self.vec4)
def GetP(self):
return np.sqrt(self.vec4[0]**2.0 + self.vec4[1]**2.0 + self.vec4[2]**2.0)
def GetInvMass(self):
return np.sqrt(self.vec4[3]**2.0 - self.GetP()**2.0)
def GetKE(self):
return self.vec4[3] - self.GetInvMass()
def GetTheta(self):
return np.arccos(self.vec4[2]/self.GetP())
def GetPhi(self):
result = np.arctan2(self.vec4[1], self.vec4[0])
if result < 0.0:
result += 2.0*np.pi
return result
def GetExcitation(self):
return self.GetInvMass() - self.gsMass
def GetBoostToCMFrame(self):
boost_vec = np.zeros(3)
boost_vec[0] = self.vec4[0]/self.vec4[3]
boost_vec[1] = self.vec4[1]/self.vec4[3]
boost_vec[2] = self.vec4[2]/self.vec4[3]
return boost_vec
def ApplyBoost(self, boost_vec):
beta2 = np.linalg.norm(boost_vec)**2.0
gamma = 1.0/np.sqrt(1.0 - beta2)
bdotp = boost_vec[0]*self.vec4[0] + boost_vec[1]*self.vec4[1] + boost_vec[2]*self.vec4[2]
gfactor = (gamma-1.0)/beta2 if beta2 > 0.0 else 0.0
px = self.vec4[0]+gfactor*bdotp*boost_vec[0]+gamma*boost_vec[0]*self.vec4[3]
py = self.vec4[1]+gfactor*bdotp*boost_vec[1]+gamma*boost_vec[1]*self.vec4[3]
pz = self.vec4[2]+gfactor*bdotp*boost_vec[2]+gamma*boost_vec[2]*self.vec4[3]
E = gamma*(self.vec4[3] + bdotp)
self.SetVectorCart(px, py, pz, E);
def main():
nuc = Nucleus(1,1)
print("First",nuc)
nuc2 = Nucleus(2,4)
print("Second", nuc2)
result = nuc + nuc2
print("Addition", result)
result2 = nuc2 - nuc
print("Subtraction", result2)
if __name__ == '__main__':
main()

135
src/Plotters/Python/PyPlotter.py Executable file
View File

@ -0,0 +1,135 @@
#!/usr/bin/env python3
import numpy as np
import matplotlib.pyplot as plt
from Nucleus import Nucleus
from MaskFile import MaskFile, MaskFileData
from NucData import Masses
import pickle
import sys
def PlotData(inputname, outputname):
rad2deg = 180.0/np.pi
datafile = MaskFile(inputname)
datafile.ReadHeader()
print("MaskFile opened -- rxntype:", datafile.rxntype, "number of samples:", datafile.nsamples)
data = MaskFileData(datafile.N_nuclei)
ke = np.zeros((datafile.N_nuclei, datafile.nsamples))
ke_d = np.zeros((datafile.N_nuclei, datafile.nsamples))
theta = np.zeros((datafile.N_nuclei, datafile.nsamples))
theta_d = np.zeros((datafile.N_nuclei, datafile.nsamples))
phi = np.zeros((datafile.N_nuclei, datafile.nsamples))
phi_d = np.zeros((datafile.N_nuclei, datafile.nsamples))
detect_mask = np.ones((datafile.N_nuclei, datafile.nsamples), dtype=bool)
names = []
for i in range(datafile.N_nuclei):
names.append(" ")
nuc = Nucleus()
for i in range(datafile.nsamples):
data = datafile.ReadData()
if i == 0:
for j in range(datafile.N_nuclei):
names[j] = Masses.GetSymbol(data.Z[j], data.A[j])
for j in range(datafile.N_nuclei):
nuc.SetIsotope(data.Z[j], data.A[j])
nuc.SetVectorSpher(data.theta[j], data.phi[j], data.p[j], data.E[j])
ke[j][i] = nuc.GetKE()
theta[j][i] = data.theta[j]*rad2deg
phi[j][i] = data.phi[j]*rad2deg
if data.dFlag[j] == True:
ke_d[j][i] = data.KE[j]
theta_d[j][i] = data.theta[j]*rad2deg
phi_d[j][i] = data.phi[j]*rad2deg
else:
detect_mask[j][i] = False
datafile.Close()
#Remove empty values from detection arrays
final_theta_d = theta_d[detect_mask]
final_phi_d = phi_d[detect_mask]
final_ke_d = ke_d[detect_mask]
#figs = {}
#axes = {}
'''
for i in range(len(names)):
figs[i], axes[i] = plt.subplots(2,2)
'''
fig, axes = plt.subplots(len(names)-1,4)
fig.set_size_inches(12, 12)
for i in range(1, len(names)):
'''
axes[i][0][0].plot(theta[i], ke[i], marker=',', linestyle='None')
axes[i][0][0].set_title(names[i]+" KE vs. Theta")
axes[i][0][0].set_xlabel(r"$\theta$ (degrees)")
axes[i][0][0].set_ylabel("KE (MeV)")
axes[i][0][1].plot(phi[i], ke[i], marker=",", linestyle='None')
axes[i][0][1].set_title(names[i]+" KE vs. Phi")
axes[i][0][1].set_xlabel(r"$\phi$ (degrees)")
axes[i][0][1].set_ylabel("KE (MeV)")
axes[i][1][0].plot(theta_d[i], ke_d[i], marker=',', linestyle='None')
axes[i][1][0].set_title(names[i]+" KE vs. Theta -- Detected")
axes[i][1][0].set_xlabel(r"$\theta$ (degrees)")
axes[i][1][0].set_ylabel("KE (MeV)")
axes[i][1][1].plot(phi_d[i], ke_d[i], marker=",", linestyle='None')
axes[i][1][1].set_title(names[i]+" KE vs. Phi -- Detected")
axes[i][1][1].set_xlabel(r"$\phi$ (degrees)")
axes[i][1][1].set_ylabel("KE (MeV)")
'''
axes[i-1][0].plot(theta[i], ke[i], marker=',', linestyle='None')
axes[i-1][0].set_title(names[i]+" KE vs. Theta")
axes[i-1][0].set_xlabel(r"$\theta$ (degrees)")
axes[i-1][0].set_ylabel("KE (MeV)")
axes[i-1][1].plot(phi[i], ke[i], marker=",", linestyle='None')
axes[i-1][1].set_title(names[i]+" KE vs. Phi")
axes[i-1][1].set_xlabel(r"$\phi$ (degrees)")
axes[i-1][1].set_ylabel("KE (MeV)")
axes[i-1][2].plot(theta_d[i], ke_d[i], marker=',', linestyle='None')
axes[i-1][2].set_title(names[i]+" KE vs. Theta -- Detected")
axes[i-1][2].set_xlabel(r"$\theta$ (degrees)")
axes[i-1][2].set_ylabel("KE (MeV)")
axes[i-1][3].plot(phi_d[i], ke_d[i], marker=",", linestyle='None')
axes[i-1][3].set_title(names[i]+" KE vs. Phi -- Detected")
axes[i-1][3].set_xlabel(r"$\phi$ (degrees)")
axes[i-1][3].set_ylabel("KE (MeV)")
plt.tight_layout()
plt.show(block=True)
print("Writing figure to file:", outputname)
with open(outputname, "wb") as outfile:
pickle.dump(fig, outfile)
outfile.close()
print("Finished.")
def main():
if len(sys.argv) == 3:
PlotData(sys.argv[1], sys.argv[2])
else:
print("Unable to run PyPlotter, incorrect number of arguments! Need an input datafile name, and an output plot file name")
if __name__ == '__main__':
main()

View File

@ -0,0 +1,32 @@
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np
import pickle
import sys
def SetManager(figure):
dummy = plt.figure()
manager = dummy.canvas.manager
manager.canvas.figure = figure
figure.set_canvas(manager.canvas)
def ViewPyPlots(filename):
figure = pickle.load(open(filename, "rb"))
SetManager(figure)
figure.set_size_inches(12, 12)
plt.tight_layout()
plt.show(block=True)
def main():
if len(sys.argv) == 2:
ViewPyPlots(sys.argv[1])
else:
print("Unable to run ViewPyPlots, incorrect number of commandline arguments -- requires an input pickle file")
if __name__ == '__main__':
main()