Added support to import LongTrack settings file and to match with user defined twiss values

This commit is contained in:
2026-03-05 11:00:17 +01:00
parent bc81dcce00
commit 9bef0adc13
6 changed files with 340 additions and 20 deletions
+13 -2
View File
@@ -87,7 +87,12 @@ class OpticsTools(QtWidgets.QMainWindow, QtCore.QObject, Ui_OpticsGUI):
vars = self.getMatchVariables()
else:
vars = None
twiss = self.match.match(self.model.om, variables = vars, Injector = injector,Athos = athos, Aramis = aramis, Porthos = porthos)
inittwiss={}
inittwiss['betax']=float(str(self.UIInitBetax.text()))
inittwiss['betay'] = float(str(self.UIInitBetay.text()))
inittwiss['alphax'] = float(str(self.UIInitAlphax.text()))
inittwiss['alphay'] = float(str(self.UIInitAlphay.text()))
twiss = self.match.match(self.model.om, variables = vars, initCond = inittwiss, Injector = injector,Athos = athos, Aramis = aramis, Porthos = porthos)
self.updateMatchResult(self.match.matchresult)
energy = self.model.calcEnergyProfile(twiss)
#enfore the writing of a new lattice so that the magnet settings are in the new lattice
@@ -187,7 +192,7 @@ class OpticsTools(QtWidgets.QMainWindow, QtCore.QObject, Ui_OpticsGUI):
"Json Files (*.json)", options=options)
if not fileName:
return
self.saveSettingdirect(fileName)
self.saveSettingsdirect(fileName)
@@ -206,9 +211,15 @@ class OpticsTools(QtWidgets.QMainWindow, QtCore.QObject, Ui_OpticsGUI):
def loadSettingsdirect(self,fileName):
print('Loading settings from %s ...' % fileName)
with open(fileName, 'r', encoding='utf-8') as f:
settings = json.load(f)
status=self.model.loadSettings(settings)
if 'InitialCondition' in settings.keys():
self.UIInitBetax.setText('%7.3f' % settings['InitialCondition']['betx'])
self.UIInitBetay.setText('%7.3f' % settings['InitialCondition']['bety'])
self.UIInitAlphax.setText('%7.3f' % settings['InitialCondition']['alfx'])
self.UIInitAlphay.setText('%7.3f' % settings['InitialCondition']['alfy'])
if status:
print('Reference loaded from file %s' % fileName)
self.status('Reference file loaded')
+4 -1
View File
@@ -81,7 +81,7 @@ class MatchMaker:
def match(self, om, variables = None, Injector=True, Athos = True, Aramis = False, Porthos = False):
def match(self, om, variables = None, initCond=None, Injector=True, Athos = True, Aramis = False, Porthos = False):
self.matchresult.clear()
cwd = os.getcwd()
@@ -98,6 +98,9 @@ class MatchMaker:
madx.updateLattice(om, target) # write lattice
madx.commonHeader('SwissFEL', '#s/#e', None) # sets header
madx.madx.call('initTwiss.madx')
if not initCond is None:
madx.madx.input('Twiss0: beta0, betx = %f, alfx = %f, bety = %f, alfy = %f;\n'
% (initCond['betax'],initCond['alphax'],initCond['betay'],initCond['alphay']))
if not variables is None:
madx.definePresets(variables)
if Injector:
+3 -2
View File
@@ -105,11 +105,12 @@ class Model:
self.om.setRegExpElement(name[0:7], name[8:15], 'kx', kx)
self.om.setRegExpElement(name[0:7], name[8:15], 'ky', ky)
if 'RSYS' in name:
grad = float(val[0])
grad = float(val[0])*1e6
phase = float(val[1])
if 'CB' in name[0:7]:
grad = grad/ 4.
grad = grad/2
if 'SINSB03' in name[0:7] or 'SINSB04' in name[0:7] or 'SINXB' in name[0:7]:
grad = grad/2.
L = self.om.getRegExpElement(name[0:7], 'RACC', 'Length')[0]
self.om.setRegExpElement(name[0:7], 'RACC', 'Gradient', grad/L)
self.om.setRegExpElement(name[0:7], 'RACC', 'Phase', phase)
+86
View File
@@ -1,6 +1,10 @@
from dataclasses import field
from PyQt5 import QtCore, QtGui, QtWidgets
import numpy as np
import re
import scipy
import json
CGrey = QtGui.QColor(230,230,230)
CBeige = QtGui.QColor(250, 240, 200)
@@ -20,6 +24,7 @@ class Sandbox:
self.parent.Mach2ModUnd.clicked.connect(self.updateModelEvent)
self.parent.SB2ModUnd.clicked.connect(self.updateModelEvent)
self.parent.SB2MachineMag.clicked.connect(self.updateMachine)
self.parent.SBLongTrack.clicked.connect(self.updateFromLongTrack)
def updateMachine(self):
vals = self.getSBbyCol(self.parent.MagSB,1)
@@ -244,3 +249,84 @@ class Sandbox:
colors.append(sbcol)
self.updateSandboxCommon(sb, values, colors, labels)
def updateFromLongTrack(self):
options = QtWidgets.QFileDialog.Options()
options |= QtWidgets.QFileDialog.DontUseNativeDialog
fileName,_ = QtWidgets.QFileDialog.getOpenFileName(self.parent, "Open LongTrack Settings",".","Json Files (*.json)", options=options)
if not fileName:
return
with open(fileName,'r') as f:
data = json.load(f)
for sec in ['SINSB','SINXB','Linac1-1','Linac1-2','Linac2','Linac3']:
self.updateLTRF(data,sec)
for sec in ['BC1','BC2','Laser Heater']:
self.updateLTBC(data,sec)
self.updateSandbox()
self.parent.model.forceLatticeUpdate()
self.parent.status('Sandbox mode')
def updateLTBC(self,data,section):
if not section in data.keys():
return
self.rootR56=data[section]['R56']
self.rootLb = data[section]['Dipole Length']
self.rootLd = data[section]['L1']
x=data[section]['Angle']
if self.rootR56 > 0:
res = scipy.optimize.root_scalar(self.calc56,method='bisect',bracket=[1e-5,0.2])
angle = -res.root*180/np.pi
else:
angle = 0.
if 'BC1' in section:
self.parent.model.updateElement('SINBC02.MBND', [angle])
elif 'BC2' in section:
self.parent.model.updateElement('S10BC02.MBND', [angle])
elif 'Laser Heater' in section:
self.parent.model.updateElement('SINLH02.MBND', [angle])
def calc56(self, x):
return 2* (4* x / np.sin(x) * self.rootLb + 2 * self.rootLd / np.cos(x)-4*self.rootLb-2*self.rootLd)-self.rootR56
def updateLTRF(self,data,section):
if not section in data.keys():
return
phase=data[section]['Phase']
gain=data[section]['Voltage']
if 'Linac3' in section:
gain/=13.
for i in range(1,14):
field='S30CB%2.2d-RSYS' % i
val = [gain, phase]
self.parent.model.updateElement(field.replace('-', '.'), val)
elif 'Linac2' in section:
gain/=4
for i in range(1,5):
field='S20CB%2.2d-RSYS' % i
val = [gain, phase]
self.parent.model.updateElement(field.replace('-', '.'), val)
elif 'Linac1-2' in section:
gain/=7
for i in range(3,10):
field='S10CB%2.2d-RSYS' % i
val = [gain, phase]
self.parent.model.updateElement(field.replace('-', '.'), val)
elif 'Linac1-1' in section:
gain/=2
for i in range(1,3):
field='S10CB%2.2d-RSYS' % i
val = [gain, phase]
self.parent.model.updateElement(field.replace('-', '.'), val)
elif 'SINSB' in section:
gain/=2
for i in range(3,5):
field='SINSB%2.2d-RSYS' % i
val = [gain, phase]
self.parent.model.updateElement(field.replace('-', '.'), val)
elif 'SINXB' in section:
for i in range(1,2):
field='SINXB%2.2d-RSYS' % i
val = [gain, phase]
self.parent.model.updateElement(field.replace('-', '.'), val)
+95 -7
View File
@@ -17,8 +17,8 @@ class Ui_OpticsGUI(object):
OpticsGUI.resize(938, 791)
self.centralwidget = QtWidgets.QWidget(OpticsGUI)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.TabMaster = QtWidgets.QTabWidget(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
@@ -356,6 +356,80 @@ class Ui_OpticsGUI(object):
self.UIInitAllMagnets = QtWidgets.QCheckBox(self.widget)
self.UIInitAllMagnets.setObjectName("UIInitAllMagnets")
self.verticalLayout_3.addWidget(self.UIInitAllMagnets)
self.label_20 = QtWidgets.QLabel(self.widget)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_20.setFont(font)
self.label_20.setObjectName("label_20")
self.verticalLayout_3.addWidget(self.label_20)
self.gridLayout_6 = QtWidgets.QGridLayout()
self.gridLayout_6.setObjectName("gridLayout_6")
self.label_15 = QtWidgets.QLabel(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_15.sizePolicy().hasHeightForWidth())
self.label_15.setSizePolicy(sizePolicy)
self.label_15.setObjectName("label_15")
self.gridLayout_6.addWidget(self.label_15, 0, 2, 1, 1)
self.UIInitAlphax = QtWidgets.QLineEdit(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.UIInitAlphax.sizePolicy().hasHeightForWidth())
self.UIInitAlphax.setSizePolicy(sizePolicy)
self.UIInitAlphax.setObjectName("UIInitAlphax")
self.gridLayout_6.addWidget(self.UIInitAlphax, 2, 1, 1, 1)
self.label_14 = QtWidgets.QLabel(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_14.sizePolicy().hasHeightForWidth())
self.label_14.setSizePolicy(sizePolicy)
self.label_14.setObjectName("label_14")
self.gridLayout_6.addWidget(self.label_14, 0, 1, 1, 1)
self.label_16 = QtWidgets.QLabel(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_16.sizePolicy().hasHeightForWidth())
self.label_16.setSizePolicy(sizePolicy)
self.label_16.setObjectName("label_16")
self.gridLayout_6.addWidget(self.label_16, 1, 0, 1, 1)
self.UIInitBetax = QtWidgets.QLineEdit(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.UIInitBetax.sizePolicy().hasHeightForWidth())
self.UIInitBetax.setSizePolicy(sizePolicy)
self.UIInitBetax.setObjectName("UIInitBetax")
self.gridLayout_6.addWidget(self.UIInitBetax, 1, 1, 1, 1)
self.UIInitBetay = QtWidgets.QLineEdit(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.UIInitBetay.sizePolicy().hasHeightForWidth())
self.UIInitBetay.setSizePolicy(sizePolicy)
self.UIInitBetay.setObjectName("UIInitBetay")
self.gridLayout_6.addWidget(self.UIInitBetay, 1, 2, 1, 1)
self.UIInitAlphay = QtWidgets.QLineEdit(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.UIInitAlphay.sizePolicy().hasHeightForWidth())
self.UIInitAlphay.setSizePolicy(sizePolicy)
self.UIInitAlphay.setObjectName("UIInitAlphay")
self.gridLayout_6.addWidget(self.UIInitAlphay, 2, 2, 1, 1)
self.label_17 = QtWidgets.QLabel(self.widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_17.sizePolicy().hasHeightForWidth())
self.label_17.setSizePolicy(sizePolicy)
self.label_17.setObjectName("label_17")
self.gridLayout_6.addWidget(self.label_17, 2, 0, 1, 1)
self.verticalLayout_3.addLayout(self.gridLayout_6)
self.label_19 = QtWidgets.QLabel(self.widget)
font = QtGui.QFont()
font.setBold(True)
@@ -380,9 +454,6 @@ class Ui_OpticsGUI(object):
item = QtWidgets.QTableWidgetItem()
self.UIMatchKnobs.setHorizontalHeaderItem(1, item)
self.verticalLayout_3.addWidget(self.UIMatchKnobs)
self.UIReportMagnetStrength = QtWidgets.QPushButton(self.widget)
self.UIReportMagnetStrength.setObjectName("UIReportMagnetStrength")
self.verticalLayout_3.addWidget(self.UIReportMagnetStrength)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_3.addItem(spacerItem1)
self.horizontalLayout_4.addWidget(self.widget)
@@ -417,6 +488,9 @@ class Ui_OpticsGUI(object):
self.UIReportMagnetResult.setFont(font)
self.UIReportMagnetResult.setObjectName("UIReportMagnetResult")
self.verticalLayout_2.addWidget(self.UIReportMagnetResult)
self.UIReportMagnetStrength = QtWidgets.QPushButton(self.groupBox)
self.UIReportMagnetStrength.setObjectName("UIReportMagnetStrength")
self.verticalLayout_2.addWidget(self.UIReportMagnetStrength)
self.horizontalLayout_4.addWidget(self.groupBox)
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_4.addItem(spacerItem2)
@@ -504,9 +578,13 @@ class Ui_OpticsGUI(object):
self.SB2ModUnd = QtWidgets.QPushButton(self.groupBox_9)
self.SB2ModUnd.setObjectName("SB2ModUnd")
self.verticalLayout_17.addWidget(self.SB2ModUnd)
self.SBLongTrack = QtWidgets.QPushButton(self.groupBox_9)
self.SBLongTrack.setStyleSheet("background-color: rgb(255, 255, 127);")
self.SBLongTrack.setObjectName("SBLongTrack")
self.verticalLayout_17.addWidget(self.SBLongTrack)
self.horizontalLayout_5.addWidget(self.groupBox_9)
self.TabMaster.addTab(self.tab_8, "")
self.verticalLayout_4.addWidget(self.TabMaster)
self.horizontalLayout_2.addWidget(self.TabMaster)
OpticsGUI.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(OpticsGUI)
self.menubar.setGeometry(QtCore.QRect(0, 0, 938, 22))
@@ -692,16 +770,25 @@ class Ui_OpticsGUI(object):
self.UIMatchAramis.setText(_translate("OpticsGUI", "Aramis"))
self.UISaveMatchSettings.setText(_translate("OpticsGUI", "Save matched machine settings automtically"))
self.UIInitAllMagnets.setText(_translate("OpticsGUI", "Initialize all magnets to zero before matching"))
self.label_20.setText(_translate("OpticsGUI", "Initial Conditions"))
self.label_15.setText(_translate("OpticsGUI", "y"))
self.UIInitAlphax.setText(_translate("OpticsGUI", "0"))
self.label_14.setText(_translate("OpticsGUI", "x"))
self.label_16.setText(_translate("OpticsGUI", "beta"))
self.UIInitBetax.setText(_translate("OpticsGUI", "20"))
self.UIInitBetay.setText(_translate("OpticsGUI", "20"))
self.UIInitAlphay.setText(_translate("OpticsGUI", "0"))
self.label_17.setText(_translate("OpticsGUI", "alpha"))
self.label_19.setText(_translate("OpticsGUI", "Matching Variables"))
self.UIModifyKnobs.setText(_translate("OpticsGUI", "Overwrite default values for matching variables "))
item = self.UIMatchKnobs.horizontalHeaderItem(0)
item.setText(_translate("OpticsGUI", "Parameter"))
item = self.UIMatchKnobs.horizontalHeaderItem(1)
item.setText(_translate("OpticsGUI", "Value"))
self.UIReportMagnetStrength.setText(_translate("OpticsGUI", "Report Matched Quadrupole Strength"))
self.groupBox.setTitle(_translate("OpticsGUI", "Matching Results"))
self.label_11.setText(_translate("OpticsGUI", "Matching"))
self.label_12.setText(_translate("OpticsGUI", "Magnet Strength"))
self.UIReportMagnetStrength.setText(_translate("OpticsGUI", "Report Matched Quadrupole Strength"))
self.TabMaster.setTabText(self.TabMaster.indexOf(self.tab_3), _translate("OpticsGUI", "Track"))
self.groupBox_8.setTitle(_translate("OpticsGUI", "Magnets (Angle/ k1L / k2L)"))
self.label_23.setText(_translate("OpticsGUI", "Start"))
@@ -713,6 +800,7 @@ class Ui_OpticsGUI(object):
self.label_26.setText(_translate("OpticsGUI", "Energy"))
self.Mach2ModUnd.setText(_translate("OpticsGUI", "Model <- Sandbox <- Machine"))
self.SB2ModUnd.setText(_translate("OpticsGUI", "Model <- Sandbox"))
self.SBLongTrack.setText(_translate("OpticsGUI", "Import LongTracker Settings"))
self.TabMaster.setTabText(self.TabMaster.indexOf(self.tab_8), _translate("OpticsGUI", "Sandbox"))
self.menuFile.setTitle(_translate("OpticsGUI", "File"))
self.menuHelp.setTitle(_translate("OpticsGUI", "Help"))
+139 -8
View File
@@ -14,7 +14,7 @@
<string>SwissFEL Optics</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_4">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QTabWidget" name="TabMaster">
<property name="sizePolicy">
@@ -581,6 +581,127 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_20">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Initial Conditions</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="2">
<widget class="QLabel" name="label_15">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>y</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="UIInitAlphax">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_14">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>x</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_16">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>beta</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="UIInitBetax">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>20</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="UIInitBetay">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>20</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="UIInitAlphay">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_17">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>alpha</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_19">
<property name="font">
@@ -621,13 +742,6 @@
</column>
</widget>
</item>
<item>
<widget class="QPushButton" name="UIReportMagnetStrength">
<property name="text">
<string>Report Matched Quadrupole Strength</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
@@ -693,6 +807,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="UIReportMagnetStrength">
<property name="text">
<string>Report Matched Quadrupole Strength</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@@ -843,6 +964,16 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="SBLongTrack">
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 127);</string>
</property>
<property name="text">
<string>Import LongTracker Settings</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>