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

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

Revision 189 (checked in by cbc, 16 years ago)

Saving work.

Line 
1 #!/usr/bin/env python
2 """
3 Parse sodar data and assert what data and info goes into
4 creating and updating monthly netcdf files.
5
6 >> (parse, create, update) = load_processors('proc_rdi_rawdata_sodar')
7 >> data = parse(lines)
8 >> create(platform_info, sensor_info, data)
9 >> update(platform_info, sensor_info, data)
10 """
11
12 from sodar import rawData
13 import math
14 import numpy as n
15 from datetime import timedelta
16 from procutil import scanf_datetime, dt2es
17
18 INVALID       = '-9999'
19 BLOCKNUMBER   = 'BL#'
20 MONTH         = 'MONTH'
21 DAY           = 'DAY'
22 YEAR          = 'YEAR'
23 HOUR          = 'HOUR'
24 MINUTE        = 'MIN'
25 VALIDATIONS1  = 'VAL1'
26 VALIDATIONS2  = 'VAL2'
27 VALIDATIONS3  = 'VAL3'
28 VALIDATIONS4  = 'VAL4'
29 PROBABILITY1  = 'SPU1'
30 PROBABILITY2  = 'SPU2'
31 PROBABILITY3  = 'SPU3'
32 PROBABILITY4  = 'SPU4'
33 AMBIENTNOISE1 = 'NOIS1'
34 AMBIENTNOISE2 = 'NOIS2'
35 AMBIENTNOISE3 = 'NOIS3'
36 AMBIENTNOISE4 = 'NOIS4'
37 CLUTTER       = 'FEMAX'
38 SOFTWARE      = 'SOFTW'
39 FREQUENCIES11 = 'FE11'
40 FREQUENCIES12 = 'FE12'
41 FREQUENCIES21 = 'FE21'
42 FREQUENCIES22 = 'FE22'
43 SIGNALNOISE1  = 'SNR1'
44 SIGNALNOISE2  = 'SNR2'
45 SIGNALNOISE3  = 'SNR3'
46 SIGNALNOISE4  = 'SNR4'
47 REFERENCE     = 'CHECK'
48 JAM           = 'JAM'
49 ALTITUDE      = 'ALT'
50 ECHO          = 'CT'
51 RADIAL        = 'SPEED'
52 THETA         = 'DIR'
53 VERTICAL      = 'W'
54
55 def parser(platform_info, sensor_info, lines):
56     """
57     Parse and assign wind profile data from raw Sodar file.
58     """
59    
60     rawDataObject = rawdata.RawData('\n'.join(lines))
61    
62     numSamples       = len(rawDataObject)
63     minAltitude      = sensor_info[min_altitude]
64     altitudeInterval = sensor_info[altitude_interval]
65     numAltitudes     = sensor_info[num_altitudes]
66     sensorElevation  = sensor_info[sensor_elevation]
67    
68     altitudes = [(altitudeNum * altitudeInterval) + minAltitude
69                   for altitudeNum in range(numAltitudes)]
70     elevations  = [altitude + sensorElevation for altitude in altitudes]
71     altitudes = [str(altitude) for altitude in altitudes]
72    
73     data = {
74         'block'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
75         'dt'      : n.array(n.ones((numSamples,), dtype=object) * n.nan),
76         'es'      : n.array(n.ones((numSamples,), dtype=long) * n.nan),
77         'val1'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
78         'val2'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
79         'val3'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
80         'val4'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
81         'spu1'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
82         'spu2'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
83         'spu3'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
84         'spu4'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
85         'nois1'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
86         'nois2'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
87         'nois3'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
88         'nois4'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
89         'femax'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
90         'softw'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
91         'fe11'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
92         'fe12'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
93         'fe21'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
94         'fe22'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
95         'snr1'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
96         'snr2'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
97         'snr3'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
98         'snr4'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
99         'check'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
100         'jam'     : n.array(n.ones((numSamples,), dtype=int) * n.nan),
101         'z'       : n.array(elevations, dtype=float),
102         'u'       : n.array(n.ones((numSamples,
103                                     numAltitudes), dtype=float) * n.nan),
104         'v'       : n.array(n.ones((numSamples,
105                                     numAltitudes), dtype=float) * n.nan),
106         'w'       : n.array(n.ones((numSamples,
107                                     numAltitudes), dtype=float) * n.nan),
108         'echo'    : n.array(n.ones((numSamples,
109                                     numAltitudes), dtype = int) * n.nan),
110         }
111    
112     for sample in rawDataObject:
113         sampleIndex = rawDataObject.index(sample)
114        
115         data['block'][sampleIndex] = int(sample[BLOCKNUM])
116                                
117         dt = {'month' : int(sample[MONTH]),
118               'day'   : int(sample[DAY]),
119               'year'  : int(sample[YEAR]),
120               'hour'  : int(sample[HOUR]),
121               'min'   : int(sample[MINUTE]),
122             }
123         dt = '%(month)02d-%(day)02d-%(year)04d %(hour)02d:%02d(min)' % dt
124         dt = scanf_datetime(dt, fmt='%m-%d-%Y %H:%M')
125         if sensor_info['utc_offset']:
126             dt = dt + timedelta(hours=sensor_info['utc_offset'])
127         data['dt'][sampleIndex] = dt
128        
129         data['es'][sampleIndex] = dt2es(dt)
130        
131         data['val1'][sampleIndex] = int(sample[VALIDATIONS1])
132         data['val2'][sampleIndex] = int(sample[VALIDATIONS2])
133         data['val3'][sampleIndex] = int(sample[VALIDATIONS3])
134         data['val4'][sampleIndex] = int(sample[VALIDATIONS4])
135        
136         data['spu1'][sampleIndex] = int(sample[PROBABILITY1])
137         data['spu2'][sampleIndex] = int(sample[PROBABILITY2])
138         data['spu3'][sampleIndex] = int(sample[PROBABILITY])
139         data['spu4'][sampleIndex] = int(sample[PROBABILITY4])
140        
141         data['nois1'][sampleIndex] = int(sample[AMBIENTNOISE1])
142         data['nois2'][sampleIndex] = int(sample[AMBIENTNOISE2])
143         data['nois3'][sampleIndex] = int(sample[AMBIENTNOISE3])
144         data['nois4'][sampleIndex] = int(sample[AMBIENTNOISE4])
145
146         data['femax'][sampleIndex] = int(sample[CLUTTER])
147         data['softw'][sampleIndex] = int(sample[SOFTWARE])
148        
149         data['fe11'][sampleIndex] = int(sample[FREQUENCIES11])
150         data['fe12'][sampleIndex] = int(sample[FREQUENCIES12])
151         data['fe21'][sampleIndex] = int(sample[FREQUENCIES21])
152         data['fe22'][sampleIndex] = int(sample[FREQUENCIES22])
153        
154         data['snr1'][sampleIndex] = int(sample[SIGNALNOISE1])
155         data['snr2'][sampleIndex] = int(sample[SIGNALNOISE2])
156         data['snr3'][sampleIndex] = int(sample[SIGNALNOISE3])
157         data['snr4'][sampleIndex] = int(sample[SIGNALNOISE4])
158
159         data['check'][sampleIndex] = int(sample[REFERENCE])
160         data['jam'][sampleIndex]   = int(sample[JAM])
161        
162         for altitude,alttitudeIndex in zip(altitudes, range(len(altitudes))):
163             echo   = sample[altitude][ECHO]
164             radial = sample[altitude][RADIAL]
165             theta  = sample[altitude][THETA]
166             vertical = sample[altitude][VERTICAL]
167            
168             if radial != INVALID and theta != INVALID:
169                 theta  = math.pi * float(theta) / 180.0
170                 radial = float(radial)
171                 data['u'][sampleIndex][altitideIndex] = radial * math.sin(theta)
172                 data['v'][sampleIndex][altitudeIndex] = radial * math.cos(theta)
173            
174             if echo != INVALID:
175                 data['echo'][sampleIndex][altitudeIndex] = echo
176                
177             if vertical != INVALID:
178                 data['w'][sampleIndex][altitudeIndex] = vertical
179    
180     return data
181
182 def creator(platform_info, sensor_info, data):
183     #
184     #
185     title_str = sensor_info['description']+' at '+ platform_info['location']
186     global_atts = {
187         'title' : title_str,
188         'institution' : 'Unversity of North Carolina at Chapel Hill (UNC-CH)',
189         'institution_url' : 'http://nccoos.unc.edu',
190         'institution_dods_url' : 'http://nccoos.unc.edu',
191         'metadata_url' : 'http://nccoos.unc.edu',
192         'references' : 'http://nccoos.unc.edu',
193         'contact' : 'Sara Haines (haines@email.unc.edu)',
194         #
195         'source' : 'fixed-profiler (acoustic doppler) observation',
196         'history' : 'Data processed by NCCOOS',
197         'comment' : 'File created using pycdf'+pycdfVersion()+' and numpy '+pycdfArrayPkg(),
198         # conventions
199         'Conventions' : 'CF-1.0; SEACOOS-CDL-v2.0',
200         # SEACOOS CDL codes
201         'format_category_code' : 'fixed-profiler',
202         'institution_code' : platform_info['instituion'],
203         'platform_code' : platform_info['id'],
204         'package_code' : sensor_info['id'],
205         # institution specific
206         'project' : 'North Carolina Coastal Ocean Observing System (NCCOOS)',
207         'project_url' : 'http://nccoos.unc.edu',
208         # timeframe of data contained in file yyyy-mm-dd HH:MM:SS
209         'start_date' : data['sample_dt'].strftime("%Y-%m-%d %H:%M:%S"),
210         'end_date' : data['sample_dt'].strftime("%Y-%m-%d %H:%M:%S"),
211         'release_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
212         #
213         'creation_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
214         'modification_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
215         'process_level' : 'level1',
216         #
217         # must type match to data (e.g. fillvalue is real if data is real)
218         '_FillValue' : -99999.,
219         }
220
221     var_atts = {
222         # coordinate variables
223         'time' : {'short_name': 'time',
224                   'long_name': 'Time',
225                   'standard_name': 'time',
226                   'units': 'seconds since 1970-1-1 00:00:00 -0', # UTC
227                   'axis': 'T',
228                   },
229         'lat' : {'short_name': 'lat',
230              'long_name': 'Latitude',
231              'standard_name': 'latitude',
232              'reference':'geographic coordinates',
233              'units': 'degrees_north',
234              'valid_range':(-90.,90.),
235              'axis': 'Y',
236              },
237         'lon' : {'short_name': 'lon',
238                  'long_name': 'Longtitude',
239                  'standard_name': 'longtitude',
240                  'reference':'geographic coordinates',
241                  'units': 'degrees_east',
242                  'valid_range':(-180.,180.),
243                  'axis': 'Y',
244                  },
245         'z' : {'short_name': 'z',
246                'long_name': 'Height',
247                'standard_name': 'height',
248                'reference':'zero at sea-surface',
249                'units': 'm',
250                'axis': 'Z',
251                },
252         # data variables
253         'u': {'long_name': 'East/West Component of Current',
254               'standard_name': 'eastward_current',
255               'units': 'm s-1',
256               'reference': 'clockwise from True East',
257               },
258         'v': {'long_name': 'North/South Component of Current',
259               'standard_name': 'northward_current',                         
260               'units': 'm s-1',
261               'reference': 'clockwise from True North',
262               },
263         'w': {'long_name': 'Upward/Downward Component of Current',
264               'standard_name': 'upward_current',                         
265               'units': 'm s-1',
266               'positive': 'up',
267               },
268         'back_scatter':{'long_name': 'Backscatter',
269                         'standard_name': 'back_scatter',                   
270                         'units': 'decibels',
271                         },
272         'wtemp': {'long_name': 'Water Temperature',
273                   'standard_name': 'water_temperature',
274                   'units': 'degrees Celsius',
275                   },
276         }
277
278
279     # integer values
280     ntime=NC.UNLIMITED
281     nlat=1
282     nlon=1
283     nz=sensor_info['nbins']
284    
285     # dimension names use tuple so order of initialization is maintained
286     dimensions = ('ntime', 'nlat', 'nlon', 'nz')
287    
288     # using tuple of tuples so order of initialization is maintained
289     # using dict for attributes order of init not important
290     # use dimension names not values
291     # (varName, varType, (dimName1, [dimName2], ...))
292     var_inits = (
293         # coordinate variables
294         ('time', NC.INT, ('ntime',)),
295         ('lat', NC.FLOAT, ('nlat',)),
296         ('lon', NC.FLOAT, ('nlon',)),
297         ('z',  NC.FLOAT, ('nz',)),
298         # data variables
299         ('u', NC.FLOAT, ('ntime', 'nz')),
300         ('v', NC.FLOAT, ('ntime', 'nz')),
301         ('w', NC.FLOAT, ('ntime', 'nz')),
302         ('back_scatter', NC.FLOAT, ('ntime', 'nz')),
303         ('wtemp', NC.FLOAT, ('ntime',)),
304         )
305    
306     # var data
307     var_data = (
308         ('lat',  platform_info['lat']),
309         ('lon', platform_info['lon']),
310         ('z', []),
311         ('u', []),
312         ('v', []),
313         ('w', []),
314         ('back_scatter', []),
315         ('wtemp', []),
316         )
317
318     return (global_atts, dimensions, var_inits, var_data)
319
320 def updater(platform_info, sensor_info, data):
321     #
322     global_atts = {
323         # timeframe of data contained in file yyyy-mm-dd HH:MM:SS
324         'end_date' : data['sample_dt'].strftime("%Y-%m-%d %H:%M:%S"),
325         'release_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
326         #
327         'creation_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
328         'modification_date' : now.strftime("%Y-%m-%d %H:%M:%S"),
329         }
330     # var data
331     var_data = (
332         ('u', data['u']),
333         ('v', data['v']),
334         ('w',  data['w']),
335         ('back_scatter', data['back_scatter']),
336         ('wtemp', data['wtemp']),
337         )
338     return (global_atts, var_data)
339 #
340
Note: See TracBrowser for help on using the browser.