Package MDSplus :: Module compound
[frames] | no frames]

Source Code for Module MDSplus.compound

  1  from mdsdata import Data,makeData 
  2  from _mdsdtypes import DTYPE_ACTION,DTYPE_CALL,DTYPE_CONGLOM,DTYPE_DEPENDENCY,DTYPE_DIMENSION 
  3  from _mdsdtypes import DTYPE_DISPATCH,DTYPE_FUNCTION,DTYPE_METHOD,DTYPE_PROCEDURE,DTYPE_PROGRAM 
  4  from _mdsdtypes import DTYPE_RANGE,DTYPE_ROUTINE,DTYPE_SIGNAL,DTYPE_WINDOW 
  5   
  6   
7 -class Compound(Data):
8
9 - def __init__(self,*args, **params):
10 """MDSplus compound data. 11 """ 12 if self.__class__.__name__=='Compound': 13 raise TypeError,"Cannot create instances of class Compound" 14 if 'args' in params: 15 args=params['args'] 16 exec 'self._dtype=DTYPE_'+self.__class__.__name__.upper() 17 if 'opcode' in params: 18 self._opcode=params['opcode'] 19 try: 20 self._argOffset=self.argOffset 21 except: 22 self._argOffset=len(self.fields) 23 if isinstance(args,tuple): 24 if len(args) > 0: 25 if isinstance(args[0],tuple): 26 args=args[0] 27 self.args=args 28 for keyword in params: 29 if keyword in self.fields: 30 super(type(self),self).__setitem__(self._fields[keyword],params[keyword])
31
32 - def __getattr__(self,name,*args):
33 if name in self.__dict__: 34 return self.__dict__[name] 35 if name == '_opcode_name': 36 return 'undefined' 37 if name == '_fields': 38 return dict() 39 if name == 'args': 40 try: 41 return self.__dict__[name] 42 except: 43 return None 44 if name == '_opcode': 45 return None 46 if name == '_argOffset': 47 return 0 48 if name == 'opcode': 49 return self._opcode 50 if name == self._opcode_name: 51 return self._opcode 52 if name in self._fields: 53 try: 54 return self.args[self._fields[name]] 55 except: 56 return None 57 raise AttributeError,'No such attribute '+str(name)
58
59 - def __getitem__(self,num):
60 try: 61 return self.args[num] 62 except: 63 return None
64
65 - def __setattr__(self,name,value):
66 if name == 'opcode': 67 self._opcode=value 68 if name == 'args': 69 if isinstance(value,tuple): 70 self.__dict__[name]=value 71 return 72 else: 73 raise TypeError,'args attribute must be a tuple' 74 if name in self._fields: 75 tmp=list(self.args) 76 while len(tmp) < self._fields[name]: 77 tmp.append(None) 78 tmp[self._fields[name]]=value 79 self.args=tuple(tmp) 80 return 81 if name == self._opcode_name: 82 self._opcode=value 83 return 84 super(Compound,self).__setattr__(name,value)
85 86
87 - def __setitem__(self,num,value):
88 if isinstance(num,slice): 89 indices=num.indices(num.start+len(value)) 90 idx=0 91 for i in range(indices[0],indices[1],indices[2]): 92 self.__setitem__(i,value[idx]) 93 idx=idx+1 94 else: 95 try: 96 tmp=list(self.args) 97 except: 98 tmp=list() 99 while len(tmp) <= num: 100 tmp.append(None) 101 tmp[num]=value 102 self.args=tuple(tmp) 103 return
104 105
106 - def getArgumentAt(self,idx):
107 """Return argument at index idx (indexes start at 0) 108 @rtype: Data,None 109 """ 110 return super(type(self),self).__getitem__(idx+self._argOffset)
111
112 - def getArguments(self):
113 """Return arguments 114 @rtype: Data,None 115 """ 116 return super(type(self),self).__getitem__(slice(self._argOffset,None))
117
118 - def getDescAt(self,idx):
119 """Return descriptor with index idx (first descriptor is 0) 120 @rtype: Data 121 """ 122 return super(type(self),self).__getitem__(idx)
123
124 - def getDescs(self):
125 """Return descriptors or None if no descriptors 126 @rtype: tuple,None 127 """ 128 return self.args
129
130 - def getNumDescs(self):
131 """Return number of descriptors 132 @rtype: int 133 """ 134 try: 135 return len(self.args) 136 except: 137 return 0
138
139 - def setArgumentAt(self,idx,value):
140 """Set argument at index idx (indexes start at 0)""" 141 return super(type(self),self).__setitem__(idx,value)
142
143 - def setArguments(self,args):
144 """Set arguments 145 @type args: tuple 146 """ 147 return super(type(self),self).__setitem__(slice(self._argOffset,None),args)
148
149 - def setDescAt(self,n,value):
150 """Set descriptor at index idx (indexes start at 0)""" 151 return super(type(self),self).__setitem__(n,value)
152
153 - def setDescs(self,args):
154 """Set descriptors 155 @type args: tuple 156 """ 157 self.args=value
158 159
160 -class MetaClass(type):
161
162 - def __new__(meta,classname,bases,classDict):
163 newClassDict=classDict 164 newClassDict['_fields']=dict() 165 idx=0 166 for f in classDict['fields']: 167 name=f[0:1].upper()+f[1:] 168 exec "def get"+name+"(self): return self.__getattr__('"+f+"')" 169 exec "newClassDict['get'+name]=get"+name 170 newClassDict['get'+name].__doc__='Get the '+f+' field\n@rtype: Data' 171 exec 'def set'+name+'(self,value): return self.__setattr__("'+f+'",value)' 172 exec "newClassDict['set'+name]=set"+name 173 newClassDict['set'+name].__doc__='Set the '+f+' field\n@type value: Data\n@rtype: None' 174 exec "newClassDict['_dtype']=DTYPE_"+classname.upper() 175 newClassDict['_fields'][f]=idx 176 idx=idx+1 177 c=type.__new__(meta,classname,bases,newClassDict) 178 return c
179
180 -class Action(Compound):
181 """ 182 An Action is used for describing an operation to be performed by an MDSplus action server. Actions are typically dispatched using the mdstcl DISPATCH command 183 """ 184 fields=('dispatch','task','errorLog','completionMessage','performance') 185 __metaclass__=MetaClass
186
187 -class Call(Compound):
188 """ 189 A Call is used to call routines in shared libraries. 190 """ 191 fields=('image','routine') 192 _opcode_name='retType' 193 __metaclass__=MetaClass
194
195 -class Conglom(Compound):
196 """A Conglom is used at the head of an MDSplus conglomerate. A conglomerate is a set of tree nodes used 197 to define a device such as a piece of data acquisition hardware. A conglomerate is associated with some 198 external code providing various methods which can be performed on the device. The Conglom class contains 199 information used for locating the external code. 200 """ 201 fields=('image','model','name','qualifiers') 202 __metaclass__=MetaClass
203
204 -class Dependency(Compound):
205 """A Dependency object is used to describe action dependencies. This is a legacy class and may not be recognized by 206 some dispatching systems 207 """ 208 fields=('arg1','arg2') 209 __metaclass__=MetaClass
210
211 -class Dimension(Compound):
212 """A dimension object is used to describe a signal dimension, typically a time axis. It provides a compact description 213 of the timing information of measurements recorded by devices such as transient recorders. It associates a Window 214 object with an axis. The axis is generally a range with possibly no start or end but simply a delta. The Window 215 object is then used to bracket the axis to resolve the appropriate timestamps. 216 """ 217 fields=('window','axis') 218 __metaclass__=MetaClass
219
220 -class Dispatch(Compound):
221 """A Dispatch object is used to describe when an where an action should be dispatched to an MDSplus action server. 222 """ 223 fields=('ident','phase','when','completion') 224 __metaclass__=MetaClass
225
226 -class Function(Compound):
227 """A Function object is used to reference builtin MDSplus functions. For example the expression 1+2 228 is represented in as Function instance created by Function(opcode='ADD',args=(1,2)) 229 """ 230 fields=tuple() 231 __metaclass__=MetaClass 232
233 - def __init__(self,opcode,args):
234 """Create a compiled MDSplus function reference. 235 Number of arguments allowed depends on the opcode supplied. 236 """ 237 from _opcodes.opcodes import find_opcode 238 super(Function,self).__init__(args=args,opcode=opcode) 239 opc=find_opcode(self._opcode) 240 if opc: 241 opc.check_args(args) 242 self._opcode=opc.number 243 else: 244 raise Exception("Invalid opcode - "+str(self._opcode)) 245 self.__dict__['opc']=opc
246
247 - def setOpcode(self,opcode):
248 """Set opcode 249 @param opcode: either a string or a index number of the builtin operation 250 @type opcode: str,int 251 """ 252 from _opcodes.opcodes import find_opcode 253 opc=find_opcode(opcode) 254 if not opc: 255 raise Exception("Invalid opcode - "+str(opcode)) 256 self.opcode=opcode 257 self.__dict__['opc']=opc
258 259 # 260 # The following code can be used if we want to implement TDI opcodes in python code using the opcodes.py module. 261 # If it is commened out, it will default to using TdiEvaluate to perform the evaluation. 262 # 263 # def evaluate(self): 264 # """Returns the answer when the function is evaluated.""" 265 # return self.opc.evaluate(self.args) 266 # 267 # def __str__(self): 268 # """Returns the string representation of the function.""" 269 # return self.opc.str(self.args) 270 # 271 #def compile_function(name,*args): 272 # 273 # opcode=find_opcode(name) 274 # if opcode: 275 # if opcode.class_of: 276 # return opcode.class_of(*args) 277 # else: 278 # return opc(opcode.number,*args) 279 # else: 280 # return opc('BUILD_CALL',None,*args) 281
282 -class Method(Compound):
283 """A Method object is used to describe an operation to be performed on an MDSplus conglomerate/device 284 """ 285 fields=('timeout','method','object') 286 __metaclass__=MetaClass
287
288 -class Procedure(Compound):
289 """A Procedure is a deprecated object 290 """ 291 fields=('timeout','language','procedure') 292 __metaclass__=MetaClass
293
294 -class Program(Compound):
295 """A Program is a deprecated object""" 296 fields=('timeout','program') 297 __metaclass__=MetaClass
298
299 -class Range(Compound):
300 """A Range describes a ramp. When used as an axis in a Dimension object along with a Window object it can be 301 used to describe a clock. In this context it is possible to have missing begin and ending values or even have the 302 begin, ending, and delta fields specified as arrays to indicate a multi-speed clock. 303 """ 304 fields=('begin','ending','delta') 305 __metaclass__=MetaClass
306
307 -class Routine(Compound):
308 """A Routine is a deprecated object""" 309 fields=('timeout','image','routine') 310 __metaclass__=MetaClass
311
312 -class Signal(Compound):
313 """A Signal is used to describe a measurement, usually time dependent, and associated the data with its independent 314 axis (Dimensions). When Signals are indexed using s[idx], the index is resolved using the dimension of the signal 315 """ 316 fields=('value','raw') 317 __metaclass__=MetaClass 318
319 - def _getDims(self):
320 return self.getArguments()
321 322 dims=property(_getDims) 323 """The dimensions of the signal""" 324
325 - def dim_of(self,idx=0):
326 """Return the signals dimension 327 @rtype: Data 328 """ 329 if idx < len(self.dims): 330 return self.dims[idx] 331 else: 332 return makeData(None)
333
334 - def __getitem__(self,idx):
335 """Subscripting <==> signal[subscript]. Uses the dimension information for subscripting 336 @param idx: index or Range used for subscripting the signal based on the signals dimensions 337 @type idx: Data 338 @rtype: Signal 339 """ 340 return Data.execute('$[$]',self,idx)
341
342 - def getDimensionAt(self,idx=0):
343 """Return the dimension of the signal 344 @param idx: The index of the desired dimension. Indexes start at 0. 0=default 345 @type idx: int 346 @rtype: Data 347 """ 348 try: 349 return self.dims[idx] 350 except: 351 return None
352
353 - def getDimensions(self):
354 """Return all the dimensions of the signal 355 @rtype: tuple 356 """ 357 return self.dims
358
359 - def setDimensionAt(self,idx,value):
360 """Set the dimension 361 @param idx: The index into the dimensions of the signal. 362 @rtype: None 363 """ 364 return self.setArgumentAt(idx,value)
365
366 - def setDimensions(self,value):
367 """Set all the dimensions of a signal 368 @param value: The dimensions 369 @type value: tuple 370 @rtype: None 371 """ 372 return self.setArguments(value)
373
374 -class Window(Compound):
375 """A Window object can be used to construct a Dimension object. It brackets the axis information stored in the 376 Dimension to construct the independent axis of a signal. 377 """ 378 fields=('startIdx','endIdx','timeAt0') 379 __metaclass__=MetaClass
380