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

Last change on this file since 7678 was 7678, checked in by fountain, 15 years ago

updates to bunbury storm surge model

File size: 9.4 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 = 'case_1' # Baseline TC Alby event
25
26ENV_INUNDATIONHOME = 'INUNDATIONHOME'
27home = os.path.join(os.getenv(ENV_INUNDATIONHOME), 'data') # Absolute path for data folder
28# GEMS_folder = os.path.join(home, state, scenario_folder, 'GEMS')
29anuga_folder = os.path.join(home, state, scenario_folder, 'anuga')
30boundaries_folder = os.path.join(anuga_folder, 'boundaries')
31event_folder = os.path.join(boundaries_folder, event)
32
33# input_dir = os.path.join(GEMS_folder, event)
34
35#-----------------------
36# Input files from GEMS
37#-----------------------
38elevation_file_name = os.path.join(event_folder, ***'topog_flip.asc'***) # Name of the vertically flipped elevation grid
39grid_file_names = glob.glob(os.path.join(event_folder, '*.gz'))
40grid_file_names.sort()
41number_of_timesteps = len(grid_file_names)
42grid_size = 20 #0.0005 # cellsize from the GEMSURGE output grids
43start_time = 0  # all times in seconds
44end_time = 142560 #88200 # all times in seconds
45timestep = 720 #1800 # all times in seconds
46refzone = 50 # UTM zone
47x_origin = ***#115.550 #364221.03   # xllcorner from GEMSURGE output grids
48y_origin = ***#-32.790 #6371062.71  # yllcorner from GEMSURGE output grids
49event_sts = os.path.join(event_folder, event)
50
51assert number_of_timesteps * timestep == end_time - start_time
52
53elevation = []
54stage = []
55speed = []
56theta = []
57
58elevation_file = open(elevation_file_name, 'rb')
59lines = elevation_file.readlines()
60elevation_file.close()
61
62# Strip off the ASCII header and also read ncols, nrows,
63# x_origin, y_origin, grid_size, no_data value, and read in elevation grid:
64for i, L in enumerate(lines):
65    if i == 0:
66        ncols = int(L.strip().split()[1])
67    if i == 1:
68        nrows = int(L.strip().split()[1])
69    # if i == 2:
70        # x_origin = int(float(L.strip().split()[1])) # this assumes an integer xllcorner
71    # if i == 3:
72        # y_origin = int(float(L.strip().split()[1])) # this assumes an integer yllcorner
73    # if i == 4:
74        # grid_size = int(float(L.strip().split()[1]))
75    # if i == 5:
76        # no_data = int(float(L.strip().split()[1]))
77    if i > 5:
78        elevation+= L.strip().split()
79
80print 'Number or columns: ', ncols
81print 'Number of rows: ', nrows
82print 'Grid size: ', grid_size
83print 'X origin: ', x_origin
84print 'Y origin: ', y_origin
85 
86for f in grid_file_names:
87    print 'file: ', f
88   
89    gz_file = gzip.open(f, 'rb')
90    lines = gz_file.readlines()
91    gz_file.close()
92
93    for i, L in enumerate(lines):
94       
95        if i > 7 and i < (8 + nrows):        # Number 7 refers to the number of rows of header info that we skip - CHECK format
96            stage += [L.strip().split()]
97           
98        if i > (9 + nrows) and i < (10 + 2*nrows):
99            speed += [L.strip().split()]
100           
101        if i > (11 + 2*nrows):
102            theta += [L.strip().split()]
103
104#------------------------------------------------------
105# Create arrays of elevation, stage, speed and theta
106#-------------------------------------------------------
107print 'creating numpy arrays: elevation, stage, speed, theta'
108           
109elevation = numpy.array(elevation).astype('d')
110
111stage_array = numpy.empty([number_of_timesteps*nrows, ncols], dtype=float)
112speed_array = numpy.empty([number_of_timesteps*nrows, ncols], dtype=float)
113theta_array = numpy.empty([number_of_timesteps*nrows, ncols], dtype=float)
114
115for i in range(number_of_timesteps):
116    ii = nrows*i
117    stage_array[ii:ii+nrows, :] = numpy.flipud(numpy.array(stage[ii : ii + nrows]).astype('d'))
118    speed_array[ii:ii+nrows, :] = numpy.flipud(numpy.array(speed[ii:ii + nrows]).astype('d'))
119    theta_array[ii:ii+nrows, :] = numpy.flipud(numpy.array(theta[ii:ii + nrows]).astype('d'))
120
121stage = stage_array.ravel()
122speed = speed_array.ravel()
123theta = theta_array.ravel()
124   
125print 'Size of elevation array: ', elevation.size
126print 'Size of stage array: ', stage.size
127print 'Size of speed array: ', speed.size
128print 'Size of theta array: ', theta.size
129
130assert stage.size == speed.size == theta.size == ncols * nrows * number_of_timesteps
131assert stage.size == number_of_timesteps * elevation.size
132
133depth = numpy.empty(stage.size, dtype='d')
134number_of_points = ncols * nrows
135
136for i in xrange(number_of_timesteps):
137    j = number_of_points * i
138    k = j + number_of_points
139    depth[j:k] = stage[j:k] - elevation # Check GEMS elevations below sea level are negative
140
141momentum = depth * speed
142
143xmomentum = numpy.empty(momentum.size, dtype='d')
144ymomentum = numpy.empty(momentum.size, dtype='d')
145
146print 'Calculating xmomentum and ymomentum'
147
148for i, t in enumerate(theta):
149
150    if t > 0.0 and t < 90.0:
151        mx = momentum[i]*math.sin(math.radians(t)) #Assuming t is in the "to" direction and 0 degrees is north
152        my = momentum[i]*math.cos(math.radians(t))
153        assert mx > 0 and my > 0
154    if t > 90.0 and t < 180.0:
155        mx = momentum[i]*math.sin(math.radians(180 - t))
156        my = momentum[i]*math.cos(math.radians(180 - t))
157        assert mx > 0 and my < 0
158    if t > 180.0 and t < 270.0:
159        mx = momentum[i]*math.cos(math.radians(270 - t))
160        my = momentum[i]*math.sin(math.radians(270 - t))
161        assert mx < 0 and my < 0
162    if t > 270.0 and t < 360.0:
163        mx = momentum[i]*math.sin(math.radians(360 - t))
164        my = momentum[i]*math.cos(math.radians(360 - t))
165        assert mx < 0 and my > 0
166    if t == 0.0 or t == 360.0:
167        mx = 0
168        my = momentum[i]
169        assert my > 0
170    if t == 90.0:
171        mx = momentum[i]
172        my = 0
173        assert mx > 0
174    if t == 180.0:
175        mx = 0
176        my = momentum[i]
177        assert my < 0
178    if t == 270.0:
179        mx = momentum[i]
180        my = 0
181        assert mx < 0
182       
183    xmomentum[i] = mx
184    ymomentum[i] = my
185
186    assert mx[i]^2 + my[i]^2 == momentum[i]
187   
188x_origin_int = int(10000*x_origin)
189y_origin_int = int(10000*y_origin)
190grid_size_int = int(10000*grid_size)
191
192x = numpy.tile(numpy.arange(x_origin_int, (x_origin_int + ncols * grid_size_int), grid_size_int)/10000.0, nrows)
193y = numpy.repeat(numpy.arange(y_origin_int, (y_origin_int + nrows * grid_size_int), grid_size_int)/10000.0, ncols)
194
195assert x.size == y.size == number_of_points
196
197time = numpy.arange(start_time, end_time, timestep, dtype='i')
198
199assert time.size == number_of_timesteps
200assert momentum.size == stage.size
201
202#-----------------------------
203# Create the STS file
204#-----------------------------
205print "Creating the STS NetCDF file"
206
207fid = NetCDFFile(os.path.join(event_folder, event + '_master.sts'), 'w')
208fid.institution = 'Geoscience Australia'
209fid.description = "description"
210fid.starttime = 0.0
211fid.ncols = ncols
212fid.nrows = nrows
213fid.grid_size = grid_size
214fid.no_data = no_data
215fid.createDimension('number_of_points', number_of_points)
216fid.createDimension('number_of_timesteps', number_of_timesteps)
217fid.createDimension('numbers_in_range', 2)
218
219fid.createVariable('x', 'd', ('number_of_points',))
220fid.createVariable('y', 'd', ('number_of_points',))
221fid.createVariable('elevation', 'd', ('number_of_points',))
222fid.createVariable('elevation_range', 'd', ('numbers_in_range',))
223fid.createVariable('time', 'i', ('number_of_timesteps',))
224fid.createVariable('stage', 'd', ('number_of_timesteps', 'number_of_points'))
225fid.createVariable('stage_range', 'd', ('numbers_in_range', ))
226fid.createVariable('xmomentum', 'd', ('number_of_timesteps', 'number_of_points'))
227fid.createVariable('xmomentum_range', 'd', ('numbers_in_range',))
228fid.createVariable('ymomentum', 'd', ('number_of_timesteps', 'number_of_points'))
229fid.createVariable('ymomentum_range', 'd', ('numbers_in_range',))
230
231fid.variables['elevation_range'][:] = numpy.array([1e+036, -1e+036])
232fid.variables['stage_range'][:] = numpy.array([1e+036, -1e+036])
233fid.variables['xmomentum_range'][:] = numpy.array([1e+036, -1e+036])
234fid.variables['ymomentum_range'][:] = numpy.array([1e+036, -1e+036])
235fid.variables['elevation'][:] = elevation
236fid.variables['time'][:] = time
237
238s = fid.variables['stage']
239xm = fid.variables['xmomentum']
240ym = fid.variables['ymomentum']
241
242for i in xrange(number_of_timesteps):
243    ii = i*number_of_points
244    s[i] = stage[ii : ii + number_of_points]
245    xm[i] = xmomentum[ii : ii + number_of_points]
246    ym[i] = ymomentum[ii : ii + number_of_points]
247       
248origin = Geo_reference(refzone, min(x), min(y)) # Check this section for inputs in eastings and northings - it works for long and lat
249geo_ref = write_NetCDF_georeference(origin, fid)
250
251fid.variables['x'][:] = x - geo_ref.get_xllcorner()
252fid.variables['y'][:] = y - geo_ref.get_yllcorner()
253
254fid.close()
Note: See TracBrowser for help on using the repository browser.