Package SpecClient :: Module SpecScan
[hide private]
[frames] | no frames]

Source Code for Module SpecClient.SpecScan

  1  """Helper module for managing scans""" 
  2   
  3  import copy 
  4  import cStringIO 
  5  import logging 
  6  import time 
  7  import tokenize 
  8  import types 
  9   
 10  import numpy as np 
 11   
 12  from SpecClient.SpecConnectionsManager import SpecConnectionsManager 
 13  from SpecClient import SpecCommand 
 14  from SpecClient import SpecEventsDispatcher 
 15  from SpecClient import SpecWaitObject 
 16   
 17   
 18  __author__ = 'Matias Guijarro (ESRF) / Darren Dale (CHESS)' 
 19  __version__ = 1 
 20   
 21   
 22  (TIMESCAN) = (16) 
 23   
 24  DEBUG = False 
25 26 27 -def _iterable(next, terminator):
28 out = [] 29 token = next() 30 while token[1] != terminator: 31 out.append(_atom(next, token)) 32 token = next() 33 if token[1] == ",": 34 token = next() 35 return out
36
37 -def _dictable(next):
38 out = [] 39 token = next() 40 while token[1] != '}': 41 k = _atom(next, token) 42 token = next() 43 token = next() 44 v = _atom(next, token) 45 out.append((k, v)) 46 token = next() 47 if token[1] == ",": 48 token = next() 49 return dict(out)
50
51 -def _atom(next, token):
52 if token[1] == "(": 53 return tuple(_iterable(next, ')')) 54 if token[1] == "[": 55 return list(_iterable(next, ']')) 56 if token[1] == "{": 57 return _dictable(next) 58 if token[1] == "array": 59 token = next() 60 return np.array(*_iterable(next, ')')) 61 elif token[0] is tokenize.STRING: 62 return token[1][1:-1].decode("string-escape") 63 elif token[0] is tokenize.NUMBER: 64 try: 65 return int(token[1], 0) 66 except ValueError: 67 return float(token[1]) 68 elif token[1] == "-": 69 token = list(next()) 70 token[1] = "-" + token[1] 71 return _atom(next, token) 72 elif token[0] is tokenize.NAME: 73 if token[1] == 'None': 74 return None 75 raise ValueError('tokenize NAME: %s unrecognized' % token[1]) 76 elif not token[0]: 77 return 78 for i, v in tokenize.__dict__.iteritems(): 79 if v == token[0]: 80 raise ValueError("tokenize.%s unrecognized: %s" % (i, token[1]))
81
82 -def simple_eval(source):
83 """a safe version of the builtin eval function, """ 84 src = cStringIO.StringIO(source).readline 85 src = tokenize.generate_tokens(src) 86 return _atom(src.next, src.next())
87
88 89 -class SpecScanA:
90 91 @property
92 - def paused(self):
93 # False when a scan is running or has completed normally 94 return self.__status == 'paused'
95 96 @property
97 - def ready(self):
98 # False when a scan starts, only True once a scan completes normally 99 return self.__status == 'ready'
100 101 @property
102 - def scanning(self):
103 # True when a scan is running, False when scan completes or is paused 104 return self.__status == 'scanning'
105 106 @property
107 - def specVersion(self):
108 return self.__specVersion
109
110 - def __init__(self, specVersion = None):
111 self.scanParams = {} 112 self.scanCounterMne = None 113 self.__status = 'ready' 114 self.__specVersion = None 115 116 if specVersion is not None: 117 self.connectToSpec(specVersion) 118 else: 119 self.connection = None
120 121
122 - def connectToSpec(self, specVersion):
123 self.connection = SpecConnectionsManager().getConnection(specVersion) 124 self.__specVersion = specVersion 125 126 SpecEventsDispatcher.connect(self.connection, 'connected', 127 self.connected) 128 SpecEventsDispatcher.connect(self.connection, 'disconnected', 129 self.__disconnected) 130 131 self.connection.registerChannel('status/ready', self.__statusReady, 132 dispatchMode=SpecEventsDispatcher.FIREEVENT) 133 self.connection.registerChannel('var/_SC_NEWSCAN', self.__newScan, 134 dispatchMode=SpecEventsDispatcher.FIREEVENT) 135 self.connection.registerChannel('var/_SC_NEWPLOTDATA', 136 self.__newScanPoint, 137 dispatchMode=SpecEventsDispatcher.FIREEVENT) 138 self.connection.registerChannel('var/_SC_NEWSCANDATA', 139 self.__newScanData, 140 dispatchMode=SpecEventsDispatcher.FIREEVENT) 141 142 if self.connection.isSpecConnected(): 143 self.connected()
144 145
146 - def isConnected(self):
147 return self.connection and self.connection.isSpecConnected()
148 149
150 - def connected(self):
151 pass
152 153
154 - def __disconnected(self):
155 self.scanCounterMne = None 156 self.__status = 'ready' 157 self.scanParams = {} 158 159 self.disconnected()
160 161
162 - def disconnected(self):
163 pass
164 165
166 - def getScanType(self):
167 try: 168 return self.scanParams['scantype'] 169 except: 170 return -1
171 172
173 - def isScanning(self):
174 return self.scanning
175 176
177 - def __newScan(self, scanParams):
178 if DEBUG: print "SpecScanA.__newScan", scanParams 179 180 if not scanParams: 181 if self.scanning: 182 # receive 0 when scan ends normally 183 self.__status = 'ready' 184 self.scanFinished() 185 return 186 187 if not self.ready: 188 # a new scan was started before the old one completed 189 # lets provide an opportunity to clean up 190 self.scanAborted() 191 192 self.__status = 'scanning' 193 194 self.scanParams = simple_eval(scanParams) 195 196 if type(self.scanParams) != types.DictType: 197 return 198 199 self.newScan(self.scanParams) 200 201 self.scanCounterMne = self.scanParams.get('counter') 202 if (not self.scanCounterMne) or self.scanCounterMne == '?': 203 logging.getLogger("SpecClient").error( 204 "No counter selected for scan.") 205 self.scanCounterMne = None 206 return 207 208 self.scanStarted() # A.B
209 210
211 - def newScan(self, scanParameters):
212 if DEBUG: print "SpecScanA.newScan", scanParameters 213 pass
214 215
216 - def __newScanData(self, scanData):
217 if DEBUG: print "SpecScanA.__newScanData", scanData 218 if self.paused and scanData: 219 self.__status = 'scanning' 220 self.scanResumed() 221 if self.scanning and scanData: 222 scanData = simple_eval(scanData) 223 224 self.newScanData(scanData)
225 226
227 - def newScanData(self, scanData):
228 if DEBUG: print "SpecScanA.newScanData", scanData 229 pass
230 231
232 - def __newScanPoint(self, scanData):
233 if DEBUG: print "SpecScanA.__newScanPoint", scanData 234 if self.paused and scanData: 235 self.__status = 'scanning' 236 self.scanResumed() 237 if self.scanning and scanData: 238 scanData = simple_eval(scanData) 239 240 i = scanData['i'] 241 x = scanData['x'] 242 y = scanData[self.scanCounterMne] 243 244 # hack to know if we should call newScanPoint with 245 # scanData or not (for backward compatiblity) 246 if len(self.newScanPoint.im_func.func_code.co_varnames) > 4: 247 self.newScanPoint(i, x, y, scanData) 248 else: 249 self.newScanPoint(i, x, y)
250 251
252 - def newScanPoint(self, i, x, y, counters_value):
253 if DEBUG: print "SpecScanA.newScanPoint", i, x, y, counters_value 254 pass
255 256
257 - def abort(self):
258 if self.isConnected and (self.scanning or self.paused): 259 if self.scanning: 260 self.connection.abort() 261 self.__status = 'ready' 262 self.scanAborted()
263 264
265 - def pause(self):
266 if self.isConnected() and self.scanning: 267 self.connection.abort()
268 269
270 - def resume(self):
271 if self.isConnected() and self.paused: 272 SpecCommand.SpecCommandA('scan_on', self.specVersion)()
273 274
275 - def scanAborted(self):
276 pass
277 278
279 - def scanFinished(self):
280 pass
281 282
283 - def scanPaused(self):
284 pass
285 286
287 - def scanResumed(self):
288 pass
289 290
291 - def scanStarted(self): # A.B
292 pass # A.B
293 294
295 - def __statusReady(self, status):
296 if status and self.scanning: 297 self.__status = 'paused' 298 self.scanPaused()
299 300
301 - def ascan(self, motorMne, startPos, endPos, nbPoints, countTime):
302 if self.connection.isSpecConnected(): 303 cmd = "ascan %s %f %f %d %f" % (motorMne, startPos, endPos, 304 nbPoints, countTime) 305 self.connection.send_msg_cmd(cmd) 306 return True 307 else: 308 return False
309