import json import copy from PyQt5 import QtCore, QtGui, QtWidgets from numpy.ma.core import floor_divide from generateMatchSettings import configMatching 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.matchfile='' 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('MatchingConfig/Reference.json') self.parent.UITrackReference.currentIndexChanged.connect(self.updateReferenceWidgets) self.parent.UIMatchOrder.itemClicked.connect(self.displayMatchingPoint) self.parent.UIConfigMatching.clicked.connect(self.configMatching) def configMatching(self): label=str(self.parent.UIMatchingConfigLabel.text()) var = {} var['SYR56'] = float(str(self.parent.UIMatchConfigSYComp.text())) * 0.01 fname = configMatching(label,var) self.loadReference(fname) def clearMatching(self): self.save.clear() self.updateMatchOrder() def updateMatchOrder(self): secs={} self.parent.UIMatchOrder.clear() for i,ele in enumerate(self.settings['Order']): label = ele['MatchID'] ref = ele['Reference'] if ref is None: color = CBeige else: if ref in secs.keys(): color = secs[ref] else: idx = len(secs)+2 color = QtGui.QColor(220, 240-idx*5, 200+idx*4) secs[ref]=color if not ref is None: label += ' ('+ref+')' self.parent.UIMatchOrder.addItem(label) self.parent.UIMatchOrder.item(i).setBackground(color) 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.matchfile=filename 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()) ID = ID.split('(')[0].strip() 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) if 'User' in self.parameter[ID]: for key in self.parameter[ID]['User'].keys(): variable[key]={'Val':self.parameter[ID]['User'][key],'Max':None} 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'] elif 'Preset' in target.keys(): cond['Preset']=target['Preset'] 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'])) elif 'Preset' in config['target'].keys(): irow = 0 for key in config['target']['Preset'].keys(): self.parent.UIMatchTargets.insertRow(irow) self.parent.UIMatchTargets.setItem(irow, 0, QtWidgets.QTableWidgetItem(key)) self.parent.UIMatchTargets.setItem(irow, 1, QtWidgets.QTableWidgetItem('%7.3f' % config['target']['Preset'][key])) irow +=1 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 if key=='': # some quick solution in the case that the referenc epoints are regenerated, generating a signal for empty table 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')