188 lines
7.1 KiB
Python
188 lines
7.1 KiB
Python
import sys
|
|
import json
|
|
import webbrowser
|
|
import subprocess
|
|
from argparse import ArgumentParser
|
|
|
|
from PyQt5 import QtWidgets,QtGui
|
|
|
|
from ui.OpticsToolsGui import Ui_OpticsGUI
|
|
from plot import OpticsPlot
|
|
from model import Model
|
|
from machine import Machine
|
|
from reference import ReferenceManager
|
|
from sandbox import Sandbox
|
|
from matchmaker import MatchMaker
|
|
|
|
|
|
class OpticsTools(QtWidgets.QMainWindow, Ui_OpticsGUI):
|
|
def __init__(self,phase=0, office= 1):
|
|
super(OpticsTools, self).__init__()
|
|
self.setupUi(self)
|
|
|
|
office = office == 1
|
|
if phase > 0:
|
|
office = True
|
|
|
|
self.version = '1.1.1'
|
|
self.setWindowIcon(QtGui.QIcon("rsc/iconoptics.png"))
|
|
|
|
self.plot = OpticsPlot(parent=self)
|
|
self.plot.show()
|
|
|
|
# initialize online model
|
|
self.model = Model(phase=phase,parent=self)
|
|
|
|
# initialize modeling
|
|
self.match = MatchMaker()
|
|
self.UIMatchOpticsSelect.clear()
|
|
for key in self.match.matchlist.keys():
|
|
self.UIMatchOpticsSelect.addItem(key)
|
|
self.UIMatchOpticsSelect.setCurrentIndex(0)
|
|
self.updateMatchingCase()
|
|
|
|
|
|
self.machine = Machine(parent = True, office = office)
|
|
self.machine.initPVs(self.model.getElements())
|
|
self.sandbox = Sandbox(parent = self, machine = self.machine)
|
|
self.sandbox.updateSandbox()
|
|
self.reference = ReferenceManager(parent=self)
|
|
self.reference.initReferencePoints(self.match)
|
|
|
|
title = "SwissFEL Optics Tools - Lattice %s (Phase %d)" % (self.model.getLatticeVersion(),phase)
|
|
if office:
|
|
title += " - offline"
|
|
self.setWindowTitle(title)
|
|
|
|
|
|
# events handling
|
|
self.UIMatchOpticsSelect.currentIndexChanged.connect(self.updateMatchingCase)
|
|
self.UIMatchSelected.clicked.connect(self.doMatch)
|
|
self.actionOpen_2.triggered.connect(self.loadSettings)
|
|
self.actionSave.triggered.connect(self.saveSettings)
|
|
self.UIUpdateFromMachine.clicked.connect(self.fullUpdate)
|
|
self.actionHelp.triggered.connect(self.openGit)
|
|
self.actionAbout.triggered.connect(self.about)
|
|
self.actionOpenScriptEditor.triggered.connect(self.editMatchingScript)
|
|
|
|
|
|
def doMatch(self):
|
|
"""
|
|
match the lattice for the given matching scripts. These can be selected by the individual check boxed.
|
|
The matching is in the order: Injector -> Athos -> Porthos -> Aramis.
|
|
The online model is updated with the updated match values.
|
|
:return: None
|
|
"""
|
|
injector = self.UIMatchInjector.isChecked()
|
|
aramis = self.UIMatchAramis.isChecked()
|
|
athos = self.UIMatchAthos.isChecked()
|
|
porthos = self.UIMatchPorthos.isChecked()
|
|
twiss = self.match.match(self.model.om,Injector = injector,Athos = athos, Aramis = aramis, Porthos = porthos)
|
|
energy = self.model.calcEnergyProfile(twiss)
|
|
#enfore the writing of a new lattice so that the magnet settings are in the new lattice
|
|
self.model.forceLat = True
|
|
self.plot.newData(twiss, energy)
|
|
|
|
|
|
def updateMatchingCase(self):
|
|
"""
|
|
Update the check box for selecting the different matching steps and initial settings if reference file is present
|
|
:return: None
|
|
"""
|
|
target = self.UIMatchOpticsSelect.currentText()
|
|
self.match.initScripts(target)
|
|
self.updateMatchingCaseScript(self.UIMatchInjector,self.match.scriptInjector)
|
|
self.updateMatchingCaseScript(self.UIMatchAthos, self.match.scriptAthos)
|
|
self.updateMatchingCaseScript(self.UIMatchAramis, self.match.scriptAramis)
|
|
self.updateMatchingCaseScript(self.UIMatchPorthos, self.match.scriptPorthos)
|
|
|
|
def updateMatchingCaseScript(self,widget,state):
|
|
"""
|
|
Generalized routine to select and enable checkbox widgets
|
|
:param widget: checkbox widget
|
|
:param state: True or False
|
|
:return: None
|
|
"""
|
|
widget.setChecked(state)
|
|
widget.setEnabled(state)
|
|
|
|
def closeEvent(self, event):
|
|
self.plot.close()
|
|
event.accept()
|
|
|
|
def about(self):
|
|
QtWidgets.QMessageBox.about(self, "Optics Tool",
|
|
"Version:%s\nContact: Sven Reiche\nEmail: sven.reiche@psi.ch" % self.version)
|
|
|
|
def openGit(self):
|
|
webbrowser.open("https://gitea.psi.ch/reiche/opticstool")
|
|
|
|
def editMatchingScript(self):
|
|
options = QtWidgets.QFileDialog.Options()
|
|
options |= QtWidgets.QFileDialog.DontUseNativeDialog
|
|
fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Open Matching Script File",
|
|
"Scripts/switchyard.madx",
|
|
"MadX Files (*.madx)", options=options)
|
|
if not fileName:
|
|
return
|
|
subprocess.Popen(["emacs", fileName])
|
|
|
|
##################################################
|
|
def saveSettings(self):
|
|
options = QtWidgets.QFileDialog.Options()
|
|
options |= QtWidgets.QFileDialog.DontUseNativeDialog
|
|
fileName, _ = QtWidgets.QFileDialog.getSaveFileName(self, "Save Settings",
|
|
"Settings/newSetting.json",
|
|
"Json Files (*.json)", options=options)
|
|
if not fileName:
|
|
return
|
|
self.saveSettingDirect(fileName)
|
|
|
|
|
|
def loadSettings(self):
|
|
options = QtWidgets.QFileDialog.Options()
|
|
options |= QtWidgets.QFileDialog.DontUseNativeDialog
|
|
fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Open Settings",
|
|
"Settings/ReferenceSetting.json",
|
|
"Json Files (*.json)", options=options)
|
|
if not fileName:
|
|
return
|
|
self.loadSettingsdirect(fileName)
|
|
|
|
def loadSettingsdirect(self,fileName):
|
|
with open(fileName, 'r', encoding='utf-8') as f:
|
|
settings = json.load(f)
|
|
self.model.loadSettings(settings)
|
|
self.status('Reference loaded')
|
|
|
|
def saveSettingsdirect(self,fileName):
|
|
settings = self.model.getSettings()
|
|
with open(fileName, 'w', encoding='utf-8') as f:
|
|
json.dump(settings, f, ensure_ascii=False, indent=4)
|
|
|
|
####################################################
|
|
def fullUpdate(self):
|
|
machine = self.machine.getMachineStatus()
|
|
self.model.updateFromMachine(machine)
|
|
self.sandbox.updateSandbox()
|
|
self.status('Machine Settings')
|
|
|
|
def status(self,msg=''):
|
|
self.UIStatus.setText(msg)
|
|
# --------------------------------
|
|
# Main routine
|
|
|
|
|
|
if __name__ == '__main__':
|
|
QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create("plastique"))
|
|
parser = ArgumentParser()
|
|
parser.add_argument('-phase', type=int, help='Select Phase of the Lattice', default=0)
|
|
parser.add_argument('-offline', type=int, help='Excludes any connection to control system', default=1)
|
|
args = parser.parse_args()
|
|
app = QtWidgets.QApplication(sys.argv)
|
|
|
|
main = OpticsTools(phase = args.phase, office = args.offline)
|
|
if main:
|
|
main.show()
|
|
sys.exit(app.exec_())
|