Initial Round of Sandbox implementation

This commit is contained in:
2025-05-06 16:52:59 +02:00
committed by Sven
parent b90935d1a5
commit a241e2889f
6 changed files with 337 additions and 152 deletions

View File

@@ -1,25 +1,95 @@
import re
import sys
from typing import is_typeddict
from sfbd.interface import getSnapPV,getSnapVal
from epics import PV
class Machine:
def __init__(self):
print('Initializing PVs for Snapshot...')
mags = ['SINLH02-MBND100', 'SINBC02-MBND100', 'S10BC02-MBND100', 'SARCL02-MBND100', 'SATCL01-MBND100',
'SATUN05-MBND100']
self.snapPVs = getSnapPV() + [PV('%s:ENERGY-OP' % ele, auto_monitor=False) for ele in mags]
self.omfilter = ['.*-RMSM:SM-SET','.*-RSYS:REQUIRED-OP','.*-RSYS:SET-ACC-VOLT','.*-RSYS:SET-BEAM-PHASE']
def __init__(self, parent=None, office=False):
self.parent=parent
self.offline = office
self.PVs={}
self.PVNames = []
def initPVs(self,elements=None):
filters = ['-RMSM:SM-SET', '-RSYS:REQUIRED-OP', '-RSYS:SET-ACC-VOLT', '-RSYS:SET-BEAM-PHASE']
self.PVNames.clear()
for ele0 in elements:
ele = ele0.Name.replace('.','-').upper()
if 'MQUA' in ele:
self.PVNames += [ele+':K1L-SET']
if 'MSEX' in ele:
self.PVNames += [ele+':K2L-SET']
if 'MBND' in ele:
if 'MBND100' in ele:
self.PVNames += [ele + ':K0L-SET']
elif 'SATMA01-MBND300' in ele:
self.PVNames += [ele + ':K0L-SET']
if 'RACC100' in ele:
name=ele[0:7]
self.PVNames += [name + filter for filter in filters]
if 'UMOD' in ele:
self.PVNames += [ele[0:7] + '-UMOD:K-SET']
if 'UIND' in ele:
if 'SARUN' in ele:
self.PVNames += [ele + ':K_UND_SET']
elif 'SATUN' in ele:
self.PVNames += [ele + ':K_READ', ele + ':POL-SET']
elif 'SINLH' in ele:
self.PVNames += [ele + ':K-SP', ele + ':X-SP']
self.PVNames += ['SINLH02-MBND100:ENERGY-OP']
def getSnap(self,filters = ['.*']):
if isinstance(filters, str):
filters = [filters]
recomp = re.compile('|'.join(filters))
# pvget = [pv for pv in self.snapPVs if recomp.match(pv.pvname)]
# self.snap = getSnapVal(pvget)
if self.offline:
self.PVs = {ele: None for ele in self.PVNames}
else:
self.PVs={ele:PV(ele, auto_monitor=False) for ele in self.PVNames}
def getMachineStatus(self):
if self.offline:
values = {ele: self.PVs[ele] for ele in self.PVs.keys()}
else:
values = {ele:self.PVs[ele].get() for ele in self.PVs.keys()}
magnets={}
rf = {}
und={}
energy={}
for key in self.PVs.keys():
if 'MQUA' in key or 'MSEX' in key:
magnets[key[0:15]]=values[key]
if 'MBND' in key:
if 'SINBC' in key or 'SINLH' in key or 'S10BC' in key or 'SATMA' in key or 'SATUN' in key:
magnets[key[0:15]] = values[key]
if 'UMOD' in key:
und[key[0:12]]=[values[key],0.]
if 'UIND' in key:
if 'SARUN' in key:
und[key[0:15]]=[values[key],0]
elif 'SATUN' in key and 'K_READ' in key:
und[key[0:15]]=[values[key],values[key.replace('K_READ','POL-SET')]]
elif 'SINLH' in key and 'K-SP' in key:
x = values[key.replace('K-SP','X-SP')]
if x is None:
und[key[0:15]] = [None,0]
elif x < -100:
und[key[0:15]]=[0,0]
else:
und[key[0:15]] = [values[key], 0]
if 'RMSM' in key:
if values[key]is None:
rf[key[0:7]+'-RSYS']=[None,0]
elif values[key]<9:
rf[key[0:7]+'-RSYS']=[0,0]
else:
# ['-RMSM:SM-SET', '-RSYS:REQUIRED-OP', '-RSYS:SET-ACC-VOLT', '-RSYS:SET-BEAM-PHASE']
key = key.replace('RMSM:SM-SET','RSYS:REQUIRED-OP')
if values[key] == 0:
rf[key[0:7] + '-RSYS'] = [0, 0]
else:
key1 = key.replace('SM-SET','SET-ACC-VOLT')
key2 = key.replace('SM-SET', 'SET-BEAM-PHASE')
rf[key[0:7] + '-RSYS'] = [values[key1], values[key2]]
if 'ENERGY-OP' in key:
energy[key[0:15]]=values[key]
status={'Magnet':magnets,'RF':rf,'Undulator':und,'Energy':energy}
return status

