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

root/raw2proc/tags/raw2proc-1.0/proc_scintec_maindata_sfas.py

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

Added Scintec sodar processing and Billy Mitchell config.

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': 'Y',
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               'units': 'm s-1',
171              },
172         'v': {'short_name' : 'v',
173               'long_name': 'North/South Component of Wind',
174               'standard_name': 'northward_wind',                         
175               'units': 'm s-1',
176              },
177         'w': {'short_name' : 'w',
178               'long_name': 'Vertical Component of Wind',
179               'standard_name': 'upward_wind',                         
180               'units': 'm s-1',
181              },
182         'sigw': {'short_name' : 'sigw',
183                  'long_name': 'Standard Deviation of Vertical Component',
184                  'standard_name': 'sigma_upward_wind',
185                 },
186         'bck' : {'short_name': 'bck',
187                  'long_name': 'Backscatter',
188                  'standard_name': 'backscatter'
189                 },
190         'error' : {'short_name': 'error',
191                    'long_name': 'Error Code',
192                    'standard_name': 'error_code'
193                   },
194         }
195    
196     # dimension names use tuple so order of initialization is maintained
197     dim_inits = (
198         ('ntime', pycdf.NC.UNLIMITED),
199         ('nlat', 1),
200         ('nlon', 1),
201         ('nz', sensor_info['num_altitudes'])
202         )
203    
204     # using tuple of tuples so order of initialization is maintained
205     # using dict for attributes order of init not important
206     # use dimension names not values
207     # (varName, varType, (dimName1, [dimName2], ...))
208     var_inits = (
209         # coordinate variables
210         ('time',  pycdf.NC.INT,   ('ntime',)),
211         ('lat',   pycdf.NC.FLOAT, ('nlat',)),
212         ('lon',   pycdf.NC.FLOAT, ('nlon',)),
213         ('z',     pycdf.NC.FLOAT, ('nz',)),
214         # data variables
215         ('u',     pycdf.NC.FLOAT, ('ntime', 'nz')),
216         ('v',     pycdf.NC.FLOAT, ('ntime', 'nz')),
217         ('w',     pycdf.NC.FLOAT, ('ntime', 'nz')),
218         ('sigw',  pycdf.NC.FLOAT, ('ntime', 'nz')),
219         ('bck',   pycdf.NC.FLOAT, ('ntime', 'nz')),
220         ('error', pycdf.NC.INT,   ('ntime', 'nz')),
221                 )
222    
223     # subset data only to month being processed (see raw2proc.process())
224     i = data['in']
225    
226     # var data
227     var_data = (
228         ('time',  data['time'][i]),
229         ('lat',   platform_info['lat']),
230         ('lon',   platform_info['lon']),
231         ('z',     data['z']),
232         ('u',     data['u'][i]),
233         ('v',     data['v'][i]),
234         ('w',     data['w'][i]),
235         ('sigw',  data['sigw'][i]),
236         ('bck',   data['bck'][i]),
237         ('error', data['error'][i]),
238         )
239    
240     return (global_atts, var_atts, dim_inits, var_inits, var_data)
241
242 def updater(platform_info, sensor_info, data):
243     #
244     global_atts = {
245         # update times of data contained in file (yyyy-mm-dd HH:MM:SS)
246         # last date in monthly file
247         'end_date' : data['dt'][-1].strftime("%Y-%m-%d %H:%M:%S"),
248         'release_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
249         #
250         'modification_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
251         }
252    
253     # data variables
254     # update any variable attributes like range, min, max
255     var_atts = {}
256    
257     # subset data only to month being processed (see raw2proc.process())
258     i = data['in']
259    
260     # data
261     var_data = (
262         ('time',  data['time'][i]),
263         ('u',     data['u'][i]),
264         ('v',     data['v'][i]),
265         ('w',     data['w'][i]),
266         ('sigw',  data['sigw'][i]),
267         ('bck',   data['bck'][i]),
268         ('error', data['error'][i]),
269         )
270    
271     return (global_atts, var_atts, var_data)
Note: See TracBrowser for help on using the browser.