This commit is contained in:
Ryan Tang 2024-11-07 16:17:28 -05:00
parent f1b2d4a580
commit b73d95574f
4 changed files with 82 additions and 33 deletions

View File

@ -19,7 +19,8 @@ class ExWindow(QWidget):
super().__init__() super().__init__()
self.setWindowTitle("Ex Plot") self.setWindowTitle("Ex Plot")
self.setGeometry(100, 100, 400, 800) # self.setGeometry(100, 100, 400, 800)
self.resize(400, 800)
self.ASym = "" self.ASym = ""
self.maxEx = 0 self.maxEx = 0

View File

@ -2,11 +2,35 @@
import numpy as np import numpy as np
from scipy.optimize import curve_fit from scipy.optimize import curve_fit
from PyQt6.QtWidgets import (
QVBoxLayout, QWidget
)
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from matplotlib.backends.backend_qtagg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from ExtractXsecPy import read_DWBA from ExtractXsecPy import read_DWBA
class Fitting: class FitPlotWidget(QWidget):
def __init__(self, figure):
super().__init__()
self.setWindowTitle("Fit Plot")
self.resize(800, 600)
self.canvas = FigureCanvas(figure)
self.toolbar = NavigationToolbar(self.canvas, self)
layout = QVBoxLayout(self)
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
self.setLayout(layout)
class Fitting():
def __init__(self): def __init__(self):
self.ExList = [] self.ExList = []
@ -37,7 +61,7 @@ class Fitting:
continue continue
# Check for excitation energy lines # Check for excitation energy lines
if line.startswith("#======================"): if line.startswith("#="):
# If there's an existing data block, save it # If there's an existing data block, save it
if current_data: if current_data:
self.expData.append(np.array(current_data, dtype=float)) self.expData.append(np.array(current_data, dtype=float))
@ -77,12 +101,12 @@ class Fitting:
def FitData(self): def FitData(self):
# Set initial offset values figure_list = []
x_offset, y_offset = 2000, 100
figure = []
for expDataID in range(len(self.expData)): for expDataID in range(len(self.expData)):
print("============================================")
# Get the number of fit options and cross-sections # Get the number of fit options and cross-sections
nFit = len(self.fitOption[expDataID]) nFit = len(self.fitOption[expDataID])
nXsec = len(self.data) nXsec = len(self.data)
@ -97,6 +121,8 @@ class Fitting:
fitTheory_lower = [] fitTheory_lower = []
fitTheory_upper = [] fitTheory_upper = []
chi_squared = []
for k in range(nFit): for k in range(nFit):
# Get the cross-section IDs for the current fit option and strip extra spaces # Get the cross-section IDs for the current fit option and strip extra spaces
xsecIDStr = self.fitOption[expDataID][k].strip() xsecIDStr = self.fitOption[expDataID][k].strip()
@ -129,7 +155,14 @@ class Fitting:
bounds=(lower_bounds, upper_bounds)) bounds=(lower_bounds, upper_bounds))
perr = np.sqrt(np.diag(pcov)) # Standard deviation of the parameters perr = np.sqrt(np.diag(pcov)) # Standard deviation of the parameters
print(f"Fitted scale for fit {k+1}: {popt} +/- {perr}")
# Get the fitted model values
y_fit = fit_func(x_exp, *popt)
residuals = y_exp - y_fit
chi_squared.append(np.sum((residuals / y_err) ** 2))
print(f"Fitted scale for fit {k}: {', '.join([f'{x:.3f}' for x in popt])} +/- {', '.join([f'{x:.3f}' for x in perr])} | Chi^2 : {chi_squared[-1]:.4f}")
# print(f"Fitted scale for fit {k}: {popt} +/- {perr} | Chi^2 : {chi_squared[-1]:.4f}")
# Append the theoretical fit for this fit option # Append the theoretical fit for this fit option
fitTheory.append(np.zeros_like(self.dataX)) fitTheory.append(np.zeros_like(self.dataX))
@ -146,14 +179,14 @@ class Fitting:
fitTheory_lower[k] += (popt[p] - perr[p]) * np.interp(self.dataX, self.dataX, self.data[id]) fitTheory_lower[k] += (popt[p] - perr[p]) * np.interp(self.dataX, self.dataX, self.data[id])
fig = plt.figure() fig = plt.figure()
figure.append(fig) figure_list.append(fig)
# Plot results # Plot results
plt.errorbar(x_exp, y_exp, xerr=x_err, yerr=y_err, fmt='o', label='Experimental Data', color='blue') plt.errorbar(x_exp, y_exp, xerr=x_err, yerr=y_err, fmt='x', label='Experimental Data', color='black', markersize = 15, elinewidth=2)
# Plot all fit theories # Plot all fit theories
for i, fit in enumerate(fitTheory): for i, fit in enumerate(fitTheory):
plt.plot(self.dataX, fit, label=f'Xsec:{self.fitOption[expDataID][i]} Fit') plt.plot(self.dataX, fit, label=f'Chi2:{chi_squared[i]:.3f} | Xsec:{self.fitOption[expDataID][i]} Fit')
plt.fill_between(self.dataX, fitTheory_lower[i], fitTheory_upper[i], alpha=0.2) plt.fill_between(self.dataX, fitTheory_lower[i], fitTheory_upper[i], alpha=0.2)
# Customize plot # Customize plot
@ -168,11 +201,6 @@ class Fitting:
plt.text(0.05, 0.05, f'Fit for Exp Data : {self.ExList[expDataID]} MeV', transform=plt.gca().transAxes, plt.text(0.05, 0.05, f'Fit for Exp Data : {self.ExList[expDataID]} MeV', transform=plt.gca().transAxes,
fontsize=12, verticalalignment='bottom', horizontalalignment='left', color='black') fontsize=12, verticalalignment='bottom', horizontalalignment='left', color='black')
manager = plt.get_current_fig_manager()
# manager.window.wm_geometry(f"+{x_offset}+{y_offset}")
manager.set_window_title(f"Exp Data : {self.ExList[expDataID]} MeV")
x_offset += 100
y_offset += 100
plt.show()
return figure_list