View File

@@ -16,17 +16,19 @@ class Model:
# hook up events
self.eventHandling()
def getElements(self):
return self.om.listElement('*', 1)
def getSettings(self):
elements = self.om.listElement('*',1)
elements = self.getElements()
quadrupoles={}
sextupoles={}
dipoles={}
rf={}
undulators={}
kicker={}
loc = 'SINLH01.DBAM010'
energy={'location': loc, 'energy':self.om.EnergyAt(loc)}
loc = 'SINLH02.MBND100'
energy={'location': loc, 'energy':self.om.EnergyAt(loc)[0]}
for ele in elements:
if 'MQUA' in ele.Name:
quadrupoles[ele.Name]={'k1':ele.k1,'k1L':ele.k1*ele.Length}
@@ -35,10 +37,10 @@ class Model:
elif 'MBND' in ele.Name:
if 'SINLH' in ele.Name or 'SINBC' in ele.Name or 'S10BC' in ele.Name or 'SATMA' in ele.Name or 'SATUN' in ele.Name:
dipoles[ele.Name]={'angle':ele.angle}
elif 'UIND' in ele.Name:
elif 'UIND' in ele.Name or 'UMOD' in ele.Name:
undulators[ele.Name]={'K':ele.K,'kx':ele.kx,'ky':ele.ky}
elif 'RACC' in ele.Name:
rf[ele.Name]={'Gradient':ele.Gradient,'Phase':ele.Phase}
rf[ele.Name]={'Gradient':ele.Gradient*ele.Length,'Phase':ele.Phase}
elif 'MKAC' in ele.Name or 'MKDC' in ele.Name:
kicker[ele.Name] = {'cory': ele.cory}
return {'Quadrupole':quadrupoles,'Sextupole':sextupoles,'Dipole':dipoles,'RF':rf,'Undulator':undulators,'Kicker':kicker,'Energy':energy}

View File

@@ -27,16 +27,20 @@ class OpticsTools(QtWidgets.QMainWindow, Ui_OpticsGUI):
# initialize online model
self.model = Model(phase=phase,parent=self)
if phase == 0 and office == False:
self.machine = Machine()
else:
self.machine = None
if phase > 0:
office = True
self.machine = Machine(parent = True, office = office)
self.machine.initPVs(self.model.getElements())
self.reference = ReferenceManager(parent = self)
self.sandbox = Sandbox(parent = self, machine = self.machine)
# initialization
self.loadSettingsdirect("/sf/data/applications/BD-OpticsTools/reference/settings/ReferenceSetting.json")
self.sandbox.updateSandbox()
# events handling
self.actionOpen_2.triggered.connect(self.loadSettings)
self.actionSave.triggered.connect(self.saveSettings)

View File

