|
2 | 2 |
|
3 | 3 | from netCDF4 import Dataset
|
4 | 4 | import numpy as np
|
| 5 | +import logging |
5 | 6 |
|
6 | 7 |
|
7 | 8 | class GlobalTracking(object):
|
8 | 9 | """
|
9 | 10 |
|
10 | 11 | """
|
| 12 | + |
| 13 | + VAR_DESCR = dict( |
| 14 | + time=dict( |
| 15 | + attr_name='new_time_tmp', |
| 16 | + nc_name='j1', |
| 17 | + nc_type='int32', |
| 18 | + nc_dims=('Nobs',), |
| 19 | + nc_attr=dict( |
| 20 | + long_name='Julian date', |
| 21 | + units='days', |
| 22 | + description='date of this observation', |
| 23 | + reference=2448623, |
| 24 | + reference_description="Julian date on Jan 1, 1992", |
| 25 | + ) |
| 26 | + ), |
| 27 | + type_cyc=dict( |
| 28 | + attr_name=None, |
| 29 | + nc_name='cyc', |
| 30 | + nc_type='byte', |
| 31 | + nc_dims=('Nobs',), |
| 32 | + nc_attr=dict( |
| 33 | + long_name='cyclonic', |
| 34 | + units='boolean', |
| 35 | + description='cyclonic -1; anti-cyclonic +1', |
| 36 | + ) |
| 37 | + ), |
| 38 | + lon=dict( |
| 39 | + attr_name='new_lon_tmp', |
| 40 | + nc_name='lon', |
| 41 | + nc_type='float32', |
| 42 | + nc_dims=('Nobs',), |
| 43 | + nc_attr=dict( |
| 44 | + units='deg. longitude', |
| 45 | + ) |
| 46 | + ), |
| 47 | + lat=dict( |
| 48 | + attr_name='new_lat_tmp', |
| 49 | + nc_name='lat', |
| 50 | + nc_type='float32', |
| 51 | + nc_dims=('Nobs',), |
| 52 | + nc_attr=dict( |
| 53 | + units='deg. latitude', |
| 54 | + ) |
| 55 | + ), |
| 56 | + amplitude=dict( |
| 57 | + attr_name='new_amp_tmp', |
| 58 | + nc_name='A', |
| 59 | + nc_type='float32', |
| 60 | + nc_dims=('Nobs',), |
| 61 | + nc_attr=dict( |
| 62 | + long_name='amplitude', |
| 63 | + units='cm', |
| 64 | + description='magnitude of the height difference between the ' |
| 65 | + 'extremum of SSH within the eddy and the SSH ' |
| 66 | + 'around the contour defining the eddy perimeter', |
| 67 | + ) |
| 68 | + ), |
| 69 | + rayon=dict( |
| 70 | + attr_name=None, |
| 71 | + nc_name='L', |
| 72 | + nc_type='float32', |
| 73 | + nc_dims=('Nobs',), |
| 74 | + nc_attr=dict( |
| 75 | + long_name='speed radius scale', |
| 76 | + units='km', |
| 77 | + description='radius of a circle whose area is equal to that ' |
| 78 | + 'enclosed by the contour of maximum circum-average' |
| 79 | + ' speed', |
| 80 | + ) |
| 81 | + ), |
| 82 | + speed_radius=dict( |
| 83 | + attr_name='new_uavg_tmp', |
| 84 | + nc_name='U', |
| 85 | + nc_type='float32', |
| 86 | + nc_dims=('Nobs',), |
| 87 | + nc_attr=dict( |
| 88 | + long_name='maximum circum-averaged speed', |
| 89 | + units='cm/sec', |
| 90 | + description='average speed of the contour defining the radius ' |
| 91 | + 'scale L', |
| 92 | + ) |
| 93 | + ), |
| 94 | + eke=dict( |
| 95 | + attr_name='new_teke_tmp', |
| 96 | + nc_name='Teke', |
| 97 | + nc_type='float32', |
| 98 | + nc_dims=('Nobs',), |
| 99 | + nc_attr=dict( |
| 100 | + long_name='sum EKE within contour Ceff', |
| 101 | + units='m^2/sec^2', |
| 102 | + description='sum of eddy kinetic energy within contour ' |
| 103 | + 'defining the effective radius', |
| 104 | + ) |
| 105 | + ), |
| 106 | + radius_e=dict( |
| 107 | + attr_name='new_radii_e_tmp', |
| 108 | + nc_name='radius_e', |
| 109 | + nc_type='float32', |
| 110 | + nc_dims=('Nobs',), |
| 111 | + nc_attr=dict( |
| 112 | + long_name='effective radius scale', |
| 113 | + units='km', |
| 114 | + description='effective eddy radius', |
| 115 | + ) |
| 116 | + ), |
| 117 | + ) |
| 118 | + |
11 | 119 | def __init__(self, eddy, ymd_str):
|
12 | 120 | """
|
13 | 121 | """
|
14 |
| - self.tracklist = eddy.tracklist |
15 |
| - self.sign_type = eddy.SIGN_TYPE |
16 | 122 | self.ymd_str = ymd_str
|
17 |
| - self.num_tracks = np.sum([i.alive for i in self.tracklist]) |
| 123 | + self.eddy = eddy |
| 124 | + |
| 125 | + @property |
| 126 | + def sign_type(self): |
| 127 | + return self.eddy.SIGN_TYPE |
18 | 128 |
|
19 | 129 | def create_netcdf(self):
|
20 | 130 | """
|
21 | 131 | """
|
22 |
| - with Dataset('%s_%s.nc' % (self.sign_type, self.ymd_str), |
23 |
| - 'w', format='NETCDF4') as nc: |
| 132 | + eddy_size = None |
| 133 | + for key in self.VAR_DESCR: |
| 134 | + attr_name = self.VAR_DESCR[key]['attr_name'] |
| 135 | + if attr_name is not None and hasattr(self.eddy, attr_name): |
| 136 | + eddy_size = len(getattr(self.eddy, attr_name)) |
| 137 | + break |
24 | 138 |
|
| 139 | + filename = '%s_%s.nc' % (self.sign_type, self.ymd_str) |
| 140 | + with Dataset(filename, 'w', format='NETCDF4') as h_nc: |
| 141 | + logging.info('Create intermediary file %s', filename) |
25 | 142 | # Create dimensions
|
26 |
| - nc.createDimension('tracks', self.num_tracks) |
27 |
| - nc.createDimension('properties', None) |
28 |
| - # Create variables |
29 |
| - t = 0 |
30 |
| - for track in self.tracklist: |
31 |
| -# if track.alive: |
32 |
| - varname = 'track_%s' % np.str(t).zfill(4) |
33 |
| - nc.createVariable(varname, np.float64, ('properties')) |
34 |
| - t += 1 |
35 |
| - nc.createVariable('track_lengths', np.int, ('tracks')) |
| 143 | + logging.debug('Create Dimensions "Nobs"') |
| 144 | + h_nc.createDimension('Nobs', eddy_size) |
| 145 | + # Iter on variables to create: |
| 146 | + for key, value in self.VAR_DESCR.iteritems(): |
| 147 | + attr_name = value['attr_name'] |
| 148 | + if attr_name is None or not hasattr(self.eddy, attr_name): |
| 149 | + continue |
| 150 | + logging.debug('Create Variable %s', |
| 151 | + value['nc_name']) |
| 152 | + var = h_nc.createVariable( |
| 153 | + varname=value['nc_name'], |
| 154 | + datatype=value['nc_type'], |
| 155 | + dimensions=value['nc_dims'], |
| 156 | + zlib=True, |
| 157 | + complevel=1, |
| 158 | + ) |
| 159 | + for attr, attr_value in value['nc_attr'].iteritems(): |
| 160 | + var.setncattr(attr, attr_value) |
| 161 | + |
| 162 | + var[:] = getattr(self.eddy, attr_name) |
36 | 163 |
|
37 | 164 | def write_tracks(self):
|
38 | 165 | """
|
39 | 166 | """
|
40 |
| - t = 0 |
41 |
| - for track in self.tracklist: |
42 |
| - tracklen = len(track.lon) |
43 |
| - if track.alive: |
44 |
| - properties = np.hstack(( |
45 |
| - track.dayzero, track.saved2nc, |
46 |
| - track.save_extras, track.lon, track.lat, |
47 |
| - track.amplitude, track.radius_s, |
48 |
| - track.radius_e, track.uavg, |
49 |
| - track.teke, track.ocean_time)) |
50 |
| - |
51 |
| - with Dataset('%s_%s.nc' % (self.sign_type, self.ymd_str), 'a') as nc: |
52 |
| - varname = 'track_%s' % np.str(t).zfill(4) |
53 |
| - nc.variables[varname][:] = properties |
54 |
| - nc.variables['track_lengths'][t] = tracklen |
55 |
| - t += 1 |
| 167 | +# t = 0 |
| 168 | +# print self.old_lon |
| 169 | +# for track in self.tracklist: |
| 170 | +# tracklen = len(track.lon) |
| 171 | +# if track.alive: |
| 172 | +# properties = np.hstack(( |
| 173 | +# track.dayzero, track.saved2nc, |
| 174 | +# track.save_extras, track.lon, track.lat, |
| 175 | +# track.amplitude, track.radius_s, |
| 176 | +# track.radius_e, track.uavg, |
| 177 | +# track.teke, track.ocean_time)) |
| 178 | +# |
| 179 | +# with Dataset('%s_%s.nc' % (self.sign_type, |
| 180 | +# self.ymd_str), 'a') as nc: |
| 181 | +# varname = 'track_%s' % np.str(t).zfill(4) |
| 182 | +# nc.variables[varname][:] = properties |
| 183 | +# nc.variables['track_lengths'][t] = tracklen |
| 184 | +# t += 1 |
56 | 185 |
|
57 | 186 | def read_tracks(self):
|
58 | 187 | """
|
59 | 188 | Read and sort the property data for returning to the
|
60 | 189 | Eddy object
|
61 | 190 | """
|
62 | 191 | with Dataset('Anticyclonic_20140312.nc') as nc:
|
63 |
| - tracklens = nc.variables['track_lengths'][:] |
| 192 | + tracklengths = nc.variables['track_lengths'][:] |
64 | 193 | for t, tracklen in enumerate(tracklengths):
|
65 | 194 |
|
66 | 195 | varname = 'track_%s' % np.str(t).zfill(4)
|
|
0 commit comments