mirror of
https://github.com/gwm17/spspy.git
synced 2024-11-22 10:18:49 -05:00
commit
7ef1657578
|
@ -89,7 +89,6 @@ class Reaction:
|
||||||
beamRxnEnergy = self.params.beamEnergy - self.targetMaterial.get_incoming_energyloss(self.params.projectile.Z, self.params.projectile.mass, self.params.beamEnergy, self.rxnLayer, 0.0)
|
beamRxnEnergy = self.params.beamEnergy - self.targetMaterial.get_incoming_energyloss(self.params.projectile.Z, self.params.projectile.mass, self.params.beamEnergy, self.rxnLayer, 0.0)
|
||||||
beamRxnP = sqrt(beamRxnEnergy * (beamRxnEnergy + 2.0 * self.params.projectile.mass))
|
beamRxnP = sqrt(beamRxnEnergy * (beamRxnEnergy + 2.0 * self.params.projectile.mass))
|
||||||
|
|
||||||
|
|
||||||
residRxnEnergy = beamRxnEnergy + self.params.projectile.mass + self.params.target.mass - ejectileRxnEnergy - self.params.ejectile.mass
|
residRxnEnergy = beamRxnEnergy + self.params.projectile.mass + self.params.target.mass - ejectileRxnEnergy - self.params.ejectile.mass
|
||||||
residRxnP2 = beamRxnP**2.0 + ejectileRxnP**2.0 - 2.0 * ejectileRxnP * beamRxnP * cos(self.params.spsAngle)
|
residRxnP2 = beamRxnP**2.0 + ejectileRxnP**2.0 - 2.0 * ejectileRxnP * beamRxnP * cos(self.params.spsAngle)
|
||||||
return sqrt(residRxnEnergy**2.0 - residRxnP2) - self.residual.mass
|
return sqrt(residRxnEnergy**2.0 - residRxnP2) - self.residual.mass
|
||||||
|
|
|
@ -13,7 +13,7 @@ class TargetLayer:
|
||||||
thickness: float = 0.0 #ug/cm^2
|
thickness: float = 0.0 #ug/cm^2
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return "".join([f"{global_nuclear_data.get_data(z, a,).prettyIsotopicSymbol}<sub>{s}<\sub>" for z, a, s in self.compound_list])
|
return "".join([f"{global_nuclear_data.get_data(z, a,).prettyIsotopicSymbol}<sub>{s}</sub>" for z, a, s in self.compound_list])
|
||||||
|
|
||||||
#integrate energy loss starting from the final energy and running backwards to initial energy
|
#integrate energy loss starting from the final energy and running backwards to initial energy
|
||||||
#catima does not natively provide this type of method
|
#catima does not natively provide this type of method
|
||||||
|
@ -43,10 +43,10 @@ def get_reverse_energyloss(projectile: catima.Projectile, material: catima.Mater
|
||||||
e_step = catima.dedx(projectile, material)*x_step
|
e_step = catima.dedx(projectile, material)*x_step
|
||||||
e_initial += e_step*A_recip
|
e_initial += e_step*A_recip
|
||||||
projectile.T(e_initial)
|
projectile.T(e_initial)
|
||||||
return (e_initial - e_out)*projectile.A()
|
return (e_initial - e_out)
|
||||||
|
|
||||||
elif depth == ADAPTIVE_DEPTH_MAX:
|
elif depth == ADAPTIVE_DEPTH_MAX:
|
||||||
return e_out*projectile.A()
|
return e_out
|
||||||
else:
|
else:
|
||||||
e_step = catima.dedx(projectile, material)*x_step
|
e_step = catima.dedx(projectile, material)*x_step
|
||||||
e_initial += e_step*A_recip
|
e_initial += e_step*A_recip
|
||||||
|
@ -80,10 +80,10 @@ def get_energyloss(projectile: catima.Projectile, material: catima.Material) ->
|
||||||
e_step = catima.dedx(projectile, material)*x_step*A_recip
|
e_step = catima.dedx(projectile, material)*x_step*A_recip
|
||||||
e_final -= e_step
|
e_final -= e_step
|
||||||
projectile.T(e_final)
|
projectile.T(e_final)
|
||||||
return (e_in - e_final)*projectile.A()
|
return (e_in - e_final)
|
||||||
|
|
||||||
elif depth == ADAPTIVE_DEPTH_MAX:
|
elif depth == ADAPTIVE_DEPTH_MAX:
|
||||||
return e_in*projectile.A()
|
return e_in
|
||||||
|
|
||||||
else:
|
else:
|
||||||
e_step = catima.dedx(projectile, material)*x_step*A_recip
|
e_step = catima.dedx(projectile, material)*x_step*A_recip
|
||||||
|
@ -94,6 +94,7 @@ def get_energyloss(projectile: catima.Projectile, material: catima.Material) ->
|
||||||
|
|
||||||
|
|
||||||
class SPSTarget:
|
class SPSTarget:
|
||||||
|
MEV2U: float = 1.0/931.493614838475
|
||||||
UG2G: float = 1.0e-6 #convert ug to g
|
UG2G: float = 1.0e-6 #convert ug to g
|
||||||
def __init__(self, layers: list[TargetLayer], name: str = "default"):
|
def __init__(self, layers: list[TargetLayer], name: str = "default"):
|
||||||
self.layer_details = layers
|
self.layer_details = layers
|
||||||
|
@ -114,31 +115,33 @@ class SPSTarget:
|
||||||
if angle == pi*0.5:
|
if angle == pi*0.5:
|
||||||
return e_initial
|
return e_initial
|
||||||
|
|
||||||
projectile = catima.Projectile(ap, zp)
|
ap_u = ap * self.MEV2U
|
||||||
e_current = e_initial/ap
|
projectile = catima.Projectile(ap_u, zp)
|
||||||
|
e_current = e_initial/ap_u
|
||||||
for (idx, layer) in enumerate(self.layer_details):
|
for (idx, layer) in enumerate(self.layer_details):
|
||||||
material = catima.Material([(global_nuclear_data.get_data(z, a).mass, z, float(s)) for (z, a, s) in layer.compound_list])
|
material = catima.Material([(global_nuclear_data.get_data(z, a).mass * self.MEV2U, z, float(s)) for (z, a, s) in layer.compound_list])
|
||||||
projectile.T(e_current) #catima wants MeV/u
|
projectile.T(e_current) #catima wants MeV/u
|
||||||
if idx == rxn_layer:
|
if idx == rxn_layer:
|
||||||
material.thickness(self.layer_details[idx].thickness * self.UG2G / (2.0 * abs(cos(angle))))
|
material.thickness(self.layer_details[idx].thickness * self.UG2G / (2.0 * abs(cos(angle))))
|
||||||
e_current -= get_energyloss(projectile, material)
|
e_current -= get_energyloss(projectile, material)
|
||||||
return e_initial - e_current*ap
|
return e_initial - e_current*ap_u
|
||||||
else:
|
else:
|
||||||
material.thickness(self.layer_details[idx].thickness * self.UG2G / abs(cos(angle)))
|
material.thickness(self.layer_details[idx].thickness * self.UG2G / abs(cos(angle)))
|
||||||
e_current -= get_energyloss(projectile, material)
|
e_current -= get_energyloss(projectile, material)
|
||||||
|
|
||||||
return e_initial - e_current*ap
|
return e_initial - e_current*ap_u
|
||||||
|
|
||||||
#Calculate energy loss for a particle leaving the target, from rxn layer (halfway through rxn layer) to end
|
#Calculate energy loss for a particle leaving the target, from rxn layer (halfway through rxn layer) to end
|
||||||
def get_outgoing_energyloss(self, zp: int, ap: float, e_initial: float, rxn_layer: int, angle: float) -> float:
|
def get_outgoing_energyloss(self, zp: int, ap: float, e_initial: float, rxn_layer: int, angle: float) -> float:
|
||||||
if angle == pi*0.5:
|
if angle == pi*0.5:
|
||||||
return e_initial
|
return e_initial
|
||||||
|
|
||||||
projectile = catima.Projectile(ap, zp)
|
ap_u = ap * self.MEV2U
|
||||||
e_current = e_initial/ap
|
projectile = catima.Projectile(ap_u, zp)
|
||||||
|
e_current = e_initial/ap_u
|
||||||
|
|
||||||
for (idx, layer) in enumerate(self.layer_details[rxn_layer:], start=rxn_layer):
|
for (idx, layer) in enumerate(self.layer_details[rxn_layer:], start=rxn_layer):
|
||||||
material = catima.Material([(global_nuclear_data.get_data(z, a).mass, z, float(s)) for (z, a, s) in layer.compound_list])
|
material = catima.Material([(global_nuclear_data.get_data(z, a).mass * self.MEV2U, z, float(s)) for (z, a, s) in layer.compound_list])
|
||||||
projectile.T(e_current) #catima wants MeV/u
|
projectile.T(e_current) #catima wants MeV/u
|
||||||
if idx == rxn_layer:
|
if idx == rxn_layer:
|
||||||
material.thickness(self.layer_details[idx].thickness * self.UG2G / (2.0 * abs(cos(angle))))
|
material.thickness(self.layer_details[idx].thickness * self.UG2G / (2.0 * abs(cos(angle))))
|
||||||
|
@ -146,19 +149,20 @@ class SPSTarget:
|
||||||
material.thickness(self.layer_details[idx].thickness * self.UG2G / abs(cos(angle)))
|
material.thickness(self.layer_details[idx].thickness * self.UG2G / abs(cos(angle)))
|
||||||
e_current -= get_energyloss(projectile, material)
|
e_current -= get_energyloss(projectile, material)
|
||||||
|
|
||||||
return e_initial - e_current*ap
|
return e_initial - e_current*ap_u
|
||||||
|
|
||||||
#Calculate reverse energy loss (energy gain) for a particle that left the target after a reaction (end -> rxn_layer)
|
#Calculate reverse energy loss (energy gain) for a particle that left the target after a reaction (end -> rxn_layer)
|
||||||
def get_outgoing_reverse_energyloss(self, zp: int, ap: float, e_final: float, rxn_layer: int, angle: float) -> float:
|
def get_outgoing_reverse_energyloss(self, zp: int, ap: float, e_final: float, rxn_layer: int, angle: float) -> float:
|
||||||
if angle == pi*0.5:
|
if angle == pi*0.5:
|
||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
projectile = catima.Projectile(ap, zp)
|
ap_u = ap * self.MEV2U
|
||||||
e_current = e_final/ap
|
projectile = catima.Projectile(ap_u, zp)
|
||||||
|
e_current = e_final/ap_u
|
||||||
sublist = self.layer_details[rxn_layer:] #only care about rxn_layer -> exit
|
sublist = self.layer_details[rxn_layer:] #only care about rxn_layer -> exit
|
||||||
reveresedRxnLayer = len(sublist) -1 #when reversed rxn_layer is the last layer
|
reveresedRxnLayer = len(sublist) -1 #when reversed rxn_layer is the last layer
|
||||||
for (idx, layer) in reversed(list(enumerate(sublist))):
|
for (idx, layer) in reversed(list(enumerate(sublist))):
|
||||||
material = catima.Material([(global_nuclear_data.get_data(z, a).mass, z, float(s)) for (z, a, s) in layer.compound_list])
|
material = catima.Material([(global_nuclear_data.get_data(z, a).mass * self.MEV2U, z, float(s)) for (z, a, s) in layer.compound_list])
|
||||||
projectile.T(e_current) #catima wants MeV/u
|
projectile.T(e_current) #catima wants MeV/u
|
||||||
if idx == reveresedRxnLayer:
|
if idx == reveresedRxnLayer:
|
||||||
material.thickness(self.layer_details[idx].thickness * self.UG2G / (2.0 * abs(cos(angle))))
|
material.thickness(self.layer_details[idx].thickness * self.UG2G / (2.0 * abs(cos(angle))))
|
||||||
|
@ -166,5 +170,5 @@ class SPSTarget:
|
||||||
material.thickness(self.layer_details[idx].thickness * self.UG2G / abs(cos(angle)))
|
material.thickness(self.layer_details[idx].thickness * self.UG2G / abs(cos(angle)))
|
||||||
e_current += get_reverse_energyloss(projectile, material)
|
e_current += get_reverse_energyloss(projectile, material)
|
||||||
|
|
||||||
return e_current*ap - e_final
|
return e_current*ap_u - e_final
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import numpy as np
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
INVALID_PEAK_ID: int = -1
|
INVALID_PEAK_ID: int = -1
|
||||||
|
DEG2RAD: float = np.pi / 180.0
|
||||||
|
|
||||||
class PeakType(Enum):
|
class PeakType(Enum):
|
||||||
CALIBRATION = "Calibration"
|
CALIBRATION = "Calibration"
|
||||||
|
@ -58,6 +59,7 @@ class Spanc:
|
||||||
print("Cannot create reaction with non-existant target ", targetName)
|
print("Cannot create reaction with non-existant target ", targetName)
|
||||||
return
|
return
|
||||||
key = f"Rxn{len(self.reactions)}"
|
key = f"Rxn{len(self.reactions)}"
|
||||||
|
params.spsAngle *= DEG2RAD
|
||||||
rxn = Reaction(params, target=self.targets[targetName])
|
rxn = Reaction(params, target=self.targets[targetName])
|
||||||
self.reactions[key] = rxn
|
self.reactions[key] = rxn
|
||||||
|
|
||||||
|
@ -65,7 +67,7 @@ class Spanc:
|
||||||
if rxnName in self.reactions:
|
if rxnName in self.reactions:
|
||||||
rxn = self.reactions[rxnName]
|
rxn = self.reactions[rxnName]
|
||||||
rxn.params.beamEnergy = beamEnergy
|
rxn.params.beamEnergy = beamEnergy
|
||||||
rxn.params.spsAngle = spsAngle
|
rxn.params.spsAngle = spsAngle * DEG2RAD
|
||||||
rxn.params.magneticField = magneticField
|
rxn.params.magneticField = magneticField
|
||||||
|
|
||||||
def add_calibration(self, data: Peak) -> None:
|
def add_calibration(self, data: Peak) -> None:
|
||||||
|
@ -77,6 +79,12 @@ class Spanc:
|
||||||
data.peakID = len(self.calibrations)
|
data.peakID = len(self.calibrations)
|
||||||
self.calibrations[data.peakID] = data
|
self.calibrations[data.peakID] = data
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def remove_calibration(self, data: Peak) -> bool:
|
||||||
|
if data.peakID not in self.calibrations.keys():
|
||||||
|
return False
|
||||||
|
self.calibrations.pop(data.peakID)
|
||||||
|
return True
|
||||||
|
|
||||||
def add_output(self, data: Peak) -> None:
|
def add_output(self, data: Peak) -> None:
|
||||||
if data.peakID == INVALID_PEAK_ID:
|
if data.peakID == INVALID_PEAK_ID:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from .Spanc import Spanc, PeakType
|
from .Spanc import Spanc, PeakType, DEG2RAD
|
||||||
from .Fitter import convert_fit_points_to_arrays, convert_resid_points_to_arrays
|
from .Fitter import convert_fit_points_to_arrays, convert_resid_points_to_arrays
|
||||||
from .ui.MPLCanvas import MPLCanvas
|
from .ui.MPLCanvas import MPLCanvas
|
||||||
from .ui.ReactionDialog import ReactionDialog
|
from .ui.ReactionDialog import ReactionDialog
|
||||||
|
@ -116,6 +116,7 @@ class SpancGUI(QMainWindow):
|
||||||
self.tablelayout.addWidget(self.targetGroup)
|
self.tablelayout.addWidget(self.targetGroup)
|
||||||
self.targetTable.resizeColumnsToContents()
|
self.targetTable.resizeColumnsToContents()
|
||||||
self.targetTable.cellDoubleClicked.connect(self.handle_update_target)
|
self.targetTable.cellDoubleClicked.connect(self.handle_update_target)
|
||||||
|
self.targetTable.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
|
||||||
|
|
||||||
def create_reaction_table(self) -> None:
|
def create_reaction_table(self) -> None:
|
||||||
self.rxnGroup = QGroupBox("Reactions", self.tableTab)
|
self.rxnGroup = QGroupBox("Reactions", self.tableTab)
|
||||||
|
@ -128,30 +129,33 @@ class SpancGUI(QMainWindow):
|
||||||
self.tablelayout.addWidget(self.rxnGroup)
|
self.tablelayout.addWidget(self.rxnGroup)
|
||||||
self.reactionTable.resizeColumnsToContents()
|
self.reactionTable.resizeColumnsToContents()
|
||||||
self.reactionTable.cellDoubleClicked.connect(self.handle_update_reaction)
|
self.reactionTable.cellDoubleClicked.connect(self.handle_update_reaction)
|
||||||
|
self.reactionTable.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
|
||||||
|
|
||||||
def create_calibration_table(self) -> None:
|
def create_calibration_table(self) -> None:
|
||||||
self.calGroup = QGroupBox("Calibration Peaks", self.tableTab)
|
self.calGroup = QGroupBox("Calibration Peaks", self.tableTab)
|
||||||
calLayout = QVBoxLayout()
|
calLayout = QVBoxLayout()
|
||||||
self.calibrationTable = QTableWidget(self.calGroup)
|
self.calibrationTable = QTableWidget(self.calGroup)
|
||||||
self.calibrationTable.setColumnCount(8)
|
self.calibrationTable.setColumnCount(9)
|
||||||
self.calibrationTable.setHorizontalHeaderLabels(["Reaction","x(mm)","ux stat.(mm)","ux sys.(mm)","rho(cm)","urho(cm)","Ex(MeV)","uEx(MeV)"])
|
self.calibrationTable.setHorizontalHeaderLabels(["Peak ID","Reaction","x(mm)","ux stat.(mm)","ux sys.(mm)","rho(cm)","urho(cm)","Ex(MeV)","uEx(MeV)"])
|
||||||
calLayout.addWidget(self.calibrationTable)
|
calLayout.addWidget(self.calibrationTable)
|
||||||
self.calGroup.setLayout(calLayout)
|
self.calGroup.setLayout(calLayout)
|
||||||
self.tablelayout.addWidget(self.calGroup)
|
self.tablelayout.addWidget(self.calGroup)
|
||||||
self.calibrationTable.resizeColumnsToContents()
|
self.calibrationTable.resizeColumnsToContents()
|
||||||
self.calibrationTable.cellDoubleClicked.connect(self.handle_update_calibration)
|
self.calibrationTable.cellDoubleClicked.connect(self.handle_update_calibration)
|
||||||
|
self.calibrationTable.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
|
||||||
|
|
||||||
def create_output_table(self) -> None:
|
def create_output_table(self) -> None:
|
||||||
self.outGroup = QGroupBox("Output Peaks", self.tableTab)
|
self.outGroup = QGroupBox("Output Peaks", self.tableTab)
|
||||||
outLayout = QVBoxLayout()
|
outLayout = QVBoxLayout()
|
||||||
self.outputTable = QTableWidget(self.outGroup)
|
self.outputTable = QTableWidget(self.outGroup)
|
||||||
self.outputTable.setColumnCount(12)
|
self.outputTable.setColumnCount(13)
|
||||||
self.outputTable.setHorizontalHeaderLabels(["Reaction","x(mm)","ux stat.(mm)","ux sys.(mm)","rho(cm)","urho(cm)","Ex(MeV)","uEx(MeV)","FWHM(mm)","uFWHM(mm)","FWHM(MeV)","uFWHM(MeV)"])
|
self.outputTable.setHorizontalHeaderLabels(["Peak ID", "Reaction","x(mm)","ux stat.(mm)","ux sys.(mm)","rho(cm)","urho(cm)","Ex(MeV)","uEx(MeV)","FWHM(mm)","uFWHM(mm)","FWHM(MeV)","uFWHM(MeV)"])
|
||||||
outLayout.addWidget(self.outputTable)
|
outLayout.addWidget(self.outputTable)
|
||||||
self.outGroup.setLayout(outLayout)
|
self.outGroup.setLayout(outLayout)
|
||||||
self.tablelayout.addWidget(self.outGroup)
|
self.tablelayout.addWidget(self.outGroup)
|
||||||
self.outputTable.resizeColumnsToContents()
|
self.outputTable.resizeColumnsToContents()
|
||||||
self.outputTable.cellDoubleClicked.connect(self.handle_update_output)
|
self.outputTable.cellDoubleClicked.connect(self.handle_update_output)
|
||||||
|
self.outputTable.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
|
||||||
|
|
||||||
def create_fit_result_text(self) -> None:
|
def create_fit_result_text(self) -> None:
|
||||||
self.fitTextGroup = QGroupBox("Fit Results", self.plotTab)
|
self.fitTextGroup = QGroupBox("Fit Results", self.plotTab)
|
||||||
|
@ -234,11 +238,15 @@ class SpancGUI(QMainWindow):
|
||||||
return
|
return
|
||||||
|
|
||||||
def handle_update_calibration(self, row: int, col: int) -> None:
|
def handle_update_calibration(self, row: int, col: int) -> None:
|
||||||
peakData = self.spanc.calibrations[row]
|
peakID = int(self.calibrationTable.item(row, 0).text())
|
||||||
|
peakData = self.spanc.calibrations[peakID]
|
||||||
calDia = PeakDialog(PeakType.CALIBRATION, self.spanc.reactions.keys(), self, peak=peakData)
|
calDia = PeakDialog(PeakType.CALIBRATION, self.spanc.reactions.keys(), self, peak=peakData)
|
||||||
calDia.new_peak.connect(self.spanc.add_calibration)
|
calDia.new_peak.connect(self.spanc.add_calibration)
|
||||||
|
calDia.delete_peak.connect(self.spanc.remove_calibration)
|
||||||
if calDia.exec():
|
if calDia.exec():
|
||||||
self.update_calibration_table()
|
self.update_calibration_table()
|
||||||
|
if self.spanc.isFit == True:
|
||||||
|
self.handle_run_fit()
|
||||||
return
|
return
|
||||||
|
|
||||||
def handle_new_output(self) -> None:
|
def handle_new_output(self) -> None:
|
||||||
|
@ -249,7 +257,8 @@ class SpancGUI(QMainWindow):
|
||||||
return
|
return
|
||||||
|
|
||||||
def handle_update_output(self, row: int, col: int) -> None:
|
def handle_update_output(self, row: int, col: int) -> None:
|
||||||
peakData = self.spanc.calibrations[row]
|
peakID = int(self.calibrationTable.item(row, 0).text())
|
||||||
|
peakData = self.spanc.outputs[peakID]
|
||||||
outDia = PeakDialog(PeakType.OUTPUT, self.spanc.reactions.keys(), self, peak=peakData)
|
outDia = PeakDialog(PeakType.OUTPUT, self.spanc.reactions.keys(), self, peak=peakData)
|
||||||
outDia.new_peak.connect(self.spanc.add_output)
|
outDia.new_peak.connect(self.spanc.add_output)
|
||||||
if outDia.exec():
|
if outDia.exec():
|
||||||
|
@ -311,7 +320,7 @@ class SpancGUI(QMainWindow):
|
||||||
self.reactionTable.setCellWidget(row, 1, QLabel(str(rxn)))
|
self.reactionTable.setCellWidget(row, 1, QLabel(str(rxn)))
|
||||||
self.reactionTable.setItem(row, 2, QTableWidgetItem(str(rxn.params.beamEnergy)))
|
self.reactionTable.setItem(row, 2, QTableWidgetItem(str(rxn.params.beamEnergy)))
|
||||||
self.reactionTable.setItem(row, 3, QTableWidgetItem(str(rxn.params.magneticField)))
|
self.reactionTable.setItem(row, 3, QTableWidgetItem(str(rxn.params.magneticField)))
|
||||||
self.reactionTable.setItem(row, 4, QTableWidgetItem(str(rxn.params.spsAngle)))
|
self.reactionTable.setItem(row, 4, QTableWidgetItem(str(rxn.params.spsAngle / DEG2RAD)))
|
||||||
self.reactionTable.resizeColumnsToContents()
|
self.reactionTable.resizeColumnsToContents()
|
||||||
self.reactionTable.resizeRowsToContents()
|
self.reactionTable.resizeRowsToContents()
|
||||||
|
|
||||||
|
@ -319,14 +328,15 @@ class SpancGUI(QMainWindow):
|
||||||
self.calibrationTable.setRowCount(len(self.spanc.calibrations))
|
self.calibrationTable.setRowCount(len(self.spanc.calibrations))
|
||||||
self.calibrationTable.setVerticalHeaderLabels(self.spanc.calibrations.keys())
|
self.calibrationTable.setVerticalHeaderLabels(self.spanc.calibrations.keys())
|
||||||
for row, peak in enumerate(self.spanc.calibrations.values()):
|
for row, peak in enumerate(self.spanc.calibrations.values()):
|
||||||
self.calibrationTable.setItem(row, 0, QTableWidgetItem(peak.rxnName))
|
self.calibrationTable.setItem(row, 0, QTableWidgetItem(str(peak.peakID)))
|
||||||
self.calibrationTable.setItem(row, 1, QTableWidgetItem(str(peak.position)))
|
self.calibrationTable.setItem(row, 1, QTableWidgetItem(peak.rxnName))
|
||||||
self.calibrationTable.setItem(row, 2, QTableWidgetItem(str(peak.positionErrStat)))
|
self.calibrationTable.setItem(row, 2, QTableWidgetItem(str(peak.position)))
|
||||||
self.calibrationTable.setItem(row, 3, QTableWidgetItem(str(peak.positionErrSys)))
|
self.calibrationTable.setItem(row, 3, QTableWidgetItem(str(peak.positionErrStat)))
|
||||||
self.calibrationTable.setItem(row, 4, QTableWidgetItem(str(peak.rho)))
|
self.calibrationTable.setItem(row, 4, QTableWidgetItem(str(peak.positionErrSys)))
|
||||||
self.calibrationTable.setItem(row, 5, QTableWidgetItem(str(peak.rhoErr)))
|
self.calibrationTable.setItem(row, 5, QTableWidgetItem(str(peak.rho)))
|
||||||
self.calibrationTable.setItem(row, 6, QTableWidgetItem(str(peak.excitation)))
|
self.calibrationTable.setItem(row, 6, QTableWidgetItem(str(peak.rhoErr)))
|
||||||
self.calibrationTable.setItem(row, 7, QTableWidgetItem(str(peak.excitationErr)))
|
self.calibrationTable.setItem(row, 7, QTableWidgetItem(str(peak.excitation)))
|
||||||
|
self.calibrationTable.setItem(row, 8, QTableWidgetItem(str(peak.excitationErr)))
|
||||||
self.calibrationTable.resizeColumnsToContents()
|
self.calibrationTable.resizeColumnsToContents()
|
||||||
self.calibrationTable.resizeRowsToContents()
|
self.calibrationTable.resizeRowsToContents()
|
||||||
|
|
||||||
|
@ -334,18 +344,19 @@ class SpancGUI(QMainWindow):
|
||||||
self.outputTable.setRowCount(len(self.spanc.outputs))
|
self.outputTable.setRowCount(len(self.spanc.outputs))
|
||||||
self.outputTable.setVerticalHeaderLabels(self.spanc.outputs.keys())
|
self.outputTable.setVerticalHeaderLabels(self.spanc.outputs.keys())
|
||||||
for row, peak in enumerate(self.spanc.outputs.values()):
|
for row, peak in enumerate(self.spanc.outputs.values()):
|
||||||
self.outputTable.setItem(row, 0, QTableWidgetItem(peak.rxnName))
|
self.outputTable.setItem(row, 0, QTableWidgetItem(str(peak.peakID)))
|
||||||
self.outputTable.setItem(row, 1, QTableWidgetItem(str(peak.position)))
|
self.outputTable.setItem(row, 1, QTableWidgetItem(peak.rxnName))
|
||||||
self.outputTable.setItem(row, 2, QTableWidgetItem(str(peak.positionErrStat)))
|
self.outputTable.setItem(row, 2, QTableWidgetItem(str(peak.position)))
|
||||||
self.outputTable.setItem(row, 3, QTableWidgetItem(str(peak.positionErrSys)))
|
self.outputTable.setItem(row, 3, QTableWidgetItem(str(peak.positionErrStat)))
|
||||||
self.outputTable.setItem(row, 4, QTableWidgetItem(str(peak.rho)))
|
self.outputTable.setItem(row, 4, QTableWidgetItem(str(peak.positionErrSys)))
|
||||||
self.outputTable.setItem(row, 5, QTableWidgetItem(str(peak.rhoErr)))
|
self.outputTable.setItem(row, 5, QTableWidgetItem(str(peak.rho)))
|
||||||
self.outputTable.setItem(row, 6, QTableWidgetItem(str(peak.excitation)))
|
self.outputTable.setItem(row, 6, QTableWidgetItem(str(peak.rhoErr)))
|
||||||
self.outputTable.setItem(row, 7, QTableWidgetItem(str(peak.excitationErr)))
|
self.outputTable.setItem(row, 7, QTableWidgetItem(str(peak.excitation)))
|
||||||
self.outputTable.setItem(row, 8, QTableWidgetItem(str(peak.positionFWHM)))
|
self.outputTable.setItem(row, 8, QTableWidgetItem(str(peak.excitationErr)))
|
||||||
self.outputTable.setItem(row, 9, QTableWidgetItem(str(peak.positionFWHMErr)))
|
self.outputTable.setItem(row, 9, QTableWidgetItem(str(peak.positionFWHM)))
|
||||||
self.outputTable.setItem(row, 10, QTableWidgetItem(str(peak.excitationFWHM)))
|
self.outputTable.setItem(row, 10, QTableWidgetItem(str(peak.positionFWHMErr)))
|
||||||
self.outputTable.setItem(row, 11, QTableWidgetItem(str(peak.excitationFWHMErr)))
|
self.outputTable.setItem(row, 11, QTableWidgetItem(str(peak.excitationFWHM)))
|
||||||
|
self.outputTable.setItem(row, 12, QTableWidgetItem(str(peak.excitationFWHMErr)))
|
||||||
self.outputTable.resizeColumnsToContents()
|
self.outputTable.resizeColumnsToContents()
|
||||||
self.outputTable.resizeRowsToContents()
|
self.outputTable.resizeRowsToContents()
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ def get_excitations(Z: int, A: int) -> list[float]:
|
||||||
levels = []
|
levels = []
|
||||||
text = ''
|
text = ''
|
||||||
symbol = global_nuclear_data.get_data(Z, A).isotopicSymbol
|
symbol = global_nuclear_data.get_data(Z, A).isotopicSymbol
|
||||||
site = req.get(f"https://www.nndc.bnl.gov/nudat2/getdatasetClassic.jsp?nucleus={symbol}&unc=nds")
|
site = req.get(f"https://www.nndc.bnl.gov/nudat3/getdatasetClassic.jsp?nucleus={symbol}&unc=nds")
|
||||||
contents = xhtml.fromstring(site.content)
|
contents = xhtml.fromstring(site.content)
|
||||||
tables = contents.xpath("//table")
|
tables = contents.xpath("//table")
|
||||||
rows = tables[2].xpath("./tr")
|
rows = tables[2].xpath("./tr")
|
||||||
|
|
|
@ -2,11 +2,12 @@ from ..Spanc import Peak, PeakType, INVALID_PEAK_ID
|
||||||
from PySide6.QtWidgets import QLabel
|
from PySide6.QtWidgets import QLabel
|
||||||
from PySide6.QtWidgets import QVBoxLayout, QFormLayout, QGroupBox
|
from PySide6.QtWidgets import QVBoxLayout, QFormLayout, QGroupBox
|
||||||
from PySide6.QtWidgets import QComboBox, QDoubleSpinBox
|
from PySide6.QtWidgets import QComboBox, QDoubleSpinBox
|
||||||
from PySide6.QtWidgets import QDialog, QDialogButtonBox
|
from PySide6.QtWidgets import QDialog, QDialogButtonBox, QPushButton
|
||||||
from PySide6.QtCore import Signal
|
from PySide6.QtCore import Signal
|
||||||
|
|
||||||
class PeakDialog(QDialog):
|
class PeakDialog(QDialog):
|
||||||
new_peak = Signal(Peak)
|
new_peak = Signal(Peak)
|
||||||
|
delete_peak = Signal(Peak)
|
||||||
|
|
||||||
def __init__(self, peakType: PeakType, rxnList: list[str], parent=None, peak: Peak=None):
|
def __init__(self, peakType: PeakType, rxnList: list[str], parent=None, peak: Peak=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
@ -26,14 +27,19 @@ class PeakDialog(QDialog):
|
||||||
if peakType == PeakType.CALIBRATION:
|
if peakType == PeakType.CALIBRATION:
|
||||||
self.create_calibration_inputs()
|
self.create_calibration_inputs()
|
||||||
if peak is not None:
|
if peak is not None:
|
||||||
|
self.setWindowTitle(f"Update A {peakType.value} Peak")
|
||||||
self.set_calibration_inputs(peak)
|
self.set_calibration_inputs(peak)
|
||||||
self.peakID = peak.peakID
|
self.peakID = peak.peakID
|
||||||
self.buttonBox.accepted.connect(self.send_update_calibration_peak)
|
self.buttonBox.accepted.connect(self.send_update_calibration_peak)
|
||||||
|
self.deleteButton = QPushButton("Delete", self)
|
||||||
|
self.deleteButton.clicked.connect(self.send_delete_calibration_peak)
|
||||||
|
self.centralLayout.addWidget(self.deleteButton)
|
||||||
else:
|
else:
|
||||||
self.buttonBox.accepted.connect(self.send_calibration_peak)
|
self.buttonBox.accepted.connect(self.send_calibration_peak)
|
||||||
elif peakType == PeakType.OUTPUT:
|
elif peakType == PeakType.OUTPUT:
|
||||||
self.create_output_inputs()
|
self.create_output_inputs()
|
||||||
if peak is not None:
|
if peak is not None:
|
||||||
|
self.setWindowTitle(f"Update A {peakType.value} Peak")
|
||||||
self.set_output_inputs(peak)
|
self.set_output_inputs(peak)
|
||||||
self.peakID = peak.peakID
|
self.peakID = peak.peakID
|
||||||
self.buttonBox.accepted.connect(self.send_update_output_peak)
|
self.buttonBox.accepted.connect(self.send_update_output_peak)
|
||||||
|
@ -58,8 +64,8 @@ class PeakDialog(QDialog):
|
||||||
self.uexInput = QDoubleSpinBox(self.inputGroupBox)
|
self.uexInput = QDoubleSpinBox(self.inputGroupBox)
|
||||||
self.uexInput.setDecimals(6)
|
self.uexInput.setDecimals(6)
|
||||||
inputLayout.addRow("Position(mm)", self.xInput)
|
inputLayout.addRow("Position(mm)", self.xInput)
|
||||||
inputLayout.addRow("Position Stat. Error(mm)", self.uxstatInput)
|
|
||||||
inputLayout.addRow("Position Sys. Error(mm)", self.uxsysInput)
|
inputLayout.addRow("Position Sys. Error(mm)", self.uxsysInput)
|
||||||
|
inputLayout.addRow("Position Stat. Error(mm)", self.uxstatInput)
|
||||||
inputLayout.addRow("Excitation Energy(MeV)", self.exInput)
|
inputLayout.addRow("Excitation Energy(MeV)", self.exInput)
|
||||||
inputLayout.addRow("Excitation Energy Error(MeV)", self.uexInput)
|
inputLayout.addRow("Excitation Energy Error(MeV)", self.uexInput)
|
||||||
self.inputGroupBox.setLayout(inputLayout)
|
self.inputGroupBox.setLayout(inputLayout)
|
||||||
|
@ -82,8 +88,8 @@ class PeakDialog(QDialog):
|
||||||
self.ufwhmInput = QDoubleSpinBox(self.inputGroupBox)
|
self.ufwhmInput = QDoubleSpinBox(self.inputGroupBox)
|
||||||
self.ufwhmInput.setDecimals(6)
|
self.ufwhmInput.setDecimals(6)
|
||||||
inputLayout.addRow("Position(mm)", self.xInput)
|
inputLayout.addRow("Position(mm)", self.xInput)
|
||||||
inputLayout.addRow("Position Stat. Error(mm)", self.uxstatInput)
|
|
||||||
inputLayout.addRow("Position Sys. Error(mm)", self.uxsysInput)
|
inputLayout.addRow("Position Sys. Error(mm)", self.uxsysInput)
|
||||||
|
inputLayout.addRow("Position Stat. Error(mm)", self.uxstatInput)
|
||||||
inputLayout.addRow("Position FWHM(mm)", self.fwhmInput)
|
inputLayout.addRow("Position FWHM(mm)", self.fwhmInput)
|
||||||
inputLayout.addRow("Position FWHM Error(mm)", self.ufwhmInput)
|
inputLayout.addRow("Position FWHM Error(mm)", self.ufwhmInput)
|
||||||
self.inputGroupBox.setLayout(inputLayout)
|
self.inputGroupBox.setLayout(inputLayout)
|
||||||
|
@ -114,6 +120,12 @@ class PeakDialog(QDialog):
|
||||||
peak = Peak(excitation=self.exInput.value(), excitationErr=self.uexInput.value(), position=self.xInput.value(),
|
peak = Peak(excitation=self.exInput.value(), excitationErr=self.uexInput.value(), position=self.xInput.value(),
|
||||||
positionErrStat=self.uxstatInput.value(), positionErrSys=self.uxsysInput.value(), rxnName=self.rxnNameBox.currentText(), peakID=self.peakID)
|
positionErrStat=self.uxstatInput.value(), positionErrSys=self.uxsysInput.value(), rxnName=self.rxnNameBox.currentText(), peakID=self.peakID)
|
||||||
self.new_peak.emit(peak)
|
self.new_peak.emit(peak)
|
||||||
|
|
||||||
|
def send_delete_calibration_peak(self) -> None:
|
||||||
|
peak = Peak(excitation=self.exInput.value(), excitationErr=self.uexInput.value(), position=self.xInput.value(),
|
||||||
|
positionErrStat=self.uxstatInput.value(), positionErrSys=self.uxsysInput.value(), rxnName=self.rxnNameBox.currentText(), peakID=self.peakID)
|
||||||
|
self.delete_peak.emit(peak)
|
||||||
|
self.done(3)
|
||||||
|
|
||||||
def send_output_peak(self) -> None:
|
def send_output_peak(self) -> None:
|
||||||
peak = Peak(position=self.xInput.value(), positionErrStat=self.uxstatInput.value(), positionErrSys=self.uxsysInput.value(),
|
peak = Peak(position=self.xInput.value(), positionErrStat=self.uxstatInput.value(), positionErrSys=self.uxsysInput.value(),
|
||||||
|
|
|
@ -5,6 +5,7 @@ from PySide6.QtWidgets import QVBoxLayout, QFormLayout, QGroupBox
|
||||||
from PySide6.QtWidgets import QSpinBox, QDoubleSpinBox, QComboBox
|
from PySide6.QtWidgets import QSpinBox, QDoubleSpinBox, QComboBox
|
||||||
from PySide6.QtWidgets import QDialog, QDialogButtonBox
|
from PySide6.QtWidgets import QDialog, QDialogButtonBox
|
||||||
from PySide6.QtCore import Signal
|
from PySide6.QtCore import Signal
|
||||||
|
from numpy import rad2deg
|
||||||
|
|
||||||
MAXIMUM_NUCLEAR_Z: int = 110
|
MAXIMUM_NUCLEAR_Z: int = 110
|
||||||
MAXIMUM_NUCLEAR_A: int = 270
|
MAXIMUM_NUCLEAR_A: int = 270
|
||||||
|
@ -116,6 +117,6 @@ class ReactionDialog(QDialog):
|
||||||
self.aeInput.setValue(rxn.params.ejectile.A)
|
self.aeInput.setValue(rxn.params.ejectile.A)
|
||||||
self.aeInput.setEnabled(False)
|
self.aeInput.setEnabled(False)
|
||||||
self.bkeInput.setValue(rxn.params.beamEnergy)
|
self.bkeInput.setValue(rxn.params.beamEnergy)
|
||||||
self.thetaInput.setValue(rxn.params.spsAngle)
|
self.thetaInput.setValue(rad2deg(rxn.params.spsAngle))
|
||||||
self.bfieldInput.setValue(rxn.params.magneticField)
|
self.bfieldInput.setValue(rxn.params.magneticField)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user