@@ -1,10 +1,196 @@
from PyQt5 import QtCore, QtGui, QtWidgets
import numpy as np
import re
CGrey = QtGui.QColor(230,230,230)
CBeige = QtGui.QColor(250, 240, 200)
CGreen = QtGui.QColor(100, 255, 100)
CYellow = QtGui.QColor(255, 255, 0)
CRed = QtGui.QColor(255, 100, 100)
CWhite = QtGui.QColor(255, 255, 255)
class Sandbox:
def __init__(self, parent=None,machine=False):
self.parent=parent
self.machine=machine
self.parent.MagReStart.editingFinished.connect(self.updateSandbox)
self.parent.MagReFilter.editingFinished.connect(self.updateSandbox)
def updateSandbox(self):
a = 1
machine = self.parent.machine.getMachineStatus()
model = self.parent.model.getSettings()
self.updateMagSandbox(self.parent.MagSB,model,machine['Magnet'])
self.updateUndSandbox(self.parent.UndSB,model,machine['Undulator'])
self.updateRFSandbox(self.parent.RFSB, model, machine['RF'])
self.updateEnergySandbox(model['Energy'],machine['Energy'])
def updateEnergySandbox(self,model,machine):
E0=1.e-6*model['energy']
self.parent.SBE0Model.setText('%7.3f' % E0)
E0 = None
for key in machine.keys():
E0 = machine[key]
if E0 is None:
self.parent.SBE0Machine.setText("---")
else:
self.parent.SBE0Machine.setText('%7.3f' % E0)
def updateSandboxCommon(self,sb,values,colors,labels):
sb.clear()
ncol = len(labels)
nrow = len(values)
sb.setColumnCount(ncol)
sb.setRowCount(nrow)
for i in range(ncol):
sb.setHorizontalHeaderItem(i, QtWidgets.QTableWidgetItem(labels[i]))
for irow,value in enumerate(values):
color=colors[irow]
for icol in range(ncol):
sb.setItem(irow, icol, QtWidgets.QTableWidgetItem(value[icol]))
sb.item(irow, icol).setBackground(color[icol])
sb.resizeColumnsToContents()
sb.verticalHeader().hide()
def updateRFSandbox(self,sb,model,machine):
labels = ['Station', 'Model', 'Model', 'Machine', 'Machine']
values = []
colors = []
for key in machine.keys():
sbvalue = [key[0:7]]
sbcolor = [CWhite]
mokey = key[0:7]+'.RACC100'
print(mokey)
scl=1.
if 'CB' in mokey:
scl = 4
elif 'SINSB03' in mokey or 'SINSB04' in mokey or 'SINXB' in mokey:
scl = 2
if mokey in model['RF'].keys():
Grad=1e-6*model['RF'][mokey]['Gradient']*scl
Phase= model['RF'][mokey]['Phase']
sbvalue+=['%7.3f' % Grad,'%7.3f' % Phase]
sbcolor += [CBeige, CBeige]
else:
sbvalue += ['---', '---']
sbcolor += [CGrey, CGrey]
value = machine[key]
if value[0] is None:
sbvalue += ['---', '---']
sbcolor += [CGrey, CGrey]
else:
sbvalue += ['%f' % machine[key]['Gradient'], '%f' % machine[key]['Phase']]
sbcolor += [CBeige, CBeige]
values.append(sbvalue)
colors.append(sbcolor)
self.updateSandboxCommon(sb, values, colors, labels)
def updateUndSandbox(self,sb,model,machine,):
labels = ['Undulator', 'Model', 'Model', 'Machine', 'Machine']
values=[]
colors=[]
pol = ['LH', 'LV+', 'LV-', 'C+', 'C-', 'ZL']
for key in machine.keys():
sbvalue=[key]
sbcolor=[CWhite]
mokey = key.replace('-', '.')
if 'UMOD' in mokey:
if 'SATDI' in mokey:
mokey = mokey + '050'
else:
mokey = mokey + '030'
if mokey in model['Undulator'].keys():
value = model['Undulator'][mokey]
K = '%7.3f' % value['K']
kx = value['kx']
ky = value['ky']
if np.abs(kx - 1) < 0.1:
Pol = 'LV'
elif np.abs(ky - 1) < 0.1:
Pol = 'LH'
elif np.abs(kx - ky) < 0.1:
Pol = 'C'
else:
Pol = 'undef'
sbvalue+=[K,Pol]
sbcolor+=[CBeige,CBeige]
else:
sbvalue+=['---','---']
sbcolor+=[CGrey,CGrey]
value = machine[key]
# machine
if value[0] is None:
sbvalue +=['---','---']
sbcolor += [CGrey, CGrey]
else:
sbvalue += ['%7.3f' % value[0], pol[int(value[1])]]
sbcolor += [CBeige,CBeige]
values.append(sbvalue)
colors.append(sbcolor)
self.updateSandboxCommon(sb,values,colors,labels)
def updateMagSandbox(self,sb,magnets,machine):
labels = ['Magnet', 'Model', 'Machine']
filt = str(self.parent.MagReStart.text())
found = False
if filt == '' or filt == '*':
found = True
regpat = re.compile(filt)
filt2 = str(self.parent.MagReFilter.text())
filt2 = '.*' + filt2
regpat2 = re.compile(filt2)
values = []
colors=[]
for key in machine.keys():
if regpat.match(key):
found = True
if not (found and regpat2.match(key)):
continue
sbval=[key]
sbcol=[CWhite]
maval = machine[key]
moval=None
mokey = key.replace('-','.')
if 'MQUA' in key and mokey in magnets['Quadrupole'].keys():
moval = magnets['Quadrupole'][mokey]['k1L']
if 'MSEX' in key and mokey in magnets['Sextupole'].keys():
moval = magnets['Sextupole'][mokey]['k2L']
if 'MBND' in key and mokey in magnets['Dipole'].keys():
moval = magnets['Dipole'][mokey]['angle']
if moval is None: # model
sbval.append('---')
sbcol.append(CGrey)
else:
sbval.append('%7.3f' % moval)
sbcol.append(CBeige)
if maval is None: # machine
sbval.append('---')
sbcol.append(CGrey)
else:
sbval.append('%7.3' % maval)
if moval is None:
sbcol.append(CGrey)
else:
df = np.abs(moval-maval)
if df < 0.001:
sbcol.append(CGreen)
elif df < 0.01:
sbcol.append(CYellow)
else:
sbcol.append(CRed)
values.append(sbval)
colors.append(sbcol)
self.updateSandboxCommon(sb, values, colors, labels)

