source: trunk/anuga_core/source/anuga/utilities/sww_merge.py @ 8277

Last change on this file since 8277 was 8277, checked in by steve, 12 years ago

Trying to fix sww_merge.py

File size: 6.8 KB
Line 
1"""
2    Merge a list of .sww files together into a single file.
3"""
4
5import numpy as num
6from anuga.utilities.numerical_tools import ensure_numeric
7
8from Scientific.IO.NetCDF import NetCDFFile
9from anuga.config import netcdf_mode_r, netcdf_mode_w, netcdf_mode_a
10from anuga.config import netcdf_float, netcdf_float32, netcdf_int
11from anuga.file.sww import SWW_file, Write_sww
12
13def sww_merge(domain_global_name, np, verbose=False):
14
15    output = domain_global_name+".sww"
16    swwfiles = [ domain_global_name+"_P"+str(v)+"_"+str(np)+".sww" for v in range(np)]
17
18    _sww_merge(swwfiles, output, verbose)
19
20
21def _sww_merge(swwfiles, output, verbose):
22    """
23        Merge a list of sww files into a single file.
24       
25        May be useful for parallel runs. Note that colinear points and
26        edges are not merged: there will essentially be multiple meshes within
27        the one sww file.
28       
29        The sww files to be merged must have exactly the same timesteps. Note
30        that some advanced information and custom quantities may not be
31        exported.
32       
33        swwfiles is a list of .sww files to merge.
34        output is the output filename, including .sww extension.
35        verbose True to log output information
36    """
37
38    if verbose:
39        print "MERGING SWW Files"
40       
41    static_quantities = ['elevation']
42    dynamic_quantities = ['stage', 'xmomentum', 'ymomentum']
43   
44    first_file = True
45    tri_offset = 0
46    for filename in swwfiles:
47        if verbose:
48            print 'Reading file ', filename, ':'   
49   
50        fid = NetCDFFile(filename, netcdf_mode_r)
51
52       
53       
54        tris = fid.variables['volumes'][:]       
55         
56        if first_file:
57            times = fid.variables['time'][:]
58            x = []
59            y = []
60            out_tris = list(tris) 
61            out_s_quantities = {}
62            out_d_quantities = {}
63
64
65            xllcorner = fid.xllcorner
66            yllcorner = fid.yllcorner
67
68            print 'zone',fid.zone
69
70            print """
71            fid.order
72            fid.xllcorner;
73            fid.yllcorner ;
74            fid.zone;
75            fid.false_easting;
76            fid.false_northing;
77            fid.datum;
78            fid.projection;
79            """
80
81
82            print fid.order
83            print fid.xllcorner;
84            print fid.yllcorner ;
85            print fid.zone;
86            print fid.false_easting;
87            print fid.false_northing;
88            print fid.datum;
89            print fid.projection;
90
91            order      = fid.order
92            xllcorner  = fid.xllcorner;
93            yllcorner  = fid.yllcorner ;
94            zone       = fid.zone;
95            false_easting  = fid.false_easting;
96            false_northing = fid.false_northing;
97            datum      = fid.datum;
98            projection = fid.projection;
99
100           
101            for quantity in static_quantities:
102                out_s_quantities[quantity] = []
103
104            # Quantities are stored as a 2D array of timesteps x data.
105            for quantity in dynamic_quantities:
106                out_d_quantities[quantity] = [ [] for _ in range(len(times))]
107                 
108            description = 'merged:' + getattr(fid, 'description')         
109            first_file = False
110        else:
111            for tri in tris:
112                # Advance new tri indices to point at newly appended points.
113                verts = [vertex+tri_offset for vertex in tri]
114                out_tris.append(verts)
115
116        num_pts = fid.dimensions['number_of_points']
117        tri_offset += num_pts
118       
119        if verbose:
120            print '  new triangle index offset is ', tri_offset
121           
122        x.extend(list(fid.variables['x'][:]))
123        y.extend(list(fid.variables['y'][:]))
124       
125        # Grow the list of static quantities associated with the x,y points
126        for quantity in static_quantities:
127            out_s_quantities[quantity].extend(fid.variables[quantity][:])
128           
129        #Collate all dynamic quantities according to their timestep
130        for quantity in dynamic_quantities:
131            time_chunks = fid.variables[quantity][:]
132            for i, time_chunk in enumerate(time_chunks):
133                out_d_quantities[quantity][i].extend(time_chunk)           
134   
135    # Mash all points into a single big list   
136    points = [[xx, yy] for xx, yy in zip(x, y)]
137
138    points = num.asarray(points, dtype='f')
139    print points
140    fid.close()
141
142    #---------------------------
143    # Write out the SWW file
144    #---------------------------
145
146    if verbose:
147            print 'Writing file ', output, ':'
148    fido = NetCDFFile(output, netcdf_mode_w)
149    sww = Write_sww(static_quantities, dynamic_quantities)
150    sww.store_header(fido, times,
151                             len(out_tris),
152                             len(points),
153                             description=description,
154                             sww_precision=netcdf_float32)
155
156
157   
158   
159    sww.store_triangulation(fido, points, out_tris)
160
161    fido.order      = order
162    fido.xllcorner  = xllcorner;
163    fido.yllcorner  = yllcorner ;
164    fido.zone       = zone;
165    fido.false_easting  = false_easting;
166    fido.false_northing = false_northing;
167    fido.datum      = datum;
168    fido.projection = projection;
169       
170    sww.store_static_quantities(fido, verbose=verbose, **out_s_quantities)
171
172    # Write out all the dynamic quantities for each timestep
173    for q in dynamic_quantities:
174        q_values = out_d_quantities[q]
175        for i, time_slice in enumerate(q_values):
176            fido.variables[q][i] = num.array(time_slice, netcdf_float32)
177       
178        # This updates the _range values
179        q_range = fido.variables[q + Write_sww.RANGE][:]
180        q_values_min = num.min(q_values)
181        if q_values_min < q_range[0]:
182            fido.variables[q + Write_sww.RANGE][0] = q_values_min
183        q_values_max = num.max(q_values)
184        if q_values_max > q_range[1]:
185            fido.variables[q + Write_sww.RANGE][1] = q_values_max       
186
187                                       
188    fido.close()
189   
190
191if __name__ == "__main__":
192
193    import argparse
194    from anuga.anuga_exceptions import ANUGAError
195
196
197    parser = argparse.ArgumentParser(description='Merge sww files created from parallel run')
198    parser.add_argument('-np', type=int, default = 4,
199                   help='number of processors used to produce sww files')
200    parser.add_argument('-f', type=str, default="domain",
201                   help='domain global name')
202    parser.add_argument('-v', nargs='?', type=bool, const=True, default=False,
203                   help='verbosity')
204
205    args = parser.parse_args()
206
207    np = args.np
208    domain_global_name = args.f
209    verbose = args.v
210
211
212    try:
213        sww_merge(domain_global_name, np, verbose)
214    except:
215        msg = 'ERROR: When merging sww files %s '% domain_global_name
216        print msg
217        raise
Note: See TracBrowser for help on using the repository browser.