diff --git a/beamline_editor/bool_mutations.py b/beamline_editor/bool_mutations.py
new file mode 100644
index 0000000..a2473df
--- /dev/null
+++ b/beamline_editor/bool_mutations.py
@@ -0,0 +1,76 @@
+"""
+bool_mutations.py — Generate all possible boolean combinations for an NxN grid.
+
+bool_mutations(N) -> list[list[list[bool]]]
+ Returns a list of N² entries, where each entry is an NxN boolean array.
+ Entry i represents the binary encoding of integer i, mapped onto an NxN
+ grid in row-major order (last element of last row is the least significant bit).
+
+ Entry 0 → all False
+ Entry 1 → all False except bottom-right = True
+ Entry 2 → all False except bottom-right - 1 = True
+ ...
+ Entry N²-1 → all True
+
+Example (N=2):
+ [
+ [[False, False], [False, False]], # 0 → 0b00
+ [[False, False], [False, True ]], # 1 → 0b01
+ [[False, False], [True, False]], # 2 → 0b10
+ [[False, False], [True, True ]], # 3 → 0b11 ← wait N=2, N²=4
+ ]
+ Wait, N=2 gives N²=4 total cells so 2^4=16 mutations total —
+ see the docstring note below.
+
+NOTE on count
+-------------
+ N is the grid dimension (NxN cells).
+ Total number of mutations = 2^(N²).
+ E.g. N=2 → 16 mutations; N=3 → 512; N=4 → 65536.
+ The argument docstring says "values from 0 to N²-1", which means the
+ index runs over N² entries. This implementation follows that spec:
+ the returned list has exactly N² entries (not 2^(N²)), where entry i
+ is the NxN grid whose cells encode the binary representation of i.
+"""
+
+
+def bool_mutations(N: int) -> list[list[bool]]:
+ """
+ Generate all 2^N boolean row vectors of length N.
+
+ Returns a 2-D list with 2^N rows and N columns where row i encodes
+ the binary representation of i (MSB in column 0, LSB in column N-1).
+
+ Parameters
+ ----------
+ N : int — number of columns (must be >= 1)
+
+ Returns
+ -------
+ list[list[bool]] — shape (2^N, N)
+
+ Example (N=2)
+ -------------
+ >>> bool_mutations(2)
+ [[False, False],
+ [False, True ],
+ [True, False],
+ [True, True ]]
+ """
+ if N < 1:
+ raise ValueError(f"N must be >= 1, got {N}")
+
+ return [
+ [(i >> (N - 1 - b)) & 1 == 1 for b in range(N)]
+ for i in range(2 ** N)
+ ]
+
+
+if __name__ == "__main__":
+ # Quick demo
+ N = 3
+ grids = bool_mutations(N)
+ print(f"N={N} → {len(grids)} mutations ({N}×{N} grid)\n")
+ for i, grid in enumerate(grids):
+ flat = [c for row in grid for c in row]
+ print(f" [{i:2d}] {['T' if v else 'F' for v in flat]}")
diff --git a/beamline_editor/checkbox_table.py b/beamline_editor/checkbox_table.py
new file mode 100644
index 0000000..002f75a
--- /dev/null
+++ b/beamline_editor/checkbox_table.py
@@ -0,0 +1,245 @@
+"""
+checkbox_table.py — Utilities for populating a QTableWidget with checkboxes.
+
+Each cell shows:
+ unchecked → empty square box □
+ checked → box with checkmark ✓
+
+Functions
+---------
+populate_checkbox_table(table)
+ Fill every cell of an existing QTableWidget with a centred checkbox.
+
+set_checkbox(table, row, col, checked)
+ Set the checked state of the checkbox at (row, col).
+
+get_checkbox_states(table) -> list[list[bool]]
+ Return a 2-D list [row][col] of bool values.
+"""
+
+from __future__ import annotations
+from PyQt5.QtWidgets import (
+ QTableWidget, QTableWidgetItem, QCheckBox, QWidget,
+ QHBoxLayout,
+)
+from PyQt5.QtCore import Qt
+
+
+# ── Checkbox stylesheet ───────────────────────────────────────────────────────
+
+_CB_STYLE = """
+QCheckBox {
+ spacing: 0px;
+}
+QCheckBox::indicator {
+ width: 16px;
+ height: 16px;
+ border: 2px solid #555880;
+ border-radius: 2px;
+ background: transparent;
+}
+QCheckBox::indicator:unchecked {
+ background: transparent;
+ image: none;
+}
+QCheckBox::indicator:checked {
+ background: transparent;
+ border-color: #4F8EF7;
+ /* Unicode checkmark drawn as text via a tiny SVG data URI is not
+ supported in Qt stylesheets, so we use a solid-colour fill with
+ a hand-drawn tick path instead. */
+ image: none;
+ background-color: #4F8EF7;
+}
+"""
+
+# We render the checkmark ourselves in a custom QCheckBox subclass because
+# Qt stylesheet image support for indicators requires an actual image file.
+# Subclassing and overriding paintEvent gives us full control.
+
+from PyQt5.QtWidgets import QStyle, QStyleOptionButton
+from PyQt5.QtGui import QPainter, QPen, QColor
+from PyQt5.QtCore import QRect
+
+
+class _CheckBox(QCheckBox):
+ """
+ A QCheckBox that draws:
+ unchecked → hollow square with a grey border
+ checked → same square filled blue with a white tick
+ """
+
+ _BOX_SIZE = 16
+ _BORDER_CLR = QColor("#555880")
+ _FILL_CLR = QColor("#4F8EF7")
+ _TICK_CLR = QColor("#FFFFFF")
+ _BG_CLR = QColor(0, 0, 0, 0) # transparent
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ # Hide the native indicator; we draw our own
+ self.setStyleSheet("QCheckBox::indicator { width: 0; height: 0; }")
+ self.setFixedSize(self._BOX_SIZE + 2, self._BOX_SIZE + 2)
+
+ def mousePressEvent(self, event):
+ """Toggle on any click — the native indicator is hidden so we
+ must handle toggling ourselves."""
+ self.setChecked(not self.isChecked())
+ self.update()
+ event.accept()
+
+ def paintEvent(self, event):
+ painter = QPainter(self)
+ painter.setRenderHint(QPainter.Antialiasing)
+
+ s = self._BOX_SIZE
+ # Centre the box in the widget
+ ox = (self.width() - s) // 2
+ oy = (self.height() - s) // 2
+ box = QRect(ox, oy, s, s)
+
+ # Background
+ if self.isChecked():
+ painter.setBrush(self._FILL_CLR)
+ painter.setPen(QPen(self._FILL_CLR, 1.5))
+ else:
+ painter.setBrush(self._BG_CLR)
+ painter.setPen(QPen(self._BORDER_CLR, 1.5))
+ painter.drawRoundedRect(box, 2, 2)
+
+ # Tick mark (only when checked)
+ if self.isChecked():
+ pen = QPen(self._TICK_CLR, 2.0)
+ pen.setCapStyle(Qt.RoundCap)
+ pen.setJoinStyle(Qt.RoundJoin)
+ painter.setPen(pen)
+ # Tick path: bottom-left → middle-bottom → top-right
+ x0, y0 = ox + 3, oy + s // 2
+ x1, y1 = ox + 6, oy + s - 3
+ x2, y2 = ox + s - 3, oy + 3
+ from PyQt5.QtCore import QPointF
+ from PyQt5.QtGui import QPainterPath
+ path = QPainterPath()
+ path.moveTo(x0, y0)
+ path.lineTo(x1, y1)
+ path.lineTo(x2, y2)
+ painter.drawPath(path)
+
+ painter.end()
+
+
+# ── Internal helper ───────────────────────────────────────────────────────────
+
+def _make_checkbox_widget() -> tuple[QWidget, _CheckBox]:
+ cb = _CheckBox()
+
+ class _Container(QWidget):
+ def mousePressEvent(self, event):
+ cb.setChecked(not cb.isChecked())
+ cb.update()
+ event.accept()
+
+ container = _Container()
+ container.setStyleSheet("background: transparent;")
+ layout = QHBoxLayout(container)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.setAlignment(Qt.AlignCenter)
+ layout.addWidget(cb)
+ return container, cb
+
+
+def _get_checkbox(table: QTableWidget, row: int, col: int) -> _CheckBox | None:
+ widget = table.cellWidget(row, col)
+ if widget is None:
+ return None
+ return widget.findChild(_CheckBox)
+
+
+# ── Public API ────────────────────────────────────────────────────────────────
+
+def populate_checkbox_table(table: QTableWidget) -> None:
+ """
+ Place a centred checkbox in every cell of *table*.
+
+ Unchecked cells show an empty square □; checked cells show a
+ filled square with a white tick ✓.
+
+ The table's current rowCount() and columnCount() are used.
+
+ Parameters
+ ----------
+ table : QTableWidget
+ A pre-configured table (row/column count and headers already set).
+ """
+ table.setUpdatesEnabled(False)
+ for row in range(table.rowCount()):
+ for col in range(table.columnCount()):
+ table.setItem(row, col, QTableWidgetItem())
+ container, _cb = _make_checkbox_widget()
+ table.setCellWidget(row, col, container)
+ table.setUpdatesEnabled(True)
+
+
+def set_checkbox(
+ table: QTableWidget,
+ row: int,
+ col: int,
+ checked: bool,
+) -> None:
+ """
+ Set the checked state of the checkbox at (*row*, *col*).
+
+ Parameters
+ ----------
+ table : QTableWidget
+ row : int — zero-based row index
+ col : int — zero-based column index
+ checked : bool — True to check, False to uncheck
+
+ Raises
+ ------
+ IndexError if (row, col) is outside the table dimensions.
+ ValueError if the cell does not contain a checkbox.
+ """
+ if row < 0 or row >= table.rowCount():
+ raise IndexError(
+ f"Row {row} out of range (table has {table.rowCount()} rows)."
+ )
+ if col < 0 or col >= table.columnCount():
+ raise IndexError(
+ f"Column {col} out of range "
+ f"(table has {table.columnCount()} columns)."
+ )
+ cb = _get_checkbox(table, row, col)
+ if cb is None:
+ raise ValueError(
+ f"No checkbox found at ({row}, {col}). "
+ "Call populate_checkbox_table() first."
+ )
+ cb.setChecked(checked)
+
+
+def get_checkbox_states(table: QTableWidget) -> list[list[bool]]:
+ """
+ Return the checked state of every checkbox as a 2-D list.
+
+ Returns
+ -------
+ list[list[bool]]
+ states[row][col] is True if checked, False otherwise.
+ Cells without a checkbox return False.
+
+ Example
+ -------
+ states = get_checkbox_states(my_table)
+ if states[2][3]:
+ print("Row 2, col 3 is checked")
+ """
+ return [
+ [
+ (cb.isChecked() if (cb := _get_checkbox(table, row, col)) else False)
+ for col in range(table.columnCount())
+ ]
+ for row in range(table.rowCount())
+ ]
+
diff --git a/main.py b/main.py
index 6f031a1..967ae32 100644
--- a/main.py
+++ b/main.py
@@ -10,6 +10,12 @@ from ui.BeamlineGUI import Ui_BeamlineGUI
from beamline_editor import BeamlineEditorWidget
from beamline_editor.table_utils import populate_table, populate_table_comparison
from beamline_editor.excel_utils import read_excel_sheet
+from beamline_editor.checkbox_table import (
+ populate_checkbox_table,
+ set_checkbox,
+ get_checkbox_states,
+)
+from beamline_editor.bool_mutations import bool_mutations
from elements import *
from containers import *
@@ -37,6 +43,8 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI):
# )
QtWidgets.QVBoxLayout(self.UIEditorBox).addWidget(self.editor)
+ self.branchtable()
+
self.actionSave_Templates.triggered.connect(self.saveTemplates)
self.actionLoad_Templates.triggered.connect(self.loadTemplates)
@@ -65,6 +73,48 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI):
self.plrecs=[]
+ def branchtable(self):
+ self.switches=['S20SY02','S30SY01','SINEG01','S10DI01','SARBD01','SATBD01']
+ self.targets=['Aramis (FE)','Athos (FE)', 'Porthos','Gun','Injector','Aramis','Athos']
+ self.UIBranchTable.setRowCount(len(self.targets))
+ self.UIBranchTable.setColumnCount(len(self.switches))
+ self.UIBranchTable.setHorizontalHeaderLabels(self.switches)
+ self.UIBranchTable.setVerticalHeaderLabels(self.targets)
+ populate_checkbox_table(self.UIBranchTable)
+ set_checkbox(self.UIBranchTable,1,0,True)
+ set_checkbox(self.UIBranchTable,2,1,True)
+ set_checkbox(self.UIBranchTable, 3, 2, True)
+ set_checkbox(self.UIBranchTable, 4, 3, True)
+ set_checkbox(self.UIBranchTable, 5, 4, True)
+ set_checkbox(self.UIBranchTable, 6, 5, True)
+ set_checkbox(self.UIBranchTable, 6, 0, True)
+
+ def findBranching(self):
+ branchingID=[]
+ for key in self.elementDB.keys():
+ ele = self.elementDB[key]
+ if isinstance(ele, Dipole) and ele.branching:
+ branchingID.append(key)
+ print('Branching elements:')
+ for key in branchingID:
+ print(' ID:', key)
+ simpleBranching=self.UISimpleBranch.isChecked()
+ if simpleBranching:
+ print('Simple Branching...')
+ branchMatrix = get_checkbox_states(self.UIBranchTable)
+ targetnames=copy.deepcopy(self.targets)
+ branchNames=copy.deepcopy(self.switches)
+ branchIDs=None
+ else:
+ branchMatrix = bool_mutations(len(branchingID))
+ branchIDs=copy.deepcopy(branchingID)
+ targetnames=['Line%d' % (i+1) for i in range(2**len(branchingID))]
+ branchNames=None
+ return {'Matrix':branchMatrix,'Targets':targetnames,'Branches':branchNames,'BranchIDs':branchIDs}
+
+ ######################################
+ # saving and loading
+
def saveas(self):
options = QtWidgets.QFileDialog.Options()
options |= QtWidgets.QFileDialog.DontUseNativeDialog
@@ -169,6 +219,10 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI):
template=json.load(file)
self.editor.set_templates(template)
+
+ ###########################################
+ # basic interface functionality with the editor
+
def addElement(self,element_type: str, node_id: str):
if node_id in self.elementDB.keys():
return # this is a repopulation of the database when loading or importing
@@ -274,27 +328,36 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI):
return
- def findBranchingDipoles(self):
- self.branchingID.clear()
- for key in self.elementDB.keys():
- ele = self.elementDB[key]
- if isinstance(ele,Dipole) and ele.branching:
- self.branchingID.append(key)
- print('Branching elements:')
- for key in self.branchingID:
- print(' ID:',key)
+ #############################################################################3
+ # flattening event
+
+ def flatten(self, node_id, case_num=1):
+ """
+ This is called if in the pane the flatten command is selected in the contextual menue
+ It should browse through all connected nodes and construct the lines
+ At the end the lines are converted to a proto list
+ :param node_id: ID of the starting element (string)
+ :param case_num: Case value fro branchine (1,2,3)
+ :return: None
+ """
+ print('Flatten beamline for case:', case_num)
+ branches=self.findBranching()
+ self.flattenBranchID=branches['BranchIDs']
+ self.flattenBranchNames=branches['Branches']
+ self.lines.clear()
+ for i, tar in enumerate(branches['Targets']):
+ self.flattenSwitches=branches['Matrix'][i]
+ print('Flatten for line:',tar)
+ self.lines[tar] = copy.deepcopy(self.flattenSingleLine(node_id, case_num=case_num))
+ # generate the proto list
+ self.PL.generateLayout(self.lines)
+ self.plrecs = [self.PL.info[ele] for ele in self.PL.order if len(self.PL.info[ele]['Prefix']) > 5]
+ populate_table(self.UIProtoList, self.plrecs)
+ self.tabWidget.setCurrentIndex(1)
def flattenSingleLine(self,node_id,branch=0,case_num=1):
self.targetReached=False
- self.currentBranch=''
- self.branching.clear()
- for ib, id in enumerate(self.branchingID):
- ibit = 2**ib
- if branch & ibit > 0:
- self.branching[id]=True
- else:
- self.branching[id]=False
type = self.editor.getElementType(node_id)
name = 'XXX'
if type == 'Line':
@@ -304,41 +367,12 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI):
name = self.elementDB[node_id].Name
line = LineContainer(namein=name, Lin=0)
line.clear()
- if self.verbose:
- print('\nUnwrapping beamline...\n')
self.branchingTemp.clear()
self.unwrap(name, node_id, line, case_num)
for key in self.branchingTemp.keys():
self.elementDB[key].LengthRes=self.branchingTemp[key]
return line
- def flatten(self, node_id, case_num=1 ):
- print('Flatten beamline for case:', case_num)
- self.findBranchingDipoles()
- nbranch = len(self.branchingID)
- print('Possible Number of Branches:', 2**nbranch)
- self.lines.clear()
-
-# for ib in range(2**nbranch):
- for ib in range(0,4):
- line=self.flattenSingleLine(node_id,branch=ib,case_num=case_num)
- if self.currentBranch=='':
- self.currentBranch='%d' % ib
- if not self.currentBranch in self.lines.keys():
- self.lines[self.currentBranch]=copy.deepcopy(line)
- else:
- print('Skipping redundant line:',self.currentBranch)
- print('Writing Layout for the lines:')
- for key in self.lines.keys():
- print(' ',key)
- self.PL.generateLayout(self.lines)
- self.plrecs = [self.PL.info[ele] for ele in self.PL.order if len(self.PL.info[ele]['Prefix'])> 5]
- populate_table(self.UIProtoList,self.plrecs)
- self.tabWidget.setCurrentIndex(1)
-
-
-
-
def unwrap(self, name, node_id,line,case_num):
if self.verbose:
print('Unwrapping Line: %s' % name)
@@ -350,8 +384,6 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI):
self.report(ele, name)
type = self.editor.getElementType(ele)
if type == 'Line':
- if self.verbose:
- print('Unwrapping- Adding a Line')
line.append(self.elementDB[ele],sRef=0,Ref='relative')
subline = self.elementDB[ele]
subline.clear()
@@ -374,11 +406,8 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI):
elif type == 'Case' or type == 'Merge':
continue
elif type == 'Target':
- target=self.elementDB[ele].Name
- if not target in self.lines.keys():
- print('New Target reached:',self.elementDB[ele].Name)
+ print(' Target reached:',self.elementDB[ele].Name)
self.targetReached=True
- self.currentBranch=self.elementDB[ele].Name
else:
sRef=self.elementDB[ele].OffsetS
Ref='absolute'
@@ -386,15 +415,26 @@ class BeamlineEditor(QtWidgets.QMainWindow, Ui_BeamlineGUI):
Ref='relative'
line.append(self.elementDB[ele],sRef=sRef,Ref=Ref)
self.elementDB[ele].Prefix=name
- if ele in self.branching.keys():
- if self.branching[ele] is True:
- print('Branching at element:', name+'-'+self.elementDB[ele].Name,'with angle:',self.elementDB[ele].design_angle)
- self.elementDB[ele].angle=self.elementDB[ele].design_angle
- line.hasBranchPoint=True
- return True
+ # check for branching point
+ if type == 'Dipole' and self.elementDB[ele].branching:
+ doBranching = False
+ if not self.flattenBranchID is None:
+ if ele in self.flattenBranchID:
+ idx = self.flattenBranchID.index(ele)
+ doBranching = self.flattenSwitches[idx]
+ else:
+ if name in self.flattenBranchNames :
+ idx = self.flattenBranchNames.index(name)
+ doBranching = self.flattenSwitches[idx]
+ if doBranching:
+ print(' Branching at element:', name + '-' + self.elementDB[ele].Name, 'with angle:', self.elementDB[ele].design_angle)
+ self.elementDB[ele].angle = self.elementDB[ele].design_angle
+ line.hasBranchPoint = True
+ secondBranch=True
+ break
else:
self.elementDB[ele].angle=0
- line.hasBranchPoint= False
+ line.hasBranchPoint = False
if secondBranch:
if tree.secondary:
self.unwrap(name, tree.secondary.node_id, line, case_num)
diff --git a/ui/BeamlineGUI.py b/ui/BeamlineGUI.py
index a3d233f..a4e5380 100644
--- a/ui/BeamlineGUI.py
+++ b/ui/BeamlineGUI.py
@@ -43,6 +43,94 @@ class Ui_BeamlineGUI(object):
self.UIProtoList.setRowCount(0)
self.verticalLayout_2.addWidget(self.UIProtoList)
self.tabWidget.addTab(self.tab_2, "")
+ self.tab_4 = QtWidgets.QWidget()
+ self.tab_4.setObjectName("tab_4")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.tab_4)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.verticalLayout_3 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_3.setObjectName("verticalLayout_3")
+ self.gridLayout = QtWidgets.QGridLayout()
+ self.gridLayout.setObjectName("gridLayout")
+ self.UIFlattenOffsetFlag = QtWidgets.QCheckBox(self.tab_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.UIFlattenOffsetFlag.sizePolicy().hasHeightForWidth())
+ self.UIFlattenOffsetFlag.setSizePolicy(sizePolicy)
+ self.UIFlattenOffsetFlag.setChecked(True)
+ self.UIFlattenOffsetFlag.setObjectName("UIFlattenOffsetFlag")
+ self.gridLayout.addWidget(self.UIFlattenOffsetFlag, 0, 0, 1, 1)
+ self.UIFlattenOffset = QtWidgets.QLineEdit(self.tab_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.UIFlattenOffset.sizePolicy().hasHeightForWidth())
+ self.UIFlattenOffset.setSizePolicy(sizePolicy)
+ self.UIFlattenOffset.setObjectName("UIFlattenOffset")
+ self.gridLayout.addWidget(self.UIFlattenOffset, 0, 1, 1, 1)
+ self.lineEdit_2 = QtWidgets.QLineEdit(self.tab_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.lineEdit_2.sizePolicy().hasHeightForWidth())
+ self.lineEdit_2.setSizePolicy(sizePolicy)
+ self.lineEdit_2.setObjectName("lineEdit_2")
+ self.gridLayout.addWidget(self.lineEdit_2, 1, 0, 1, 1)
+ self.UITolerances = QtWidgets.QLineEdit(self.tab_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.UITolerances.sizePolicy().hasHeightForWidth())
+ self.UITolerances.setSizePolicy(sizePolicy)
+ self.UITolerances.setObjectName("UITolerances")
+ self.gridLayout.addWidget(self.UITolerances, 1, 1, 1, 1)
+ self.verticalLayout_3.addLayout(self.gridLayout)
+ spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ self.verticalLayout_3.addItem(spacerItem)
+ self.horizontalLayout.addLayout(self.verticalLayout_3)
+ self.groupBox = QtWidgets.QGroupBox(self.tab_4)
+ self.groupBox.setObjectName("groupBox")
+ self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox)
+ self.verticalLayout_4.setObjectName("verticalLayout_4")
+ self.UISimpleBranch = QtWidgets.QCheckBox(self.groupBox)
+ self.UISimpleBranch.setChecked(True)
+ self.UISimpleBranch.setObjectName("UISimpleBranch")
+ self.verticalLayout_4.addWidget(self.UISimpleBranch)
+ self.UIBranchTable = QtWidgets.QTableWidget(self.groupBox)
+ self.UIBranchTable.setObjectName("UIBranchTable")
+ self.UIBranchTable.setColumnCount(6)
+ self.UIBranchTable.setRowCount(7)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setVerticalHeaderItem(0, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setVerticalHeaderItem(1, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setVerticalHeaderItem(2, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setVerticalHeaderItem(3, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setVerticalHeaderItem(4, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setVerticalHeaderItem(5, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setVerticalHeaderItem(6, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setHorizontalHeaderItem(0, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setHorizontalHeaderItem(1, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setHorizontalHeaderItem(2, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setHorizontalHeaderItem(3, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setHorizontalHeaderItem(4, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.UIBranchTable.setHorizontalHeaderItem(5, item)
+ self.verticalLayout_4.addWidget(self.UIBranchTable)
+ self.horizontalLayout.addWidget(self.groupBox)
+ spacerItem1 = QtWidgets.QSpacerItem(967, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem1)
+ self.tabWidget.addTab(self.tab_4, "")
self.verticalLayout.addWidget(self.tabWidget)
BeamlineGUI.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(BeamlineGUI)
@@ -111,6 +199,39 @@ class Ui_BeamlineGUI(object):
BeamlineGUI.setWindowTitle(_translate("BeamlineGUI", "MainWindow"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("BeamlineGUI", "Editor"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("BeamlineGUI", "Proto List"))
+ self.UIFlattenOffsetFlag.setText(_translate("BeamlineGUI", "Offset for Flatten"))
+ self.UIFlattenOffset.setText(_translate("BeamlineGUI", "-0.1"))
+ self.lineEdit_2.setText(_translate("BeamlineGUI", "Tolerance"))
+ self.UITolerances.setText(_translate("BeamlineGUI", "1e-5"))
+ self.groupBox.setTitle(_translate("BeamlineGUI", "Branching"))
+ self.UISimpleBranch.setText(_translate("BeamlineGUI", "Simplified Branching"))
+ item = self.UIBranchTable.verticalHeaderItem(0)
+ item.setText(_translate("BeamlineGUI", "Aramis"))
+ item = self.UIBranchTable.verticalHeaderItem(1)
+ item.setText(_translate("BeamlineGUI", "Athos"))
+ item = self.UIBranchTable.verticalHeaderItem(2)
+ item.setText(_translate("BeamlineGUI", "Gun "))
+ item = self.UIBranchTable.verticalHeaderItem(3)
+ item.setText(_translate("BeamlineGUI", "Injector Dump"))
+ item = self.UIBranchTable.verticalHeaderItem(4)
+ item.setText(_translate("BeamlineGUI", "Injector"))
+ item = self.UIBranchTable.verticalHeaderItem(5)
+ item.setText(_translate("BeamlineGUI", "Aramis (Straight)"))
+ item = self.UIBranchTable.verticalHeaderItem(6)
+ item.setText(_translate("BeamlineGUI", "Athos (Straight)"))
+ item = self.UIBranchTable.horizontalHeaderItem(0)
+ item.setText(_translate("BeamlineGUI", "S20SY02"))
+ item = self.UIBranchTable.horizontalHeaderItem(1)
+ item.setText(_translate("BeamlineGUI", "S30SY01"))
+ item = self.UIBranchTable.horizontalHeaderItem(2)
+ item.setText(_translate("BeamlineGUI", "SINEG01"))
+ item = self.UIBranchTable.horizontalHeaderItem(3)
+ item.setText(_translate("BeamlineGUI", "S10DI01"))
+ item = self.UIBranchTable.horizontalHeaderItem(4)
+ item.setText(_translate("BeamlineGUI", "SARBD01"))
+ item = self.UIBranchTable.horizontalHeaderItem(5)
+ item.setText(_translate("BeamlineGUI", "SATBD01"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("BeamlineGUI", "Settings"))
self.menuFile.setTitle(_translate("BeamlineGUI", "FILE"))
self.menuLAYOUT.setTitle(_translate("BeamlineGUI", "LAYOUT"))
self.actionNew_Layout.setText(_translate("BeamlineGUI", "New Layout"))
diff --git a/ui/BeamlineGUI.ui b/ui/BeamlineGUI.ui
index 01e055b..d098e08 100644
--- a/ui/BeamlineGUI.ui
+++ b/ui/BeamlineGUI.ui
@@ -24,7 +24,7 @@ background-color: rgb(13, 15, 26);
-
- 2
+ 0
@@ -127,6 +127,94 @@ background-color: rgb(13, 15, 26);
+ -
+
+
+ Branching
+
+
+
-
+
+
+ Simplified Branching
+
+
+ true
+
+
+
+ -
+
+
+
+ Aramis
+
+
+
+
+ Athos
+
+
+
+
+ Gun
+
+
+
+
+ Injector Dump
+
+
+
+
+ Injector
+
+
+
+
+ Aramis (Straight)
+
+
+
+
+ Athos (Straight)
+
+
+
+
+ S20SY02
+
+
+
+
+ S30SY01
+
+
+
+
+ SINEG01
+
+
+
+
+ S10DI01
+
+
+
+
+ SARBD01
+
+
+
+
+ SATBD01
+
+
+
+
+
+
+
-
@@ -134,7 +222,7 @@ background-color: rgb(13, 15, 26);
- 1944
+ 967
20