Changeset 642
- Timestamp:
- Oct 4, 2011 1:32:41 AM (12 years ago)
- Location:
- moxy/trunk/src/moxy
- Files:
-
- 1 added
- 1 deleted
- 7 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
moxy/trunk/src/moxy/examples/USAXS_XY.xml
r56 r642 1 1 <?xml version="1.0" ?> 2 <?xml-stylesheet type="text/xsl" href=" wxmtxy_settings.xsl" ?>2 <?xml-stylesheet type="text/xsl" href="moxy_settings.xsl" ?> 3 3 4 4 <!-- … … 12 12 --> 13 13 14 < wxmtxy date="2009-04-12" time="17:04:29" version="1.0">14 <moxy date="2009-04-12" time="17:04:29" version="1.0"> 15 15 <XYpair name="sample" selected="True"> 16 16 <EPICS_configuration> 17 17 <axis name="y"> 18 18 <flag isMotorRec="True"/> 19 <field name="VAL" pv=" 32idbLAX:m58:c2:m2"/>19 <field name="VAL" pv="prj:m2"/> 20 20 </axis> 21 21 <axis name="x"> 22 22 <flag isMotorRec="True"/> 23 <field name="VAL" pv=" 32idbLAX:m58:c2:m1"/>23 <field name="VAL" pv="prj:m1"/> 24 24 </axis> 25 25 </EPICS_configuration> … … 49 49 <axis name="y"> 50 50 <flag isMotorRec="True"/> 51 <field name="VAL" pv=" 32idbLAX:m58:c2:m5"/>51 <field name="VAL" pv="prj:m4"/> 52 52 </axis> 53 53 <axis name="x"> 54 54 <flag isMotorRec="True"/> 55 <field name="VAL" pv=" 32idbLAX:m58:c2:m4"/>55 <field name="VAL" pv="prj:m3"/> 56 56 </axis> 57 57 </EPICS_configuration> … … 88 88 </tab> 89 89 </XYpair> 90 </ wxmtxy>90 </moxy> -
moxy/trunk/src/moxy/examples/test-settings.xml
r56 r642 1 1 <?xml version="1.0" ?> 2 <?xml-stylesheet type="text/xsl" href=" wxmtxy_settings.xsl" ?>2 <?xml-stylesheet type="text/xsl" href="moxy_settings.xsl" ?> 3 3 4 4 <!-- … … 12 12 --> 13 13 14 < wxmtxy date="2009-04-21" time="22:42:25" version="1.0">14 <moxy date="2009-04-21" time="22:42:25" version="1.0"> 15 15 <XYpair name="a1y & a2y test motors" selected="True"> 16 16 <EPICS_configuration> 17 17 <axis name="y"> 18 18 <flag isMotorRec="True"/> 19 <field name="VAL" pv=" 32idbLAX:m58:c1:m2"/>19 <field name="VAL" pv="prj:m2"/> 20 20 </axis> 21 21 <axis name="x"> 22 22 <flag isMotorRec="True"/> 23 <field name="VAL" pv=" 32idbLAX:m58:c1:m1"/>23 <field name="VAL" pv="prj:m1"/> 24 24 </axis> 25 25 </EPICS_configuration> … … 30 30 </tab> 31 31 </XYpair> 32 <!-- 32 33 <XYpair name="torture set" selected="not True"> 33 34 <EPICS_configuration> … … 83 84 <tab/> 84 85 </XYpair> 86 --> 85 87 <XYpair> 86 88 <EPICS_configuration> … … 115 117 <axis name="y"> 116 118 <flag isMotorRec="True"/> 117 <field name="VAL" pv="32idbLAX:m58:c1:m2.VAL"/>118 <field name="RBV" pv="32idbLAX:m58:c1:m2.RBV"/>119 <field name="EGU" pv="32idbLAX:m58:c1:m2.EGU"/>120 <field name="DESC" pv=" 32idbLAX:m58:c1:m2.DESC"/>121 <field name="DMOV" pv=" 32idbLAX:m58:c1:m2.DMOV"/>122 <field name="STOP" pv=" 32idbLAX:m58:c1:m2.STOP"/>119 <field name="VAL" pv="prj:m4.VAL"/> 120 <field name="RBV" pv="prj:m4.RBV"/> 121 <field name="EGU" pv="prj:m4.EGU"/> 122 <field name="DESC" pv="prj:m4.DESC"/> 123 <field name="DMOV" pv="prj:m4.DMOV"/> 124 <field name="STOP" pv="prj:m4.STOP"/> 123 125 </axis> 124 126 <axis name="x"> 125 127 <flag isMotorRec="True"/> 126 <field name="VAL" pv=" 32idbLAX:m58:c1:m1"/>128 <field name="VAL" pv="prj:m3"/> 127 129 </axis> 128 130 </EPICS_configuration> … … 142 144 </tab> 143 145 </XYpair> 144 </ wxmtxy>146 </moxy> -
moxy/trunk/src/moxy/moxy.py
r641 r642 57 57 58 58 59 # Note: If you are using Ubuntu 11.04 and cannot see a menubar, 60 # this is a bug in Ubuntu 11.04. Try setting the environment 61 # variable: UBUNTU_MENUPROXY=1 62 import os 63 os.environ['UBUNTU_MENUPROXY'] = '1' 64 65 59 66 import wx 60 67 import root 61 #import pvConnect62 68 import sys 63 69 … … 86 92 87 93 88 #def on_exit(timer, epics_db):89 # '''Exit handler to stop the ca.poll()90 # @param timer: CaPollWx object91 # @param epics_db: Python list of pvConnect.EpicsPv objects to be released'''92 # #print __name__, "exit handler"93 # #for item in epics_db:94 # # item.release()95 # if pvConnect.IMPORTED_CACHANNEL:96 # pvConnect.on_exit(timer)97 98 99 94 def main(): 100 95 '''operate the tool''' … … 104 99 settingsFile = sys.argv[1] 105 100 root.root(None, settingsFile).Show() 106 #capoll_timer = None107 #if pvConnect.IMPORTED_CACHANNEL:108 # capoll_timer = pvConnect.CaPollWx(0.1)109 # capoll_timer.start()110 101 application.MainLoop() 111 #on_exit(capoll_timer, None)112 102 113 103 -
moxy/trunk/src/moxy/moxy_axis.py
r641 r642 1 1 #!/usr/bin/env python 2 from compiler.ast import TryExcept3 2 4 3 #************************************************************************* … … 11 10 #************************************************************************* 12 11 13 '''EPICS PVs and connections for one axis 12 ''' 13 EPICS PVs and connections for one axis 14 ''' 14 15 15 @version: 16 16 17 ########### SVN repository information ################### 17 18 # $Date$ … … 21 22 # $Id$ 22 23 ########### SVN repository information ################### 23 '''24 24 25 25 … … 79 79 self.config = copy.deepcopy(config) 80 80 81 def Connect(self ):81 def Connect(self, **args): 82 82 ''' 83 83 Try to initiate EPICS connection with named PVs 84 84 85 :param dict args: table of callback handlers using fields as the keys 85 86 :return: if all axes connected 86 87 :rtype: bool … … 101 102 # Now, connect and monitor each PV 102 103 for field, pv in self.pvname.items(): 103 ch = epics.PV(pv) 104 self.db[field] = ch 104 self.db[field] = ch = epics.PV(pv) 105 105 kw = {'index': None, 106 106 'with_ctrlvars': True, 107 107 'field': field, 108 108 } 109 i = ch.add_callback(onChanges, **kw) 110 self.cb_index[field] = i # use later to disconnect 109 if 'axis' in args: 110 kw['axis'] = args['axis'] 111 if field in args: 112 callback = args[field] 113 else: 114 callback = onChanges 115 if callback is not None: 116 self.cb_index[field] = ch.add_callback(callback, **kw) # use later to disconnect 111 117 112 118 return failures == 0 … … 138 144 139 145 140 #class _data:141 # '''the internal data associated with a single PV'''142 #143 # def __init__(self):144 # '''only create the space'''145 # self.pv = None146 # self.connection = None147 # self.widget = None148 #149 # def GetPv(self):150 # ''':return: [string] EPICS PV name'''151 # return self.pv152 #153 # def SetPv(self, pv):154 # '''155 # set the PV name156 #157 # :param str pv: EPICS PV name158 # :see: http://cars9.uchicago.edu/software/python/pyepics3/pv.html159 # '''160 # self.pv = pv161 # self.connection = epics.PV(pv)162 #163 # def GetConnection(self):164 # '''@return: pyEpics.PV object'''165 # return self.connection166 #167 # def GetWidget(self):168 # '''@return: widget object'''169 # return self.widget170 #171 # def SetWidget(self, widget):172 # '''set widget object to be used in a callback173 # :param widget: used as self.widget(value)'''174 # self.widget = widget175 #176 # def _callback(self, value):177 # '''178 # receive EPICS CA monitor value179 #180 # :param value: from epics_get['pv_value']181 # '''182 # # print __name__, self.pv, value, self.connection.epics_args, self.connection.user_args183 # if self.widget != None:184 # self.widget(value)185 186 187 146 # example code follows 188 147 … … 196 155 print kw['timestamp'], kw['pvname'], kw['value'] 197 156 198 def _main_callback(epics_args, user_args):199 '''EPICS monitor event received for test code'''200 value = epics_args['pv_value']201 pv = user_args[0]202 # pprint.pprint(epics_args)203 print '_main_callback:', pv, value204 157 205 206 if __name__ == '__main__': 158 def main (): 207 159 config = { 208 160 'x': { … … 222 174 axes = {} 223 175 for axis in config: 224 225 176 axes[axis] = item = Axis() 226 177 item.SetConfigure(config[axis]) … … 239 190 for axis in config: 240 191 axes[axis].Disconnect() 192 193 194 if __name__ == '__main__': 195 main() -
moxy/trunk/src/moxy/pair.py
r635 r642 30 30 import moxy_axis 31 31 import wx.lib.scrolledpanel 32 #import pvConnect33 32 import copy 34 33 import pprint … … 239 238 #self.SetMotorColor("x", True) 240 239 #self.SetMotorColor("y", False) 241 self.SetEpicsConfig({'x': { }, 'y': {}})240 self.SetEpicsConfig({'x': {'isMotorRec': False}, 'y': {'isMotorRec': False}}) 242 241 243 242 # ################################ … … 353 352 self.epics[axis].SetConfigure(copy.deepcopy(config[axis])) 354 353 355 def CallbackPositions(self, epics_args, user_args): 356 '''receive a callback on the VAL and RBV fields''' 357 axis = user_args[0][0] 358 field = user_args[0][1] 359 value = epics_args['pv_value'] 360 if epics_args.has_key('pv_precision'): 354 def onChangePositions(self, **kw): 355 '''receive a PyEpics callback on the VAL and RBV fields''' 356 # TODO: logging? 357 axis = kw['axis'] 358 field = kw['field'] 359 value = kw['value'] 360 print "onChangePositions", axis, field, value 361 if 'precision' in kw: 361 362 # what about display precision? 362 fmt = '%.' + str( epics_args['pv_precision'])363 fmt = '%.' + str(kw['precision']) 363 364 abs_value = abs(value) 364 365 if abs_value >= 1e5 or (abs_value < 1e-5 and abs_value > 0): … … 369 370 else: 370 371 str_value = str(value) 371 self.widget[axis][field] .SetLabel(str_value) 372 # TODO: either callbacks or widget updates should be in a different thread 373 self.widget[axis][field].SetLabel(str_value) 372 374 self.Layout() 373 375 374 def CallbackTitle(self, epics_args, user_args): 375 '''receive a callback on the DESC and EGU fields''' 376 axis = user_args[0][0] 377 field = user_args[0][1] 378 value = epics_args['pv_value'] 376 def onChangeTitle(self, **kw): 377 '''receive a PyEpics callback on the DESC and EGU fields''' 378 # TODO: logging? 379 axis = kw['axis'] 380 field = kw['field'] 381 value = kw['value'] 382 print "onChangePositions", axis, field, value 379 383 self.titles[axis][field] = value 380 384 title = "%s, %s" % (self.titles[axis]['DESC'], self.titles[axis]['EGU']) 381 self.widget[axis]['title'] .SetLabel(title) 382 383 def CallbackDMOV(self, epics_args, user_args): 384 '''receive a callback on the DMOV field''' 385 axis = user_args[0][0] 386 value = epics_args['pv_value'] 385 # TODO: either callbacks or widget updates should be in a different thread 386 self.widget[axis]['title'].SetLabel(title) 387 388 def onChangeDMOV(self, **kw): 389 '''receive a PyEpics callback on the DMOV field''' 390 #print "onChangeDMOV", kw.keys() 391 # TODO: logging? 392 axis = kw['axis'] 393 value = kw['value'] 394 # TODO: either callbacks or widget updates should be in a different thread 387 395 self.SetMotorColor(axis, value == 1) 388 396 389 397 def ConnectEpics(self): 390 398 '''try to connect the XY_pair PV names with EPICS''' 391 #+++++++++++++++++++++++++++++++ 392 # need to replace this starting from the example in moxy_axis.main() 393 #+++++++++++++++++++++++++++++++ 394 for axis in ['x', 'y']: 395 cfg = self.epics[axis].GetConfigure() 396 for field in ['VAL', 'RBV']: 397 item = self.epics[axis].db[field] 398 item.connection.SetUserCallback(self.CallbackPositions) 399 item.connection.SetUserArgs((axis, field)) 400 item.SetWidget(self.widget[axis][field] .SetLabel) 401 402 # advanced handling 403 desc = self.epics[axis].db['DESC'] 404 desc.connection.SetUserCallback(self.CallbackTitle) 405 desc.connection.SetUserArgs((axis, 'DESC')) 406 407 egu = self.epics[axis].db['EGU'] 408 egu.connection.SetUserCallback(self.CallbackTitle) 409 egu.connection.SetUserArgs((axis, 'EGU')) 410 411 dmov = self.epics[axis].db['DMOV'] 412 dmov.connection.SetUserCallback(self.CallbackDMOV) 413 dmov.connection.SetUserArgs((axis, 'DMOV')) 414 415 # do not need to setup the STOP button 416 417 cfg['AXIS'] = axis 418 #pprint.pprint(cfg) 419 self.epics[axis].Connect() 399 redirects = { 400 'VAL': self.onChangePositions, 401 'RBV': self.onChangePositions, 402 'EGU': self.onChangeTitle, 403 'DESC': self.onChangeTitle, 404 'DMOV': self.onChangeDMOV, 405 'STOP': None, 406 } 407 for axis in ['x', 'y']: 408 item = self.epics[axis] 409 redirects['axis'] = axis 410 if not item.Connect(**redirects): 411 raise RuntimeError, "Did not connect %s axis" % axis 420 412 421 413 def ReleaseEpics(self): -
moxy/trunk/src/moxy/pvsetup.py
r641 r642 579 579 580 580 581 if __name__ == '__main__':581 def main (): 582 582 '''example of how to set up the caller for this dialog''' 583 583 config = { … … 608 608 dlg.Destroy() 609 609 app.MainLoop() 610 611 612 if __name__ == '__main__': 613 main() -
moxy/trunk/src/moxy/root.py
r635 r642 11 11 #************************************************************************* 12 12 13 '''root: Define the GUI elements and interface (this is the main code)14 15 13 ########### SVN repository information ################### 16 14 # $Date$ … … 21 19 ########### SVN repository information ################### 22 20 23 @note: for an undo example, see: http://wiki.wxpython.org/AnotherTutorial 21 '''root: Define the GUI elements and interface (this is the main code) 22 23 :note: for an undo example, see: http://wiki.wxpython.org/AnotherTutorial 24 24 ''' 25 25 … … 39 39 '''created by Boa-constructor''' 40 40 return root(parent) 41 41 42 42 43 ################################# … … 235 236 self._init_ctrls(parent) 236 237 self.title = self.GetTitle() 237 self._dirty(False) # settings need to be saved to a file if True238 238 self.pwd = os.getcwd() 239 239 self.settingsFile = settingsFile … … 243 243 self.SetStatusText('opening: %s' % self.settingsFile) 244 244 self.OpenSettingsFile(self.settingsFile) 245 self._dirty(False) # settings need to be saved to a file if True 245 246 # disable these menu items until they are implemented 246 247 #self.menuAbout.FindItemById(wxID_ROOTMENUABOUTHELP).Enable(False) … … 274 275 def _dirty(self, state=True): 275 276 '''Declare the settings dirty (means that changes are unsaved) 276 @param state: [Boolean] True means there are unsaved changes''' 277 278 :param bool state: True means there are unsaved changes 279 ''' 277 280 self.dirty = state 278 281 title = self.title … … 283 286 def NewPair(self, newtab=True): 284 287 '''Create a page for a new X,Y pair 285 @param newtab: [Boolean] option to create a first tab''' 288 289 :param bool newtab: option to create a first tab 290 ''' 286 291 self.paircounter += 1 # unique for each new page 287 292 name = 'panel' + repr(self.paircounter)
Note: See TracChangeset
for help on using the changeset viewer.