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

root/raw2proc/trunk/raw2proc/proc_remtech_rawdata_pa0.py

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

Add Remtech sodar processing and Duke Forest and IMS configurations.

Line 
1 #!/usr/bin/env python
2 """
3 Parse data and assert what data creates and updates monthly NetCDF files.
4
5 Remtech PA0 processed sodar wind profile data.
6 """
7
8 import math
9 import numpy as n
10 import pycdf
11 import datetime
12 import procutil
13 from sodar.remtech import rawData
14
15 INVALID       = '-9999'
16
17 nowDt = datetime.datetime.utcnow().replace(microsecond=0)
18
19 def parser(platform_info, sensor_info, lines):
20     """
21     Parse and assign wind profile data from raw Sodar file.
22     """
23    
24     rawDataObject = rawData.RawData(''.join(lines))
25    
26     numSamples       = len(rawDataObject)
27     minAltitude      = sensor_info['min_altitude']
28     altitudeInterval = sensor_info['altitude_interval']
29     numAltitudes     = sensor_info['num_altitudes']
30     sensorElevation  = sensor_info['sensor_elevation']
31    
32     altitudes = [(altitudeNum * altitudeInterval) + minAltitude
33                   for altitudeNum in range(numAltitudes)]
34     elevations  = [altitude + sensorElevation for altitude in altitudes]
35     altitudes = [str(altitude) for altitude in altitudes]
36    
37     data = {
38         'block'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
39         'dt'      : n.array(n.ones((numSamples,), dtype=object) * n.nan),
40         'time'    : n.array(n.ones((numSamples,), dtype=long) * n.nan),
41         'val1'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
42         'val2'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
43         'val3'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
44         'val4'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
45         'spu1'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
46         'spu2'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
47         'spu3'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
48         'spu4'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
49         'nois1'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
50         'nois2'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
51         'nois3'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
52         'nois4'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
53         'femax'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
54         'softw'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
55         'fe11'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
56         'fe12'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
57         'fe21'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
58         'fe22'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
59         'snr1'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
60         'snr2'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
61         'snr3'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
62         'snr4'    : n.array(n.ones((numSamples,), dtype=int) * n.nan),
63         'check'   : n.array(n.ones((numSamples,), dtype=int) * n.nan),
64         'jam'     : n.array(n.ones((numSamples,), dtype=int) * n.nan),
65         'z'       : n.array(elevations, dtype=float),
66         'u'       : n.array(n.ones((numSamples,
67                                     numAltitudes), dtype=float) * n.nan),
68         'v'       : n.array(n.ones((numSamples,
69                                     numAltitudes), dtype=float) * n.nan),
70         'w'       : n.array(n.ones((numSamples,
71                                     numAltitudes), dtype=float) * n.nan),
72         'echo'    : n.array(n.ones((numSamples,
73                                     numAltitudes), dtype = int) * n.nan),
74         }
75    
76     for sample in rawDataObject:
77         sampleIndex = rawDataObject.index(sample)
78        
79         data['block'][sampleIndex] = int(sample['BL#'])
80                                
81         dt = {'month' : int(sample['MONTH']),
82               'day'   : int(sample['DAY']),
83               'year'  : int(sample['YEAR']),
84               'hour'  : int(sample['HOUR']),
85               'min'   : int(sample['MIN']),
86             }
87         dt = '%(month)02d-%(day)02d-%(year)04d %(hour)02d:%(min)02d' % dt
88         dt = procutil.scanf_datetime(dt, fmt='%m-%d-%Y %H:%M')
89         if sensor_info['utc_offset']:
90             dt = dt + datetime.timedelta(hours=sensor_info['utc_offset'])
91         data['dt'][sampleIndex] = dt
92        
93         data['time'][sampleIndex] = procutil.dt2es(dt)
94        
95         data['val1'][sampleIndex] = int(sample['VAL1'])
96         data['val2'][sampleIndex] = int(sample['VAL2'])
97         data['val3'][sampleIndex] = int(sample['VAL3'])
98         data['val4'][sampleIndex] = int(sample['VAL4'])
99        
100         data['spu1'][sampleIndex] = int(sample['SPU1'])
101         data['spu2'][sampleIndex] = int(sample['SPU2'])
102         data['spu3'][sampleIndex] = int(sample['SPU3'])
103         data['spu4'][sampleIndex] = int(sample['SPU4'])
104        
105         data['nois1'][sampleIndex] = int(sample['NOIS1'])
106         data['nois2'][sampleIndex] = int(sample['NOIS2'])
107         data['nois3'][sampleIndex] = int(sample['NOIS3'])
108         data['nois4'][sampleIndex] = int(sample['NOIS4'])
109        
110         data['femax'][sampleIndex] = int(sample['FEMAX'])
111         data['softw'][sampleIndex] = int(sample['SOFTW'])
112        
113         data['fe11'][sampleIndex] = int(sample['FE11'])
114         data['fe12'][sampleIndex] = int(sample['FE12'])
115         data['fe21'][sampleIndex] = int(sample['FE21'])
116         data['fe22'][sampleIndex] = int(sample['FE22'])
117        
118         data['snr1'][sampleIndex] = int(sample['SNR1'])
119         data['snr2'][sampleIndex] = int(sample['SNR2'])
120         data['snr3'][sampleIndex] = int(sample['SNR3'])
121         data['snr4'][sampleIndex] = int(sample['SNR4'])
122        
123         data['check'][sampleIndex] = int(sample['CHECK'])
124         data['jam'][sampleIndex]   = int(sample['JAM'])
125        
126         for altitude,altitudeIndex in zip(altitudes, range(len(altitudes))):
127             echo   = sample[altitude]['CT']
128             radial = sample[altitude]['SPEED']
129             theta  = sample[altitude]['DIR']
130             vertical = sample[altitude]['W']
131            
132             if radial != INVALID and theta != INVALID:
133                 theta  = math.pi * float(theta) / 180.0
134                 radial = float(radial)
135                 data['u'][sampleIndex][altitudeIndex] = radial * math.sin(theta)
136                 data['v'][sampleIndex][altitudeIndex] = radial * math.cos(theta)
137            
138             if echo != INVALID:
139                 data['echo'][sampleIndex][altitudeIndex] = echo
140                
141             if vertical != INVALID:
142                 data['w'][sampleIndex][altitudeIndex] = vertical
143    
144     return data
145
146 def creator(platform_info, sensor_info, data):
147     #
148     #
149     title_str = sensor_info['description']+' at '+ platform_info['location']
150     global_atts = {
151         'title' : title_str,
152         'institution' : 'Unversity of North Carolina at Chapel Hill (UNC-CH)',
153         'institution_url' : 'http://nccoos.unc.edu',
154         'institution_dods_url' : 'http://nccoos.unc.edu',
155         'metadata_url' : 'http://nccoos.unc.edu',
156         'references' : 'http://nccoos.unc.edu',
157         'contact' : 'cbc (cbc@unc.edu)',
158         #
159         'source' : 'fixed-profiler (acoustic doppler) observation',
160         'history' : 'raw2proc using ' + sensor_info['process_module'],
161         'comment' : 'File created using pycdf'+pycdf.pycdfVersion()+' and numpy '+pycdf.pycdfArrayPkg(),
162         # conventions
163         'Conventions' : 'CF-1.0; SEACOOS-CDL-v2.0',
164         # SEACOOS CDL codes
165         'format_category_code' : 'fixed-profiler',
166         'institution_code' : platform_info['institution'],
167         'platform_code' : platform_info['id'],
168         'package_code' : sensor_info['id'],
169         # institution specific
170         'project' : 'North Carolina Coastal Ocean Observing System (NCCOOS)',
171         'project_url' : 'http://nccoos.unc.edu',
172         # timeframe of data contained in file yyyy-mm-dd HH:MM:SS
173         # first date in monthly file
174         'start_date' : data['dt'][0].strftime("%Y-%m-%d %H:%M:%S"),
175         # last date in monthly file
176         'end_date' : data['dt'][-1].strftime("%Y-%m-%d %H:%M:%S"),
177         'release_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
178         #
179         'creation_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
180         'modification_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
181         'process_level' : 'level1',
182         #
183         # must type match to data (e.g. fillvalue is real if data is real)
184         '_FillValue' : -99999.,
185         }
186
187     var_atts = {
188         # coordinate variables
189         'time' : {'short_name': 'time',
190                   'long_name': 'Time',
191                   'standard_name': 'time',
192                   'units': 'seconds since 1970-1-1 00:00:00 -0', # UTC
193                   'axis': 'T',
194                   },
195         'lat' : {'short_name': 'lat',
196              'long_name': 'Latitude',
197              'standard_name': 'latitude',
198              'reference':'geographic coordinates',
199              'units': 'degrees_north',
200              'valid_range':(-90.,90.),
201              'axis': 'Y',
202              },
203         'lon' : {'short_name': 'lon',
204                  'long_name': 'Longtitude',
205                  'standard_name': 'longtitude',
206                  'reference':'geographic coordinates',
207                  'units': 'degrees_east',
208                  'valid_range':(-180.,180.),
209                  'axis': 'Y',
210                  },
211         'z' : {'short_name': 'z',
212                'long_name': 'Height',
213                'standard_name': 'height',
214                'reference':'zero at sea-surface',
215                'positive' : 'up',
216                'units': 'm',
217                'axis': 'Z',
218                },
219         # data variables
220         'u': {'short_name' : 'u',
221               'long_name': 'East/West Component of Wind',
222               'standard_name': 'eastward_wind',
223               'units': 'cm s-1',
224               },
225         'v': {'short_name' : 'v',
226               'long_name': 'North/South Component of Wind',
227               'standard_name': 'northward_wind',                         
228               'units': 'cm s-1',
229               },
230         'w': {'short_name' : 'w',
231               'long_name': 'Vertical Component of Wind',
232               'standard_name': 'upward_wind',                         
233               'units': 'cm s-1',
234               },
235         'echo': {'short_name' : 'echo',
236                  'long_name': 'Echo Stength',
237                  'standard_name': 'echo_strenth',
238                  },
239         'block' : {'short_name': 'block',
240                    'long_name': 'Block Number',
241                    'standard_name': 'block_number'
242                    },
243         'val1': {'short_name' : 'val1',
244                  'long_name': 'Number of Beam Validations 1',
245                  'standard_name': 'validations_1',
246                  },
247         'val2': {'short_name' : 'val2',
248                  'long_name': 'Number of Beam Validations 2',
249                  'standard_name': 'validations_2',
250                  },
251         'val3': {'short_name' : 'val3',
252                  'long_name': 'Number of Beam Validations 3',
253                  'standard_name': 'validations_3',
254                  },
255         'val4': {'short_name' : 'val4',
256                  'long_name': 'Number of Beam Validations 4',
257                  'standard_name': 'validations_4',
258                  },
259         'spu1': {'short_name' : 'spu1',
260                  'long_name': 'Normalized Probability of False Signal 1',
261                  'standard_name': 'probability_1',
262                  },
263         'spu2': {'short_name' : 'spu2',
264                  'long_name': 'Normalized Probability of False Signal 1',
265                  'standard_name': 'probability_2',
266                  },
267         'spu3': {'short_name' : 'spu3',
268                  'long_name': 'Normalized Probability of False Signal 3',
269                  'standard_name': 'probability_3',
270                  },
271         'spu4': {'short_name' : 'spu4',
272                  'long_name': 'Normalized Probability of False Signal 4',
273                  'standard_name': 'probability_4',
274                  },
275         'nois1': {'short_name' : 'nois1',
276                   'long_name': 'Environmental Noise 1',
277                   'standard_name': 'ambient_1',
278                   'units': 'dB',
279               },
280         'nois2': {'short_name' : 'nois2',
281                   'long_name': 'Environmental Noise 2',
282                   'standard_name': 'ambient_2',
283                   'units': 'dB',
284               },
285         'nois3': {'short_name' : 'nois3',
286                   'long_name': 'Environmental Noise 3',
287                   'standard_name': 'ambient_3',
288                   'units': 'dB',
289               },
290         'nois4': {'short_name' : 'nois4',
291                   'long_name': 'Environmental Noise 4',
292                   'standard_name': 'ambient_4',
293                   'units': 'dB',
294               },
295         'femax': {'short_name': 'femax',
296                   'long_name': 'Maximum Ground Clutter',
297                   'standard_name': 'max_clutter',
298                   },
299         'softw': {'short_name': 'softw',
300                         'long_name': 'Software Version',
301                         'standard_name': 'software',
302                         },
303         'fe11': {'short_name': 'fe11',
304                  'long_name': 'Number of Frequencies Emitted 11',
305                  'standard_name': 'frequencies_11',
306                  },
307         'fe12': {'short_name': 'fe12',
308                  'long_name': 'Number of Frequencies Emitted 12',
309                  'standard_name': 'frequencies_12',
310                  },
311         'fe21': {'short_name': 'fe21',
312                  'long_name': 'Number of Frequencies Emitted 21',
313                  'standard_name': 'frequencies_21',
314                  },
315         'fe22': {'short_name': 'fe22',
316                  'long_name': 'Number of Frequencies Emitted 22',
317                  'standard_name': 'frequencies_22',
318                  },
319         'snr1': {'short_name' : 'snr1',
320                  'long_name': 'Average Signal To Noise Ratio 1',
321                  'standard_name': 'signal_to_noise_1',
322                  'units': 'dB',
323                  },
324         'snr2': {'short_name' : 'snr2',
325                  'long_name': 'Average Signal To Noise Ratio 2',
326                  'standard_name': 'signal_to_noise_2',
327                  'units': 'dB',
328                  },
329         'snr3': {'short_name' : 'snr3',
330                  'long_name': 'Average Signal To Noise Ratio 3',
331                  'standard_name': 'signal_to_noise_3',
332                  'units': 'dB',
333                  },
334         'snr4': {'short_name' : 'snr4',
335                  'long_name': 'Average Signal To Noise Ratio 4',
336                  'standard_name': 'signal_to_noise_4',
337                  'units': 'dB',
338                  },
339         }
340
341     # dimension names use tuple so order of initialization is maintained
342     dim_inits = (
343         ('ntime', pycdf.NC.UNLIMITED),
344         ('nlat', 1),
345         ('nlon', 1),
346         ('nz', sensor_info['num_altitudes'])
347         )
348    
349     # using tuple of tuples so order of initialization is maintained
350     # using dict for attributes order of init not important
351     # use dimension names not values
352     # (varName, varType, (dimName1, [dimName2], ...))
353     var_inits = (
354         # coordinate variables
355         ('time',  pycdf.NC.INT,   ('ntime',)),
356         ('lat',   pycdf.NC.FLOAT, ('nlat',)),
357         ('lon',   pycdf.NC.FLOAT, ('nlon',)),
358         ('z',     pycdf.NC.FLOAT, ('nz',)),
359         # data variables
360         ('u',     pycdf.NC.FLOAT, ('ntime', 'nz')),
361         ('v',     pycdf.NC.FLOAT, ('ntime', 'nz')),
362         ('w',     pycdf.NC.FLOAT, ('ntime', 'nz')),
363         ('echo',  pycdf.NC.FLOAT, ('ntime', 'nz')),
364         ('block', pycdf.NC.INT,   ('ntime',)),
365         ('val1',  pycdf.NC.INT,   ('ntime',)),
366         ('val2',  pycdf.NC.INT,   ('ntime',)),
367         ('val3',  pycdf.NC.INT,   ('ntime',)),
368         ('val4',  pycdf.NC.INT,   ('ntime',)),
369         ('spu1',  pycdf.NC.INT,   ('ntime',)),
370         ('spu2',  pycdf.NC.INT,   ('ntime',)),
371         ('spu3',  pycdf.NC.INT,   ('ntime',)),
372         ('spu4',  pycdf.NC.INT,   ('ntime',)),
373         ('nois1', pycdf.NC.INT,   ('ntime',)),
374         ('nois2', pycdf.NC.INT,   ('ntime',)),
375         ('nois3', pycdf.NC.INT,   ('ntime',)),
376         ('nois4', pycdf.NC.INT,   ('ntime',)),
377         ('femax', pycdf.NC.INT,   ('ntime',)),
378         ('softw', pycdf.NC.INT,   ('ntime',)),
379         ('fe11',  pycdf.NC.INT,   ('ntime',)),
380         ('fe12',  pycdf.NC.INT,   ('ntime',)),
381         ('fe21',  pycdf.NC.INT,   ('ntime',)),
382         ('fe22',  pycdf.NC.INT,   ('ntime',)),
383         ('snr1',  pycdf.NC.INT,   ('ntime',)),
384         ('snr2',  pycdf.NC.INT,   ('ntime',)),
385         ('snr3',  pycdf.NC.INT,   ('ntime',)),
386         ('snr4',  pycdf.NC.INT,   ('ntime',)),
387         )
388
389     # subset data only to month being processed (see raw2proc.process())
390     i = data['in']
391    
392     # var data
393     var_data = (
394         ('time',  data['time'][i]),
395         ('lat',   platform_info['lat']),
396         ('lon',   platform_info['lon']),
397         ('z',     data['z']),
398         ('u',     data['u'][i]),
399         ('v',     data['v'][i]),
400         ('w',     data['w'][i]),
401         ('echo',  data['echo'][i]),
402         ('block', data['block'][i]),
403         ('val1',  data['val1'][i]),
404         ('val2',  data['val1'][i]),
405         ('val3',  data['val1'][i]),
406         ('val4',  data['val1'][i]),
407         ('spu1',  data['spu1'][i]),
408         ('spu2',  data['spu2'][i]),
409         ('spu3',  data['spu3'][i]),
410         ('spu4',  data['spu4'][i]),
411         ('nois1', data['nois1'][i]),
412         ('nois2', data['nois2'][i]),
413         ('nois3', data['nois3'][i]),
414         ('nois4', data['nois4'][i]),
415         ('femax', data['femax'][i]),
416         ('softw', data['softw'][i]),
417         ('fe11',  data['fe11'][i]),
418         ('fe12',  data['fe12'][i]),
419         ('fe21',  data['fe21'][i]),
420         ('fe22',  data['fe22'][i]),
421         ('snr1',  data['snr1'][i]),
422         ('snr2',  data['snr2'][i]),
423         ('snr3',  data['snr3'][i]),
424         ('snr4',  data['snr4'][i]),
425         )
426
427     return (global_atts, var_atts, dim_inits, var_inits, var_data)
428
429 def updater(platform_info, sensor_info, data):
430     #
431     global_atts = {
432         # update times of data contained in file (yyyy-mm-dd HH:MM:SS)
433         # last date in monthly file
434         'end_date' : data['dt'][-1].strftime("%Y-%m-%d %H:%M:%S"),
435         'release_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
436         #
437         'modification_date' : nowDt.strftime("%Y-%m-%d %H:%M:%S"),
438         }
439
440     # data variables
441     # update any variable attributes like range, min, max
442     var_atts = {}
443    
444     # subset data only to month being processed (see raw2proc.process())
445     i = data['in']
446
447     # data
448     var_data = (
449         ('time',  data['time'][i]),
450         ('u',     data['u'][i]),
451         ('v',     data['v'][i]),
452         ('w',     data['w'][i]),
453         ('echo',  data['echo'][i]),
454         ('block', data['block'][i]),
455         ('val1',  data['val1'][i]),
456         ('val2',  data['val1'][i]),
457         ('val3',  data['val1'][i]),
458         ('val4',  data['val1'][i]),
459         ('spu1',  data['spu1'][i]),
460         ('spu2',  data['spu2'][i]),
461         ('spu3',  data['spu3'][i]),
462         ('spu4',  data['spu4'][i]),
463         ('nois1', data['nois1'][i]),
464         ('nois2', data['nois2'][i]),
465         ('nois3', data['nois3'][i]),
466         ('nois4', data['nois4'][i]),
467         ('femax', data['femax'][i]),
468         ('softw', data['softw'][i]),
469         ('fe11',  data['fe11'][i]),
470         ('fe12',  data['fe12'][i]),
471         ('fe21',  data['fe21'][i]),
472         ('fe22',  data['fe22'][i]),
473         ('snr1',  data['snr1'][i]),
474         ('snr2',  data['snr2'][i]),
475         ('snr3',  data['snr3'][i]),
476         ('snr4',  data['snr4'][i]),
477         )
478
479     return (global_atts, var_atts, var_data)
Note: See TracBrowser for help on using the browser.