source: branches/anuga_1_1/anuga_work/production/bunbury_storm_surge_2009/process_gems_grids.py @ 7723

Last change on this file since 7723 was 7723, checked in by sexton, 13 years ago

updates

File size: 9.6 KB
Line 
1# ---------------------------------------------------------------------------
2# This python script reads in GEMSURGE outputs and writes them into a master
3# STS file that contains all the data across the entire model domain at all
4# timesteps. It requires a vertically flipped elevation ASCII grid which is
5# merged with the GEMSURGE data to calculate the required quantities of
6# xmomentum and ymomentum.
7# Written by Nariman Habili and Leharne Fountain, 2010
8# ---------------------------------------------------------------------------
9
10import glob
11import os
12import gzip
13import pdb 
14import numpy
15import math
16from Scientific.IO.NetCDF import NetCDFFile
17from anuga.coordinate_transforms.geo_reference import Geo_reference, write_NetCDF_georeference
18
19#-----------------
20# Directory setup
21#-------------------
22state = 'western_australia'
23scenario_folder = 'bunbury_storm_surge_scenario_2009'
24event = 'gcom_60min'
25
26print "Processing event: ", event
27
28ENV_INUNDATIONHOME = 'INUNDATIONHOME'
29home = os.path.join(os.getenv(ENV_INUNDATIONHOME), 'data') # Absolute path for data folder
30# GEMS_folder = os.path.join(home, state, scenario_folder, 'GEMS')
31anuga_folder = os.path.join(home, state, scenario_folder, 'anuga')
32boundaries_folder = os.path.join(anuga_folder, 'boundaries')
33event_folder = os.path.join(boundaries_folder, event)
34
35# input_dir = os.path.join(GEMS_folder, event)
36
37#-----------------------
38# Input files from GEMS
39#-----------------------
40elevation_file_name = os.path.join(event_folder, 'buntopog_20m_flip.asc')  # Name of the vertically flipped elevation grid
41
42print "Elevation file name: ", elevation_file_name
43
44grid_file_names = glob.glob(os.path.join(event_folder, 'gcom*.gz'))
45grid_file_names.sort()
46
47grid_file_names_temp = []
48for i in range(1, 32, 1):
49    grid_file_names_temp.append(grid_file_names[i])
50
51grid_file_names = grid_file_names_temp
52   
53number_of_timesteps = len(grid_file_names)
54
55print "Number of timesteps: ", number_of_timesteps
56
57start_time = 0      # all times in seconds
58timestep = 3600 #1440 #720     # all times in seconds
59end_time =  start_time + (timestep*number_of_timesteps) # all times in seconds
60refzone = 50        # UTM zone of model
61event_sts = os.path.join(event_folder, event)
62
63elevation = []
64
65elevation_file = open(elevation_file_name, 'rb')
66lines = elevation_file.readlines()
67elevation_file.close()
68
69# Strip off the ASCII header and also read ncols, nrows,
70# x_origin, y_origin, grid_size, no_data value, and read in elevation grid:
71for i, L in enumerate(lines):
72    if i == 0:
73        ncols = int(L.strip().split()[1])
74    if i == 1:
75        nrows = int(L.strip().split()[1])
76    if i == 2:
77        x_origin = int(L.strip().split()[1])
78    if i == 3:
79        y_origin = int(L.strip().split()[1])
80    if i == 4:
81        grid_size = int(L.strip().split()[1])
82    if i == 5:
83        no_data = int(float(L.strip().split()[1]))
84    if i > 5:
85        elevation+= L.strip().split()
86
87print 'Number or columns: ', ncols
88print 'Number of rows: ', nrows
89print 'X origin: ', x_origin
90print 'Y origin: ', y_origin
91print 'Grid size: ', grid_size
92print 'No data value: ', no_data
93
94#------------------------------------------------------
95# Create arrays of elevation, stage, speed and theta
96#-------------------------------------------------------
97print 'creating numpy arrays: elevation, stage, speed, theta'
98
99stage = numpy.empty(number_of_timesteps*nrows*ncols, dtype=float)
100speed = numpy.empty(number_of_timesteps*nrows*ncols, dtype=float)
101theta = numpy.empty(number_of_timesteps*nrows*ncols, dtype=float)
102
103for j, f in enumerate(grid_file_names):
104    print 'file: ', f
105   
106    gz_file = gzip.open(f, 'rb')
107
108    st = []
109    sp = []
110    t = []
111
112    for i, L in enumerate(gz_file):
113       
114        if i > 7 and i < (8 + nrows):   #  7 refers to the number of rows of header info that we skip - always CHECK format
115            st += L.strip().split()
116           
117        if i > (9 + nrows) and i < (10 + 2*nrows):
118            sp += L.strip().split()
119           
120        if i > (11 + 2*nrows):
121            t += L.strip().split()
122
123    stage[j*nrows*ncols : (j+1)*nrows*ncols] = numpy.flipud(numpy.array(st).astype('d'))
124    speed[j*nrows*ncols : (j+1)*nrows*ncols] = numpy.flipud(numpy.array(sp).astype('d'))
125    theta[j*nrows*ncols : (j+1)*nrows*ncols] = numpy.flipud(numpy.array(t).astype('d'))
126
127    gz_file.close()
128
129elevation = numpy.array(elevation).astype('d')
130
131print 'Size of elevation array: ', elevation.size
132print 'Size of stage array: ', stage.size
133print 'Size of speed array: ', speed.size
134print 'Size of theta array: ', theta.size
135
136assert stage.size == speed.size == theta.size == ncols * nrows * number_of_timesteps
137assert stage.size == number_of_timesteps * elevation.size
138
139depth = numpy.empty(stage.size, dtype='d')
140number_of_points = ncols * nrows
141
142# ---------------------------------------------
143# Create mask of no_data values across stage, speed and theta to ensure all three quantities
144# have no_data values in corresponding cells - this is a work-around until GEMS can produce a
145# a consistant dataset
146# ---------------------------------------------
147import pdb
148pdb.set_trace()
149no_value_index = numpy.where(((stage < -100) + (speed < 0) + (theta < 0)) == True)[0]
150depth = stage - numpy.tile(elevation, number_of_timesteps)
151
152numpy.put(stage, no_value_index, -9999)
153numpy.put(speed, no_value_index, -9999)
154numpy.put(theta, no_value_index, -9999)
155numpy.put(depth, no_value_index, 0)
156   
157# Taking absolute value is to account for -ve depths obtained when stage-elevation
158# is slightly -ve  - why I don't know, possbly a rounding error?
159momentum = numpy.absolute(depth * speed)
160
161print 'Calculating xmomentum and ymomentum'
162
163xmomentum = momentum*numpy.sin(numpy.radians(theta))
164ymomentum = momentum*numpy.cos(numpy.radians(theta))
165
166numpy.put(xmomentum, no_value_index, 0)
167numpy.put(ymomentum, no_value_index, 0)
168
169#    if t > 0.0 and t < 90.0:
170#        assert mx >= 0 and my >= 0
171       
172#    elif t > 90.0 and t < 180.0:
173#        assert mx >= 0 and my <= 0
174       
175#    elif t > 180.0 and t < 270.0:
176#        assert mx <= 0  and my <= 0
177       
178#    elif t > 270.0 and t < 360.0:
179#        assert mx <= 0 and my >= 0
180       
181#    elif t == 0.0 or t == 360.0:
182#        assert my >= 0
183       
184#    elif t == 90.0:
185#        assert mx >= 0
186       
187#    elif t == 180.0:
188#        assert my <= 0
189       
190#    elif t == 270.0:
191#        assert mx <= 0
192       
193#    elif t == -9999:
194#        mx = 0
195#        my = 0
196#    else:
197#        print "Unexpected value of theta"
198#        exit()
199       
200#    xmomentum[i] = mx
201#    ymomentum[i] = my
202
203assert len(numpy.where((numpy.sqrt(xmomentum**2 + ymomentum**2) - momentum) > 1.e-06)[0]) == 0
204   
205x_origin_int = int(10000*x_origin)
206y_origin_int = int(10000*y_origin)
207grid_size_int = int(10000*grid_size)
208
209x = numpy.tile(numpy.arange(x_origin_int, (x_origin_int + ncols * grid_size_int), grid_size_int)/10000.0, nrows)
210y = numpy.repeat(numpy.arange(y_origin_int, (y_origin_int + nrows * grid_size_int), grid_size_int)/10000.0, ncols)
211
212assert x.size == y.size == number_of_points
213
214time = numpy.arange(start_time, end_time, timestep, dtype='i')
215
216assert time.size == number_of_timesteps
217assert momentum.size == stage.size
218
219# -----------------------------
220# Create the STS file
221# -----------------------------
222print "Creating the STS NetCDF file"
223
224#for j in range(2):
225
226fid = NetCDFFile(os.path.join(event_folder, event + '_master_2_1.sts'), 'wl')
227fid.institution = 'Geoscience Australia'
228fid.description = "description"
229fid.starttime = 0.0
230fid.ncols = ncols
231fid.nrows = nrows
232fid.grid_size = grid_size
233fid.no_data = no_data
234fid.createDimension('number_of_points', number_of_points)
235fid.createDimension('number_of_timesteps', number_of_timesteps)
236fid.createDimension('numbers_in_range', 2)
237
238fid.createVariable('x', 'd', ('number_of_points',))
239fid.createVariable('y', 'd', ('number_of_points',))
240fid.createVariable('elevation', 'd', ('number_of_points',))
241fid.createVariable('elevation_range', 'd', ('numbers_in_range',))
242fid.createVariable('time', 'i', ('number_of_timesteps',))
243fid.createVariable('stage', 'd', ('number_of_timesteps', 'number_of_points'))
244fid.createVariable('stage_range', 'd', ('numbers_in_range', ))
245fid.createVariable('xmomentum', 'd', ('number_of_timesteps', 'number_of_points'))
246fid.createVariable('xmomentum_range', 'd', ('numbers_in_range',))
247fid.createVariable('ymomentum', 'd', ('number_of_timesteps', 'number_of_points'))
248fid.createVariable('ymomentum_range', 'd', ('numbers_in_range',))
249
250fid.variables['elevation_range'][:] = numpy.array([1e+036, -1e+036])
251fid.variables['stage_range'][:] = numpy.array([1e+036, -1e+036])
252fid.variables['xmomentum_range'][:] = numpy.array([1e+036, -1e+036])
253fid.variables['ymomentum_range'][:] = numpy.array([1e+036, -1e+036])
254fid.variables['elevation'][:] = elevation
255fid.variables['time'][:] = time#[j*60 : j*60 + 60]
256
257s = fid.variables['stage']
258xm = fid.variables['xmomentum']
259ym = fid.variables['ymomentum']
260
261#jj = j*number_of_points*(number_of_timesteps/2)
262
263for i in xrange(number_of_timesteps):
264    ii = i*number_of_points# + jj
265    s[i] = stage[ii : ii + number_of_points]
266    xm[i] = xmomentum[ii : ii + number_of_points]
267    ym[i] = ymomentum[ii : ii + number_of_points]
268
269origin = Geo_reference(refzone, min(x), min(y)) # Check this section for inputs in eastings and northings - it works for long and lat
270geo_ref = write_NetCDF_georeference(origin, fid)
271
272fid.variables['x'][:] = x - geo_ref.get_xllcorner()
273fid.variables['y'][:] = y - geo_ref.get_yllcorner()
274
275fid.close()
276
Note: See TracBrowser for help on using the repository browser.