source: inundation/pyvolution/interpolate_sww.py @ 2891

Last change on this file since 2891 was 2750, checked in by duncan, 19 years ago

Do interpolation using fit_interpolate/interpolate.py, instead of least_squares.py.

File size: 6.9 KB
Line 
1""" Interpolation of a sww file.
2Used to interpolate height information from sww files.
3
4When using as a stand alone application,
5Input;
6 - The sww file with stage and bed elevation information
7 - An xya file specifying the points (x,y) where the height values
8   (w.r.t. time) are needed.
9
10Ouput;
11An xya file with x,y and height values w.r.t. time.
12
13The first row of the output xya file has the time value for each height
14Each following row has the format x,y,[height,]
15
16NOTE: stage = bed elevation + height
17
18   Ole Nielsen, Stephen Roberts, Duncan Gray, Christopher Zoppou
19   Geoscience Australia, 2004.   
20"""
21
22##FIXME (DSG-DSG)  no sww file? give a better error message.
23
24from Numeric import transpose
25from least_squares import Interpolation
26
27DEFAULT_QUANTITY = "depth"
28
29def  interpolate_sww2xya(sww_file, quantity_name,point_file_in,
30                         point_file_out, display_errors = True):
31    """
32    This function catches exceptions.
33    """
34    try:
35        interp = Interpolate_sww(sww_file, quantity_name)
36        interp.interpolate_xya(point_file_in)
37        interp.write_depth_xya(point_file_out)
38    except IOError,e: #need to convert key error to ioerror
39        if display_errors:
40            print "Could not load bad file. ", e
41        import sys; sys.exit()
42
43        # FIXME (DSG-DSG): how are bad quantities caught?
44        #try:
45        #    interp = Interpolate_sww(sww_file, quantity_name)
46        #except KeyError:
47        #    print "Error: Unknown quantity"
48        #    sys.exit(1)
49
50        interp.interpolate_xya(point_file_in)
51        interp.write_depth_xya(point_file_out)
52
53
54
55class Interpolate_sww:
56    def __init__(self, file_name, quantity_name):
57
58        #It's bad to have the quantity_name passed in here.
59        # But it works with how the program is currently used.
60        # Refactor when necessary. - DSG
61
62        print "Obsolete."
63        x, y, volumes, time, quantity = self.read_sww(file_name, quantity_name)
64        vertex_coordinates = transpose([x,y])
65       
66        if False:
67            print "****************************"
68            print "x "
69            print x
70            print "****************************"
71            print "Y "
72            print y
73            print "****************************"
74            print "V "
75            print volumes
76            print "****************************"
77            print "Time "
78            print time
79            print "****************************"
80            print "quantity "
81            print quantity
82            print "****************************"
83            print "vertex_coordinates"
84            print vertex_coordinates
85            print "****************************"
86       
87        self.interp = Interpolation(vertex_coordinates, volumes, alpha=0)
88        self.time = time
89
90        self.quantity_name = quantity_name
91        self.quantity = quantity
92       
93    def interpolate_xya(self, file_name):
94        """
95        Given a point file, interpolate the height w.r.t. time at the points
96        specified in the point file.
97
98        Input;
99        file_name - the xya file
100        """
101       
102        from load_mesh.loadASCII import import_points_file
103       
104        point_dict = import_points_file(file_name)
105        self.point_coordinates = point_dict['pointlist']
106        self.interp.build_interpolation_matrix_A(self.point_coordinates)
107        self.interpolated_quantity_raw = self.interp.interpolate(transpose(self.quantity))
108        self.interpolated_quantity = {}
109        for i,time_slice in enumerate(self.time):
110            self.interpolated_quantity[str(time_slice)] = self.interpolated_quantity_raw[:,i]
111       
112           
113    def read_sww(self, file_name, quantity_name):
114        """
115        Read in an sww file.
116
117        Input;
118        file_name - the sww file
119
120        Output;
121        x - Vector of x values
122        y - Vector of y values
123        z - Vector of bed elevation
124        volumes - Array.  Each row has 3 values, representing
125                  the vertices that define the volume
126        time - Vector of the times where there is stage information
127        stage - array with respect to time and vertices (x,y)
128        """
129       
130        #FIXME Have this reader as part of data_manager?
131
132        from Scientific.IO.NetCDF import NetCDFFile     
133        import tempfile
134        import sys
135        import os
136           
137        #Check contents
138        #Get NetCDF
139   
140        # see if the file is there.  Throw a QUIET IO error if it isn't
141        fd = open(file_name,'r')
142        fd.close()
143
144        #throws prints to screen if file not present
145       
146        junk = tempfile.mktemp(".txt")
147        fd = open(junk,'w')
148        stdout = sys.stdout
149        sys.stdout = fd
150        fid = NetCDFFile(file_name, 'r') 
151        sys.stdout = stdout
152        fd.close()
153        #clean up
154        os.remove(junk)         
155     
156        # Get the variables
157        x = fid.variables['x'][:]
158        y = fid.variables['y'][:]
159        volumes = fid.variables['volumes'][:] 
160        time = fid.variables['time'][:]
161        try:
162            if quantity_name == 'depth':
163                z = fid.variables['elevation'][:]
164                stage = fid.variables['stage'][:,:]
165                quantity = stage - z  # 2D, using broadcasting
166                #print quantity
167            else:
168                quantity = fid.variables[quantity_name][:,:]   # 2D
169        except (KeyError, IndexError),e:
170            fid.close()
171            raise KeyError
172           
173        fid.close()
174        return x, y, volumes, time, quantity
175
176    def write_depth_xya(self,point_file, delimiter = ','):
177        """
178        pre condition:
179        point attributes have been determined
180        (interpolate_xya has been called)
181        The time list is defined
182        """
183        from load_mesh.loadASCII import export_points_file
184
185        xya_dict = {}
186        xya_dict['pointlist'] = self.point_coordinates
187        xya_dict['attributelist'] = self.interpolated_quantity
188        export_points_file(point_file, xya_dict)
189       
190       
191#-------------------------------------------------------------
192
193
194if __name__ == "__main__":
195    """
196    Load in an sww file and an xya file and return an xya file
197    """
198    import os, sys
199    usage = "usage: %s pyvolution_results.sww points.xya depth.xya [depth|stage|(other quantities)]" %         os.path.basename(sys.argv[0])
200    if len(sys.argv) < 4:
201        print usage
202    else:
203        sww_file = sys.argv[1]
204        point_file_in = sys.argv[2]
205        point_file_out = sys.argv[3]
206        if len(sys.argv) == 5:
207            quantity_name = sys.argv[4]
208        else:
209            quantity_name = DEFAULT_QUANTITY   
210        #print "quantity",quantity
211        interpolate_sww2xya(sww_file, quantity_name,point_file_in,
212                            point_file_out)
213
214
215
216
217
218
219
Note: See TracBrowser for help on using the repository browser.