Changeset 343 for nappy/trunk/naFile.py


Ignore:
Timestamp:
15/06/04 13:46:42 (15 years ago)
Author:
astephen
Message:

Latest version with new files in test directory.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • nappy/trunk/naFile.py

    r339 r343  
    33========= 
    44 
    5 A module to hold the mixin base class NAFile that is subclassed 
    6 for individual FFIs. Further classes are the subclasses for other FFIs. 
     5A containter module for the mixin base class NAFile that is subclassed 
     6for individual FFIs. Each FFI class is held in an individual file. 
    77 
    88""" 
    99 
    10 # Imports from Python standard library 
     10# Imports from python standard library 
    1111import sys 
    1212import time 
    1313import re 
    1414 
    15 # Imports from local package 
    16 from naCore import * 
     15# Imports from nappy package 
     16import naCore 
    1717from textParser import * 
    18 from cdmsMap import cdmsMap 
    19  
    20 # Import external packages (if available) 
    21 if sys.platform.find("win")>-1: 
    22     pass 
    23 else: 
    24     try: 
    25         import cdms, Numeric  
    26     except: 
    27         print "Cannot import cdms package, CDAT-dependent features will not work." 
    28  
    29 # Define global variables 
    30 NAPlatformError="Platform error: You cannot use the CDAT-dependent features on a Windows Platform." 
    31 safe_nc_id=re.compile(r"[\s\^%$£\"'\[\]\(\)\{\}=+!/]+") 
    32 cdms.setAutoBounds("off") 
    33  
    34  
    35 class NAFile(NACore): 
    36  
    37     def __init__(self, filename, mode="r", naDict=None): 
    38         NACore.__init__(self) 
     18from naError import * 
     19import naToCdms 
     20 
     21class NAFile(naCore.NACore, naToCdms.NAToCdms): 
     22 
     23    """ 
     24    NAFile class is a sub-class of NACore and NAToCdms mixin classes. 
     25    NAFile is also a mixin class and should not be called directly. 
     26     
     27    NAFile holds all the methods are common to either all or more than 
     28    one NASA Ames FFI class. These methods set up the main read and write 
     29    functionality for the NASA Ames format. 
     30 
     31    When a sub-class of NAFile is called with a read ('r' - default) or 
     32    write ('w') mode the header in the file is automatically read or written. 
     33    However, the user must explicitly read or write the data section with a 
     34    call to the 'readData' or 'writeData' methods. 
     35 
     36    """ 
     37 
     38    def __init__(self, filename, mode="r", naDict={}, spacer="    ", floatFormat="%8.3f"): 
     39        """ 
     40        Initialization of class, decides if user wishes to read or write 
     41        NASA Ames file. 
     42        """ 
     43        naCore.NACore.__init__(self) 
    3944        self.naDict=naDict 
    4045        self.filename=filename 
    41         self.open(mode) 
     46        self._open(mode) 
     47        self.spacer=spacer 
     48        self.floatFormat=floatFormat 
     49 
    4250        if mode=="r": 
    43             self.normalizedX="yes" 
     51            self._normalizedX="yes" 
    4452            self.readHeader() 
    45             self.readData() 
    4653        elif mode=="w": 
    47             self.parseDictionary() 
     54            self._parseDictionary() 
    4855            self.writeHeader() 
    4956            self.writeData() 
     
    5259        self.close() 
    5360         
    54     def open(self, mode): 
     61    def _open(self, mode): 
     62        "Wrapper to builtin open file function." 
    5563        self.file=open(self.filename, mode) 
    5664 
    5765    def close(self): 
     66        "Wrapper to builtin close file function." 
    5867        self.file.close() 
    5968 
    60     def parseDictionary(self): 
     69    def _parseDictionary(self): 
     70        """ 
     71        Parser for the optional naDict argument containing a dictionary 
     72        of NASA Ames internal variables. These are saved as instance attributes 
     73        with the name used in the NASA Ames documentation. 
     74        """ 
    6175        for i in self.naDict.keys(): 
    6276            setattr(self, i, self.naDict[i]) 
    6377 
    64     def readTopLine(self): 
     78    def _readTopLine(self): 
    6579        """ 
    6680        Reads number of header lines and File Format Index from top line. 
    67         Also assigns a value to NIV for the number of indepndent variables 
     81        Also assigns a value to NIV for the number of independent variables 
    6882        based on the first character in the FFI. 
     83 
     84        Returns NLHEAD and FFI in a tuple. 
    6985        """ 
    7086        (self.NLHEAD, self.FFI)=readItemsFromLine(self.file.readline(), 2, int) 
     
    7288        return (self.NLHEAD, self.FFI) 
    7389 
    74     def readLines(self, nlines): 
     90    def _readLines(self, nlines): 
     91        "Reads nlines lines from a file and returns them in a list." 
    7592        lines=[] 
    7693        for i in range(nlines): 
     
    7895        return lines 
    7996 
    80     def checkForBlankLines(self, datalines): 
     97    def _checkForBlankLines(self, datalines): 
    8198        """ 
    8299        Searches for empty lines in the middle of the data section and raises 
     
    98115        return rtlines 
    99116 
    100     def readCommonHeader(self): 
    101         self.readTopLine() 
     117    def _readCommonHeader(self): 
     118        """ 
     119        Reads the header section common to all NASA Ames files. 
     120        """ 
     121        self._readTopLine() 
    102122        self.ONAME=readItemFromLine(self.file.readline(), str) 
    103123        self.ORG=readItemFromLine(self.file.readline(), str) 
     
    108128        (self.DATE, self.RDATE)=(dates[:3], dates[3:]) 
    109129 
    110     def writeCommonHeader(self): 
     130    def _writeCommonHeader(self): 
     131        """ 
     132        Writes the header section common to all NASA Ames files. 
     133        """ 
    111134        self.file.write("%s    %s\n" % (self.NLHEAD, self.FFI)) 
    112135        self.file.write("%s\n" % self.ONAME) 
     
    117140        self.file.write("%s %s %s    %s %s %s\n" % (self.DATE[0], self.DATE[1], self.DATE[2], self.RDATE[0], self.RDATE[1], self.RDATE[2])) 
    118141 
    119     def readVariablesHeaderSection(self): 
    120         """Assumes we are at the right point in the file""" 
     142    def _readVariablesHeaderSection(self): 
     143        """ 
     144        Reads the variables section of the header. 
     145        Assumes we are at the right point in the file. 
     146        """ 
    121147        self.NV=readItemFromLine(self.file.readline(), int) 
    122148        self.VSCAL=readItemsFromUnknownLines(self.file, self.NV, float) 
    123149        self.VMISS=readItemsFromUnknownLines(self.file, self.NV, float) 
    124         self.VNAME=readItemsFromLines(self.readLines(self.NV), self.NV, str) 
    125  
    126     def writeVariablesHeaderSection(self): 
     150        self.VNAME=readItemsFromLines(self._readLines(self.NV), self.NV, str) 
     151 
     152    def _writeVariablesHeaderSection(self): 
     153        """ 
     154        Writes the variables section of the header. 
     155        Assumes we are at the right point in the file. 
     156        """         
    127157        self.file.write("%s\n" % self.NV) 
    128158        self.file.write(("%s "*self.NV+"\n") % tuple(self.VSCAL)) 
     
    130160        self.file.write("%s\n"*self.NV % tuple(self.VNAME)) 
    131161 
    132     def readAuxVariablesHeaderSection(self): 
    133         """Assumes we are at the right point in the file""" 
     162    def _readAuxVariablesHeaderSection(self): 
     163        """ 
     164        Reads the auxiliary variables section of the header. 
     165        Assumes we are at the right point in the file. 
     166        """ 
    134167        self.NAUXV=readItemFromLine(self.file.readline(), int) 
    135168        if self.NAUXV>0:         
    136169            self.ASCAL=readItemsFromUnknownLines(self.file, self.NAUXV, float) 
    137170            self.AMISS=readItemsFromUnknownLines(self.file, self.NAUXV, float) 
    138             self.ANAME=readItemsFromLines(self.readLines(self.NAUXV), self.NAUXV, str) 
    139  
    140     def writeAuxVariablesHeaderSection(self): 
     171            self.ANAME=readItemsFromLines(self._readLines(self.NAUXV), self.NAUXV, str) 
     172 
     173    def _writeAuxVariablesHeaderSection(self): 
     174        """ 
     175        Writes the auxiliary variables section of the header. 
     176        Assumes we are at the right point in the file. 
     177        """         
    141178        self.file.write("%s\n" % self.NAUXV) 
    142179        if self.NAUXV>0: 
     
    145182            self.file.write("%s\n"*self.NV % tuple(self.ANAME)) 
    146183 
    147     def readCharAuxVariablesHeaderSection(self): 
    148         """Assumes we are at the right point in the file""" 
     184    def _readCharAuxVariablesHeaderSection(self): 
     185        """ 
     186        Reads the character-encoded auxiliary variables section of the header. 
     187        Assumes we are at the right point in the file. 
     188        """ 
    149189        self.NAUXV=readItemFromLine(self.file.readline(), int) 
    150190        self.NAUXC=readItemFromLine(self.file.readline(), int) 
     
    157197                self.LENA.insert(0, None) 
    158198            self.AMISS=self.AMISS+readItemsFromUnknownLines(self.file, self.NAUXC, str)     
    159             self.ANAME=readItemsFromLines(self.readLines(self.NAUXV), self.NAUXV, str)         
     199            self.ANAME=readItemsFromLines(self._readLines(self.NAUXV), self.NAUXV, str)         
    160200             
    161     def readComments(self): 
    162         """Assumes we are at the right point in the file"""         
     201    def _readComments(self): 
     202        """ 
     203        Reads the special and normal comments sections. 
     204        Assumes we are at the right point in the file. 
     205        """         
    163206        self.NSCOML=readItemFromLine(self.file.readline(), int) 
    164         self.readSpecialComments() 
     207        self._readSpecialComments() 
    165208        self.NNCOML=readItemFromLine(self.file.readline(), int) 
    166         self.readNormalComments() 
    167  
    168     def writeComments(self): 
     209        self._readNormalComments() 
     210 
     211    def _writeComments(self): 
     212        """ 
     213        Writes the special and normal comments sections. 
     214        Assumes we are at the right point in the file. 
     215        """   
    169216        self.file.write("%s\n" % self.NSCOML) 
    170217        self.file.write("%s\n"*self.NSCOML % tuple(self.SCOM)) 
     
    172219        self.file.write("%s\n"*self.NNCOML % tuple(self.NCOM)) 
    173220 
    174     def readSpecialComments(self): 
    175         """Assumes that we are at the right point in the 
    176         file and that NSCOML variable is known.""" 
    177         self.SCOM=self.readLines(self.NSCOML) 
     221    def _readSpecialComments(self): 
     222        """ 
     223        Reads the special comments section.         
     224        Assumes that we are at the right point in the file and that NSCOML 
     225        variable is known. 
     226        """ 
     227        self.SCOM=self._readLines(self.NSCOML) 
    178228        return self.SCOM 
    179229 
    180     def readNormalComments(self): 
    181         """Assumes that we are at the right point in the 
    182         file and requires NNCOML variable.""" 
    183         self.NCOM=self.readLines(self.NNCOML) 
     230    def _readNormalComments(self): 
     231        """ 
     232        Reads the normal comments section.         
     233        Assumes that we are at the right point in the file and that NNCOML 
     234        variable is known. 
     235        """ 
     236        self.NCOM=self._readLines(self.NNCOML) 
    184237        return self.NCOM 
    185238 
    186     def _recursiveListPopulator(self, inlist, array, dimlist): 
    187         """ 
    188         Populates the list object 'inlist' (e.g. []) with sublists of 
    189         dimensionality defined in the 'dimlist' list of dimensions (e.g [181, 360]). 
    190         At the deepest level it then inserts values from the long list 
    191         'array'. 
    192         """ 
    193         if not hasattr(self, "_counter"): 
    194             self._counter=0 
    195         if len(dimlist[1:])>0: 
    196             for i in range(dimlist[0]): 
    197                 inlist.append([]) 
    198                 self._recursiveListPopulator(inlist[i], array, dimlist[1:]) 
    199         else: 
    200             count=self._counter 
    201             self._counter=self._counter+dimlist[0] 
    202             endcount=self._counter 
    203             for i in range(count, endcount): 
    204                 inlist.append(array[i]) 
    205         return inlist 
    206  
    207     def _recursiveListWriter(self, inlist, dimlist): 
    208         """ 
    209         Goes through all the levels of the multi-level list object 'inlist' and 
    210         writes out appropriate values to lines of the output file 'self.file'. 
    211         'dimlist' is a list of the dimensions within 'inlist'. 
    212         """ 
    213         if len(dimlist[1:])>0: 
    214             for i in range(dimlist[0]): 
    215                 self._recursiveListWriter(inlist[i], dimlist[1:]) 
    216         else: 
    217             var_string="" 
    218             for i in range(dimlist[0]): 
    219                 var_string=var_string+("%s    " % inlist[i]) 
    220             self.file.write("%s\n" % var_string.rstrip()) 
    221  
    222  
    223     def toCdmsFile(self, filename, variables="all", aux_variable="all", global_attributes={"Conventions":"CF-1.0"}, ffi=None): 
    224         if sys.platform.find("win")>-1: 
    225             raise NAPlatformError 
    226  
    227         self.cdmsFilename=filename 
    228         self.cdmsFile=cdms.open(self.cdmsFilename, 'w') 
    229          
    230         # at file level: write global attributes 
    231         for key in global_attributes.keys(): 
    232             setattr(self.cdmsFile, key, global_attributes[key]) 
    233  
    234         for key in cdmsMap["fromNA"].keys(): 
    235             if type(key)==tuple: 
    236                 if key==("SCOM", "NCOM"): 
    237                     commentline="NASA Ames Special Comments:\n" 
    238                     for i in self.SCOM: commentline=commentline+"\n"+i 
    239                     commentline=commentline+"NASA Ames Normal Comments:\n" 
    240                     for i in self.NCOM: commentline=commentline+"\n"+i 
    241                     self.cdmsFile.comment=commentline 
    242                 else: 
    243                     item=(getattr(self, key[0]))+"\n"+(getattr(self, key[1])) 
    244                     setattr(self.cdmsFile, cdmsMap["fromNA"][key], item) 
    245             elif key=="RDATE": 
    246                 dateparts=getattr(self, "RDATE") 
    247                 datestring="%.4d-%.2d-%.2d" % tuple(dateparts) 
    248                 item=datestring+" - NASA Ames File created/revised.\n" 
    249                 timestring=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) 
    250                 item=item+"\n"+timestring+" - Data written to NetCDF file." 
    251             else: 
    252                 setattr(self.cdmsFile, cdmsMap["fromNA"][key], getattr(self, key)) 
    253  
    254         # Then do dimensions 
    255         if not hasattr(self, 'cdmsAxes'):  self.createCdmsAxes() 
    256  
    257         # Then do variables 
    258         if not hasattr(self, 'cdmsVariables'):  self.createCdmsVariables() 
    259         for var in self.cdmsVariables: 
    260             self.cdmsFile.write(var) 
    261  
    262         # Then do auxiliary variables 
    263         if hasattr(self, "NAUXV") and type(self.NAUXV)==int:   # Are there any auxiliary variables? 
    264             if not hasattr(self, 'cdmsAuxVariables'):  self.createCdmsAuxVariables() 
    265             for avar in self.cdmsAuxVariables: 
    266                 self.cdmsFile.write(avar) 
    267  
    268         self.cdmsFile.close() 
    269         return "Cdmsfile '%s' written successfully." % self.cdmsFilename 
    270  
    271     def createCdmsVariables(self): 
    272         self.cdmsVariables=[] 
    273         for var_number in range(self.NV): 
    274             self.cdmsVariables.append(self.toCdmsVariable(var_number)) 
    275  
    276  
    277     def toCdmsVariable(self, var_number, attributes={}): 
    278         if sys.platform.find("win")>-1: 
    279             raise NAPlatformError 
    280         (varname, units, miss, scal)=self.getVariable(var_number) 
    281  
    282         array=Numeric.array(self.V[var_number]) 
    283         array=array*scal 
    284         # Set up axes 
    285         if not hasattr(self, 'cdmsAxes'): 
    286             self.createCdmsAxes() 
    287  
    288         # Set up variable 
    289         var=cdms.createVariable(array, axes=self.cdmsAxes, fill_value=miss, attributes=attributes) 
    290  
    291         # Sort units etc 
    292         if units:   var.units=units 
    293         if len(varname)<20: 
    294             var.id=safe_nc_id.sub("_", varname).lower() 
    295         else: 
    296             var.id="naVariable_%s" % (var_number) 
    297  
    298         var.long_name=var.name=varname 
    299         if varname in ("standard_name_list",) or varname in ("badc_list",): 
    300             var.standard_name="name from the list*****" 
    301  
    302         return var 
    303  
    304     def createCdmsAuxVariables(self): 
    305         self.cdmsAuxVariables=[] 
    306         for avar_number in range(self.NAUXV): 
    307             self.cdmsAuxVariables.append(self.auxToCdmsVariable(avar_number)) 
    308  
    309     def auxToCdmsVariable(self, avar_number, attributes={}): 
    310         if sys.platform.find("win")>-1: 
    311             raise NAPlatformError 
    312         (varname, units, miss, scal)=self.getAuxVariable(avar_number) 
    313         array=Numeric.array(self.A[avar_number]) 
    314         array=array*scal 
    315  
    316         # Set up axes 
    317         if not hasattr(self, 'cdmsAxes'): 
    318             self.createCdmsAxes() 
    319  
    320         # Set up variable 
    321         var=cdms.createVariable(array, axes=[self.cdmsAxes[0]], fill_value=miss, attributes=attributes) 
    322  
    323         # Sort units etc 
    324         if units:   var.units=units 
    325         if len(varname)<20: 
    326             var.id=safe_nc_id.sub("_", varname).lower() 
    327         else: 
    328             var.id="naAuxVariable_%s" % (avar_number) 
    329  
    330         var.long_name=var.name=varname 
    331         if varname in ("standard_name_list",) or varname in ("badc_list",): 
    332             var.standard_name="name from the list*****" 
    333  
    334         return var         
    335  
    336     def createCdmsAxes(self): 
    337         if sys.platform.find("win")>-1: 
    338             raise NAPlatformError 
    339         if not hasattr(self, 'cdmsAxes'):         
    340             self.cdmsAxes=[] 
    341         for ivar_number in range(self.NIV): 
    342             self.cdmsAxes.append(self.toCdmsAxis(ivar_number)) 
    343  
    344     def toCdmsAxis(self, ivar_number): 
    345         if sys.platform.find("win")>-1: 
    346             raise NAPlatformError 
    347  
    348         if self.normalizedX=="no": self._normalizeIndVars() 
    349  
    350         if self.NIV==1: 
    351             array=self.X 
    352         else: 
    353             array=self.X[ivar_number] 
    354         axis=cdms.createAxis(array) 
    355         axis.id=axis.name=axis.long_name=self.XNAME[ivar_number] 
    356         (varname, units)=self.getIndependentVariable(ivar_number) 
    357         # Sort units etc 
    358         if units:   axis.units=units 
    359         if len(varname)<20: 
    360             axis.id=safe_nc_id.sub("_", varname).lower() 
    361         else: 
    362             axis.id="naAuxVariable_%s" % (ivar_number) 
    363  
    364         if units: axis.units=units 
    365         axis_types=("longitude", "latitude", "level", "time") 
    366         designators={"longitude":axis.designateLongitude, "latitude":axis.designateLatitude, 
    367                      "level":axis.designateLevel, "time":axis.designateTime} 
    368         for axis_type in axis_types: 
    369             if re.search(axis_type, varname, re.IGNORECASE): 
    370                 axis.standard_name=axis.id=axis_type 
    371                 apply(designators[axis_type.lower()]) 
    372         return axis 
    373  
    374  
    375 class NAFile1001(NAFile): 
    376  
    377     def readHeader(self): 
    378         self.readCommonHeader() 
    379         self.DX=readItemsFromLine(self.file.readline(), self.NIV, float) 
    380         self.XNAME=readItemsFromLines(self.readLines(self.NIV), self.NIV, str) 
    381         self.readVariablesHeaderSection() 
    382         self.readComments() 
    383  
    384     def writeHeader(self): 
    385         self.writeCommonHeader() 
    386         self.file.write(("%s "*self.NIV+"\n") % tuple(self.DX)) 
    387         self.file.write("%s\n"*self.NIV % tuple(self.XNAME)) 
    388         self.writeVariablesHeaderSection() 
    389         self.writeComments() 
    390  
    391239    def readData(self): 
     240        """ 
     241        Reads the data section of the file. This method actually calls a number 
     242        of FFI specific methods to setup the data arrays (lists of lists) and 
     243        read the various data sections. 
     244 
     245        This method can be called directly by the user. 
     246        """ 
    392247        self._setupArrays() 
    393248        datalines=open(self.filename).readlines()[self.NLHEAD:] 
    394         datalines=self.checkForBlankLines(datalines) 
     249        datalines=self._checkForBlankLines(datalines) 
    395250 
    396251        # Set up loop over unbounded indpendent variable 
     
    401256            m=m+1     
    402257 
    403     def _setupArrays(self): 
    404         self.X=[] 
    405         self.V=[] 
    406         # Set up the variables list 
    407         for n in range(self.NV): 
    408             self.V.append([]) 
    409              
    410     def _readData1(self, datalines, ivar_count):  
    411         # Start with independent and Auxilliary vars 
    412         (x2_and_a, rtlines)=readItemsFromUnknownLines(datalines, 1+self.NAUXV, float) 
    413         (x, aux)=(x2_and_a[0], x2_and_a[1:]) 
    414         self.X[0].append(x) 
    415         count=0 
    416         for a in range(self.NAUXV): 
    417             self.A[a].append(aux[count]) 
    418             count=count+1 
    419         return rtlines 
    420  
    421     def _readData1(self, datalines, ivar_count):  
    422         (x_and_v, rtlines)=readItemsFromUnknownLines(datalines, 1+self.NV, float) 
    423         (x, v)=(x_and_v[0], x_and_v[1:]) 
    424         self.X.append(x) 
    425         count=0 
    426         # Set up mth list in self.V 
    427         for n in range(self.NV): 
    428             self.V[n].append(v[count]) 
    429             count=count+1 
    430         return rtlines     
    431  
    432     def _readData2(self, datalines, ivar_count):                   
    433         return datalines   
    434  
    435     def writeData(self): 
    436         for i in range(len(self.X)): 
    437             var_string="" 
    438             for n in range(self.NV): 
    439                 var_string=var_string+("%s    " % self.V[n][i]) 
    440             self.file.write("%s    %s\n" % (self.X[i], var_string)) 
    441                  
    442          
    443 class NAFile1010(NAFile1001): 
    444  
    445     def readHeader(self): 
    446         self.readCommonHeader() 
    447         self.DX=readItemsFromLine(self.file.readline(), self.NIV, float) 
    448         self.XNAME=readItemsFromLines(self.readLines(self.NIV), self.NIV, str) 
    449         self.readVariablesHeaderSection() 
    450         self.readAuxVariablesHeaderSection() 
    451         self.readComments() 
    452  
    453     def _setupArrays(self): 
    454         self.X=[] 
    455         self.V=[] 
    456         self.A=[] 
    457         for n in range(self.NV): 
    458             self.V.append([]) 
    459         for a in range(self.NAUXV): 
    460             self.A.append([]) 
    461  
    462     def _readData1(self, datalines, ivar_count):  
    463         # Start with independent and Auxilliary vars 
    464         (x2_and_a, rtlines)=readItemsFromUnknownLines(datalines, 1+self.NAUXV, float) 
    465         (x, aux)=(x2_and_a[0], x2_and_a[1:]) 
    466         self.X.append(x) 
    467         count=0 
    468         for a in range(self.NAUXV): 
    469             self.A[a].append(aux[count]) 
    470             count=count+1 
    471         return rtlines 
    472     
    473     def _readData2(self, datalines, ivar_count):  
    474         # Now get the dependent variables 
    475         (v, rtlines)=readItemsFromUnknownLines(datalines, self.NV, float)               
    476         # Set up mth list in self.V             
    477         self.V.append([]) 
    478         count=0 
    479         for n in range(self.NV): 
    480             self.V[n].append([]) 
    481             self.V[ivar_count].append(v[count]) 
    482             count=count+1 
    483         return rtlines 
    484              
    485  
    486 class NAFile1020(NAFile1010): 
    487  
    488     def readHeader(self): 
    489         self.normalizedX="no" 
    490         self.readCommonHeader() 
    491         self.DX=readItemsFromLine(self.file.readline(), self.NIV, float) 
    492         if self.DX==0: 
    493             raise "DX found to be zero (0). Not allowed for FFI 1020." 
    494  
    495         self.NVPM=readItemFromLine(self.file.readline(), int) 
    496         self.XNAME=readItemsFromLines(self.readLines(self.NIV), self.NIV, str) 
    497         self.readVariablesHeaderSection() 
    498         self.readAuxVariablesHeaderSection() 
    499         self.readComments() 
    500    
    501     def _readData2(self, datalines, ivar_count):  
    502         # Now get the dependent variables 
    503         (v, rtlines)=readItemsFromUnknownLines(datalines, self.NV*self.NVPM, float)               
    504         count=0 
    505         for n in range(self.NV): 
    506             self.V[n].append([]) 
    507             for i in range(self.NVPM):   # Number of steps where independent variable is implied 
    508                 self.V[n][ivar_count].append(v[count]) 
    509             count=count+1 
    510         return rtlines 
    511  
    512     def _normalizeIndVars(self): 
    513         """ 
    514         Normalizes the values in the unbounded independent variable for FFIs 
    515         that store an abbreviated version of this axis. 
    516         """ 
    517         newX=[] 
    518         for x in self.X[0]: 
    519             for i in range(self.NVPM): 
    520                 newX.append(x+(i*self.DX)) 
    521         self.X[0]=newX 
    522         self.normalizedX="yes" 
    523  
    524  
    525 class NAFile2010(NAFile): 
    526  
    527     def readHeader(self): 
    528         self.normalizedX="no" 
    529         self.readCommonHeader() 
    530         self.DX=readItemsFromLine(self.file.readline(), self.NIV, float) 
    531         self.DX.reverse()  # Reverse because C-type array is least-changing first 
    532         self.NX=readItemsFromLine(self.file.readline(), self.NIV-1, int) 
    533         self.NX.reverse()  # Reverse because C-type array is least-changing first 
    534         self.NXDEF=readItemsFromLine(self.file.readline(), self.NIV-1, int) 
    535         self.NXDEF.reverse()  # Reverse because C-type array is least-changing first 
    536         self.X=[] 
    537         for i in range(self.NIV-1): 
    538             self.X.append(readItemsFromUnknownLines(self.file, self.NXDEF[i], float)) 
    539         # Unbounded Independent variable should be first so insert empty list at start 
    540         self.X.insert(0, []) 
    541         self.XNAME=readItemsFromLines(self.readLines(self.NIV), self.NIV, str) 
    542         self.XNAME.reverse()  # Reverse because C-type array is least-changing first 
    543         self.readVariablesHeaderSection() 
    544         self.readAuxVariablesHeaderSection() 
    545         self.readComments() 
    546  
    547     def writeHeader(self): 
    548         self.writeCommonHeader() 
    549         self.DX.reverse() 
    550         self.file.write(("%s "*self.NIV+"\n") % tuple(self.DX)) 
    551         self.NX.reverse() 
    552         self.file.write(("%s "*(self.NIV-1)+"\n") % tuple(self.NX)) 
    553         self.NXDEF.reverse() 
    554         self.file.write(("%s "*(self.NIV-1)+"\n") % tuple(self.NXDEF)) 
    555         for i in range(self.NIV-1): 
    556             self.file.write(("%s "*self.NXDEF[i]+"\n") % tuple(self.X[i+1][0:self.NXDEF[i]]))             
    557         self.XNAME.reverse() 
    558         self.file.write("%s\n"*self.NIV % tuple(self.XNAME)) 
    559         self.writeVariablesHeaderSection() 
    560         self.writeAuxVariablesHeaderSection() 
    561         self.writeComments()         
    562  
    563     def readData(self): 
    564         self._setupArrays() 
    565         datalines=open(self.filename).readlines()[self.NLHEAD:] 
    566         datalines=self.checkForBlankLines(datalines) 
    567  
    568         # Set up loop over unbounded indpendent variable 
    569         m=0   # Unbounded independent variable mark         
    570         while len(datalines)>0: 
    571             datalines=self._readData1(datalines, m) 
    572             datalines=self._readData2(datalines, m) 
    573             m=m+1     
    574  
    575     def _setupArrays(self): 
    576         self.V=[] 
    577         self.A=[] 
    578         # Create an array size to request using read routines 
    579         self.arraySize=1 
    580         for i in self.NX: 
    581             self.arraySize=self.arraySize*i        
    582         for n in range(self.NV): 
    583             self.V.append([]) 
    584         for a in range(self.NAUXV): 
    585             self.A.append([]) 
    586              
    587     def _readData1(self, datalines, ivar_count):  
    588         # Start with independent and Auxilliary vars 
    589         (x2_and_a, rtlines)=readItemsFromUnknownLines(datalines, 1+self.NAUXV, float) 
    590         (x, aux)=(x2_and_a[0], x2_and_a[1:]) 
    591         self.X[0].append(x) 
    592         count=0 
    593         for a in range(self.NAUXV): 
    594             self.A[a].append(aux[count]) 
    595             count=count+1 
    596         return rtlines 
    597  
    598     def _readData2(self, datalines, ivar_count): 
    599         # Now get the dependent variables           
    600         (v, rtlines)=readItemsFromUnknownLines(datalines, self.arraySize, float) 
    601         for n in range(self.NV): 
    602             self.V[n].append([]) 
    603             self._recursiveListPopulator(self.V[n][ivar_count], v, self.NX) 
    604             del self._counter 
    605         return rtlines     
    606  
    607     def writeData(self): 
    608         # Set up unbounded IV loop 
    609         self.NX.reverse() 
    610         for m in range(len(self.X[0])): 
    611             # Write Independent variable mark and auxiliary variables 
    612             var_string="%s    " % self.X[0][m] 
    613             for a in range(self.NAUXV): 
    614                 var_string=var_string+("%s    " % self.A[a][m]) 
    615             self.file.write("%s\n" % var_string.rstrip()) 
    616             # Write Variables 
    617             for n in range(self.NV): 
    618                 self._recursiveListWriter(self.V[n][m], self.NX) 
    619  
    620     def _normalizeIndVars(self): 
    621         """ 
    622         Normalizes the values in the unbounded independent variable for FFIs 
    623         that store an abbreviated version of this axis. 
    624         """ 
    625         for i in range(self.NIV-1): 
    626             if self.NXDEF[i]==self.NX[i]: 
    627                 pass 
    628             else: 
    629                 del self.X[i+1][1:] 
    630                 count=0 
    631                 while len(self.X[i+1])<self.NX[i]: 
    632                     nextx=self.X[i+1][count]+self.DX[i+1] 
    633                     self.X[i+1].append(nextx) 
    634                     count=count+1 
    635         self.normalizedX="yes" 
    636  
    637  
    638 class NAFile2110(NAFile2010): 
    639  
    640     def readHeader(self): 
    641         self.readCommonHeader() 
    642         self.DX=readItemsFromLine(self.file.readline(), self.NIV, float) 
    643         self.DX.reverse()  # Reverse because C-type array is least-changing first         
    644         self.XNAME=readItemsFromLines(self.readLines(self.NIV), self.NIV, str) 
    645         self.XNAME.reverse()  # Reverse because C-type array is least-changing first         
    646         self.readVariablesHeaderSection() 
    647         self.readAuxVariablesHeaderSection() 
    648         self.readComments() 
    649  
    650     def _setupArrays(self): 
    651         self.V=[] 
    652         self.A=[] 
    653         self.X=[]  # Needs to be a list of sublists each containing [x0n, [x1n, x1n+1, x1n+2....]] 
    654         self.NX=[] 
    655   
    656         for n in range(self.NV): 
    657             self.V.append([]) 
    658         for i in range(self.NAUXV): 
    659             self.A.append([]) 
    660  
    661     def _readData1(self, datalines, ivar_count):  
    662         # Start with independent and Auxilliary vars 
    663         (x_and_a, rtlines)=readItemsFromUnknownLines(datalines, self.NAUXV+1, float) 
    664         (x, aux)=(x_and_a[0], x_and_a[1:]) 
    665         for a in range(self.NAUXV): 
    666             self.A.append(aux[a]) 
    667         self.X.append([]) 
    668         self.X[ivar_count].append(x) 
    669         # Set up list to take second changing independent variable 
    670         self.X[ivar_count].append([])   
    671         self.NX.append(int(aux[0])) 
    672         return rtlines 
    673     
    674     def _readData2(self, datalines, ivar_count):  
    675         # Now get the dependent variables 
    676         for n in range(self.NV): 
    677             self.V[n].append([]) 
    678         for c in range(self.NX[ivar_count]): 
    679             (x_and_v, datalines)=readItemsFromUnknownLines(datalines, self.NV+1, float) 
    680             (x, v)=(x_and_v[0], x_and_v[1:]) 
    681             self.X[ivar_count][1].append(x) 
    682             count=0 
    683             for n in range(self.NV): 
    684                 self.V[n][ivar_count].append(v[count]) 
    685                 count=count+1 
    686         rtlines=datalines 
    687         return rtlines 
    688  
    689  
    690 class NAFile2160(NAFile2110): 
    691  
    692     def readHeader(self): 
    693         self.normalizedX="no" 
    694         self.readCommonHeader() 
    695         self.DX=readItemsFromLine(self.file.readline(), 1, float) 
    696         self.LENX=readItemFromLine(self.file.readline(), float) 
    697         self.XNAME=readItemsFromLines(self.readLines(self.NIV), self.NIV, str) 
    698         self.XNAME.reverse()  # Reverse because C-type array is least-changing first           
    699         self.readVariablesHeaderSection() 
    700         self.readCharAuxVariablesHeaderSection() 
    701         self.readComments() 
    702  
    703     def _setupArrays(self): 
    704         self.V=[] 
    705         self.A=[] 
    706         self.X=[] 
    707         self.NX=[] 
    708          
    709         for n in range(self.NV): 
    710             self.V.append([]) 
    711         for i in range(self.NAUXV): 
    712             self.A.append([]) 
    713  
    714     def _readData1(self, datalines, ivar_count):  
    715         # Start with independent and Auxilliary vars 
    716         # Get character string independent variable 
    717         (x1, datalines)=readItemsFromUnknownLines(datalines, 1, str) 
    718         self.X.append([]) 
    719         self.X[ivar_count].append(x1) 
    720         # Set up list to take second changing independent variable 
    721         self.X[ivar_count].append([])   
    722         # Get NX and Non-character AUX vars 
    723         (aux, datalines)=readItemsFromUnknownLines(datalines, (self.NAUXV-self.NAUXC), float) 
    724         self.NX.append(int(aux[0])) 
    725         for a in range(self.NAUXV-self.NAUXC): 
    726             self.A.append(aux[a]) 
    727         # Get character AUX vars 
    728         (auxc)=readItemsFromLines(datalines[:self.NAUXC], self.NAUXC, str) 
    729         rtlines=datalines[self.NAUXC:] 
    730         for a in range(self.NAUXC): 
    731             self.A.append(auxc[a]) 
    732         return rtlines 
    733      
    734  
    735 class NAFile2310(NAFile2110): 
    736  
    737     def readHeader(self): 
    738         self.normalizedX="no" 
    739         self.readCommonHeader() 
    740         self.DX=readItemsFromLine(self.file.readline(), 1, float) 
    741         self.XNAME=readItemsFromLines(self.readLines(self.NIV), self.NIV, str) 
    742         self.XNAME.reverse()  # Reverse because C-type array is least-changing first           
    743         self.readVariablesHeaderSection() 
    744         self.readAuxVariablesHeaderSection() 
    745         self.readComments() 
    746      
    747     def _readData1(self, datalines, ivar_count):  
    748         # Start with independent and Auxilliary vars 
    749         (x_and_a, rtlines)=readItemsFromUnknownLines(datalines, self.NAUXV+1, float) 
    750         (x, aux)=(x_and_a[0], x_and_a[1:]) 
    751         for a in range(self.NAUXV): 
    752             self.A.append(aux[a]) 
    753         self.X.append([]) 
    754         self.X[ivar_count].append(x) 
    755         # Set up list to take second changing independent variable 
    756         self.X[ivar_count].append([aux[1]])   
    757         self.NX.append(int(aux[0])) 
    758         self.DX.append(int(aux[2])) 
    759         return rtlines 
    760     
    761     def _readData2(self, datalines, ivar_count):  
    762         # Now get the dependent variables 
    763         (v, rtlines)=readItemsFromUnknownLines(datalines, self.NV*self.NX[ivar_count], float) 
    764         count=0 
    765         for n in range(self.NV): 
    766             self.V[n].append([]) 
    767             for i in range(self.NX[ivar_count]): 
    768                 self.V[n][ivar_count].append(v[count]) 
    769                 count=count+1 
    770         return rtlines 
    771  
    772  
    773 class NAFile3010(NAFile2010): 
    774     """ 
    775     Identical class rules to FFI 3010. 
    776     """ 
    777     pass 
    778  
    779 class NAFile4010(NAFile2010): 
    780     """ 
    781     Identical class rules to FFI 4040. 
    782     """ 
    783     pass 
Note: See TracChangeset for help on using the changeset viewer.