Ignore:
Timestamp:
02/05/07 15:05:35 (13 years ago)
Author:
mggr
Message:

initial version of PML methods (will need testing) - mggr checking in for mhen

File:
1 edited

Legend:

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

    r2444 r2452  
    2525MA.set_print_limit(0) 
    2626 
     27# Generic mathematical expression solver, required by the raw and image 
     28# interfaces 
     29import NumericTransform 
     30# Part of the PIL. Required for ImageFileInterface: 
     31import Image 
    2732 
    2833class DataInterface(object): 
     
    4045                elif self.iface == 'cdunif': 
    4146                        return cdunifInterface() 
     47                elif self.iface == 'raw': 
     48                        return RawFileInterface() 
     49                elif self.iface == 'image': 
     50                        return ImageFileInterface() 
    4251                 
    4352                 
     
    4857                if fileExtension == '.nc': 
    4958                        return cdunifInterface() 
    50                 if fileExtension == '.qxf': 
     59                if fileExtension == '.qxf': 
    5160                        return cdunifInterface() 
    5261                elif fileExtension == '.pp': 
     
    5463                elif fileExtension == 'ctl': 
    5564                        return cdunifInterface() 
    56                 elif fileExtension == 'xml': 
     65                elif fileExtension == 'xml': 
    5766                        return cdmlInterface() 
     67                elif fileExtensions == 'png' or fileExtension == 'gif': 
     68                        return ImageFileInterface() 
    5869                else: 
    5970                        try: 
     
    504515        axisSize=self.file.axes[axis].length 
    505516        return axisSize 
     517 
     518 
     519class RawFileInterface(AbstractDI): 
     520 
     521   def __init__(self): 
     522      self.extractType   = 'rawExtract' 
     523      self.extractPrefix = '_rawextract_' 
     524 
     525 
     526   def openFile(self, filename): 
     527      self.file = open(filename, "rb") 
     528 
     529 
     530   def closeFile(self): 
     531      self.file.close() 
     532 
     533 
     534   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      format_index = 0 
     539       
     540      if kwargs['type'] == 'float': 
     541         format_index |= 12 # Float: Set bit 2 (float) and bit 3 (signed) 
     542      elif kwargs['signedness'] != 'unsigned': 
     543         format_index |= 8  # Signed Int: set bit 3 (signed) 
     544          
     545      # Set bits 0 and 1 depending on whether the data are 8, 16, 32 or 64  
     546      # bits wide. 
     547      if kwargs['depth'] in [8,16,32,64]: 
     548         format_index |= [8,16,32,64].index(kwargs['depth']) 
     549          
     550      # Set the endianness of the format string. (Set to Host-Endian if not 
     551      # defined 
     552      if kwargs['endianness'] == 'big': 
     553         format_str = '>' 
     554      elif kwargs['endianness'] == 'little': 
     555         format_str = '<' 
     556      else: 
     557         format_str = '=' 
     558          
     559      # Set the size of the data to read (product of dimensions) 
     560      format_str += str(reduce(lambda a,b:a*b, kwargs['dimensions'])) 
     561       
     562      # 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 
     568      if 'numericTransform' in kwargs: 
     569         self.numericTransform = NumericTransform.infixExpression(kwargs['numericTransform']) 
     570      if 'fillValue' in kwargs: 
     571         self.fillValue = kwargs['fillValue'] 
     572 
     573 
     574   # Allows data to be indexed as if it were a multidimensional array: 
     575   def index(self, *indices): 
     576      index1d = 0 
     577      factor  = 1 
     578      for n in range(len(indices)): 
     579         index1d += factor * indices[n] 
     580         factor  *= self.dimensions[n] 
     581      return self.data[index1d] 
     582 
     583 
     584   # Return the (transformed) fill value. 
     585   def getFillValue(self): 
     586      if(self.fillValue): 
     587         return numericTransform.solve( n = self.fillValue ) 
     588      else: 
     589         return None 
     590 
     591 
     592   def getDataForVar(self): 
     593      if not self.data: 
     594         self.readFile() 
     595      if self.numericTransform: 
     596         # Solve the numeric transform and return the resulting array of floats 
     597         return map(lambda val: numericTransform.solve( n = val ), self.data)  
     598      else: 
     599         return self.data 
     600 
     601 
     602   def getSubsetOfDataForVar(self, **kwargs): 
     603      # Assume subset parameters are passed as: lower=(0,0) upper=(512,512) 
     604      if 'lower' not in kwargs or 'upper' not in kwargs: 
     605         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): 
     607         raise NotImplementedError("Only supports subsets of same dimensionality as full dataset") 
     608      else: 
     609         if not self.data: 
     610            self.readFile() 
     611         subset = [] 
     612 
     613         # Recursive function for the purpose of iterating over an array of 
     614         # arbitrary dimensionality. (Iterate over the desired subset, and 
     615         # append each data item encountered to the subset array) 
     616         ptr = [None] * len(self.dimensions) 
     617         def iterate(n = 0): 
     618            for ptr[n] in range(kwargs['lower'][n], kwargs['upper'][n] + 1): 
     619               if n < len(self.dimensions) - 1: 
     620                  iterate(n + 1) 
     621               else: 
     622                  subset.insert(0, self.index(*ptr)) 
     623         iterate() 
     624 
     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 
     630 
     631 
     632# Interface from reading data from image files. Requires PIL Image module 
     633class ImageFileInterface(RawFileInterface): 
     634   def __init__(self): 
     635      self.extractType   = 'imageExtract' 
     636      self.extractPrefix = '_imageextract_' 
     637 
     638   def openFile(self, filename): 
     639      self.file = Image.open(filename) 
     640 
     641   def closeFile(self): 
     642      self.file = None 
     643 
     644   def readFile(self, **kwargs): 
     645      self.data = im.getdata() 
     646      self.dimensions = list(im.size) 
     647 
     648      if 'numericTransform' in kwargs: 
     649         self.numericTransform = NumericTransform.infixExpression(kwargs['numericTransform']) 
     650      if 'fillValue' in kwargs: 
     651         self.fillValue = kwargs['fillValue'] 
Note: See TracChangeset for help on using the changeset viewer.