View File

@ -18,7 +18,7 @@ class MatPlotLibWindow(QWidget):
super().__init__() super().__init__()
self.setWindowTitle("DWBA Plot") self.setWindowTitle("DWBA Plot")
self.setGeometry(100, 100, 800, 600) self.resize(800, 600)
self.x = [] self.x = []
self.data = [] self.data = []

View File

@ -17,7 +17,7 @@ from CustomTextEdit import CustomTextEdit
from ExtractXsecPy import extract_xsec from ExtractXsecPy import extract_xsec
from ExWindow import ExWindow from ExWindow import ExWindow
from MatPlotLibWindow import MatPlotLibWindow from MatPlotLibWindow import MatPlotLibWindow
from FitExData import Fitting from FitExData import Fitting, FitPlotWidget
################################################## MainWindow ################################################## MainWindow
class MyWindow(QMainWindow): class MyWindow(QMainWindow):
@ -25,7 +25,7 @@ class MyWindow(QMainWindow):
super().__init__() super().__init__()
self.setWindowTitle("Ptolemy GUI") self.setWindowTitle("Ptolemy GUI")
self.setGeometry(100, 100, 1000, 800) self.resize(1000, 800)
self.setMinimumSize(1000, 800) self.setMinimumSize(1000, 800)
self.lastDWBARecord = "lastDWBA.txt" self.lastDWBARecord = "lastDWBA.txt"
@ -36,6 +36,7 @@ class MyWindow(QMainWindow):
self.plot_window = MatPlotLibWindow() self.plot_window = MatPlotLibWindow()
self.Ex_window = ExWindow() self.Ex_window = ExWindow()
self.fitting = Fitting() self.fitting = Fitting()
self.fitCanvas = []
# Set up Group Box for DWBA Control # Set up Group Box for DWBA Control
self.gbDWBA = QGroupBox("DWBA") self.gbDWBA = QGroupBox("DWBA")
@ -192,6 +193,7 @@ class MyWindow(QMainWindow):
self.LoadFileToTextBox(self.DWBAFileName, True) self.LoadFileToTextBox(self.DWBAFileName, True)
self.bnSaveFile.setEnabled(True)
self.bnSaveExpDataFile.setEnabled(False) self.bnSaveExpDataFile.setEnabled(False)
# Set up the layout # Set up the layout
@ -249,6 +251,7 @@ class MyWindow(QMainWindow):
self.LoadFileToTextBox(self.DWBAFileName) self.LoadFileToTextBox(self.DWBAFileName)
self.SaveLastOpenDWBASource() self.SaveLastOpenDWBASource()
self.bnSaveExpDataFile.setEnabled(False) self.bnSaveExpDataFile.setEnabled(False)
self.bnSaveFile.setEnabled(True)
def OpenExpDataFile(self): def OpenExpDataFile(self):
file_path, _ = QFileDialog.getOpenFileName(self, "Open File", "", "Text File (*.txt)") file_path, _ = QFileDialog.getOpenFileName(self, "Open File", "", "Text File (*.txt)")
@ -257,13 +260,19 @@ class MyWindow(QMainWindow):
self.leExpDataFileName.setText(self.ExpDataFileName) self.leExpDataFileName.setText(self.ExpDataFileName)
self.LoadFileToTextBox(self.ExpDataFileName) self.LoadFileToTextBox(self.ExpDataFileName)
self.bnSaveExpDataFile.setEnabled(True) self.bnSaveExpDataFile.setEnabled(True)
self.bnSaveFile.setEnabled(False)
self.SaveLastOpenDWBASource() self.SaveLastOpenDWBASource()
def LoadExpDataToTextBox(self): def LoadExpDataToTextBox(self):
self.LoadFileToTextBox(self.ExpDataFileName) self.LoadFileToTextBox(self.ExpDataFileName)
self.leFileName.setText(self.DWBAFileName)
self.bnSaveExpDataFile.setEnabled(True) self.bnSaveExpDataFile.setEnabled(True)
self.bnSaveFile.setEnabled(False)
def LoadFileToTextBox(self, fileName, moveToButton = False):
self.bnSaveExpDataFile.setEnabled(False)
self.bnSaveFile.setEnabled(True)
def LoadFileToTextBox(self, fileName, moveToButton = False):
# print(fileName) # print(fileName)
try: try:
with open(fileName, 'r') as file: with open(fileName, 'r') as file:
@ -281,19 +290,19 @@ class MyWindow(QMainWindow):
self.text_edit.setText(f"Failed to load file:\n{e}") self.text_edit.setText(f"Failed to load file:\n{e}")
self.leStatus.setText(f"Failed to load file:\n{e}") self.leStatus.setText(f"Failed to load file:\n{e}")
self.bnSaveExpDataFile.setEnabled(False)
def SaveFile(self): def SaveFile(self):
file_path = self.leFileName.text() if self.bnSaveFile.isEnabled() :
with open(file_path, 'w') as file: file_path = self.leFileName.text()
file.write(self.text_edit.toPlainText()) with open(file_path, 'w') as file:
self.leStatus.setText(f"File saved to: {file_path}") file.write(self.text_edit.toPlainText())
self.leStatus.setText(f"File saved to: {file_path}")
def SaveExpDataFile(self): def SaveExpDataFile(self):
file_path = self.leExpDataFileName.text() if self.bnSaveExpDataFile.isEnabled() :
with open(file_path, 'w') as file: file_path = self.leExpDataFileName.text()
file.write(self.text_edit.toPlainText()) with open(file_path, 'w') as file:
self.leStatus.setText(f"File saved to: {file_path}") file.write(self.text_edit.toPlainText())
self.leStatus.setText(f"File saved to: {file_path}")
def DeleteinOutXsecFiles(self): def DeleteinOutXsecFiles(self):
if os.path.exists(self.DWBAFileName + ".in"): if os.path.exists(self.DWBAFileName + ".in"):
@ -365,9 +374,17 @@ class MyWindow(QMainWindow):
self.Ex_window.show() self.Ex_window.show()
def fitData(self): def fitData(self):
self.SaveExpDataFile()
self.fitCanvas = []
self.fitting.read_expData(self.ExpDataFileName) self.fitting.read_expData(self.ExpDataFileName)
self.fitting.read_data(self.DWBAFileName + ".Xsec.txt") self.fitting.read_data(self.DWBAFileName + ".Xsec.txt")
self.fitting.FitData() figures = self.fitting.FitData()
if figures:
for p, fig in enumerate(figures):
self.fitCanvas.append(FitPlotWidget(fig))
self.fitCanvas[-1].show()
def closeEvent(self, event): def closeEvent(self, event):
if self.plot_window: if self.plot_window:
@ -375,6 +392,9 @@ class MyWindow(QMainWindow):
if self.Ex_window: if self.Ex_window:
self.Ex_window.close() # Close the PlotWindow when MainWindow closes self.Ex_window.close() # Close the PlotWindow when MainWindow closes
self.Ex_window.__del__() self.Ex_window.__del__()
if self.fitCanvas :
for x in self.fitCanvas:
x.close()
print("============== Bye Bye ========== ") print("============== Bye Bye ========== ")
event.accept() # Accept the event to proceed with closing the main window event.accept() # Accept the event to proceed with closing the main window