NCCOOS Trac Projects: Top | Web | Platforms | Processing | Viz | Sprints | Sandbox | (Wind)

root/raw2proc/trunk/raw2proc/proc_scintec_maindata_sfas.py

Revision 511 (checked in by cbc, 10 years ago)

Change to axis metadata for Scintec sodar.

Line 
1 """
2 Parse data and assert what data creates and updates monthly NetCDF files.
3
4 Scintec SFAS processed sodar wind profile data.
5 """
6
7 import math
8 import numpy as n
9 import pycdf
10 import datetime
11 import procutil
12 from sodar.scintec import maindata
13
14 nowDt = datetime.datetime.utcnow().replace(microsecond=0)
15 manual = ['z','speed','dir','error']
16
17 def parser(platform_info, sensor_info, lines):
18     """
19     Parse and assign wind profile data from main Sodar file.
20     """
21    
22     main_data = maindata.MainData(''.join(lines))
23    
24     num_profiles       = len(main_data)
25     min_altitude      = sensor_info['min_altitude']
26     altitude_interval = sensor_info['altitude_interval']
27     num_altitudes     = sensor_info['num_altitudes']
28     sensor_elevation  = sensor_info['sensor_elevation']
29    
30     altitudes = [(altitude_num * altitude_interval) + min_altitude
31                   for altitude_num in range(num_altitudes)]
32     elevations  = [altitude + sensor_elevation for altitude in altitudes]
33    
34     data = {
35         'dt'   : n.array(n.ones((num_profiles,), dtype=object) * n.nan),
36         'time' : n.array(n.ones((num_profiles,), dtype=long) * n.nan),
37         'z'    : n.array(elevations, dtype=float),
38         'u'    : n.array(n.ones((num_profiles,
39                                  num_altitudes), dtype=float) * n.nan),
40         'v'    : n.array(n.ones((num_profiles,
41                                  num_altitudes), dtype=float) * n.nan),
42            }
43    
44     gaps = {}
45     for variable in main_data.variables:
46         symbol = variable['symbol']
47         gaps[symbol] = variable['gap']   
48         if symbol not in manual:
49             data[symbol.lower()] = n.array(n.ones((num_profiles,
50                                                    num_altitudes),
51                                                   dtype=float) * n.nan)
52    
53     data['error'] = n.array(n.ones((num_profiles,
54                                     num_altitudes), dtype = int) * n.nan)
55     for (profile_index, profile) in enumerate(main_data):
56         dt = {'month' : profile.stop.month,
57               'day'   : profile.stop.day,
58               'year'  : profile.stop.year,
59               'hour'  : profile.stop.hour,
60               'min'   : profile.stop.minute,
61              }
62         dt = '%(month)02d-%(day)02d-%(year)04d %(hour)02d:%(min)02d' % dt
63         dt = procutil.scanf_datetime(dt, fmt='%m-%d-%Y %H:%M')
64         if sensor_info['utc_offset']:
65             dt = dt + datetime.timedelta(hours=sensor_info['utc_offset'])
66         data['dt'][profile_index] = dt
67        
68         data['time'][profile_index] = procutil.dt2es(dt)
69        
70         for (observation_index, observation) in enumerate(profile):
71             radial = observation['speed']
72             theta  = observation['dir']
73            
74             if radial != gaps['speed'] and theta != gaps['dir']:
75                 theta  = math.pi * float(theta) / 180.0
76                 radial = float(radial)
77                 data['u'][profile_index][observation_index] = \
78                     -radial * math.sin(theta)
79                 data['v'][profile_index][observation_index] = \
80                     -radial * math.cos(theta)
81            
82             for variable in profile.variables:
83                if variable not in manual and \
84                observation[variable] != gaps[variable]:
85                    data[variable.lower()][profile_index][observation_index] = \
86                        float(observation[variable])
87            
88             data['error'][profile_index][observation_index] = \
89                 int(observation['error'])
90    
91     return data
92
93 def creator(platform_info, sensor_info, data):
94     #
95     #
96     title_str = sensor_info['description']+' at '+ platform_info['location']
97     global_atts = {
98         'title' : title_str,
99         'institution' : 'Unversity of North Carolina at Chapel Hill (UNC-CH)',
100         'institution_url' : 'http://nccoos.unc.edu',
101         'institution_dods_url' : 'http://nccoos.unc.edu',
102         'metadata_url' : 'http://nccoos.unc.edu',
103         'references' : 'http://nccoos.unc.edu',
104         'contact' : 'cbc (cbc@unc.edu)',
105         #
106         'source' : 'fixed-profiler (acoustic doppler) observation',
107         'history' : 'raw2proc using ' + sensor_info['process_module'],
108         'comment' : 'File created using pycdf'+pycdf.pycdfVersion()+' and numpy '+pycdf.pycdfArrayPkg(),
109         # conventions
110         'Conventions' : 'CF-1.0; SEACOOS-CDL-v2.0',
111         # SEACOOS CDL codes
112         'format_category_code' : 'fixed-profiler',
113         'institution_code' : platform_info['institution'],
114         'platform_code' : platform_info['id'],
115         'package_code' : sensor_info['id'],
116         # institution specific
117         'project' : 'North Carolina Coastal Ocean Observing System (NCCOOS)',
118         'project_url' : 'http://nccoos.unc.edu',
119         # timeframe of data contained in file yyyy-mm-dd HH:MM:SS
120         # first date in monthly file
121         'start_date' : data['dt'][0].strftime("%Y-%m-%d %H:%M:%S"),
122         # last date in monthly file
123         'end_date' : data['dt'][-1].strftime("%Y-%m-%d %H:%M:%S"),
124         'release_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
125         #
126         'creation_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
127         'modification_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
128         'process_level' : 'level1',
129         #
130         # must type match to data (e.g. fillvalue is real if data is real)
131         '_FillValue' : -99999.,
132         }
133    
134     var_atts = {
135         # coordinate variables
136         'time' : {'short_name': 'time',
137                   'long_name': 'Time',
138                   'standard_name': 'time',
139                   'units': 'seconds since 1970-1-1 00:00:00 -0', # UTC
140                   'axis': 'T',
141                  },
142         'lat' : {'short_name': 'lat',
143                  'long_name': 'Latitude',
144                  'standard_name': 'latitude',
145                  'reference':'geographic coordinates',
146                  'units': 'degrees_north',
147                  'valid_range':(-90.,90.),
148                  'axis': 'Y',
149                 },
150         'lon' : {'short_name': 'lon',
151                  'long_name': 'Longtitude',
152                  'standard_name': 'longtitude',
153                  'reference':'geographic coordinates',
154                  'units': 'degrees_east',
155                  'valid_range':(-180.,180.),
156                  'axis': 'X',
157                 },
158         'z' : {'short_name': 'z',
159                'long_name': 'Height',
160                'standard_name': 'height',
161                'reference':'zero at sea-surface',
162                'positive' : 'up',
163                'units': 'm',
164                'axis': 'Z',
165               },
166         # data variables
167         'u': {'short_name' : 'u',
168               'long_name': 'East/West Component of Wind',
169               'standard_name': 'eastward_wind',
170               'positive': 'to the east',
171               'units': 'm s-1',
172              },
173         'v': {'short_name' : 'v',
174               'long_name': 'North/South Component of Wind',
175               'standard_name': 'northward_wind',
176               'positive': 'to the north',         
177               'units': 'm s-1',
178              },
179         'w': {'short_name' : 'w',
180               'long_name': 'Vertical Component of Wind',
181               'standard_name': 'upward_wind',
182               'positive': 'from the surface',                         
183               'units': 'm s-1',
184              },
185         'sigw': {'short_name' : 'sigw',
186                  'long_name': 'Standard Deviation of Vertical Component',
187                  'standard_name': 'sigma_upward_wind',
188                 },
189         'bck' : {'short_name': 'bck',
190                  'long_name': 'Backscatter',
191                  'standard_name': 'backscatter'
192                 },
193         'error' : {'short_name': 'error',
194                    'long_name': 'Error Code',
195                    'standard_name': 'error_code'
196                   },
197         }
198    
199     # dimension names use tuple so order of initialization is maintained
200     dim_inits = (
201         ('ntime', pycdf.NC.UNLIMITED),
202         ('nlat', 1),
203         ('nlon', 1),
204         ('nz', sensor_info['num_altitudes'])
205         )
206    
207     # using tuple of tuples so order of initialization is maintained
208     # using dict for attributes order of init not important
209     # use dimension names not values
210     # (varName, varType, (dimName1, [dimName2], ...))
211     var_inits = (
212         # coordinate variables
213         ('time',  pycdf.NC.INT,   ('ntime',)),
214         ('lat',   pycdf.NC.FLOAT, ('nlat',)),
215         ('lon',   pycdf.NC.FLOAT, ('nlon',)),
216         ('z',     pycdf.NC.FLOAT, ('nz',)),
217         # data variables
218         ('u',     pycdf.NC.FLOAT, ('ntime', 'nz')),
219         ('v',     pycdf.NC.FLOAT, ('ntime', 'nz')),
220         ('w',     pycdf.NC.FLOAT, ('ntime', 'nz')),
221         ('sigw',  pycdf.NC.FLOAT, ('ntime', 'nz')),
222         ('bck',   pycdf.NC.FLOAT, ('ntime', 'nz')),
223         ('error', pycdf.NC.INT,   ('ntime', 'nz')),
224                 )
225    
226     # subset data only to month being processed (see raw2proc.process())
227     i = data['in']
228    
229     # var data
230     var_data = (
231         ('time',  data['time'][i]),
232         ('lat',   platform_info['lat']),
233         ('lon',   platform_info['lon']),
234         ('z',     data['z']),
235         ('u',     data['u'][i]),
236         ('v',     data['v'][i]),
237         ('w',     data['w'][i]),
238         ('sigw',  data['sigw'][i]),
239         ('bck',   data['bck'][i]),
240         ('error', data['error'][i]),
241         )
242    
243     return (global_atts, var_atts, dim_inits, var_inits, var_data)
244
245 def updater(platform_info, sensor_info, data):
246     #
247     global_atts = {
248         # update times of data contained in file (yyyy-mm-dd HH:MM:SS)
249         # last date in monthly file
250         'end_date' : data['dt'][-1].strftime("%Y-%m-%d %H:%M:%S"),
251         'release_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
252         #
253         'modification_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
254         }
255    
256     # data variables
257     # update any variable attributes like range, min, max
258     var_atts = {}
259    
260     # subset data only to month being processed (see raw2proc.process())
261     i = data['in']
262    
263     # data
264     var_data = (
265         ('time',  data['time'][i]),
266         ('u',     data['u'][i]),
267         ('v',     data['v'][i]),
268         ('w',     data['w'][i]),
269         ('sigw',  data['sigw'][i]),
270         ('bck',   data['bck'][i]),
271         ('error', data['error'][i]),
272         )
273    
274     return (global_atts, var_atts, var_data)
Note: See TracBrowser for help on using the browser.