diff --git a/OpticsTools.py b/OpticsTools.py index 6953beb..ceaae0b 100644 --- a/OpticsTools.py +++ b/OpticsTools.py @@ -48,6 +48,7 @@ class OpticsTools(QtWidgets.QMainWindow, Ui_OpticsGUI): self.sandbox.updateSandbox() self.reference = ReferenceManager(parent=self) self.reference.initReferencePoints(self.match) + self.updateMatchVariables() title = "SwissFEL Optics Tools - Lattice %s (Phase %d)" % (self.model.getLatticeVersion(),phase) if office: @@ -77,11 +78,20 @@ class OpticsTools(QtWidgets.QMainWindow, Ui_OpticsGUI): 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) + if self.UIInitAllMagnets.isChecked(): + self.model.initializeMagnets() + if self.UIModifyKnobs.isChecked(): + vars = self.getMatchVariables() + else: + vars = None + twiss = self.match.match(self.model.om, variables = vars, 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) + if self.UISaveMatchSettings.isChecked(): + fileName = self.match.scriptdir+'/settings.json' + self.saveSettingsdirect(fileName) def updateMatchingCase(self): @@ -106,6 +116,26 @@ class OpticsTools(QtWidgets.QMainWindow, Ui_OpticsGUI): widget.setChecked(state) widget.setEnabled(state) + def updateMatchVariables(self): + + nrow = len(self.match.variables.keys()) + self.UIMatchKnobs.setRowCount(nrow) + for irow,key in enumerate(self.match.variables.keys()): + self.UIMatchKnobs.setItem(irow, 0, QtWidgets.QTableWidgetItem(key)) + self.UIMatchKnobs.setItem(irow, 1, QtWidgets.QTableWidgetItem('%f' % self.match.variables[key]['Value'])) + self.UIMatchKnobs.item(irow, 0).setToolTip(self.match.variables[key]['Description']) + self.UIMatchKnobs.resizeColumnsToContents() + + def getMatchVariables(self): + variables={} + nrow = self.UIMatchKnobs.rowCount() + for irow in range(nrow): + name = str(self.UIMatchKnobs.item(irow,0).text()) + val = float(str(self.UIMatchKnobs.item(irow, 1).text())) + variables[name]={'Val':val} + return variables + + def closeEvent(self, event): self.plot.close() event.accept() diff --git a/Scripts/Reference-SwissFEL/initTwiss.madx b/Scripts/Reference-SwissFEL/initTwiss.madx index dc0c2d9..db1b991 100644 --- a/Scripts/Reference-SwissFEL/initTwiss.madx +++ b/Scripts/Reference-SwissFEL/initTwiss.madx @@ -5,4 +5,7 @@ TwissM1: beta0, betx = 11.2, alfx = 3.2, bety = 0.8, alfy = 0.75; ! location:si TwissM2: beta0, betx = 11.1557, alfx = -1.17, bety = 50, alfy = 0.; ! location:sindi02.mqua020$start TwissM3: beta0, betx = 4.88, alfx = 0.5546, bety = 16.11, alfy = -1.81; ! location:s10bc01.mqua020$start TwissM4: beta0, betx = 6.14, alfx = -0.83, bety = 22.86, alfy = -1.18; ! location:s10ma01.mqua020$start -Twisssep: beta0,betx = 48.26, alfx = 7.322, bety = 14.293, alfy = -3.513; ! location:s20sy02$start \ No newline at end of file +Twisssep: beta0,betx = 48.26, alfx = 7.322, bety = 14.293, alfy = -3.513; ! location:s20sy02$start +! variables +leakdisp = 0; ! Description: Leaked dispersion in SATSY01 to control R56 of switchyard +ECOLasBC = 0; ! Description: Flag to configure Aramis Energy collimator as a bunch compressor \ No newline at end of file diff --git a/Scripts/Reference-SwissFEL/matchAthos.madx b/Scripts/Reference-SwissFEL/matchAthos.madx index 840b19a..7c9bca6 100644 --- a/Scripts/Reference-SwissFEL/matchAthos.madx +++ b/Scripts/Reference-SwissFEL/matchAthos.madx @@ -82,7 +82,7 @@ CONSTRAINT, SEQUENCE=swissfel, RANGE=satsy01$end, X<10; LMDIF, CALLS=1000, TOLERANCE=1.E-21; ENDMATCH; -leakdisp = 0; + satsy01.mqua280.k1 = satsy01.mqua280.k1*(1+leakdisp); !------------------------------------------ diff --git a/matchmaker.py b/matchmaker.py index c90b72c..b1679b8 100644 --- a/matchmaker.py +++ b/matchmaker.py @@ -7,6 +7,8 @@ class MatchMaker: def __init__(self): self.matchlist={'Reference-SwissFEL':'Scripts/Reference-SwissFEL','SwissFEL+':'Scripts/SFPlus'} self.referencePoints={} + self.variables={} + self.scriptdir = None def initScripts(self,target): self.scriptdir = self.matchlist[target] @@ -22,6 +24,7 @@ class MatchMaker: def parseReferencePoints(self): file = self.scriptdir+'/initTwiss.madx' self.referencePoints.clear() + self.variables.clear() with open(file,'r') as f: lines = f.readlines() for line in lines: @@ -31,10 +34,18 @@ class MatchMaker: fields_all = tags[0].split(',') fields = [fld.split(';')[0].strip() for fld in fields_all if "=" in fld] self.referencePoints[location] = {twiss.split('=')[0].strip().lower():float(twiss.split('=')[1].strip()) for twiss in fields} + if 'Description:' in line: + tags = line.split('Description:') + description = tags[1].strip() + flds=tags[0].split('=') + name = flds[0].split(':')[0].strip() + val = float(flds[1].split(';')[0].strip()) + self.variables[name] = {'Value':val,'Description':description} + print('Found Variable',name,'with value',val) print('##### Reference Twiss values parsed') - def match(self, om, Injector=True, Athos = True, Aramis = False, Porthos = False): + def match(self, om, variables = None, Injector=True, Athos = True, Aramis = False, Porthos = False): if Athos: target = 'SATBD01' @@ -46,6 +57,8 @@ class MatchMaker: madx.updateLattice(om, target) # write lattice madx.commonHeader('SwissFEL', '#s/#e', None) # sets header madx.madx.call(self.scriptdir + '/initTwiss.madx') + if not variables is None: + madx.definePresets(variables) if Injector: madx.madx.call(self.scriptdir+'/matchInjector.madx', chdir=True) self.updateOnlineModel(om,madx.madx, 's[i1].*k1|s20sy01.*k1')