From 7452f69e6d0868ceebb751de306166e3f7d8ac09 Mon Sep 17 00:00:00 2001 From: Sven Date: Wed, 8 Jul 2026 17:31:16 +0200 Subject: [PATCH] Implementing variable container --- containers.py | 27 ++++++++++++++++++++++++++- elements.py | 3 +-- main.py | 29 +++++++++++++++++++++++------ propertytypes.py | 2 ++ protoliste.py | 3 +++ 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/containers.py b/containers.py index a7ff460..6ca426b 100644 --- a/containers.py +++ b/containers.py @@ -1,5 +1,5 @@ # line container to hold the straight section - +import numpy as np class LineContainer: @@ -17,6 +17,10 @@ class LineContainer: self.lastElement = 0 self.hasBranchPoint = False + def clear(self): + self.Ref.clear() + self.Element.clear() + def getLength(self): return self.getResLength() @@ -165,7 +169,13 @@ class LineContainer: for ele in self.Element: if isinstance(ele, LineContainer): seq += ele.writeLattice(app) + elif isinstance(ele, VariableContainer): + dL = ele.getResLength() + print('Adding Drift:',dL) + app.writeDrift(dL) + Last +=dL else: + ele.adjustLength() # update correctly reserved length, length and sref ds = self.position(ele) - Last app.writeDrift(ds) name = ele.writeElement(app) @@ -180,3 +190,18 @@ class LineContainer: return seq # app.writeLine(self, seq) # baseseq = {'Name': self.Name, 'L': self.getResLength()} + + +class VariableContainer: # used to allow variable length in the arm of a bunch compressor, stored in a line container + def __init__(self, L=0., Loff=0.,ele = None): + self.L = L + self.Loff = Loff + self.ID = 'undefined' + self.ref=None + + def getResLength(self): + angle = 0 + if self.ref: + angle = getattr(self.ref,'design_angle',0) + dL = self.L / np.cos(angle * np.asin(1) / 90) - self.Loff + return dL \ No newline at end of file diff --git a/elements.py b/elements.py index e50eb24..39667be 100644 --- a/elements.py +++ b/elements.py @@ -56,7 +56,7 @@ class SimpleContainer: if self.LengthRes <= 0: self.LengthRes = self.Length self.sRef = 0. - elif self.sRef >= 0: + elif self.sRef > 0: LRes = self.sRef + self.Length if self.LengthRes < LRes: self.LengthRes = LRes @@ -72,7 +72,6 @@ class SimpleContainer: def getResLength(self): # return the reserved length for that element - self.adjustLength() return self.LengthRes def getLength(self): diff --git a/main.py b/main.py index c37dd41..aa7850d 100644 --- a/main.py +++ b/main.py @@ -134,6 +134,8 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI): ele = Marker({"Tag":"QTAR"}) case "Alignment": ele = Alignment({"Tag":"QALI","height":0.01}) + case "Variable Line": + ele = VariableContainer() case "Line": ele = LineContainer() case _: @@ -152,6 +154,7 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI): ele = self.elementDB[id] proplist = getPropertyList(self.editor.getElementType(id)) retdict={} + retdict['Name'] = {} for key in proplist.keys(): path = proplist[key].split('/') group = path[0] @@ -181,10 +184,14 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI): name = '%s%3.3d' % (tag[0:4].upper(),idx) data['Name']['Name']=name else: - name = data['Name']['Name'] + if 'Name' in data['Name'].keys(): + name = data['Name']['Name'] + else: + name = None # update GUI type = self.editor.getElementType(node_id) - self.editor.setElementName(node_id,name) + if name: + self.editor.setElementName(node_id,name) updated = self.editor.updatePropertyPane(node_id, data) proplist=getPropertyList(type) @@ -200,15 +207,14 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI): def flatten(self, node_id ): self.lines.clear() type = self.editor.getElementType(node_id) - name = 'XXXXXXX' + name='XXX' if type == 'Line': line = self.elementDB[node_id] else: if type == 'Start': name = self.elementDB[node_id].Name - if len(name) < 1: - name='XXX' line=LineContainer(namein=name,Lin=0) + line.clear() print('\nUnwrapping beamline...\n') self.unwrap(name,node_id,line) self.PL.generateLayout(line) @@ -224,14 +230,23 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI): self.report(ele, name) type = self.editor.getElementType(ele) if type == 'Line': + print('Unwrapping- Adding a Line') line.append(self.elementDB[ele],sRef=0,Ref='relative') subline = self.elementDB[ele] + subline.clear() name1 = subline.Name ref = subline.firstElementID if ref in self.elementDB.keys(): self.unwrap(name + name1, ref, subline) else: print('Undefined reference in Line Container:', name + name1) + elif type == 'Variable Line': + id = self.elementDB[ele].ID + if id in self.elementDB.keys(): + self.elementDB[ele].ref=self.elementDB[id] + else: + self.elementDB[ele].ref=None + line.append(self.elementDB[ele],sRef=0,Ref='relative') else: sRef=self.elementDB[ele].OffsetS Ref='absolute' @@ -247,8 +262,10 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI): def report(self,node_id,prefix=''): type = self.editor.getElementType(node_id) + if type == 'Variable Line': + print('FLATTEN: Adding Variable Line') + return name = self.elementDB[node_id].Name - if type=='Start': name=prefix elif type == 'Line': diff --git a/propertytypes.py b/propertytypes.py index f5a2f30..e9cfc43 100644 --- a/propertytypes.py +++ b/propertytypes.py @@ -16,6 +16,8 @@ def getPropertyList(element_type: str | None) -> dict: return {'Name':'Name/Name','LengthRes':'Position/Reserved Length','firstElementID':'Anchor/Reference'} elif element_type == 'Start' or element_type == 'Target': return {'Name': 'Name/Name'} + elif element_type == 'Variable Line': + return {'L':'Position/Total Length','Loff':'Position/Constant Offset','ID':'Anchor/Reference'} fields={} for i , fld in enumerate(eName): diff --git a/protoliste.py b/protoliste.py index 49f241a..0e95187 100644 --- a/protoliste.py +++ b/protoliste.py @@ -318,6 +318,7 @@ class ProtoListe(ApplicationTemplate): if ele.Baugruppe=='UE38-DELAY': channels=channels+1 # print info of the element and advances the layout position over the reserved length + self.advance(ele.sRef+ele.Length*0.5,0) # propagation to the center point self.p1 = self.p1 + ele.sRef*self.ev1 self.pv = self.p1 + 0.5 * ele.Length*self.ev1 @@ -365,6 +366,8 @@ class ProtoListe(ApplicationTemplate): extmp=self.ex eytmp=self.ey eztmp=self.ez + if not ele.branching: + ele.angle = ele.design_angle angletmp=ele.angle ele.angle=ele.design_angle angrad = np.pi* ele.angle / 180.