1
0
Fork 0
mirror of https://github.com/gwm17/Mask.git synced 2024-11-22 18:28:51 -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 .DS_Store
Makefile Makefile
*.make *.make
__pycache__
###Keep this file### ###Keep this file###

2
bin/.gitignore vendored
View File

@ -1,3 +1,5 @@
###keep only the directory, not the contents### ###keep only the directory, not the contents###
* *
!.gitignore !.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 158 108 266 Hs 266 130045.252
159 110 269 Ds 269 144751.021 159 110 269 Ds 269 144751.021
160 110 270 Ds 270 144583.090 160 110 270 Ds 270 144583.090

View File

@ -43,14 +43,15 @@ private:
const int n_qqq = 4; const int n_qqq = 4;
const double sx3_length = 0.075; const double sx3_length = 0.075;
const double sx3_width = 0.04; const double sx3_width = 0.04;
const double barrel_gap = 0.013 + 0.049; //0.049 is base gap due to frames const double barrel_gap = 0.0254;
const double ring1_z = sx3_length/2.0 + barrel_gap/2.0; const double sx3_frame = 0.049; //0.049 is base gap due to frames
//const double ring2_z = -0.124 + sx3_length/2.0 + 0.0245 - barrel_gap/2.0; const double ring1_z = sx3_length/2.0 + sx3_frame + barrel_gap/2.0;
const double qqq_nom_z = 0.025 + sx3_length + 0.0245 + 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_rinner = 0.0501;
const double qqq_router = 0.0990; const double qqq_router = 0.0990;
const double qqq_deltaphi = 1.52119; 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 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_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}; 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---------- ----------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 SaveTree: yes
SavePlots: yes SavePlots: yes
----------Reaction Information---------- ----------Reaction Information----------
ReactionType: 1 ReactionType: 2
Z A (order is target, projectile, ejectile, break1, break3(if pure decay is target, ejectile)) Z A (order is target, projectile, ejectile, break1, break3(if pure decay is target, ejectile))
6 12 1 2
4 7
4 7 4 7
1 1
2 4
----------Target Information---------- ----------Target Information----------
Name: test_targ Name: test_targ
Layers: 1 Layers: 1

View File

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

View File

@ -9,7 +9,7 @@ AnasenEfficiency::AnasenEfficiency() :
for(int i=0; i<n_sx3_per_ring; i++) { 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.emplace_back(4, sx3_length, sx3_width, ring_phi[i], ring1_z, ring_rho[i]);
m_Ring1[i].TurnOnRandomizedCoordinates(); 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(); m_Ring2[i].TurnOnRandomizedCoordinates();
} }
for(int i=0; i<n_qqq; i++) { 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<<"ANASEN Geometry File -- Coordinates for Detectors"<<std::endl;
output<<"Edges: x y z"<<std::endl;
for(unsigned int i=0; i<x.size(); i++) { for(unsigned int i=0; i<x.size(); i++) {
output<<x[i]<<" "<<y[i]<<" "<<z[i]<<std::endl; 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++) { for(unsigned int i=0; i<cx.size(); i++) {
output<<cx[i]<<" "<<cy[i]<<" "<<cz[i]<<std::endl; 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()