1 | |
---|
2 | ## |
---|
3 | # @brief Convert 3 URS files back to 4 NC files. |
---|
4 | # @param basename_in Stem of the input filenames. |
---|
5 | # @param basename_outStem of the output filenames. |
---|
6 | # @note The name of the urs file names must be: |
---|
7 | # [basename_in]-z-mux |
---|
8 | # [basename_in]-e-mux |
---|
9 | # [basename_in]-n-mux |
---|
10 | def urs2nc(basename_in='o', basename_out='urs'): |
---|
11 | """Convert the 3 urs files to 4 nc files. |
---|
12 | |
---|
13 | The name of the urs file names must be; |
---|
14 | [basename_in]-z-mux |
---|
15 | [basename_in]-e-mux |
---|
16 | [basename_in]-n-mux |
---|
17 | """ |
---|
18 | |
---|
19 | files_in = [basename_in + WAVEHEIGHT_MUX_LABEL, |
---|
20 | basename_in + EAST_VELOCITY_LABEL, |
---|
21 | basename_in + NORTH_VELOCITY_LABEL] |
---|
22 | files_out = [basename_out + '_ha.nc', |
---|
23 | basename_out + '_ua.nc', |
---|
24 | basename_out + '_va.nc'] |
---|
25 | quantities = ['HA', 'UA', 'VA'] |
---|
26 | |
---|
27 | #if os.access(files_in[0]+'.mux', os.F_OK) == 0 : |
---|
28 | for i, file_name in enumerate(files_in): |
---|
29 | if os.access(file_name, os.F_OK) == 0: |
---|
30 | if os.access(file_name + '.mux', os.F_OK) == 0 : |
---|
31 | msg = 'File %s does not exist or is not accessible' % file_name |
---|
32 | raise IOError, msg |
---|
33 | else: |
---|
34 | files_in[i] += '.mux' |
---|
35 | log.critical("file_name %s" % file_name) |
---|
36 | |
---|
37 | hashed_elevation = None |
---|
38 | for file_in, file_out, quantity in map(None, files_in, |
---|
39 | files_out, |
---|
40 | quantities): |
---|
41 | lonlatdep, lon, lat, depth = _binary_c2nc(file_in, |
---|
42 | file_out, |
---|
43 | quantity) |
---|
44 | if hashed_elevation == None: |
---|
45 | elevation_file = basename_out + '_e.nc' |
---|
46 | write_elevation_nc(elevation_file, |
---|
47 | lon, |
---|
48 | lat, |
---|
49 | depth) |
---|
50 | hashed_elevation = myhash(lonlatdep) |
---|
51 | else: |
---|
52 | msg = "The elevation information in the mux files is inconsistent" |
---|
53 | assert hashed_elevation == myhash(lonlatdep), msg |
---|
54 | |
---|
55 | files_out.append(elevation_file) |
---|
56 | |
---|
57 | return files_out |
---|
58 | |
---|
59 | |
---|
60 | ## |
---|
61 | # @brief Convert a quantity URS file to a NetCDF file. |
---|
62 | # @param file_in Path to input URS file. |
---|
63 | # @param file_out Path to the output file. |
---|
64 | # @param quantity Name of the quantity to be written to the output file. |
---|
65 | # @return A tuple (lonlatdep, lon, lat, depth). |
---|
66 | def _binary_c2nc(file_in, file_out, quantity): |
---|
67 | """Reads in a quantity urs file and writes a quantity nc file. |
---|
68 | Additionally, returns the depth and lat, long info, |
---|
69 | so it can be written to a file. |
---|
70 | """ |
---|
71 | |
---|
72 | columns = 3 # long, lat , depth |
---|
73 | mux_file = open(file_in, 'rb') |
---|
74 | |
---|
75 | # Number of points/stations |
---|
76 | (points_num,) = unpack('i', mux_file.read(4)) |
---|
77 | |
---|
78 | # nt, int - Number of time steps |
---|
79 | (time_step_count,) = unpack('i', mux_file.read(4)) |
---|
80 | |
---|
81 | #dt, float - time step, seconds |
---|
82 | (time_step,) = unpack('f', mux_file.read(4)) |
---|
83 | |
---|
84 | msg = "Bad data in the mux file." |
---|
85 | if points_num < 0: |
---|
86 | mux_file.close() |
---|
87 | raise ANUGAError, msg |
---|
88 | if time_step_count < 0: |
---|
89 | mux_file.close() |
---|
90 | raise ANUGAError, msg |
---|
91 | if time_step < 0: |
---|
92 | mux_file.close() |
---|
93 | raise ANUGAError, msg |
---|
94 | |
---|
95 | lonlatdep = p_array.array('f') |
---|
96 | lonlatdep.read(mux_file, columns * points_num) |
---|
97 | lonlatdep = num.array(lonlatdep, dtype=num.float) |
---|
98 | lonlatdep = num.reshape(lonlatdep, (points_num, columns)) |
---|
99 | |
---|
100 | lon, lat, depth = lon_lat2grid(lonlatdep) |
---|
101 | lon_sorted = list(lon) |
---|
102 | lon_sorted.sort() |
---|
103 | |
---|
104 | if not num.alltrue(lon == lon_sorted): |
---|
105 | msg = "Longitudes in mux file are not in ascending order" |
---|
106 | raise IOError, msg |
---|
107 | |
---|
108 | lat_sorted = list(lat) |
---|
109 | lat_sorted.sort() |
---|
110 | |
---|
111 | nc_file = Write_nc(quantity, |
---|
112 | file_out, |
---|
113 | time_step_count, |
---|
114 | time_step, |
---|
115 | lon, |
---|
116 | lat) |
---|
117 | |
---|
118 | for i in range(time_step_count): |
---|
119 | #Read in a time slice from mux file |
---|
120 | hz_p_array = p_array.array('f') |
---|
121 | hz_p_array.read(mux_file, points_num) |
---|
122 | hz_p = num.array(hz_p_array, dtype=num.float) |
---|
123 | hz_p = num.reshape(hz_p, (len(lon), len(lat))) |
---|
124 | hz_p = num.transpose(hz_p) # mux has lat varying fastest, nc has long v.f. |
---|
125 | |
---|
126 | #write time slice to nc file |
---|
127 | nc_file.store_timestep(hz_p) |
---|
128 | |
---|
129 | mux_file.close() |
---|
130 | nc_file.close() |
---|
131 | |
---|
132 | return lonlatdep, lon, lat, depth |
---|
133 | |
---|
134 | |
---|