431 lines
15 KiB
Python
Executable File
431 lines
15 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
import os
|
|
import platform
|
|
import subprocess
|
|
import sys
|
|
from PyQt6.QtWidgets import (
|
|
QApplication, QMainWindow, QGridLayout, QPushButton,
|
|
QComboBox, QWidget, QLabel, QLineEdit, QCheckBox,
|
|
QFileDialog, QGroupBox, QVBoxLayout, QSpinBox, QDoubleSpinBox
|
|
)
|
|
from PyQt6.QtCore import Qt
|
|
|
|
sys.path.append(os.path.join(os.path.dirname(__file__), '../Cleopatra'))
|
|
|
|
from CustomTextEdit import CustomTextEdit
|
|
from ExtractXsecPy import extract_xsec
|
|
from ExWindow import ExWindow
|
|
from MatPlotLibWindow import MatPlotLibWindow
|
|
from FitExData import Fitting, FitPlotWidget
|
|
|
|
################################################## MainWindow
|
|
class MyWindow(QMainWindow):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
self.setWindowTitle("Ptolemy GUI")
|
|
self.resize(1000, 800)
|
|
self.setMinimumSize(1000, 800)
|
|
|
|
self.lastDWBARecord = "lastDWBA.txt"
|
|
self.DWBAFileName = ""
|
|
self.ExpDataFileName = ""
|
|
self.LoadLastOpenDWBASource()
|
|
self.bashResult = ""
|
|
self.plot_window = MatPlotLibWindow()
|
|
self.Ex_window = ExWindow()
|
|
self.fitting = Fitting()
|
|
self.fitCanvas = []
|
|
|
|
# Set up Group Box for DWBA Control
|
|
self.gbDWBA = QGroupBox("DWBA")
|
|
group_layout = QGridLayout()
|
|
group_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
|
self.gbDWBA.setLayout(group_layout)
|
|
|
|
self.bnOpenDWBA = QPushButton("Open DWBA")
|
|
self.bnOpenDWBA.clicked.connect(lambda: self.LoadFileToTextBox(self.DWBAFileName, True))
|
|
self.bnOpenInFile = QPushButton("Open *.in File")
|
|
self.bnOpenInFile.clicked.connect(lambda: self.LoadFileToTextBox(self.DWBAFileName + ".in"))
|
|
self.bnOpenOutFile = QPushButton("Open *.out File")
|
|
self.bnOpenOutFile.clicked.connect(lambda: self.LoadFileToTextBox(self.DWBAFileName + ".out"))
|
|
self.bnOpenXsecFile = QPushButton("Open X-sec File")
|
|
self.bnOpenXsecFile.clicked.connect(lambda: self.LoadFileToTextBox(self.DWBAFileName + ".Xsec.txt"))
|
|
|
|
self.bnDeleteFiles = QPushButton("Delete in/out/Xsec files")
|
|
self.bnDeleteFiles.clicked.connect(self.DeleteinOutXsecFiles)
|
|
|
|
lbAngMin = QLabel("angMin :")
|
|
lbAngMin.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignCenter)
|
|
lbAngMax = QLabel("angMax :")
|
|
lbAngMax.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignCenter)
|
|
lbAngSize = QLabel("angSize :")
|
|
lbAngSize.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignCenter)
|
|
self.sbAngMin = QSpinBox()
|
|
self.sbAngMin.setValue(0)
|
|
self.sbAngMin.setMinimum(0)
|
|
self.sbAngMin.setMaximum(180)
|
|
self.sbAngMax = QSpinBox()
|
|
self.sbAngMax.setValue(60)
|
|
self.sbAngMax.setMinimum(0)
|
|
self.sbAngMax.setMaximum(180)
|
|
self.sbAngSize = QDoubleSpinBox()
|
|
self.sbAngSize.setValue(0.2)
|
|
self.sbAngSize.setMinimum(0.1)
|
|
self.sbAngSize.setMaximum(10)
|
|
self.sbAngSize.setSingleStep(0.5)
|
|
|
|
self.chkCreateInFile = QCheckBox("Create InFile")
|
|
self.chkCreateInFile.setChecked(True)
|
|
self.chkRunPtolemy = QCheckBox("Run Ptolemy")
|
|
self.chkRunPtolemy.setChecked(True)
|
|
self.chkExtracrXsec = QCheckBox("Extract Xsec")
|
|
self.chkExtracrXsec.setChecked(True)
|
|
self.chkExtracrXsec.stateChanged.connect(self.OnOffXsecOption)
|
|
|
|
self.cbXsec = QComboBox()
|
|
self.cbXsec.addItem("XSec")
|
|
self.cbXsec.addItem("Ratio to Ruth.")
|
|
self.cbXsec.addItem("Ruth.")
|
|
|
|
self.chkPlot = QCheckBox("Plot")
|
|
self.chkPlot.setChecked(True)
|
|
|
|
self.bnCalDWBA = QPushButton("Calculate DWBA")
|
|
self.bnCalDWBA.setFixedHeight(50)
|
|
self.bnCalDWBA.clicked.connect(self.CalDWBA)
|
|
|
|
group_layout.addWidget(self.bnOpenDWBA, 0, 0, 1, 2)
|
|
group_layout.addWidget(self.bnOpenInFile, 1, 0, 1, 2)
|
|
group_layout.addWidget(self.bnOpenOutFile, 2, 0, 1, 2)
|
|
group_layout.addWidget(self.bnOpenXsecFile, 3, 0, 1, 2)
|
|
group_layout.addWidget(self.bnDeleteFiles, 4, 0, 1, 2)
|
|
|
|
group_layout.addWidget(lbAngMin, 5, 0)
|
|
group_layout.addWidget(self.sbAngMin, 5, 1)
|
|
group_layout.addWidget(lbAngMax, 6, 0)
|
|
group_layout.addWidget(self.sbAngMax, 6, 1)
|
|
group_layout.addWidget(lbAngSize, 7, 0)
|
|
group_layout.addWidget(self.sbAngSize, 7, 1)
|
|
|
|
group_layout.addWidget(self.chkCreateInFile, 8, 0, 1, 2)
|
|
group_layout.addWidget(self.chkRunPtolemy, 9, 0, 1, 2)
|
|
group_layout.addWidget(self.chkExtracrXsec, 10, 0, 1, 2)
|
|
|
|
group_layout.addWidget(self.cbXsec, 11, 0, 1, 2)
|
|
group_layout.addWidget(self.chkPlot, 12, 0, 1, 2)
|
|
|
|
group_layout.addWidget(self.bnCalDWBA, 13, 0, 1, 2)
|
|
|
|
# Ex Group
|
|
self.gbEx = QGroupBox("Ex")
|
|
Ex_layout = QGridLayout()
|
|
Ex_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
|
|
self.gbEx.setLayout(Ex_layout)
|
|
|
|
lbName = QLabel("Isotop :")
|
|
lbName.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignCenter)
|
|
|
|
self.leName = QLineEdit()
|
|
self.leName.setText("12C")
|
|
|
|
lbMaxEx = QLabel("Max Ex [MeV]:")
|
|
lbMaxEx.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignCenter)
|
|
|
|
self.sbMaXEx = QDoubleSpinBox()
|
|
self.sbMaXEx.setMinimum(0)
|
|
self.sbMaXEx.setMaximum(20)
|
|
self.sbMaXEx.setDecimals(1)
|
|
self.sbMaXEx.setValue(10)
|
|
|
|
buEx = QPushButton("Get And Plot Ex")
|
|
buEx.setFixedHeight(40)
|
|
buEx.clicked.connect(self.open_Ex_window)
|
|
|
|
Ex_layout.addWidget(lbName, 0, 0)
|
|
Ex_layout.addWidget(self.leName, 0, 1)
|
|
Ex_layout.addWidget(lbMaxEx, 1, 0)
|
|
Ex_layout.addWidget(self.sbMaXEx, 1, 1)
|
|
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
|
|
|
|
self.bnOpenDWBASource = QPushButton("Open DWBA Source")
|
|
self.bnOpenDWBASource.clicked.connect(self.OpenDWBASourceFile)
|
|
|
|
self.leFileName = QLineEdit("")
|
|
self.leFileName.setReadOnly(True)
|
|
self.leFileName.setText(self.DWBAFileName)
|
|
|
|
self.bnSaveFile = QPushButton("Save File")
|
|
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.leStatus = QLineEdit("")
|
|
self.leStatus.setReadOnly(True)
|
|
|
|
self.LoadFileToTextBox(self.DWBAFileName, True)
|
|
|
|
self.bnSaveFile.setEnabled(True)
|
|
self.bnSaveExpDataFile.setEnabled(False)
|
|
|
|
# Set up the layout
|
|
layout = QGridLayout()
|
|
# layout.addWidget(self.gbDWBA, 0, 0, 7, 1)
|
|
layout.addWidget(self.gbDWBA, 0, 0, 5, 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.leFileName, 0, 2, 1, 3)
|
|
layout.addWidget(self.bnSaveFile, 0, 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()) :
|
|
layout.setColumnStretch(i, 1)
|
|
|
|
# Set up the container and layout
|
|
container = QWidget()
|
|
container.setLayout(layout)
|
|
self.setCentralWidget(container)
|
|
|
|
self.text_edit.setFocus()
|
|
|
|
####################################### methods
|
|
def LoadLastOpenDWBASource(self):
|
|
try :
|
|
with open(self.lastDWBARecord, 'r') as file:
|
|
self.DWBAFileName = file.readline().strip()
|
|
self.ExpDataFileName = file.readline().strip()
|
|
except:
|
|
self.DWBAFileName = "DWBA"
|
|
self.ExpDataFileName = ""
|
|
|
|
def SaveLastOpenDWBASource(self):
|
|
with open(self.lastDWBARecord, 'w') as file:
|
|
file.write(self.DWBAFileName)
|
|
file.write("\n")
|
|
file.write(self.ExpDataFileName)
|
|
|
|
def OnOffXsecOption(self):
|
|
self.cbXsec.setEnabled(self.chkExtracrXsec.isChecked())
|
|
|
|
def OpenDWBASourceFile(self):
|
|
file_path, _ = QFileDialog.getOpenFileName(self, "Open File", "", "All Files (*)")
|
|
if file_path:
|
|
self.DWBAFileName = file_path
|
|
self.leFileName.setText(self.DWBAFileName)
|
|
self.LoadFileToTextBox(self.DWBAFileName)
|
|
self.SaveLastOpenDWBASource()
|
|
self.bnSaveExpDataFile.setEnabled(False)
|
|
self.bnSaveFile.setEnabled(True)
|
|
|
|
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.bnSaveFile.setEnabled(False)
|
|
self.SaveLastOpenDWBASource()
|
|
|
|
def LoadExpDataToTextBox(self):
|
|
if self.ExpDataFileName == "" :
|
|
self.text_edit.clear()
|
|
self.text_edit.append("$<-- for comment line")
|
|
self.text_edit.append("$No expData found, this is a template")
|
|
self.text_edit.append("$line start with '#=' starts a data set")
|
|
self.text_edit.append("#============== state")
|
|
self.text_edit.append("$line started with 'fit' indicate which DWBA Xsec to be fitted. ")
|
|
self.text_edit.append("$0 for the fist one, 0+1 fit both 0 and 1.")
|
|
self.text_edit.append("fit 0, 0+1")
|
|
self.text_edit.append("$angle_deg ang_err count count_err")
|
|
self.text_edit.append("10 1 100 10")
|
|
self.text_edit.append("20 1 200 14")
|
|
self.text_edit.append("30 1 80 7")
|
|
else:
|
|
self.LoadFileToTextBox(self.ExpDataFileName)
|
|
self.leFileName.setText(self.DWBAFileName)
|
|
|
|
self.bnSaveExpDataFile.setEnabled(True)
|
|
self.bnSaveFile.setEnabled(False)
|
|
|
|
def LoadFileToTextBox(self, fileName, moveToButton = False):
|
|
self.bnSaveExpDataFile.setEnabled(False)
|
|
self.bnSaveFile.setEnabled(True)
|
|
|
|
# print(fileName)
|
|
try:
|
|
with open(fileName, 'r') as file:
|
|
content = file.read()
|
|
self.text_edit.setText(content)
|
|
if moveToButton :
|
|
cursor = self.text_edit.textCursor()
|
|
cursor.movePosition(cursor.MoveOperation.End)
|
|
cursor.movePosition(cursor.MoveOperation.StartOfBlock)
|
|
self.text_edit.setTextCursor(cursor)
|
|
|
|
self.leStatus.setText(f"Loaded file : {fileName}")
|
|
self.leFileName.setText(fileName)
|
|
except Exception as e:
|
|
self.text_edit.setText(f"Failed to load file:\n{e}")
|
|
self.leStatus.setText(f"Failed to load file:\n{e}")
|
|
|
|
def SaveFile(self):
|
|
if self.bnSaveFile.isEnabled() :
|
|
file_path = self.leFileName.text()
|
|
with open(file_path, 'w') as file:
|
|
file.write(self.text_edit.toPlainText())
|
|
self.leStatus.setText(f"File saved to: {file_path}")
|
|
|
|
def SaveExpDataFile(self):
|
|
if self.bnSaveExpDataFile.isEnabled() :
|
|
file_path = self.leExpDataFileName.text()
|
|
if file_path == "" :
|
|
file_path, _ = QFileDialog.getSaveFileName(self, "Save File", "", "Text Files (*.txt)")
|
|
if not file_path.lower().endswith(".txt"):
|
|
file_path += ".txt"
|
|
self.leExpDataFileName.setText(file_path)
|
|
self.ExpDataFileName = file_path
|
|
|
|
with open(file_path, 'w') as file:
|
|
file.write(self.text_edit.toPlainText())
|
|
self.leStatus.setText(f"File saved to: {file_path}")
|
|
|
|
self.SaveLastOpenDWBASource()
|
|
|
|
def DeleteinOutXsecFiles(self):
|
|
if os.path.exists(self.DWBAFileName + ".in"):
|
|
os.remove(self.DWBAFileName + ".in")
|
|
if os.path.exists(self.DWBAFileName + ".out"):
|
|
os.remove(self.DWBAFileName + ".out")
|
|
if os.path.exists(self.DWBAFileName + ".Xsec.txt"):
|
|
os.remove(self.DWBAFileName + ".Xsec.txt")
|
|
self.leStatus.setText("Deleted " + self.DWBAFileName + ".in/.out/.Xsec.txt files")
|
|
|
|
def BashCommand(self, cmd):
|
|
print("Bash Command : |" + cmd + "|")
|
|
self.bashResult = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
|
|
|
print("Output:", self.bashResult.stdout)
|
|
print("Error:", self.bashResult.stderr)
|
|
print("Return Code:", self.bashResult.returncode)
|
|
|
|
def file_exists(self,file_path):
|
|
return os.path.exists(file_path) and os.path.isfile(file_path)
|
|
|
|
def CalDWBA(self):
|
|
|
|
self.SaveFile()
|
|
|
|
self.BashCommand("cd ../Cleopatra; make;cd ../PyGUIQt6")
|
|
|
|
print(" Is Create InFile : " + str(self.chkCreateInFile.isChecked() ))
|
|
print(" Is Run Ptolemy : " + str(self.chkRunPtolemy.isChecked() ))
|
|
print(" Is Extract XSec : " + str(self.chkExtracrXsec.isChecked() ))
|
|
print(" Is Plot : " + str(self.chkPlot.isChecked() ))
|
|
|
|
if self.chkCreateInFile.isChecked() :
|
|
aMin = " " + str(self.sbAngMin.value())
|
|
aMax = " " + str(self.sbAngMax.value())
|
|
aSize = " " + str(self.sbAngSize.value())
|
|
|
|
self.BashCommand("../Cleopatra/InFileCreator " + self.DWBAFileName + aMin + aMax + aSize)
|
|
|
|
isRunOK = True
|
|
if self.chkRunPtolemy.isChecked() :
|
|
os_name = platform.system()
|
|
|
|
if os_name == "Linux" :
|
|
self.BashCommand("../Cleopatra/ptolemy <" + self.DWBAFileName + ".in>" + " " + self.DWBAFileName + ".out")
|
|
|
|
if os_name == "Darwin":
|
|
self.BashCommand("../Cleopatra/ptolemy_mac <" + self.DWBAFileName + ".in>" + " " + self.DWBAFileName + ".out")
|
|
|
|
if self.bashResult.returncode != 0 :
|
|
isRunOK = False
|
|
self.leStatus.setText("Ptolemy Run Error. Should check the out File.")
|
|
|
|
if isRunOK and self.chkExtracrXsec.isChecked() and self.file_exists(self.DWBAFileName + ".out") :
|
|
extract_xsec(self.DWBAFileName + ".out", self.cbXsec.currentIndex())
|
|
|
|
if isRunOK and self.chkPlot.isChecked() and self.file_exists(self.DWBAFileName + ".Xsec.txt") :
|
|
self.open_plot_window()
|
|
|
|
def open_plot_window(self):
|
|
self.plot_window.read_data(self.DWBAFileName + ".Xsec.txt")
|
|
self.plot_window.plot_matplotlib_graph()
|
|
self.plot_window.show()
|
|
|
|
def open_Ex_window(self):
|
|
self.Ex_window.GetEx(self.leName.text(), self.sbMaXEx.value())
|
|
if self.sbMaXEx.value() > 0 :
|
|
self.Ex_window.plot_Ex_graph()
|
|
self.Ex_window.show()
|
|
|
|
def fitData(self):
|
|
self.SaveExpDataFile()
|
|
|
|
self.fitCanvas = []
|
|
self.fitting.read_expData(self.ExpDataFileName)
|
|
self.fitting.read_data(self.DWBAFileName + ".Xsec.txt")
|
|
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):
|
|
if self.plot_window:
|
|
self.plot_window.close() # Close the PlotWindow when MainWindow closes
|
|
if self.Ex_window:
|
|
self.Ex_window.close() # Close the PlotWindow when MainWindow closes
|
|
self.Ex_window.__del__()
|
|
if self.fitCanvas :
|
|
for x in self.fitCanvas:
|
|
x.close()
|
|
print("============== Bye Bye ========== ")
|
|
event.accept() # Accept the event to proceed with closing the main window
|
|
|
|
|
|
################################################## Main
|
|
if __name__ == "__main__":
|
|
app = QApplication(sys.argv)
|
|
window = MyWindow()
|
|
window.show()
|
|
sys.exit(app.exec()) |