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

root/sodar/branches/raw2proc-dev/proc_scintec_maindata_sfas.py

Revision 299 (checked in by cbc, 14 years ago)

Add billymitchell config and scintec processor.

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