Files
OpticsTools/reference.py
2026-01-26 12:51:49 +01:00

259 lines
9.9 KiB
Python

import json
import copy
from PyQt5 import QtCore, QtGui, QtWidgets
#from fontTools.misc.cython import returns
CBeige = QtGui.QColor(250, 240, 200)
CGreen = QtGui.QColor(100, 255, 100)
CYellow = QtGui.QColor(255, 255, 0)
CRed = QtGui.QColor(255, 100, 100)
class ReferenceManager:
def __init__(self, parent):
self.parent = parent
self.settings={}
self.reference={}
self.save={}
self.label=None
self.twisswidget={'betax':self.parent.UIBetax,'betay':self.parent.UIBetay,
'alphax':self.parent.UIAlphax,'alphay':self.parent.UIAlphay,
'etax':self.parent.UIEtax,'etay':self.parent.UIEtay,
'etapx':self.parent.UIEtapx,'etapy':self.parent.UIEtapy,
'x':self.parent.UIX,'y':self.parent.UIY,
'px':self.parent.UIPX,'py':self.parent.UIPY}
self.loadReference('Settings/Reference.json')
self.parent.UITrackReference.currentIndexChanged.connect(self.updateReferenceWidgets)
self.parent.UIMatchOrder.itemClicked.connect(self.displayMatchingPoint)
def clearMatching(self):
self.save.clear()
self.updateMatchOrder()
def updateMatchOrder(self):
self.parent.UIMatchOrder.clear()
for i,ele in enumerate(self.settings['Order']):
self.parent.UIMatchOrder.addItem(ele['MatchID'])
self.parent.UIMatchOrder.item(i).setBackground(CBeige)
if self.parent.UIMatchOrder.count() > 0:
self.parent.UIMatchOrder.setCurrentRow(0)
self.displayMatchingPoint()
def loadReference(self, filename):
with open(filename) as f:
self.settings = json.load(f)
self.order={ele['MatchID']:i for i,ele in enumerate(self.settings['Order'])}
self.reference=self.settings['Reference'] # this are fixed points in the lattice
self.label=self.settings['Label']
self.parameter=self.settings['Parameter']
self.dependence=self.settings['Dependence']
self.parent.UIMatchSequenceLabel.setText(self.label)
self.clearMatching()
self.updateReferenceComboBox()
self.updateReferenceWidgets()
def saveTwiss(self, ID, twiss):
self.save[ID]={'betax':twiss.betx[0],'betay':twiss.bety[0],'alphax':twiss.alfx[0],'alphay':twiss.alfy[0]}
print('saving twissvalue for',ID,':',self.save[ID])
def getMatchingPoint(self):
idx = self.parent.UIMatchOrder.currentRow()
if idx < 0:
return None
ID = str(self.parent.UIMatchOrder.item(idx).text())
idx = self.order[ID] # get index in the list
order = copy.deepcopy(self.settings['Order'][idx])
destination = order['Destination']
save = order['Save']
sequence = order['Sequence']
if not sequence is None:
if isinstance(sequence,str):
start = sequence+'$start'
end = sequence+'$end'
elif isinstance(sequence,list):
start = sequence[0]+'$start'
end = sequence[-1]+'$end'
twiss0 = {'Location': start, 'twiss': {}}
else:
end = order['End']
if end is None:
end = '#e'
start = order['Reference']
if start is None:
twiss0 = {'Location':'#s','twiss':{}}
else:
twiss0 = self.getReferenceByTag(order['Reference'])
if twiss0['Location'].upper() == 'START':
twiss0['Location']= '#s'
sequence='swissfel'
varlist = self.parameter[ID]['Variable']
variable = self.parent.model.getVariableInfo(varlist)
cond = {}
targets = self.parameter[ID]['Target']
for target in targets:
if 'Location' in target.keys():
loc = target['Location']
if not loc in cond.keys():
cond[loc]=[]
if 'Limit' in target.keys():
limit = target['Limit']
else:
limit = 0
if 'Twiss' in target.keys():
for key0 in target['Twiss'].keys():
cond[loc].append((key0,limit,target['Twiss'][key0]))
elif 'SavedID':
if target['SavedID'] in self.save.keys():
twisssaved = self.save[target['SavedID']]
for twkey in twisssaved.keys():
cond[loc].append((twkey,0,twisssaved[twkey]))
else:
cond[loc].append(target['SavedID'])
elif 'Script' in target.keys():
cond['Script']=target['Script']
config={'ID':ID,'start':twiss0,'end':end,
'destination':destination,'sequence':sequence,
'variable':variable,'target':cond,'save':save}
return config
def updateMatchPoint(self,ID,val):
idx = self.order[ID]
if val < 1e-6:
color = CGreen
elif val < 1:
color = CYellow
else:
color = CRed
self.parent.UIMatchOrder.item(idx).setBackground(color)
if val<1:
idx = self.parent.UIMatchOrder.currentRow()+1
if idx < self.parent.UIMatchOrder.count():
self.parent.UIMatchOrder.setCurrentRow(idx)
self.displayMatchingPoint()
def getDependence(self,ele):
eletag=ele.upper().replace('.','-')
if eletag in self.dependence.keys():
return [mag.lower().replace('-','.') for mag in self.dependence[eletag]]
else:
return None
#--------------------------------
# match info
def displayMatchingPoint(self):
config = self.getMatchingPoint()
if config is None:
return
self.parent.UIMatchLabel.setText(config['ID'])
self.parent.UIMatchStart.setText(config['start']['Location'])
self.parent.UIMatchEnd.setText(config['end'])
self.parent.UIMatchSequence.setText(config['sequence'])
self.parent.UIMatchKnobs.setColumnCount(3)
self.parent.UIMatchKnobs.setRowCount(len(config['variable'].keys()))
for i , key in enumerate(config['variable'].keys()):
self.parent.UIMatchKnobs.setItem(i, 0, QtWidgets.QTableWidgetItem(key))
self.parent.UIMatchKnobs.setItem(i, 1, QtWidgets.QTableWidgetItem('%7.3f' % config['variable'][key]['Val']))
arg = config['variable'][key]['Max']
if arg is None:
self.parent.UIMatchKnobs.setItem(i, 2, QtWidgets.QTableWidgetItem(''))
else:
self.parent.UIMatchKnobs.setItem(i, 2, QtWidgets.QTableWidgetItem('%7.3f' % arg))
self.parent.UIMatchKnobs.resizeColumnsToContents()
self.parent.UIMatchKnobs.verticalHeader().hide()
self.parent.UIMatchTargets.setColumnCount(2)
self.parent.UIMatchTargets.setRowCount(0)
if 'Script' in config['target'].keys():
self.parent.UIMatchTargets.insertRow(0)
self.parent.UIMatchTargets.setItem(0, 0, QtWidgets.QTableWidgetItem('Script'))
self.parent.UIMatchTargets.setItem(0, 1, QtWidgets.QTableWidgetItem(config['target']['Script']))
else:
irow = 0
for key in config['target'].keys():
for ele in config['target'][key]:
self.parent.UIMatchTargets.insertRow(irow)
self.parent.UIMatchTargets.setItem(irow, 0, QtWidgets.QTableWidgetItem(key))
if isinstance(ele, tuple):
fld = self.convertTargetTuple(ele)
self.parent.UIMatchTargets.setItem(irow, 1, QtWidgets.QTableWidgetItem(fld))
elif isinstance(ele,str):
self.parent.UIMatchTargets.setItem(irow, 1, QtWidgets.QTableWidgetItem('Result from: %s ' % ele))
self.parent.UIMatchTargets.resizeColumnsToContents()
self.parent.UIMatchTargets.verticalHeader().hide()
return
def convertTargetTuple(self,tuple_in):
sym = ['=', '<', '>']
retval = tuple_in[0]+sym[int(tuple_in[1])]
if tuple_in[2] is None:
return retval+'undefined'
flt = '%7.3f' % tuple_in[2]
return retval + flt.strip()
#--------------------------------
# obtaining reference data
def getReference(self):
return self.getReferenceLocation(),self.getReferenceTwiss()
def getReferenceByTag(self,tag):
if not tag in self.reference.keys():
return None
return self.reference[tag]
def getReferenceTwiss(self):
self.updateReferenceWidgets() # enforce that the data is consistent
twiss = {key:float(str(self.twisswidget[key].text())) for key in self.twisswidget.keys()}
return twiss
def getReferenceLocation(self):
return str(self.parent.UITrackLocation.text())
####################################################
###### only relevant for tracking
##### interaction of the tracking reference point
def swithToUserDefinedLocation(self):
n = self.parent.UITrackReference.count()
self.parent.UITrackReference.setCurrentIndex(n-1)
def updateReferenceWidgets(self):
key = str(self.parent.UITrackReference.currentText())
if key == 'User Defined':
return
twiss = self.reference[key]['Twiss']
name = self.reference[key]['Location']
self.parent.UITrackLocation.setText(name)
for key in self.twisswidget.keys():
if key in twiss.keys():
value = twiss[key]
else:
value = 0
if 'beta' in key:
value = 30
self.twisswidget[key].setText('%7.3f' % value)
def updateReferenceComboBox(self):
self.parent.UITrackReference.clear()
for ref in self.reference.keys():
self.parent.UITrackReference.addItem(ref)
self.parent.UITrackReference.addItem('User Defined')