View File

@@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_OpticsGUI(object):
def setupUi(self, OpticsGUI):
OpticsGUI.setObjectName("OpticsGUI")
OpticsGUI.resize(1052, 780)
OpticsGUI.resize(813, 775)
self.centralwidget = QtWidgets.QWidget(OpticsGUI)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.centralwidget)
@@ -298,6 +298,23 @@ class Ui_OpticsGUI(object):
self.groupBox_9.setObjectName("groupBox_9")
self.verticalLayout_17 = QtWidgets.QVBoxLayout(self.groupBox_9)
self.verticalLayout_17.setObjectName("verticalLayout_17")
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.SBE0Model = QtWidgets.QLineEdit(self.groupBox_9)
self.SBE0Model.setObjectName("SBE0Model")
self.gridLayout_2.addWidget(self.SBE0Model, 1, 1, 1, 1)
self.SBE0Machine = QtWidgets.QLineEdit(self.groupBox_9)
self.SBE0Machine.setObjectName("SBE0Machine")
self.gridLayout_2.addWidget(self.SBE0Machine, 1, 2, 1, 1)
self.label_26 = QtWidgets.QLabel(self.groupBox_9)
self.label_26.setObjectName("label_26")
self.gridLayout_2.addWidget(self.label_26, 1, 0, 1, 1)
self.verticalLayout_17.addLayout(self.gridLayout_2)
self.RFSB = QtWidgets.QTableWidget(self.groupBox_9)
self.RFSB.setObjectName("RFSB")
self.RFSB.setColumnCount(0)
self.RFSB.setRowCount(0)
self.verticalLayout_17.addWidget(self.RFSB)
self.UndSB = QtWidgets.QTableWidget(self.groupBox_9)
self.UndSB.setObjectName("UndSB")
self.UndSB.setColumnCount(0)
@@ -310,51 +327,11 @@ class Ui_OpticsGUI(object):
self.SB2ModUnd.setObjectName("SB2ModUnd")
self.verticalLayout_17.addWidget(self.SB2ModUnd)
self.horizontalLayout_5.addWidget(self.groupBox_9)
self.RFgroup = QtWidgets.QGroupBox(self.tab_8)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.RFgroup.sizePolicy().hasHeightForWidth())
self.RFgroup.setSizePolicy(sizePolicy)
self.RFgroup.setMinimumSize(QtCore.QSize(400, 0))
self.RFgroup.setObjectName("RFgroup")
self.verticalLayout_18 = QtWidgets.QVBoxLayout(self.RFgroup)
self.verticalLayout_18.setObjectName("verticalLayout_18")
self.label_25 = QtWidgets.QLabel(self.RFgroup)
self.label_25.setObjectName("label_25")
self.verticalLayout_18.addWidget(self.label_25)
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.label_26 = QtWidgets.QLabel(self.RFgroup)
self.label_26.setObjectName("label_26")
self.gridLayout_2.addWidget(self.label_26, 1, 0, 1, 1)
self.label_27 = QtWidgets.QLabel(self.RFgroup)
self.label_27.setObjectName("label_27")
self.gridLayout_2.addWidget(self.label_27, 2, 0, 1, 1)
self.SBE0Machine = QtWidgets.QLineEdit(self.RFgroup)
self.SBE0Machine.setObjectName("SBE0Machine")
self.gridLayout_2.addWidget(self.SBE0Machine, 2, 1, 1, 1)
self.SBE0Model = QtWidgets.QLineEdit(self.RFgroup)
self.SBE0Model.setObjectName("SBE0Model")
self.gridLayout_2.addWidget(self.SBE0Model, 1, 1, 1, 1)
self.verticalLayout_18.addLayout(self.gridLayout_2)
self.RFSB = QtWidgets.QTableWidget(self.RFgroup)
self.RFSB.setObjectName("RFSB")
self.RFSB.setColumnCount(0)
self.RFSB.setRowCount(0)
self.verticalLayout_18.addWidget(self.RFSB)
self.Mach2ModRF = QtWidgets.QPushButton(self.RFgroup)
self.Mach2ModRF.setObjectName("Mach2ModRF")
self.verticalLayout_18.addWidget(self.Mach2ModRF)
self.SB2ModRF = QtWidgets.QPushButton(self.RFgroup)
self.SB2ModRF.setObjectName("SB2ModRF")
self.verticalLayout_18.addWidget(self.SB2ModRF)
self.horizontalLayout_5.addWidget(self.RFgroup)
self.TabMaster.addTab(self.tab_8, "")
self.verticalLayout_4.addWidget(self.TabMaster)
OpticsGUI.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(OpticsGUI)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1052, 22))
self.menubar.setGeometry(QtCore.QRect(0, 0, 813, 22))
self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(self.menubar)
self.menuFile.setObjectName("menuFile")
@@ -480,7 +457,7 @@ class Ui_OpticsGUI(object):
self.menubar.addAction(self.menuHelp.menuAction())
self.retranslateUi(OpticsGUI)
self.TabMaster.setCurrentIndex(0)
self.TabMaster.setCurrentIndex(1)
self.actionQuit.triggered.connect(OpticsGUI.close) # type: ignore
QtCore.QMetaObject.connectSlotsByName(OpticsGUI)
@@ -521,16 +498,11 @@ class Ui_OpticsGUI(object):
self.SB2MachineMag.setText(_translate("OpticsGUI", "Model -> Machine"))
self.Mach2ModMag.setText(_translate("OpticsGUI", "Model <- Sandbox <- Machine"))
self.SB2ModMag.setText(_translate("OpticsGUI", "Model <- Sandbox"))
self.groupBox_9.setTitle(_translate("OpticsGUI", "Undulator/ID (K/Gap and Pol./Offset"))
self.groupBox_9.setTitle(_translate("OpticsGUI", "RF (Gradient & Phase) + Undulator (K, Pol)"))
self.label_26.setText(_translate("OpticsGUI", "Energy"))
self.Mach2ModUnd.setText(_translate("OpticsGUI", "Model <- Sandbox <- Machine"))
self.SB2ModUnd.setText(_translate("OpticsGUI", "Model <- Sandbox"))
self.RFgroup.setTitle(_translate("OpticsGUI", "RF (Gradient and Phase)"))
self.label_25.setText(_translate("OpticsGUI", "Initial Energy (MeV)"))
self.label_26.setText(_translate("OpticsGUI", "Model"))
self.label_27.setText(_translate("OpticsGUI", "Machine"))
self.Mach2ModRF.setText(_translate("OpticsGUI", "Model <- Sandbox <- Machine"))
self.SB2ModRF.setText(_translate("OpticsGUI", "Model <- Sandbox"))
self.TabMaster.setTabText(self.TabMaster.indexOf(self.tab_8), _translate("OpticsGUI", "Settings Sandbox"))
self.TabMaster.setTabText(self.TabMaster.indexOf(self.tab_8), _translate("OpticsGUI", "Sandbox"))
self.menuFile.setTitle(_translate("OpticsGUI", "File"))
self.menuHelp.setTitle(_translate("OpticsGUI", "Help"))
self.actionOpen_2.setText(_translate("OpticsGUI", "Open Settings..."))

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1052</width>
<height>780</height>
<width>813</width>
<height>775</height>
</rect>
</property>
<property name="windowTitle">
@@ -494,9 +494,29 @@
</size>
</property>
<property name="title">
<string>Undulator/ID (K/Gap and Pol./Offset</string>
<string>RF (Gradient &amp; Phase) + Undulator (K, Pol)</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_17">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1">
<widget class="QLineEdit" name="SBE0Model"/>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="SBE0Machine"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>Energy</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTableWidget" name="RFSB"/>
</item>
<item>
<widget class="QTableWidget" name="UndSB"/>
</item>
@@ -517,75 +537,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="RFgroup">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>RF (Gradient and Phase)</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_18">
<item>
<widget class="QLabel" name="label_25">
<property name="text">
<string>Initial Energy (MeV)</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>Model</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Machine</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="SBE0Machine"/>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="SBE0Model"/>
</item>
</layout>
</item>
<item>
<widget class="QTableWidget" name="RFSB"/>
</item>
<item>
<widget class="QPushButton" name="Mach2ModRF">
<property name="text">
<string>Model &lt;- Sandbox &lt;- Machine</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="SB2ModRF">
<property name="text">
<string>Model &lt;- Sandbox</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
@@ -597,7 +548,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1052</width>
<width>813</width>
<height>22</height>
</rect>
</property>