Add FitData.py, modified python GUI for fitting. work but not perfect
This commit is contained in:
parent
3a41e13fdf
commit
f1b2d4a580
|
@ -9,17 +9,27 @@ class PythonHighlighter(QSyntaxHighlighter):
|
||||||
super().__init__(document)
|
super().__init__(document)
|
||||||
|
|
||||||
# Define formatting for comments
|
# Define formatting for comments
|
||||||
self.comment_format = QTextCharFormat()
|
self.comment_format1 = QTextCharFormat()
|
||||||
self.comment_format.setForeground(Qt.GlobalColor.darkGreen)
|
self.comment_format1.setForeground(Qt.GlobalColor.darkGreen)
|
||||||
|
|
||||||
|
self.comment_format2 = QTextCharFormat()
|
||||||
|
self.comment_format2.setForeground(Qt.GlobalColor.blue)
|
||||||
|
self.comment_format2.setBackground(Qt.GlobalColor.yellow)
|
||||||
|
|
||||||
|
self.comment_format3 = QTextCharFormat()
|
||||||
|
self.comment_format3.setForeground(Qt.GlobalColor.magenta)
|
||||||
|
|
||||||
def highlightBlock(self, text):
|
def highlightBlock(self, text):
|
||||||
# Highlight comments
|
if text.startswith("#") and text.startswith("#=") == False:
|
||||||
if text.startswith("#"):
|
self.setFormat(0, len(text), self.comment_format1)
|
||||||
self.setFormat(0, len(text), self.comment_format)
|
|
||||||
if text.startswith("$"):
|
if text.startswith("$"):
|
||||||
self.setFormat(0, len(text), self.comment_format)
|
self.setFormat(0, len(text), self.comment_format1)
|
||||||
if text.startswith("0"):
|
if text.startswith("0"):
|
||||||
self.setFormat(0, len(text), self.comment_format)
|
self.setFormat(0, len(text), self.comment_format1)
|
||||||
|
if text.startswith("fit"):
|
||||||
|
self.setFormat(0, len(text), self.comment_format2)
|
||||||
|
if text.startswith("#="):
|
||||||
|
self.setFormat(0, len(text), self.comment_format3)
|
||||||
|
|
||||||
class CustomTextEdit(QTextEdit):
|
class CustomTextEdit(QTextEdit):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
|
@ -35,9 +45,8 @@ class CustomTextEdit(QTextEdit):
|
||||||
# Check if Ctrl+D is pressed
|
# Check if Ctrl+D is pressed
|
||||||
if event.key() == Qt.Key.Key_D and event.modifiers() == Qt.KeyboardModifier.ControlModifier:
|
if event.key() == Qt.Key.Key_D and event.modifiers() == Qt.KeyboardModifier.ControlModifier:
|
||||||
self.duplicate_line()
|
self.duplicate_line()
|
||||||
event.accept() # Prevent the default behavior of Ctrl+D
|
|
||||||
else:
|
else:
|
||||||
super().keyPressEvent(event) # Call the base class to handle other keys
|
super().keyPressEvent(event) # Call the base class to handle other keys
|
||||||
|
|
||||||
def duplicate_line(self):
|
def duplicate_line(self):
|
||||||
cursor = self.textCursor()
|
cursor = self.textCursor()
|
||||||
|
|
178
Cleopatra/FitExData.py
Normal file
178
Cleopatra/FitExData.py
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from scipy.optimize import curve_fit
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
from ExtractXsecPy import read_DWBA
|
||||||
|
|
||||||
|
class Fitting:
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
self.ExList = []
|
||||||
|
self.fitOption = []
|
||||||
|
self.expData = []
|
||||||
|
|
||||||
|
self.dataX = []
|
||||||
|
self.data = [] # is a 2D array
|
||||||
|
self.headers = []
|
||||||
|
|
||||||
|
def read_data(self,file_path):
|
||||||
|
self.headers, self.dataX, self.data = read_DWBA(file_path)
|
||||||
|
|
||||||
|
print(self.headers)
|
||||||
|
|
||||||
|
def read_expData(self, fileName):
|
||||||
|
self.ExList = []
|
||||||
|
self.fitOption = []
|
||||||
|
self.expData = []
|
||||||
|
|
||||||
|
current_data = []
|
||||||
|
|
||||||
|
with open(fileName, "r") as file:
|
||||||
|
for line in file:
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check for excitation energy lines
|
||||||
|
if line.startswith("#======================"):
|
||||||
|
# If there's an existing data block, save it
|
||||||
|
if current_data:
|
||||||
|
self.expData.append(np.array(current_data, dtype=float))
|
||||||
|
current_data = []
|
||||||
|
|
||||||
|
# Extract excitation energy
|
||||||
|
Ex_energy = line.split()[1]
|
||||||
|
self.ExList.append(float(Ex_energy))
|
||||||
|
|
||||||
|
# Check for fit option lines
|
||||||
|
elif line.startswith("fit"):
|
||||||
|
# Add fit option parameters
|
||||||
|
fit_params = [x.strip(',') for x in line.split()[1:]]
|
||||||
|
self.fitOption.append(fit_params)
|
||||||
|
|
||||||
|
# Parse data lines
|
||||||
|
elif not line.startswith("#"):
|
||||||
|
values = [float(x) for x in line.split()]
|
||||||
|
current_data.append(values)
|
||||||
|
|
||||||
|
# Append the last block
|
||||||
|
if current_data:
|
||||||
|
self.expData.append(np.array(current_data, dtype=float))
|
||||||
|
|
||||||
|
# Convert to numpy arrays
|
||||||
|
self.ExList = np.array(self.ExList)
|
||||||
|
self.expData = [np.array(data) for data in self.expData]
|
||||||
|
|
||||||
|
# Output the result
|
||||||
|
print("=========== Number of data set:", len(self.ExList))
|
||||||
|
for i in range(0, len(self.ExList)):
|
||||||
|
print("-------------------------")
|
||||||
|
print(" ExList:", self.ExList[i])
|
||||||
|
print("Fit Options:", self.fitOption[i])
|
||||||
|
print(" Data List:\n", self.expData[i])
|
||||||
|
|
||||||
|
|
||||||
|
def FitData(self):
|
||||||
|
|
||||||
|
# Set initial offset values
|
||||||
|
x_offset, y_offset = 2000, 100
|
||||||
|
|
||||||
|
figure = []
|
||||||
|
|
||||||
|
for expDataID in range(len(self.expData)):
|
||||||
|
# Get the number of fit options and cross-sections
|
||||||
|
nFit = len(self.fitOption[expDataID])
|
||||||
|
nXsec = len(self.data)
|
||||||
|
|
||||||
|
# Extract experimental data (x, y, and errors)
|
||||||
|
x_exp = self.expData[expDataID][:, 0] # x positions
|
||||||
|
x_err = self.expData[expDataID][:, 1] # x uncertainties (errors)
|
||||||
|
y_exp = self.expData[expDataID][:, 2] # y positions
|
||||||
|
y_err = self.expData[expDataID][:, 3] # y errors
|
||||||
|
|
||||||
|
fitTheory = []
|
||||||
|
fitTheory_lower = []
|
||||||
|
fitTheory_upper = []
|
||||||
|
|
||||||
|
for k in range(nFit):
|
||||||
|
# Get the cross-section IDs for the current fit option and strip extra spaces
|
||||||
|
xsecIDStr = self.fitOption[expDataID][k].strip()
|
||||||
|
xsecID = [int(part.strip()) for part in xsecIDStr.split('+')] if '+' in xsecIDStr else [int(xsecIDStr)]
|
||||||
|
|
||||||
|
# Ensure all cross-section IDs are valid
|
||||||
|
processFlag = True
|
||||||
|
for id in range(len(xsecID)):
|
||||||
|
if xsecID[id] >= nXsec:
|
||||||
|
print(f"Error: Requested Xsec-{xsecID[id]} exceeds the number of available cross-sections ({nXsec})")
|
||||||
|
processFlag = False
|
||||||
|
|
||||||
|
if processFlag == False :
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Define the fitting function: a weighted sum of the selected data
|
||||||
|
def fit_func(x, *scale):
|
||||||
|
y = np.zeros_like(x)
|
||||||
|
for p, id in enumerate(xsecID):
|
||||||
|
y += scale[p] * np.interp(x, self.dataX, self.data[id])
|
||||||
|
return y
|
||||||
|
|
||||||
|
|
||||||
|
lower_bounds = [1e-6] * len(xsecID) # Setting a small positive lower bound
|
||||||
|
upper_bounds = [np.inf] * len(xsecID) # No upper bound
|
||||||
|
|
||||||
|
# Perform curve fitting using the fit_func and experimental data with y-errors as weights
|
||||||
|
popt, pcov = curve_fit(fit_func, x_exp, y_exp, sigma=y_err, absolute_sigma=True,
|
||||||
|
p0=np.ones(len(xsecID)), # Initial guess for scale parameters
|
||||||
|
bounds=(lower_bounds, upper_bounds))
|
||||||
|
|
||||||
|
perr = np.sqrt(np.diag(pcov)) # Standard deviation of the parameters
|
||||||
|
print(f"Fitted scale for fit {k+1}: {popt} +/- {perr}")
|
||||||
|
|
||||||
|
# Append the theoretical fit for this fit option
|
||||||
|
fitTheory.append(np.zeros_like(self.dataX))
|
||||||
|
for p, id in enumerate(xsecID):
|
||||||
|
fitTheory[k] += popt[p] * np.interp(self.dataX, self.dataX, self.data[id])
|
||||||
|
|
||||||
|
# Optionally, you can plot the uncertainty as shaded regions (confidence intervals)
|
||||||
|
# Create the upper and lower bounds of the theoretical model with uncertainties
|
||||||
|
fitTheory_upper.append(np.zeros_like(self.dataX))
|
||||||
|
fitTheory_lower.append(np.zeros_like(self.dataX))
|
||||||
|
|
||||||
|
for p, id in enumerate(xsecID):
|
||||||
|
fitTheory_upper[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()
|
||||||
|
figure.append(fig)
|
||||||
|
|
||||||
|
# Plot results
|
||||||
|
plt.errorbar(x_exp, y_exp, xerr=x_err, yerr=y_err, fmt='o', label='Experimental Data', color='blue')
|
||||||
|
|
||||||
|
# Plot all fit theories
|
||||||
|
for i, fit in enumerate(fitTheory):
|
||||||
|
plt.plot(self.dataX, fit, label=f'Xsec:{self.fitOption[expDataID][i]} Fit')
|
||||||
|
plt.fill_between(self.dataX, fitTheory_lower[i], fitTheory_upper[i], alpha=0.2)
|
||||||
|
|
||||||
|
# Customize plot
|
||||||
|
plt.xlabel('Angle_CM [deg]')
|
||||||
|
plt.ylabel('X-Sec [a.u.]')
|
||||||
|
plt.legend()
|
||||||
|
plt.autoscale(enable=True, axis='x', tight=True)
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.yscale('log')
|
||||||
|
|
||||||
|
# Replace plt.title() with plt.text() to position the title inside the plot
|
||||||
|
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')
|
||||||
|
|
||||||
|
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()
|
|
@ -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
|
||||||
|
|
||||||
################################################## MainWindow
|
################################################## MainWindow
|
||||||
class MyWindow(QMainWindow):
|
class MyWindow(QMainWindow):
|
||||||
|
@ -25,15 +25,17 @@ class MyWindow(QMainWindow):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.setWindowTitle("Ptolemy GUI")
|
self.setWindowTitle("Ptolemy GUI")
|
||||||
self.setGeometry(100, 100, 1000, 700)
|
self.setGeometry(100, 100, 1000, 800)
|
||||||
self.setMinimumSize(400, 600)
|
self.setMinimumSize(1000, 800)
|
||||||
|
|
||||||
self.lastDWBARecord = "lastDWBA.txt"
|
self.lastDWBARecord = "lastDWBA.txt"
|
||||||
self.DWBAFileName = ""
|
self.DWBAFileName = ""
|
||||||
|
self.ExpDataFileName = ""
|
||||||
self.LoadLastOpenDWBASource()
|
self.LoadLastOpenDWBASource()
|
||||||
self.bashResult = ""
|
self.bashResult = ""
|
||||||
self.plot_window = MatPlotLibWindow()
|
self.plot_window = MatPlotLibWindow()
|
||||||
self.Ex_window = ExWindow()
|
self.Ex_window = ExWindow()
|
||||||
|
self.fitting = Fitting()
|
||||||
|
|
||||||
# Set up Group Box for DWBA Control
|
# Set up Group Box for DWBA Control
|
||||||
self.gbDWBA = QGroupBox("DWBA")
|
self.gbDWBA = QGroupBox("DWBA")
|
||||||
|
@ -146,6 +148,21 @@ class MyWindow(QMainWindow):
|
||||||
Ex_layout.addWidget(self.sbMaXEx, 1, 1)
|
Ex_layout.addWidget(self.sbMaXEx, 1, 1)
|
||||||
Ex_layout.addWidget(buEx, 2, 0, 1, 2)
|
Ex_layout.addWidget(buEx, 2, 0, 1, 2)
|
||||||
|
|
||||||
|
# ExpData Group
|
||||||
|
self.gbExpFit = QGroupBox("Exp Data Fit")
|
||||||
|
fit_layout = QVBoxLayout()
|
||||||
|
fit_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
||||||
|
self.gbExpFit.setLayout(fit_layout)
|
||||||
|
|
||||||
|
bnOpenExpData = QPushButton("Open ExpData")
|
||||||
|
bnOpenExpData.clicked.connect(self.LoadExpDataToTextBox)
|
||||||
|
|
||||||
|
bnFit = QPushButton("Fit")
|
||||||
|
bnFit.clicked.connect(self.fitData)
|
||||||
|
|
||||||
|
fit_layout.addWidget(bnOpenExpData)
|
||||||
|
fit_layout.addWidget(bnFit)
|
||||||
|
|
||||||
# Set up the Right Side
|
# Set up the Right Side
|
||||||
|
|
||||||
self.bnOpenDWBASource = QPushButton("Open DWBA Source")
|
self.bnOpenDWBASource = QPushButton("Open DWBA Source")
|
||||||
|
@ -158,6 +175,16 @@ class MyWindow(QMainWindow):
|
||||||
self.bnSaveFile = QPushButton("Save File")
|
self.bnSaveFile = QPushButton("Save File")
|
||||||
self.bnSaveFile.clicked.connect(self.SaveFile)
|
self.bnSaveFile.clicked.connect(self.SaveFile)
|
||||||
|
|
||||||
|
self.bnOpenExpData = QPushButton("Open Exp Data")
|
||||||
|
self.bnOpenExpData.clicked.connect(self.OpenExpDataFile)
|
||||||
|
|
||||||
|
self.leExpDataFileName = QLineEdit("")
|
||||||
|
self.leExpDataFileName.setReadOnly(True)
|
||||||
|
self.leExpDataFileName.setText(self.ExpDataFileName)
|
||||||
|
|
||||||
|
self.bnSaveExpDataFile = QPushButton("Save Exp Data File")
|
||||||
|
self.bnSaveExpDataFile.clicked.connect(self.SaveExpDataFile)
|
||||||
|
|
||||||
self.text_edit = CustomTextEdit(self)
|
self.text_edit = CustomTextEdit(self)
|
||||||
|
|
||||||
self.leStatus = QLineEdit("")
|
self.leStatus = QLineEdit("")
|
||||||
|
@ -165,17 +192,25 @@ class MyWindow(QMainWindow):
|
||||||
|
|
||||||
self.LoadFileToTextBox(self.DWBAFileName, True)
|
self.LoadFileToTextBox(self.DWBAFileName, True)
|
||||||
|
|
||||||
|
self.bnSaveExpDataFile.setEnabled(False)
|
||||||
|
|
||||||
# Set up the layout
|
# Set up the layout
|
||||||
layout = QGridLayout()
|
layout = QGridLayout()
|
||||||
# layout.addWidget(self.gbDWBA, 0, 0, 7, 1)
|
# layout.addWidget(self.gbDWBA, 0, 0, 7, 1)
|
||||||
layout.addWidget(self.gbDWBA, 0, 0, 5, 1)
|
layout.addWidget(self.gbDWBA, 0, 0, 5, 1)
|
||||||
layout.addWidget(self.gbEx, 5, 0, 2, 1)
|
layout.addWidget(self.gbEx, 5, 0, 2, 1)
|
||||||
|
layout.addWidget(self.gbExpFit, 7, 0, 2, 1)
|
||||||
|
|
||||||
layout.addWidget(self.bnOpenDWBASource, 0, 1)
|
layout.addWidget(self.bnOpenDWBASource, 0, 1)
|
||||||
layout.addWidget(self.leFileName, 0, 2, 1, 3)
|
layout.addWidget(self.leFileName, 0, 2, 1, 3)
|
||||||
layout.addWidget(self.bnSaveFile, 0, 5)
|
layout.addWidget(self.bnSaveFile, 0, 5)
|
||||||
layout.addWidget(self.text_edit, 1, 1, 5, 5)
|
|
||||||
layout.addWidget(self.leStatus, 6, 1, 1, 5)
|
layout.addWidget(self.bnOpenExpData, 1, 1)
|
||||||
|
layout.addWidget(self.leExpDataFileName, 1, 2, 1, 3)
|
||||||
|
layout.addWidget(self.bnSaveExpDataFile, 1, 5)
|
||||||
|
|
||||||
|
layout.addWidget(self.text_edit, 2, 1, 6, 5)
|
||||||
|
layout.addWidget(self.leStatus, 8, 1, 1, 5)
|
||||||
|
|
||||||
for i in range(layout.columnCount()) :
|
for i in range(layout.columnCount()) :
|
||||||
layout.setColumnStretch(i, 1)
|
layout.setColumnStretch(i, 1)
|
||||||
|
@ -192,12 +227,16 @@ class MyWindow(QMainWindow):
|
||||||
try :
|
try :
|
||||||
with open(self.lastDWBARecord, 'r') as file:
|
with open(self.lastDWBARecord, 'r') as file:
|
||||||
self.DWBAFileName = file.readline().strip()
|
self.DWBAFileName = file.readline().strip()
|
||||||
|
self.ExpDataFileName = file.readline().strip()
|
||||||
except:
|
except:
|
||||||
self.DWBAFileName = "DWBA"
|
self.DWBAFileName = "DWBA"
|
||||||
|
self.ExpDataFileName = ""
|
||||||
|
|
||||||
def SaveLastOpenDWBASource(self):
|
def SaveLastOpenDWBASource(self):
|
||||||
with open(self.lastDWBARecord, 'w') as file:
|
with open(self.lastDWBARecord, 'w') as file:
|
||||||
file.write(self.DWBAFileName)
|
file.write(self.DWBAFileName)
|
||||||
|
file.write("\n")
|
||||||
|
file.write(self.ExpDataFileName)
|
||||||
|
|
||||||
def OnOffXsecOption(self):
|
def OnOffXsecOption(self):
|
||||||
self.cbXsec.setEnabled(self.chkExtracrXsec.isChecked())
|
self.cbXsec.setEnabled(self.chkExtracrXsec.isChecked())
|
||||||
|
@ -209,6 +248,20 @@ class MyWindow(QMainWindow):
|
||||||
self.leFileName.setText(self.DWBAFileName)
|
self.leFileName.setText(self.DWBAFileName)
|
||||||
self.LoadFileToTextBox(self.DWBAFileName)
|
self.LoadFileToTextBox(self.DWBAFileName)
|
||||||
self.SaveLastOpenDWBASource()
|
self.SaveLastOpenDWBASource()
|
||||||
|
self.bnSaveExpDataFile.setEnabled(False)
|
||||||
|
|
||||||
|
def OpenExpDataFile(self):
|
||||||
|
file_path, _ = QFileDialog.getOpenFileName(self, "Open File", "", "Text File (*.txt)")
|
||||||
|
if file_path:
|
||||||
|
self.ExpDataFileName = file_path
|
||||||
|
self.leExpDataFileName.setText(self.ExpDataFileName)
|
||||||
|
self.LoadFileToTextBox(self.ExpDataFileName)
|
||||||
|
self.bnSaveExpDataFile.setEnabled(True)
|
||||||
|
self.SaveLastOpenDWBASource()
|
||||||
|
|
||||||
|
def LoadExpDataToTextBox(self):
|
||||||
|
self.LoadFileToTextBox(self.ExpDataFileName)
|
||||||
|
self.bnSaveExpDataFile.setEnabled(True)
|
||||||
|
|
||||||
def LoadFileToTextBox(self, fileName, moveToButton = False):
|
def LoadFileToTextBox(self, fileName, moveToButton = False):
|
||||||
# print(fileName)
|
# print(fileName)
|
||||||
|
@ -227,12 +280,20 @@ class MyWindow(QMainWindow):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
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()
|
file_path = self.leFileName.text()
|
||||||
with open(file_path, 'w') as file:
|
with open(file_path, 'w') as file:
|
||||||
file.write(self.text_edit.toPlainText())
|
file.write(self.text_edit.toPlainText())
|
||||||
self.leStatus.setText(f"File saved to: {file_path}")
|
self.leStatus.setText(f"File saved to: {file_path}")
|
||||||
|
|
||||||
|
def SaveExpDataFile(self):
|
||||||
|
file_path = self.leExpDataFileName.text()
|
||||||
|
with open(file_path, 'w') as file:
|
||||||
|
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"):
|
||||||
|
@ -303,6 +364,10 @@ class MyWindow(QMainWindow):
|
||||||
self.Ex_window.plot_Ex_graph()
|
self.Ex_window.plot_Ex_graph()
|
||||||
self.Ex_window.show()
|
self.Ex_window.show()
|
||||||
|
|
||||||
|
def fitData(self):
|
||||||
|
self.fitting.read_expData(self.ExpDataFileName)
|
||||||
|
self.fitting.read_data(self.DWBAFileName + ".Xsec.txt")
|
||||||
|
self.fitting.FitData()
|
||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
if self.plot_window:
|
if self.plot_window:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user