source: nappy/trunk/nappy/na_file/na_file_2010.py @ 3414

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/nappy/trunk/nappy/na_file/na_file_2010.py@3414
Revision 3414, 6.0 KB checked in by astephen, 12 years ago (diff)

Tidied up _fixHeaderLength in na_file.py.
Changed write interface so self.write(na_dict, delimiter, float_format)
is a separate call to creating the instance.
Fixed unit tests to cope with this.

BUT: broke nappy_api.openNAFile(<file>, "w") with these changes.
Hence need to think about changes being made to openNAFile() so that it
can predict (or not) the FFI.

Only 1001 unit test (worked on by CK) is broken at present.

Line 
1#   Copyright (C) 2004 CCLRC & NERC( Natural Environment Research Council ).
2#   This software may be distributed under the terms of the
3#   Q Public License, version 1.0 or later. http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
4
5"""
6naFile2010.py
7=============
8
9Container module for NAFile2010 class.
10
11"""
12
13# Imports from python standard library
14
15# Imports from local package
16import nappy.utils.text_parser
17import nappy.utils.list_manipulator
18import nappy.na_file.na_file
19
20
21class NAFile2010(nappy.na_file.na_file.NAFile):
22    """
23    Class to read, write and interact with NASA Ames files conforming to the
24    File Format Index (FFI) 2010.
25    """
26
27    def readHeader(self):
28        """
29        Reads FFI-specifc header section.
30        """       
31        self._normalized_X = False
32        self._readCommonHeader()
33        self.DX = nappy.utils.text_parser.readItemsFromLine(self.file.readline(), self.NIV, float)
34        self.DX.reverse()  # Reverse because C-type array is least-changing first
35        self.NX = nappy.utils.text_parser.readItemsFromLine(self.file.readline(), self.NIV - 1, int)
36        self.NX.reverse()  # Reverse because C-type array is least - changing first
37        self.NXDEF = nappy.utils.text_parser.readItemsFromLine(self.file.readline(), self.NIV - 1, int)
38        self.NXDEF.reverse()  # Reverse because C-type array is least-changing first
39        self.X = []
40        for i in range(self.NIV - 1):
41            self.X.append(nappy.utils.text_parser.readItemsFromUnknownLines(self.file, self.NXDEF[i], float))
42        # Unbounded Independent variable should be first so insert empty list at start
43        self.X.reverse()                 
44        self.X.insert(0, [])
45        self.XNAME = nappy.utils.text_parser.readItemsFromLines(self._readLines(self.NIV), self.NIV, str)
46        self.XNAME.reverse()  # Reverse because C-type array is least-changing first
47        self._readVariablesHeaderSection()
48        self._readAuxVariablesHeaderSection()
49        self._readComments()
50
51    def writeHeader(self):
52        """
53        Writes FFI-specifc header section.
54        """       
55        self._writeCommonHeader()
56        self.DX.reverse()
57        self.header.write(("%s " * self.NIV + "\n") % tuple(self.DX))
58        self.NX.reverse()
59        self.header.write(("%s " * (self.NIV - 1) + "\n") % tuple(self.NX))
60        self.NXDEF.reverse()
61        self.header.write(("%s " * (self.NIV - 1) + "\n") % tuple(self.NXDEF))
62        self.NXDEF.reverse()
63        X_lines = []
64
65        for i in range(self.NIV - 1):
66            X_lines.append(((self.float_format + self.delimiter) * self.NXDEF[i] + "\n") % tuple(self.X[i + 1][0:self.NXDEF[i]]))
67
68        X_lines.reverse()
69        for line in X_lines:
70            self.header.write(line.lstrip())
71
72        self.XNAME.reverse()
73        self.header.write("%s\n" * self.NIV % tuple(self.XNAME))
74        self._writeVariablesHeaderSection()
75        self._writeAuxVariablesHeaderSection()
76        self._writeComments()         
77        self._fixHeaderLength()
78        self.file.write(self.header.read())
79
80
81    def _setupArrays(self):
82        """
83        Sets up FFI-specific arrays to fill with data (lists of lists).
84        """
85        self.V = []
86        self.A = []
87
88        # Create an array size to request using read routines
89        self.arraySize = 1
90        for i in self.NX:
91                self.arraySize = self.arraySize * i
92        for n in range(self.NV):
93            self.V.append([])
94        for a in range(self.NAUXV):
95            self.A.append([])
96           
97    def _readData1(self, datalines, ivar_count):
98        """
99        Reads first line/section of current block of data.
100        """       
101        # Start with independent and Auxilliary vars
102        (x2_and_a, rtlines) = nappy.utils.text_parser.readItemsFromUnknownLines(datalines, 1 + self.NAUXV, float)
103        (x, aux) = (x2_and_a[0], x2_and_a[1:])
104        self.X[0].append(x)
105        count = 0
106        for a in range(self.NAUXV):
107            self.A[a].append(aux[count])
108            count = count + 1
109        return rtlines
110
111    def _readData2(self, datalines, ivar_count):
112        """
113        Reads second line/section (if used) of current block of data.
114        """
115        # Now get the dependent variables
116        for n in range(self.NV):
117            (v, rtlines) = nappy.utils.text_parser.readItemsFromUnknownLines(datalines, self.arraySize, float)
118            self.V[n].append([])
119            nappy.utils.list_manipulator.recursiveListPopulator(self.V[n][ivar_count], v, self.NX)
120            datalines = rtlines
121        return rtlines
122
123    def writeData(self):
124        """
125        Writes the data section of the file.
126        This method can be called directly by the user.
127        """       
128        # Set up unbounded IV loop
129        self.NX.reverse()
130        for m in range(len(self.X[0])):
131            # Write Independent variable mark and auxiliary variables
132            var_string = (self.float_format + self.delimiter) % self.X[0][m]
133            for a in range(self.NAUXV):
134                var_string = var_string + ((self.float_format + self.delimiter) % self.A[a][m])
135            self.file.write("%s\n" % var_string.rstrip())
136            # Write Variables
137            for n in range(self.NV):
138                outlines = nappy.utils.list_manipulator.recursiveListWriter(self.V[n][m], self.NX, delimiter = self.delimiter, float_format = self.float_format)
139                for line in outlines:
140                    self.file.write(line)
141
142    def _normalizeIndVars(self):
143        """
144        Normalizes the values in the unbounded independent variable for FFIs
145        that store an abbreviated version of this axis.
146        """
147        for i in range(self.NIV - 1):
148            if self.NXDEF[i] == self.NX[i]:
149                pass
150            else:
151                del self.X[i + 1][1:]
152                count = 0
153                while len(self.X[i + 1])<self.NX[i]:
154                    nextx = self.X[i + 1][count] + self.DX[i + 1]
155                    self.X[i + 1].append(nextx)
156                    count = count + 1
157        self._normalized_X = True
Note: See TracBrowser for help on using the repository browser.