diff --git a/OpticsTools.py b/OpticsTools.py index 1a38776..5263b22 100644 --- a/OpticsTools.py +++ b/OpticsTools.py @@ -12,8 +12,7 @@ from model import Model from machine import Machine from reference import ReferenceManager from sandbox import Sandbox -from matching import Matching -from elegant import Elegant +from matchmaker import MatchMaker class OpticsTools(QtWidgets.QMainWindow, Ui_OpticsGUI): @@ -34,6 +33,15 @@ class OpticsTools(QtWidgets.QMainWindow, Ui_OpticsGUI): # 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) @@ -50,6 +58,8 @@ class OpticsTools(QtWidgets.QMainWindow, Ui_OpticsGUI): # self.matching = Matching(parent=self, model=self.model, reference = self.reference) # 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) @@ -60,6 +70,45 @@ class OpticsTools(QtWidgets.QMainWindow, Ui_OpticsGUI): # self.actionOpenScriptEditor.triggered.connect(self.editMatchingScript) # self.actionExportElegant.triggered.connect(self.exportElegant) + + 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) + 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() diff --git a/Scripts/SFPlus/matchAramis.madx b/Scripts/SFPlus/matchAramis.madx index 94363cd..29b1359 100644 --- a/Scripts/SFPlus/matchAramis.madx +++ b/Scripts/SFPlus/matchAramis.madx @@ -1,15 +1,6 @@ -betax0=10; -alphax0=0; -betay0=10; -alphay0=0; -Twiss0: beta0,betx=betax0,alfy=alphay0,bety=betay0,alfy=alphay0; - -!Twisssep: beta0,betx=40,alfx=0,bety=60,alfy=5; - -Twisssep: beta0,betx=10,alfx=-0.2,bety=15,alfy=1; y_sep=0.01; diff --git a/Scripts/SFPlus/matchAthos.madx b/Scripts/SFPlus/matchAthos.madx index 7de7167..3af9c2c 100644 --- a/Scripts/SFPlus/matchAthos.madx +++ b/Scripts/SFPlus/matchAthos.madx @@ -1,13 +1,4 @@ -!!!!!!!!!!!!!!!!! septum -betax0=10; -alphax0=0; -betay0=10; -alphay0=0; - -Twiss0: beta0,betx=betax0,alfy=alphay0,bety=betay0,alfy=alphay0; -!Twisssep: beta0,betx=40,alfx=0,bety=60,alfy=5; -Twisssep: beta0,betx=10,alfx=-0.2,bety=15,alfy=1; - +! y_sep=0.01; py_sep=0.0; !dy_sep=-y_sep; diff --git a/matchmaker.py b/matchmaker.py index 4dfaedd..c73190e 100644 --- a/matchmaker.py +++ b/matchmaker.py @@ -1,17 +1,23 @@ +import os import re from onlinemodel.madx import CMadX class MatchMaker: - def __init__(self, scriptlocation = None): - self.scriptdir = scriptlocation - self.scriptInjector = 'matchInjector.madx' - self.scriptAramis = 'matchAramis.madx' - self.scriptAthos = 'matchAthos.madx' + def __init__(self): + self.matchlist={'SwissFEL+':'Scripts/SFPlus'} + + def initScripts(self,target): + self.scriptdir = self.matchlist[target] + self.scriptInjector = os.path.exists(self.scriptdir+'/matchInjector.madx') + self.scriptAramis = os.path.exists(self.scriptdir+'/matchAramis.madx') + self.scriptAthos = os.path.exists(self.scriptdir + '/matchAthos.madx') + self.scriptPorthos = os.path.exists(self.scriptdir + '/matchPorthos.madx') + self.settings = os.path.exists(self.scriptdir + '/ReferenceSettings') - def match(self, om, Injector=True, Athos = True, Aramis = False): + def match(self, om, Injector=True, Athos = True, Aramis = False, Porthos = False): if Athos: target = 'SATBD01' @@ -37,6 +43,8 @@ class MatchMaker: madx.commonHeader('SwissFEL', '#s/#e', None) # sets header madx.madx.call(self.scriptdir + '/initTwiss.madx') madx.madx.call(self.scriptdir + '/matchAramis.madx', chdir=True) + self.updateOnlineModel(om, madx.madx, 's[3a][0r].*k1|s20[bm][ca].*k1') + return madx.madx.table.twiss def updateOnlineModel(self,om,madx,filter): reg = re.compile(filter) diff --git a/model.py b/model.py index 6f8a52e..3bd3836 100644 --- a/model.py +++ b/model.py @@ -34,7 +34,7 @@ class Model: def eventHandling(self): self.parent.UITrack.clicked.connect(self.track) - self.parent.UIMatchSelected.clicked.connect(self.match) + #self.parent.UIMatchSelected.clicked.connect(self.match) def forceLatticeUpdate(self): self.forceLat=True diff --git a/ui/OpticsPlotGui.py b/ui/OpticsPlotGui.py index fca8863..3156767 100644 --- a/ui/OpticsPlotGui.py +++ b/ui/OpticsPlotGui.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'ui/OpticsPlotGui.ui' # -# Created by: PyQt5 UI code generator 5.15.10 +# Created by: PyQt5 UI code generator 5.15.11 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. diff --git a/ui/OpticsToolsGui.py b/ui/OpticsToolsGui.py index 0f4010c..55ebd0f 100644 --- a/ui/OpticsToolsGui.py +++ b/ui/OpticsToolsGui.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'ui/OpticsToolsGui.ui' # -# Created by: PyQt5 UI code generator 5.15.10 +# Created by: PyQt5 UI code generator 5.15.11 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. @@ -365,6 +365,24 @@ class Ui_OpticsGUI(object): self.horizontalLayout_9.setObjectName("horizontalLayout_9") self.verticalLayout_6 = QtWidgets.QVBoxLayout() self.verticalLayout_6.setObjectName("verticalLayout_6") + self.label_31 = QtWidgets.QLabel(self.tab_2) + self.label_31.setObjectName("label_31") + self.verticalLayout_6.addWidget(self.label_31) + self.UIMatchOpticsSelect = QtWidgets.QComboBox(self.tab_2) + self.UIMatchOpticsSelect.setObjectName("UIMatchOpticsSelect") + self.verticalLayout_6.addWidget(self.UIMatchOpticsSelect) + self.UIMatchInjector = QtWidgets.QCheckBox(self.tab_2) + self.UIMatchInjector.setObjectName("UIMatchInjector") + self.verticalLayout_6.addWidget(self.UIMatchInjector) + self.UIMatchAthos = QtWidgets.QCheckBox(self.tab_2) + self.UIMatchAthos.setObjectName("UIMatchAthos") + self.verticalLayout_6.addWidget(self.UIMatchAthos) + self.UIMatchPorthos = QtWidgets.QCheckBox(self.tab_2) + self.UIMatchPorthos.setObjectName("UIMatchPorthos") + self.verticalLayout_6.addWidget(self.UIMatchPorthos) + self.UIMatchAramis = QtWidgets.QCheckBox(self.tab_2) + self.UIMatchAramis.setObjectName("UIMatchAramis") + self.verticalLayout_6.addWidget(self.UIMatchAramis) self.UIMatchSelected = QtWidgets.QPushButton(self.tab_2) font = QtGui.QFont() font.setPointSize(12) @@ -681,7 +699,7 @@ class Ui_OpticsGUI(object): self.menubar.addAction(self.menuHelp.menuAction()) self.retranslateUi(OpticsGUI) - self.TabMaster.setCurrentIndex(0) + self.TabMaster.setCurrentIndex(2) self.actionQuit.triggered.connect(OpticsGUI.close) # type: ignore QtCore.QMetaObject.connectSlotsByName(OpticsGUI) @@ -729,6 +747,11 @@ class Ui_OpticsGUI(object): self.Mach2ModUnd.setText(_translate("OpticsGUI", "Model <- Sandbox <- Machine")) self.SB2ModUnd.setText(_translate("OpticsGUI", "Model <- Sandbox")) self.TabMaster.setTabText(self.TabMaster.indexOf(self.tab_8), _translate("OpticsGUI", "Sandbox")) + self.label_31.setText(_translate("OpticsGUI", "Optics")) + self.UIMatchInjector.setText(_translate("OpticsGUI", "Injector")) + self.UIMatchAthos.setText(_translate("OpticsGUI", "Athos")) + self.UIMatchPorthos.setText(_translate("OpticsGUI", "Porthos")) + self.UIMatchAramis.setText(_translate("OpticsGUI", "Aramis")) self.UIMatchSelected.setText(_translate("OpticsGUI", "Match Selected")) self.label_14.setText(_translate("OpticsGUI", "Label")) self.label_15.setText(_translate("OpticsGUI", "Matching Order (Closest Reference Point)")) diff --git a/ui/OpticsToolsGui.ui b/ui/OpticsToolsGui.ui index e197950..3de848e 100644 --- a/ui/OpticsToolsGui.ui +++ b/ui/OpticsToolsGui.ui @@ -24,7 +24,7 @@ - 0 + 2 @@ -598,6 +598,44 @@ + + + + Optics + + + + + + + + + + Injector + + + + + + + Athos + + + + + + + Porthos + + + + + + + Aramis + + +