Changeset 2460


Ignore:
Timestamp:
03/05/07 18:41:55 (12 years ago)
Author:
mggr
Message:

(mggr committing for mhen): ongoing development

Location:
TI02-CSML/branches/csml-pml
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • TI02-CSML/branches/csml-pml/csmllibs/NumericTransform.py

    r2452 r2460  
    99 
    1010from math import * 
     11import Numeric 
    1112import re 
    1213 
     14# Symbol Table. 
    1315# Functions: 
    14 # 
    1516#   'args':    The number of arguments accepted by the function 
    16 #   'def':     Function definition. Function must accept a list containing the 
    17 #              arguments to the function 
     17#   'def':     Function object. (*MUST* accept number of args specified in 'args') 
    1818# 
    1919# Additionaly, if function represents an infix operator, then the following must 
    2020# be defined: 
    21 # 
    2221#   'prec':    The operator precedence. Must be an integer. 
    2322#   'assoc':   'yes' if the infix operator is associative. 'left' or right' if 
     
    2625# Constants can be defined as a function that takes no arguments. 
    2726 
    28 func = { 
     27_symbols = { 
    2928   # Operators: 
    30    '*': {'args':2, 'prec':5, 'assoc':'yes',  'def':lambda arg:arg[0]*arg[1] }, 
    31    '-': {'args':2, 'prec':0, 'assoc':'left', 'def':lambda arg:arg[0]-arg[1] }, 
    32    '/': {'args':2, 'prec':5, 'assoc':'left', 'def':lambda arg:arg[0]/arg[1] }, 
    33    '+': {'args':2, 'prec':0, 'assoc':'yes',  'def':lambda arg:arg[0]+arg[1] }, 
    34    '^': {'args':2, 'prec':9, 'assoc':'right','def':lambda arg:arg[0]**arg[1]}, 
    35    '%': {'args':2, 'prec':5, 'assoc':'left', 'def':lambda arg:arg[0]%arg[1] }, 
     29   '*': {'args':2, 'prec':5, 'assoc':'yes',  'def':lambda a,b: a*b }, 
     30   '-': {'args':2, 'prec':0, 'assoc':'left', 'def':lambda a,b: a-b }, 
     31   '/': {'args':2, 'prec':5, 'assoc':'left', 'def':lambda a,b: a/b }, 
     32   '+': {'args':2, 'prec':0, 'assoc':'yes',  'def':lambda a,b: a+b }, 
     33   '^': {'args':2, 'prec':9, 'assoc':'right','def':lambda a,b: a**b}, 
     34   '%': {'args':2, 'prec':5, 'assoc':'left', 'def':lambda a,b: a%b }, 
    3635   # Functions: 
    37    'log':  {'args':2, 'def':lambda arg: log(arg[1],arg[0]) }, 
    38    'sin':  {'args':1, 'def':lambda arg: sin(arg[0]) }, 
    39    'cos':  {'args':1, 'def':lambda arg: cos(arg[0]) }, 
    40    'tan':  {'args':1, 'def':lambda arg: tan(arg[0]) }, 
    41    'asin': {'args':1, 'def':lambda arg: asin(arg[0]) }, 
    42    'acos': {'args':1, 'def':lambda arg: acos(arg[0]) }, 
    43    'atan': {'args':1, 'def':lambda arg: atan(arg[0]) }, 
    44    'sqrt': {'args':1, 'def':lambda arg: sqrt(arg[0]) }, 
    45    'floor':{'args':1, 'def':lambda arg: floor(arg[0]) }, 
    46    'ceil': {'args':1, 'def':lambda arg: ceil(arg[0]) }, 
    47    'abs':  {'args':1, 'def':lambda arg: fabs(arg[0]) }, 
     36   'log':  {'args':2, 'def':lambda base,a: log(a,base) }, 
     37   'sin':  {'args':1, 'def':lambda a: sin(a) }, 
     38   'cos':  {'args':1, 'def':lambda a: cos(a) }, 
     39   'tan':  {'args':1, 'def':lambda a: tan(a) }, 
     40   'asin': {'args':1, 'def':lambda a: asin(a) }, 
     41   'acos': {'args':1, 'def':lambda a: acos(a) }, 
     42   'atan': {'args':1, 'def':lambda a: atan(a) }, 
     43   'sqrt': {'args':1, 'def':lambda a: sqrt(a) }, 
     44   'floor':{'args':1, 'def':lambda a: floor(a) }, 
     45   'ceil': {'args':1, 'def':lambda a: ceil(a) }, 
     46   'abs':  {'args':1, 'def':lambda a: fabs(a) }, 
    4847   # Constants: 
    49    'pi':   {'args':0, 'def':lambda arg: pi }, 
    50    'e':    {'args':0, 'def':lambda arg: e } 
     48   'pi':   {'args':0, 'def':lambda: pi }, 
     49   'e':    {'args':0, 'def':lambda: e } 
    5150} 
    5251 
     
    6059   q = [] # Output queue 
    6160   for t in tokens: 
    62       if(isNumericString(t) or not (t in func or t in ['(',',',')'])): 
     61      if(isNumericString(t) or not (t in _symbols or t in ['(',',',')'])): 
    6362         q.append(t) # Float literal or unknown symbolic token (assume var) 
    64       elif(t == '(' or (t in func and 'prec' not in func[t])):            
     63      elif(t == '(' or (t in _symbols and 'prec' not in _symbols[t])):            
    6564         s.append(t) # Function, constant or left parenthesis token. 
    6665      elif(t == ')' or t == ','):  
     
    7069         if(t == ')'): 
    7170            s.pop() 
    72             if(len(s)>0 and s[len(s)-1] in func and 'prec' not in func[s[len(s)-1]]): 
     71            if(len(s)>0 and s[len(s)-1] in _symbols and 'prec' not in _symbols[s[len(s)-1]]): 
    7372               q.append(s.pop()) 
    7473      else: # Infix operator token. 
    7574         modifier = 1 
    76          if(func[t]['assoc'] == 'right'): modifier = 0 
    77          while(len(s)>0 and s[len(s)-1] in func and 'prec' in func[s[len(s)-1]]  
    78                and func[t]['prec'] < func[s[len(s)-1]]['prec'] + modifier): 
     75         if(_symbols[t]['assoc'] == 'right'): modifier = 0 
     76         while(len(s)>0 and s[len(s)-1] in _symbols and 'prec' in _symbols[s[len(s)-1]]  
     77               and _symbols[t]['prec'] < _symbols[s[len(s)-1]]['prec'] + modifier): 
    7978            q.append(s.pop()) 
    8079         s.append(t) 
    8180   while(len(s)>0):                     
    8281      t = s.pop() 
    83       if(t not in func): raise SyntaxError("Could not parse expression.") 
     82      if(t not in _symbols): raise SyntaxError("Could not parse expression.") 
    8483      q.append(t) 
    8584   return q 
     
    101100      self.stack = [] 
    102101      for token in self.tokens: 
    103          if(isNumericString(token)):       # Token is a numeric literal 
    104             self.stack.append(float(token)) 
    105          elif(token in variables):           # Token is in variables dictionary 
    106             self.stack.append(float(variables[token])) 
    107          elif(token in func):                # Token is a builtin function. 
    108             fargs = self.pop(func[token]['args']) 
    109             self.stack.append( func[token]['def'](fargs) ) 
     102         if token in variables: 
     103            self.stack.append(variables[token]) 
     104         elif token in _symbols: 
     105            # Pop reqd. no. of args off stack and pass to function in symbol table, 
     106            # putting result back onto stack: 
     107            args = self.stack[-_symbols[token]['args']:] 
     108            self.stack = self.stack[0:-_symbols[token]['args']] 
     109            self.stack.append( _symbols[token]['def'](*args) ) 
    110110         else: 
    111             raise NameError("Could not resolve symbol '"+token+"'.") 
     111            try: # Not in symbol tables, but it might be a numeric literal... 
     112               self.stack.append(float(token)) 
     113            except ValueError: # Nope, not a literal. 
     114               raise NameError("Could not resolve symbol '"+token+"'.") 
    112115      if(len(self.stack) == 1): 
    113116         return self.stack[0] 
    114117 
    115    # Method to pop multiple values of the stack. Returns a list 
    116    def pop(self, num): 
    117       popped = [] 
    118       for n in range(num): 
    119          popped.insert(0, self.stack.pop()) 
    120       return popped 
    121118 
    122119# Parse and evaluate infix expressions: 
     
    130127if __name__ == "__main__": 
    131128   expression_str = " (10* (sqrt(16) + 3) - 20)*x/10^2+-0.42  " 
    132    print "Expression:", expression_str 
     129   print "Raw Expression:", expression_str 
    133130   expression = infixExpression(expression_str) 
    134    print "Tokenised and compiled to RPN:", expression.tokens 
    135    print "Solving for x=2, (Answer should be 0.58): ", expression.solve( x=2 ) 
    136    print "Solving for x=3, (Answer should be 1.08): ", expression.solve( x=3 ) 
     131   print "Compiled (RPN) Expression:", expression.tokens 
     132   print "== Basic Tests: ==" 
     133   print "  Solving for x=2, (Answer should be 0.58): ", expression.solve( x=2 ) 
     134   print "  Solving for x=3, (Answer should be 1.08): ", expression.solve( x=3 ) 
     135   print "== NumPy Tests: ==" 
     136   print "  Solving for x=[2 3 4] (Answer should be [0.58 1.08 1.58]): ", expression.solve(x=Numeric.array((2,3,4))) 
  • TI02-CSML/branches/csml-pml/csmllibs/csmldataiface.py

    r2452 r2460  
    1313import cdms  
    1414import Numeric 
     15 
    1516try: 
    1617    import nappy  
     
    3031# Part of the PIL. Required for ImageFileInterface: 
    3132import Image 
     33# Required for RawFileInterface: 
     34import struct 
    3235 
    3336class DataInterface(object): 
     
    533536 
    534537   def readFile(self, **kwargs): 
    535        # index into an array that determines the type based on various 
    536        # combinations of settings in the CSML.  This is very clever, but 
    537        # rather obscure.. blame mhen :p 
     538      # index into an array that determines the type based on various 
     539      # combinations of settings in the CSML.  This is very clever, but 
     540      # rather obscure.. blame mhen :p 
    538541      format_index = 0 
    539        
     542 
    540543      if kwargs['type'] == 'float': 
    541544         format_index |= 12 # Float: Set bit 2 (float) and bit 3 (signed) 
     
    561564       
    562565      # Lookup the type character 
    563       format_str += "bhiq----BHIQ--fd"[format_index] 
    564  
    565       self.data = list(struct.unpack(format_str, self.file.read())) 
    566       self.dimensions = kwargs['dimensions'] 
    567  
     566      format_str += "BHIQ----bhiq--fd"[format_index] 
     567 
     568      self.data = Numeric.array(struct.unpack(format_str, self.file.read())) 
     569      self.data.shape = tuple(map(int, kwargs['dimensions'])) 
     570       
    568571      if 'numericTransform' in kwargs: 
     572         # if a numericTransform was supplied, then compile it: 
    569573         self.numericTransform = NumericTransform.infixExpression(kwargs['numericTransform']) 
     574 
    570575      if 'fillValue' in kwargs: 
    571576         self.fillValue = kwargs['fillValue'] 
     577 
    572578 
    573579 
     
    582588 
    583589 
    584    # Return the (transformed) fill value. 
     590   # Return the fill value, if set, and transform if necessary: 
    585591   def getFillValue(self): 
    586592      if(self.fillValue): 
    587          return numericTransform.solve( n = self.fillValue ) 
     593         if(self.numericTransform): 
     594            return self.numericTransform.solve( n = float(self.fillValue) ) 
     595         else: 
     596            return self.fillValue 
    588597      else: 
    589598         return None 
     
    591600 
    592601   def getDataForVar(self): 
    593       if not self.data: 
    594          self.readFile() 
    595602      if self.numericTransform: 
    596603         # Solve the numeric transform and return the resulting array of floats 
    597          return map(lambda val: numericTransform.solve( n = val ), self.data)  
     604         return self.numericTransform.solve( n = self.data ) 
    598605      else: 
    599606         return self.data 
     
    604611      if 'lower' not in kwargs or 'upper' not in kwargs: 
    605612         raise NotImplementedError("Only supports subsetting with lower+upper array indices") 
    606       elif len(kwargs['lower']) != len(self.dimensions) or len(kwargs['upper']) != len(self.dimensions): 
     613      elif len(kwargs['lower']) != len(self.data.shape) or len(kwargs['upper']) != len(self.data.shape): 
    607614         raise NotImplementedError("Only supports subsets of same dimensionality as full dataset") 
    608615      else: 
     
    614621         # arbitrary dimensionality. (Iterate over the desired subset, and 
    615622         # append each data item encountered to the subset array) 
    616          ptr = [None] * len(self.dimensions) 
     623         ptr = [None] * len(self.data.shape) 
    617624         def iterate(n = 0): 
    618625            for ptr[n] in range(kwargs['lower'][n], kwargs['upper'][n] + 1): 
    619                if n < len(self.dimensions) - 1: 
     626               if n < len(self.data.shape) - 1: 
    620627                  iterate(n + 1) 
    621628               else: 
     
    623630         iterate() 
    624631 
    625          if self.numericTransform: 
    626             # Solve the numeric transform and return the resulting array of floats 
    627             return map(lambda val: numericTransform.solve( n = val ), subset) 
    628          else: 
    629             return subset 
     632      if self.numericTransform: 
     633         # Solve the numeric transform and return the resulting array of floats 
     634         return  self.numericTransform.solve( n = subset ) 
     635      else: 
     636         return subset 
    630637 
    631638 
     
    643650 
    644651   def readFile(self, **kwargs): 
    645       self.data = im.getdata() 
    646       self.dimensions = list(im.size) 
     652      # Convert the image to a Numeric array 
     653      self.data = Numeric.array(im.getdata()) 
     654      self.data.shape = tuple(map(int, im.size)) 
    647655 
    648656      if 'numericTransform' in kwargs: 
     657         # numericTransform was specified, so compile the expression: 
    649658         self.numericTransform = NumericTransform.infixExpression(kwargs['numericTransform']) 
    650659      if 'fillValue' in kwargs: 
  • TI02-CSML/branches/csml-pml/parser.py

    r2452 r2460  
    10551055       #**kwargs can hold subsetting request. 
    10561056        
     1057 
    10571058       if fileposition is not None: 
    10581059           file = self.fileList.fileNames.CONTENT.split()[fileposition] 
     
    10631064       # raw file: 
    10641065       meta = {} 
    1065        meta['dimensions'] = self.arraySize.CONTENT.split() 
     1066       meta['dimensions'] = map(int, self.arraySize.CONTENT.split()) 
    10661067       if self.numericTransform: 
    10671068          meta['numericTransform'] = self.numericTransform.CONTENT.strip() 
     
    10801081             meta['type']       = 'float' 
    10811082             meta['depth']      = 64 
    1082           elif type == 'uint': 
     1083          elif type[0:4] == 'uint': 
    10831084             meta['signedness'] = 'unsigned' 
    10841085             meta['type']       = 'int' 
    10851086             meta['depth']      = int(type[4:]) 
    1086           elif type == 'int': 
     1087          elif type[0:3] == 'int': 
    10871088             meta['signedness'] = 'signed' 
    10881089             meta['type']       = 'int' 
     
    11041105          data = DI.getDataForVar() 
    11051106       fillValue = DI.getFillValue() 
    1106        DC=DataContainer(data) 
    1107        dataArray=DC.dataArray 
    11081107       DI.closeFile() 
    1109        return dataArray, fillValue, None, None 
    1110  
    1111  
    1112 # Note: This is derived from RawFileExtract, because it requires the overriden 
    1113 # getData(). 
    1114 class ImageFileExtract(RawFileExtract, csElement): 
    1115  
     1108       return data, fillValue, None, None 
     1109 
     1110 
     1111class ImageFileExtract(FileExtract, csElement): 
    11161112   def __init__(self,**kwargs): 
    11171113      FileExtract.__init__(self, **kwargs) 
     
    11221118      csElement.__init__(self,**kwargs) 
    11231119      self.dataInterface = csml.csmllibs.csmldataiface.ImageFileInterface 
     1120      self.getData = RawFileExtract.getData 
    11241121 
    11251122class SimpleCondition(csElement):  
Note: See TracChangeset for help on using the changeset viewer.