mirror of
https://github.com/gwm17/spspy.git
synced 2025-12-17 09:55:51 -05:00
added the ability to export excitation energy calibration data to CSV
modified: .gitignore modified: spspy/Spanc.py modified: spspy/SpancUI.py
This commit is contained in:
parent
06d60e18b5
commit
b2906cf5a8
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -5,4 +5,5 @@ __pycache__/
|
|||
.vs/
|
||||
*.sps
|
||||
*.spanc
|
||||
*.csv
|
||||
*.csv
|
||||
*.DS_Store
|
||||
|
|
@ -126,4 +126,82 @@ class Spanc:
|
|||
for calibration in self.calibrations.values():
|
||||
rxn = self.reactions[calibration.rxnName]
|
||||
calibration.rho = rxn.convert_ejectile_KE_2_rho(rxn.calculate_ejectile_KE(calibration.excitation))
|
||||
calibration.rhoErr = np.abs(rxn.convert_ejectile_KE_2_rho(rxn.calculate_ejectile_KE(calibration.excitation + calibration.excitationErr)) - calibration.rho)
|
||||
calibration.rhoErr = np.abs(rxn.convert_ejectile_KE_2_rho(rxn.calculate_ejectile_KE(calibration.excitation + calibration.excitationErr)) - calibration.rho)
|
||||
|
||||
def get_excitation_curves(self,
|
||||
x_min: float = -300.0,
|
||||
x_max: float = 300.0,
|
||||
n_bins: int = 601):
|
||||
"""
|
||||
Compute excitation-energy curves for every reaction by evaluating
|
||||
Ex = reaction.calculate_excitation( rho(x) ) across a grid of
|
||||
focal-plane positions.
|
||||
|
||||
Returns:
|
||||
x_vals: array of FP bin centers
|
||||
ex_curves: { rxn_name: Ex_array_in_MeV }
|
||||
"""
|
||||
# Bin centers (e.g. 601 values from -300 to 300)
|
||||
x_vals = np.linspace(x_min, x_max, n_bins)
|
||||
|
||||
# ρ(x) uses your fitted polynomial a0 + a1 x + ... + aN x^N
|
||||
params = self.fitter.get_parameters() # [a0, a1, ..., aN]
|
||||
rho_vals = np.polyval(params[::-1], x_vals) # reverse order for numpy poly
|
||||
|
||||
ex_curves: dict[str, np.ndarray] = {}
|
||||
|
||||
for rxn_name, rxn in self.reactions.items():
|
||||
ex_vals = np.array(
|
||||
[rxn.calculate_excitation(rho) for rho in rho_vals],
|
||||
dtype=float,
|
||||
)
|
||||
ex_curves[rxn_name] = ex_vals
|
||||
|
||||
return x_vals, ex_curves
|
||||
|
||||
def export_excitation_csv(self,
|
||||
filename: str,
|
||||
x_min: float = -300.0,
|
||||
x_max: float = 300.0,
|
||||
n_bins: int = 601):
|
||||
"""
|
||||
Export excitation-energy calibration table as CSV.
|
||||
|
||||
CSV format:
|
||||
FP_x_mm, Ex_rxn1_MeV, Ex_rxn2_MeV, ...
|
||||
|
||||
FP_x_mm runs from x_min to x_max with n_bins steps (inclusive).
|
||||
"""
|
||||
import csv
|
||||
import numpy as np
|
||||
|
||||
# Generate FP positions (601 values from -300 to 300)
|
||||
x_vals = np.linspace(x_min, x_max, n_bins)
|
||||
|
||||
# Compute rho(x) using fitted polynomial
|
||||
params = self.fitter.get_parameters() # [a0, a1, ..., aN]
|
||||
rho_vals = np.polyval(params[::-1], x_vals)
|
||||
|
||||
# Compute excitation for each reaction
|
||||
rxn_names = list(self.reactions.keys())
|
||||
ex_mev = {rxn: [] for rxn in rxn_names}
|
||||
|
||||
for rho in rho_vals:
|
||||
for rxn_name, rxn in self.reactions.items():
|
||||
ex = rxn.calculate_excitation(rho)
|
||||
ex_mev[rxn_name].append(ex)
|
||||
|
||||
# Write CSV
|
||||
with open(filename, "w", newline="") as csvfile:
|
||||
writer = csv.writer(csvfile)
|
||||
|
||||
# Header row
|
||||
header = ["x_mm"] + [f"Ex_{rxn}_MeV" for rxn in rxn_names]
|
||||
writer.writerow(header)
|
||||
|
||||
# Data rows
|
||||
for i, x in enumerate(x_vals):
|
||||
row = [f"{x:.6f}"]
|
||||
for rxn in rxn_names:
|
||||
row.append(f"{ex_mev[rxn][i]:.9f}")
|
||||
writer.writerow(row)
|
||||
|
|
@ -95,6 +95,17 @@ class SpancGUI(QMainWindow):
|
|||
fitOptionLayout.addWidget(QLabel("Polynomial Order", self.fitOptionGroup))
|
||||
fitOptionLayout.addWidget(self.fitOrderBox)
|
||||
fitOptionLayout.addWidget(self.fitButton)
|
||||
|
||||
# NEW: button to plot excitation curves for all reactions
|
||||
self.exCurveButton = QPushButton("Plot Ex vs x", self.fitOptionGroup)
|
||||
self.exCurveButton.clicked.connect(self.plot_excitation_curves)
|
||||
fitOptionLayout.addWidget(self.exCurveButton)
|
||||
|
||||
# Button to export excitation calibration CSV
|
||||
self.exportCSVButton = QPushButton("Export Ex(x) CSV", self.fitOptionGroup)
|
||||
self.exportCSVButton.clicked.connect(self.handle_export_excitation_csv)
|
||||
fitOptionLayout.addWidget(self.exportCSVButton)
|
||||
|
||||
self.fitOptionGroup.setLayout(fitOptionLayout)
|
||||
|
||||
fitLayout.addWidget(QLabel("Fit", self.fitCanvas))
|
||||
|
|
@ -374,8 +385,42 @@ class SpancGUI(QMainWindow):
|
|||
f"## Parameter Uncertanties (ua0 -> uaN): {np.array_str(self.spanc.fitter.get_parameter_errors(), precision=3)} \n \n"
|
||||
f"## Residuals (x0 -> xN): {np.array_str(residuals, precision=3)} \n \n"
|
||||
f"## Studentized Residuals (x0 -> xN): {np.array_str(studentizedResiduals, precision=3)} \n \n")
|
||||
|
||||
self.fitResultText.setMarkdown(markdownString)
|
||||
|
||||
def plot_excitation_curves(self):
|
||||
# Require a fit so rho(x) is defined
|
||||
if not self.spanc.isFit:
|
||||
print("Run the calibration fit first before plotting Ex vs x.")
|
||||
return
|
||||
|
||||
# Compute Ex at 600 bin centers from -300 to 300 for all reactions
|
||||
x_vals, ex_curves = self.spanc.get_excitation_curves(
|
||||
x_min=-300.0,
|
||||
x_max=300.0,
|
||||
n_bins=600,
|
||||
)
|
||||
|
||||
self.fitCanvas.axes.cla()
|
||||
for rxn_name, ex_vals in ex_curves.items():
|
||||
self.fitCanvas.axes.plot(x_vals, ex_vals, label=rxn_name)
|
||||
|
||||
self.fitCanvas.axes.set_xlabel(r"$x$ (mm)")
|
||||
self.fitCanvas.axes.set_ylabel(r"$E_x$ (MeV)")
|
||||
self.fitCanvas.axes.set_title("Excitation energy vs focal-plane position")
|
||||
self.fitCanvas.axes.grid(True)
|
||||
self.fitCanvas.axes.legend()
|
||||
self.fitCanvas.fig.tight_layout()
|
||||
self.fitCanvas.draw()
|
||||
|
||||
def handle_export_excitation_csv(self):
|
||||
fileName = QFileDialog.getSaveFileName(
|
||||
self, "Export Excitation CSV", "./", "CSV Files (*.csv)"
|
||||
)
|
||||
if fileName[0]:
|
||||
self.spanc.export_excitation_csv(fileName[0])
|
||||
print(f"Exported excitation calibration to {fileName[0]}")
|
||||
|
||||
def run_spanc_ui() :
|
||||
mpl.use("Qt5Agg")
|
||||
app = QApplication.instance()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user