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

root/raw2proc/trunk/raw2proc/proc_rdi_dspec_dw.py

Revision 448 (checked in by cbc, 13 years ago)

Add new Billy Mitchell configs.

Line 
1 #!/usr/bin/env python
2 # Last modified:  Time-stamp: <2010-12-09 16:13:21 haines>
3 """
4 how to parse data, and assert what data and info goes into
5 creating and updating monthly netcdf files
6
7 RDI/Wavesmon processed adcp 2-D power spectrum (Dspec) as function of
8 frequency and direction
9
10 parser : sample date and time from file name, compute wave summary
11          based on George Voulgaris' matlab script (version 8, Feb 14, 2005,
12          polar_waves_cur_rdi.m) and additional parameters.
13 creator : lat, lon, z, time, freq, dir, Sxx(time, freq, dir), Sf(time, freq),
14           Stheta(time, dir), Stheta_swell(time, dir), Stheta_wind(time, dir),
15           Hs, Hs_swell, Hs_wind,
16           Tp, Tp_swell, Tp_wind, Tm, Tm_swell, Tm_wind,
17           Dp, Dp_swell, Dp_wind, Dm, Dm_swell, Dm_wind,
18          
19 updater : time, Sxx(time, freq, dir), Sf(time, freq),
20           Stheta(time, dir), Stheta_swell(time, dir), Stheta_wind(time, dir),
21           Hs, Hs_swell, Hs_wind,
22           Tp, Tp_swell, Tp_wind, Tm, Tm_swell, Tm_wind,
23           Dp, Dp_swell, Dp_wind, Dm, Dm_swell, Dm_wind,
24
25           check that freq and dir have not changed from what is in current
26           NetCDF file
27
28 Examples
29 --------
30
31 >> (parse, create, update) = load_processors(module_name_without_dot_py)
32 For example,
33 >> (parse, create, update) = load_processors('proc_rdi_logdata_adcp')
34 or
35 >> si = get_config(cn+'.sensor_info')
36 >> (parse, create, update) = load_processors(si['adcp']['proc_module'])
37
38 Then use the generic name of processor to parse data, create or update
39 monthly output file
40
41 >> lines = load_data(filename)
42 >> data = parse(platform_info, sensor_info, lines)
43 >> create(platform_info, sensor_info, data)
44 or
45 >> update(platform_info, sensor_info, data)
46
47 """
48
49 from raw2proc import *
50 from procutil import *
51 from ncutil import *
52
53 now_dt = datetime.utcnow()
54 now_dt.replace(microsecond=0)
55
56 def parser(platform_info, sensor_info, lines):
57     """
58     parse and assign wave spectra data from RDI ADCP Dspec
59     and compute wave statistics and parameters
60
61     Notes
62     -----
63     1. adapted from polar_waves_cur_rdi.m  (Version 8 - February 14, 2005)
64        by George Voulgaris
65        Coastal Processes & Sediment Dynamics Lab
66        Department of Geological Sciences
67        University of South Carolina, Columbia, SC 29205
68        Email: gvoulgaris@geol.sc.edu
69     1. should only be one line in each file of comma-delimited data
70
71     """
72     import numpy
73     from datetime import datetime
74     from time import strptime
75
76     # get sample datetime from filename
77     fn = sensor_info['fn']
78     # print " ... %s" % (fn,)
79     if  sensor_info['utc_offset']:
80         sample_dt = filt_datetime(fn) + \
81                     timedelta(hours=sensor_info['utc_offset'])
82     else:
83         sample_dt = filt_datetime(fn)
84
85     # extract header (first 6 lines)
86     rdi = []
87     for line in [lines[2], lines[4], lines[5]]:
88         # split line and parse float and integers
89         sw = re.split(' ', line)
90         for s in sw:
91             m = re.search(REAL_RE_STR, s)
92             if m:
93                 rdi.append(float(m.groups()[0]))
94
95     # assign specific fields
96     n = len(rdi)
97     ndir = float(rdi[0])  # Number of directions (no units)
98     nfreq = float(rdi[1]) # Number of frequencies (no units)
99     freq_bw = float(rdi[2])    # Frequency bandwidth (Hz)
100     Do = float(rdi[3])  # Starting direction (degrees from True North)
101
102     if ndir!=sensor_info['ndir']:
103         print 'Number of direction bins reported in data ('+ \
104               str(ndir)+') does not match config number ('+ \
105               str(sensor_info['ndir'])+'). \nCheck for change at sensor.'
106
107     if nfreq!=sensor_info['nfreq']:
108         print 'Number of frequencies reported in data ('+ \
109               str(nfreq)+') does not match config number ('+ \
110               str(sensor_info['nfreq'])+'). \nCheck for change at sensor. '
111
112     Dtheta = 360./ndir
113     D = Do + numpy.arange(ndir)*Dtheta
114     D = numpy.mod(D,360)
115     Df = 1./nfreq
116     f = numpy.arange(1,nfreq+1)*Df
117
118     # some data checks
119     if Df != freq_bw:
120         # frequency resolution should be the same as freq_bw
121         print "Df (%f) not equal to freq_bw (%f)" % (Df, freq_bw)
122
123     # set up dict of data
124     data = {
125         'dt' : numpy.array(numpy.ones((1,), dtype=object)*numpy.nan),
126         'time' : numpy.array(numpy.ones((1,), dtype=long)*numpy.nan),
127         'dirs' : numpy.array(numpy.ones((ndir,), dtype=float)*numpy.nan),
128         'freqs' : numpy.array(numpy.ones((nfreq,), dtype=float)*numpy.nan),
129         'Sxx' : numpy.array(numpy.ones((1,nfreq,ndir), dtype=float)*numpy.nan),
130         'Sf' : numpy.array(numpy.ones((1,nfreq), dtype=float)*numpy.nan),
131         'Stheta' : numpy.array(numpy.ones((1,ndir), dtype=float)*numpy.nan),
132         'Stheta_swell' : numpy.array(numpy.ones((1,ndir), dtype=float)*numpy.nan),
133         'Stheta_wind' : numpy.array(numpy.ones((1,ndir), dtype=float)*numpy.nan),
134         'Hs' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
135         'Hs_swell' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
136         'Hs_wind' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
137         'Tm' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
138         'Tm_swell' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
139         'Tm_wind' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
140         'Tp' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
141         'Tp_swell' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
142         'Tp_wind' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
143         'Dm' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
144         'Dm_swell' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
145         'Dm_wind' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
146         'Dp' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
147         'Dp_swell' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
148         'Dp_wind' : numpy.array(numpy.ones((1,), dtype=float)*numpy.nan),
149         }
150
151     # throw a dummy datetime into dt so we can return data with no data
152     # if we encounter an unrecoverable error while parsing the file
153     data['dt'][:] = datetime(1970,1,1,0,0,0)
154
155     j = 0
156     Sxx = numpy.array(numpy.ones((nfreq,ndir), dtype=float)*numpy.nan)
157     # each line is a freq, each column is a direction
158     for line in lines[6:]:
159         rdi = []
160         # split line and parse float and integers
161         sw = re.split(' ', line)
162         for s in sw:
163             m = re.search(REAL_RE_STR, s)
164             if m:
165                 rdi.append(float(m.groups()[0]))
166
167         if len(rdi) == ndir:
168             Sxx[j][:] =  numpy.array(rdi[:])  # cross spectrum as mm^2/Hz/deg
169             j = j+1
170
171     # Did we get the number of data rows that we expected?  Should equal nfreq
172     if j != nfreq:
173         print "Number of data rows %d does not match expected number %d" % (j, nfreq)
174         print " .... skipping %s" % (fn,)
175         return data
176
177     Sxx = Sxx/360./1000./1000. # convert cross spectrum to units of m^2/Hz/deg
178     # NOTE make fupper location dependent?? (add to config_files??)
179     fupper = 0.65   # upper freq limit 0.65 Hz or wave periods less than T~1.538s
180     iswell = f<=1/10.               # swell band for T>10s
181     iwind = (f>1/10.) * (f<=fupper) # wind band 1/fupper<T<10s
182     # NOTE about python boolean overloaded operator '*' == and == bitwise_and()
183     iall = f<=fupper                # all wave freq upper limit
184
185     # compute non-directional spectrum by integrating over all angles
186     # Sxx(freq, dir)  sum axis=1 is along direction
187     Sf = Sxx.sum(axis=1)*Dtheta
188     # Sxx(freq, dir)  axis=0 is along freq
189     Stheta = Sxx[iall].sum(axis=0)*Df
190     Stheta_s = Sxx[iswell].sum(axis=0)*Df
191     Stheta_w = Sxx[iwind].sum(axis=0)*Df
192
193     # compute zeroth-, first- and second-moment from the non-directional spectrum
194     # all frequency ranges
195     m0 = Sf[iall].sum()*Df
196     m1 = (f[iall]*Sf[iall]).sum()*Df
197     m2 = ((f[iall]**2)*Sf[iall]).sum()*Df
198     # swell band
199     m0s = Sf[iswell].sum()*Df
200     m1s = (f[iswell]*Sf[iswell]).sum()*Df
201     m2s = ((f[iswell]**2)*Sf[iswell]).sum()*Df
202     # wind band
203     m0w = Sf[iwind].sum()*Df
204     m1w = (f[iwind]*Sf[iwind]).sum()*Df
205     m2w = ((f[iwind]**2)*Sf[iwind]).sum()*Df
206
207     # Significant Wave Height (Hs)
208     Hs = 4*numpy.sqrt(m0)
209     Hss = 4*numpy.sqrt(m0s)
210     Hsw = 4*numpy.sqrt(m0w)
211
212     # Mean Wave Period (Tm)
213     Tm = m0/m1
214     Tms = m0s/m1s
215     Tmw = m0w/m1w
216
217     # Peak Wave Period (Tp)
218     # imax = Sf[iall]==Sf[iall].max()
219     # Fp = f(imax)
220     # Tp = 1/Fp[0]
221     # This wave parameters added by SH (not in GV's matlab script)
222     # one-liner version of above
223     Tp = 1/(f[Sf[iall]==Sf[iall].max()][0])
224     Tps = 1/(f[Sf[iswell]==Sf[iswell].max()][0])
225
226     # account for offset of iwind by iswell in finding peak wind freq
227     nswell = len(f[iswell])
228     false_swell = numpy.array([False for i in range(nswell)])
229     imax = Sf[iwind]==Sf[iwind].max()
230     imax = numpy.concatenate((false_swell,imax))
231     Tpw = 1/(f[imax][0])
232
233     # mean direction of wave approach used by Kuik et al (1989)
234     # Mean wave direction as a function of frequency
235     # for all freq, wind and swell bands as adapted from GV's code
236     # (polar_waves_cur_rdi.m, version 8)
237     pi = numpy.pi
238     ac = numpy.cos(D*pi/180)
239     as = numpy.sin(D*pi/180)
240
241     ch0 = (ac*Stheta*Dtheta).sum()
242     sh0 = (as*Stheta*Dtheta).sum()
243     Dm = numpy.arctan2(sh0,ch0)*180/pi
244     if Dm<0: Dm = Dm+360.
245
246     ch0s = (ac*Stheta_s*Dtheta).sum()
247     sh0s = (as*Stheta_s*Dtheta).sum()
248     Dms = numpy.arctan2(sh0s,ch0s)*180/pi
249     if Dms<0: Dms = Dms+360.
250
251     ch0w = (ac*Stheta_w*Dtheta).sum()
252     sh0w = (as*Stheta_w*Dtheta).sum()
253     Dmw = numpy.arctan2(sh0w,ch0w)*180/pi
254     if Dmw<0: Dmw = Dmw+360.
255
256     # Peak Wave Direction (Dp) defined as the direction which
257     # corresponds to the "Peak frequency", or Fp.  Peak frequency is the
258     # frequency at which the "Spectral density function" is at a
259     # maximum.  The spectral density function gives the dependence
260     # with frequency of the energy of the waves considered.  also
261     # known as the one-dimensional spectrum or energy spectrum.
262     # Definitions from Metocean Glossary
263     # http://www.ifremer.fr/web-com/glossary
264     #
265     # This wave parameter added by SH (not in GV's matlab script)
266     imax = Sf[iall]==Sf[iall].max()
267     idir = numpy.squeeze(Sxx[imax,:]==Sxx[imax,:].max())
268     Dp = D[idir][0]
269    
270     imax = Sf[iswell]==Sf[iswell].max()
271     idir = numpy.squeeze(Sxx[imax,:]==Sxx[imax,:].max())
272     Dps = D[idir][0]
273    
274     imax = Sf[iwind]==Sf[iwind].max()
275     # account for swell offset of swell freq in finding max wind freq
276     imax = numpy.concatenate((false_swell, imax))
277     idir = numpy.squeeze(Sxx[imax,:]==Sxx[imax,:].max())
278     Dpw = D[idir][0]
279
280     #---------------------------------------------------------------
281     data['dt'][0] =  sample_dt
282     data['time'][0] = dt2es(sample_dt) # sample time in epoch seconds
283     data['dirs'] = D
284     data['freqs'] = f
285
286     data['Sxx'][0] = Sxx # full directional spectrum (m^2/Hz/deg)
287     data['Sf'][0] = Sf   # non-directional spectrum (m^2/Hz)
288     data['Stheta'][0] = Stheta # Energy from all freq from each direction
289     data['Stheta_swell'][0] = Stheta_s
290     data['Stheta_wind'][0] = Stheta_w
291
292     data['Hs'][0] = Hs
293     data['Hs_swell'][0] = Hss   
294     data['Hs_wind'][0] = Hsw
295
296     data['Tm'][0] = Tm
297     data['Tm_swell'][0] = Tms   
298     data['Tm_wind'][0] = Tmw
299
300     data['Tp'][0] = Tp
301     data['Tp_swell'][0] = Tps   
302     data['Tp_wind'][0] = Tpw
303
304     data['Dm'][0] = Dm
305     data['Dm_swell'][0] = Dms   
306     data['Dm_wind'][0] = Dmw
307
308     data['Dp'][0] = Dp
309     data['Dp_swell'][0] = Dps   
310     data['Dp_wind'][0] = Dpw
311
312     # print "  Waves: All / Swell / Wind"
313     # print " Hs (m): %g /%g /%g" % (Hs, Hss, Hsw)
314     # print " Tm (s): %g /%g /%g" % (Tm, Tms, Tmw)
315     # print " Dm (N): %g /%g /%g" % (Dm, Dms, Dmw)
316     # print " Dp (N): %g /%g /%g" % (Dp, Dps, Dpw)
317  
318     return data
319
320 def creator(platform_info, sensor_info, data):
321     #
322     #
323     title_str = sensor_info['description']+' at '+ platform_info['location']
324     global_atts = {
325         'title' : title_str,
326         'institution' : 'University of North Carolina at Chapel Hill (UNC-CH)',
327         'institution_url' : 'http://nccoos.unc.edu',
328         'institution_dods_url' : 'http://nccoos.unc.edu',
329         'metadata_url' : 'http://nccoos.unc.edu',
330         'references' : 'http://nccoos.unc.edu',
331         'contact' : 'Sara Haines (haines@email.unc.edu)',
332         #
333         'source' : 'directional wave (acoustic doppler) observation',
334         'history' : 'raw2proc using ' + sensor_info['process_module'],
335         'comment' : 'File created using pycdf'+pycdfVersion()+' and numpy '+pycdfArrayPkg(),
336         # conventions
337         'Conventions' : 'CF-1.0; SEACOOS-CDL-v2.0',
338         # SEACOOS CDL codes
339         'format_category_code' : 'directional waves',
340         'institution_code' : platform_info['institution'],
341         'platform_code' : platform_info['id'],
342         'package_code' : sensor_info['id'],
343         # institution specific
344         'project' : 'North Carolina Coastal Ocean Observing System (NCCOOS)',
345         'project_url' : 'http://nccoos.unc.edu',
346         # timeframe of data contained in file yyyy-mm-dd HH:MM:SS
347         'start_date' : data['dt'][0].strftime("%Y-%m-%d %H:%M:%S"),
348         'end_date' : data['dt'][-1].strftime("%Y-%m-%d %H:%M:%S"),
349         'release_date' : now_dt.strftime("%Y-%m-%d %H:%M:%S"),
350         #
351         'creation_date' : now_dt.strftime("%Y-%m-%d %H:%M:%S"),
352         'modification_date' : now_dt.strftime("%Y-%m-%d %H:%M:%S"),
353         'process_level' : 'level1',
354         #
355         # must type match to data (e.g. fillvalue is real if data is real)
356         '_FillValue' : -99999.,
357         }
358
359     var_atts = {
360         # coordinate variables
361         'time' : {'short_name': 'time',
362                   'long_name': 'Time',
363                   'standard_name': 'time',
364                   'units': 'seconds since 1970-1-1 00:00:00 -0', # UTC
365                   'axis': 'T',
366                   },
367         'lat' : {'short_name': 'lat',
368              'long_name': 'Latitude',
369              'standard_name': 'latitude',
370              'reference':'geographic coordinates',
371              'units': 'degrees_north',
372              'valid_range':(-90.,90.),
373              'axis': 'Y',
374              },
375         'lon' : {'short_name': 'lon',
376                  'long_name': 'Longitude',
377                  'standard_name': 'longitude',
378                  'reference':'geographic coordinates',
379                  'units': 'degrees_east',
380                  'valid_range':(-180.,180.),
381                  'axis': 'Y',
382                  },
383         'z' : {'short_name': 'z',
384                'long_name': 'Height',
385                'standard_name': 'height',
386                'reference':'zero at sea-surface',
387                'units': 'm',
388                'axis': 'Z',
389                },
390         'f' : {'short_name': 'f',
391                'long_name': 'Frequency',
392                'standard_name': 'frequency',
393                'units': 'Hz',
394                },
395         'd' : {'short_name': 'd',
396                'long_name': 'Direction',
397                'standard_name': 'direction',
398                'reference':'clock-wise from True North',
399                'units': 'deg',
400                },
401         # data variables
402         'Sxx' : {'short_name': 'Sxx',
403                 'long_name': 'Directional Spectral Density Function',
404                 'definition': 'Distribution of the wave energy with both frequency and direction',
405                 'standard_name': 'wave_directional_spectral_density',
406                 'units': 'm2 Hz-1 deg-1',
407                 },
408         'Sf' : {'short_name': 'Sf',
409                 'long_name': 'Spectral Density Function',
410                 'definition': 'Distribution of the wave energy with frequency from all directions',
411                 'standard_name': 'wave_spectral_density',
412                 'units': 'm2 Hz-1',
413                 },
414         'Stheta' : {'short_name': 'St',
415                     'long_name': 'Spectral Density Function',
416                     'definition': 'Distribution of the wave energy with direction from all frequencies',
417                     'standard_name': 'wave_directional_density',
418                     'units': 'm2 deg-1',
419                 },
420         'Stheta_swell' : {'short_name': 'Sts',
421                           'long_name': 'Swell Spectral Density Function',
422                           'definition': 'Distribution of the wave energy with direction from all swell frequencies',
423                           'standard_name': 'swell_wave_directional_density',
424                           'units': 'm2 deg-1',
425                           },
426         'Stheta_wind' : {'short_name': 'Stw',
427                           'long_name': 'Wind Spectral Density Function',
428                           'definition': 'Distribution of the wave energy with direction from all Wind frequencies',
429                           'standard_name': 'wind_wave_directional_density',
430                           'units': 'm2 deg-1',
431                           },
432         'Hs' : {'short_name': 'Hs',
433                 'long_name': 'Significant Wave Height',
434                 'definition': 'Four times the square root of the first moment of the wave spectrum (4*sqrt(m0))',
435                 'standard_name': 'significant_wave_height',
436                 'units': 'm',
437                 },
438         'Hs_swell' : {'short_name': 'Hss',
439                       'long_name': 'Significant Swell Wave Height',
440                       'definition': 'Four times the square root of the first moment of the swell wave spectrum (4*sqrt(m0s))',
441                       'standard_name': 'significant_swell_wave_height',
442                       'units': 'm',
443                       },
444         'Hs_wind' : {'short_name': 'Hsw',
445                       'long_name': 'Significant Wind Wave Height',
446                       'definition': 'Four times the square root of the first moment of the wind wave spectrum (4*sqrt(m0w))',
447                       'standard_name': 'significant_wind_wave_height',
448                       'units': 'm',
449                       },
450         'Tp' : {'short_name': 'Tp',
451                 'long_name': 'Peak Wave Period',
452                 'definition': 'Period of strongest wave (Sf  maximum)',
453                 'standard_name': 'peak_wave_period',                         
454                 'units': 'sec',
455                 },
456         'Tp_swell' : {'short_name': 'Tps',
457                       'long_name': 'Peak Swell Wave Period',
458                       'definition': 'Period of strongest swell (Sfs energy maximum)',
459                       'standard_name': 'peak_swell_wave_period',                         
460                       'units': 'sec',
461                       },
462         'Tp_wind' : {'short_name': 'Tpw',
463                 'long_name': 'Peak Wind Wave Period',
464                 'definition': 'Period of strongest wind wave (Sfw energy maximum)',
465                 'standard_name': 'peak_wind_wave_period',                         
466                 'units': 'sec',
467                              },
468         'Tm' : {'short_name': 'Tm',
469                 'long_name': 'Mean Wave Period',
470                 'definition': 'Zero-moment of the non-directional spectrum divided by the first-moment (m0/m1)',
471                 'standard_name': 'mean_wave_period',                         
472                 'units': 'sec',
473                 },
474         'Tm_swell' : {'short_name': 'Tms',
475                 'long_name': 'Mean Swell Wave Period',
476                 'definition': 'Zero-moment of the non-directional spectrum divided by the first-moment (m0s/m1s)',
477                 'standard_name': 'mean_swell_wave_period',                         
478                 'units': 'sec',
479                 },
480         'Tm_wind' : {'short_name': 'Tmw',
481                 'long_name': 'Mean Wind Wave Period',
482                 'definition': 'Zero-moment of the non-directional spectrum divided by the first-moment (m0w/m1w)',
483                 'standard_name': 'mean_wind_wave_period',                         
484                 'units': 'sec',
485                 },
486         'Dp' : {'short_name': 'Dp',
487                 'long_name': 'Peak Wave Direction',
488                 'definition': 'Direction from which strongest waves (wave energy) are coming (dir of max(S(Tp,dir)',
489                 'standard_name': 'peak_wave_from_direction',                         
490                 'units': 'deg from N',
491                 'reference': 'clockwise from True North',
492                            },
493         'Dp_swell' : {'short_name': 'Dps',
494                 'long_name': 'Peak Swell Wave Direction',
495                 'definition': 'Direction from which strongest waves (swell energy) are coming (dir of max(S(Tps,dir)',
496                 'standard_name': 'peak_swell_wave_from_direction',                         
497                 'units': 'deg from N',
498                 'reference': 'clockwise from True North',
499                            },
500         'Dp_wind' : {'short_name': 'Dpw',
501                 'long_name': 'Peak Wind Wave Direction',
502                 'definition': 'Direction from which strongest waves (wind wave energy) are coming (dir of max(S(Tpw,dir)',
503                 'standard_name': 'peak_wind_wave_from_direction',                         
504                 'units': 'deg from N',
505                 'reference': 'clockwise from True North',
506                            },
507         'Dm' : {'short_name': 'Dm',
508                 'long_name': 'Mean Wave Direction',
509                 'definition': 'Mean direction from which strongest waves (wave energy max) are coming for all frequencies',
510                 'standard_name': 'mean_wave_from_direction',                         
511                 'units': 'deg from N',
512                 'reference': 'clockwise from True North',
513                            },
514         'Dm_swell' : {'short_name': 'Dms',
515                 'long_name': 'Mean Swell Wave Direction',
516                 'definition': 'Mean direction from which strongest waves (wave energy max) are coming for swell frequencies',
517                 'standard_name': 'mean_swell_wave_from_direction',                         
518                 'units': 'deg from N',
519                 'reference': 'clockwise from True North',
520                            },
521         'Dm_wind' : {'short_name': 'Dmw',
522                 'long_name': 'Mean Wind Wave Direction',
523                 'definition': 'Mean direction from which strongest waves (wave energy max) are coming for wind wave frequencies',
524                 'standard_name': 'mean_wind_wave_from_direction',                         
525                 'units': 'deg from N',
526                 'reference': 'clockwise from True North',
527                            },
528         }
529
530    
531     # dimension names use tuple so order of initialization is maintained
532     dim_inits = (
533         ('ntime', NC.UNLIMITED),
534         ('nlat', 1),
535         ('nlon', 1),
536         ('nz', 1),
537         ('nfreq', sensor_info['nfreq']),
538         ('ndir', sensor_info['ndir']),
539         )
540    
541     # using tuple of tuples so order of initialization is maintained
542     # using dict for attributes order of init not important
543     # use dimension names not values
544     # (varName, varType, (dimName1, [dimName2], ...))
545     var_inits = (
546         # coordinate variables
547         ('time', NC.INT, ('ntime',)),
548         ('lat', NC.FLOAT, ('nlat',)),
549         ('lon', NC.FLOAT, ('nlon',)),
550         ('z',  NC.FLOAT, ('nz',)),
551         ('f',  NC.FLOAT, ('nfreq',)),
552         ('d',  NC.FLOAT, ('ndir',)),
553         # data variables
554         ('Sxx', NC.FLOAT, ('ntime','nfreq','ndir')),
555         ('Sf', NC.FLOAT, ('ntime','nfreq')),
556         ('Stheta', NC.FLOAT, ('ntime','ndir')),
557         ('Stheta_swell', NC.FLOAT, ('ntime','ndir')),
558         ('Stheta_wind', NC.FLOAT, ('ntime','ndir')),
559         ('Hs', NC.FLOAT, ('ntime',)),
560         ('Hs_swell', NC.FLOAT, ('ntime',)),
561         ('Hs_wind', NC.FLOAT, ('ntime',)),
562         ('Tp', NC.FLOAT, ('ntime',)),
563         ('Tp_swell', NC.FLOAT, ('ntime',)),
564         ('Tp_wind', NC.FLOAT, ('ntime',)),
565         ('Tm', NC.FLOAT, ('ntime',)),
566         ('Tm_swell', NC.FLOAT, ('ntime',)),
567         ('Tm_wind', NC.FLOAT, ('ntime',)),
568         ('Dp', NC.FLOAT, ('ntime',)),
569         ('Dp_swell', NC.FLOAT, ('ntime',)),
570         ('Dp_wind', NC.FLOAT, ('ntime',)),
571         ('Dm', NC.FLOAT, ('ntime',)),
572         ('Dm_swell', NC.FLOAT, ('ntime',)),
573         ('Dm_wind', NC.FLOAT, ('ntime',)),
574         )
575    
576     # subset data only to month being processed (see raw2proc.process())
577     i = data['in']
578
579     # var data
580     var_data = (
581         ('lat',  platform_info['lat']),
582         ('lon', platform_info['lon']),
583         ('z', 0),
584         ('f', data['freqs']),
585         ('d', data['dirs']),
586         #
587         ('time', data['time'][i]),
588         ('Sxx', data['Sxx'][i]),
589         ('Sf', data['Sf'][i]),
590         ('Stheta', data['Stheta'][i]),
591         ('Stheta_swell', data['Stheta_swell'][i]),
592         ('Stheta_wind', data['Stheta_wind'][i]),
593         ('Hs', data['Hs'][i]),
594         ('Hs_swell', data['Hs_swell'][i]),
595         ('Hs_wind', data['Hs_wind'][i]),
596         ('Tp', data['Tp'][i]),
597         ('Tp_swell', data['Tp_swell'][i]),
598         ('Tp_wind', data['Tp_wind'][i]),
599         ('Tm', data['Tm'][i]),
600         ('Tm_swell', data['Tm_swell'][i]),
601         ('Tm_wind', data['Tm_wind'][i]),
602         ('Dp', data['Dp'][i]),
603         ('Dp_swell', data['Dp_swell'][i]),
604         ('Dp_wind', data['Dp_wind'][i]),
605         ('Dm', data['Dm'][i]),
606         ('Dm_swell', data['Tm_swell'][i]),
607         ('Dm_wind', data['Tm_wind'][i]),
608         )
609
610     return (global_atts, var_atts, dim_inits, var_inits, var_data)
611
612 def updater(platform_info, sensor_info, data):
613     #
614     global_atts = {
615         # update times of data contained in file (yyyy-mm-dd HH:MM:SS)
616         # last date in monthly file
617         'end_date' : data['dt'][-1].strftime("%Y-%m-%d %H:%M:%S"),
618         'release_date' : now_dt.strftime("%Y-%m-%d %H:%M:%S"),
619         #
620         'modification_date' : now_dt.strftime("%Y-%m-%d %H:%M:%S"),
621         }
622
623     # data variables
624     # update any variable attributes like range, min, max
625     var_atts = {}
626     # var_atts = {
627     #    'u': {'max': max(data.u),
628     #          'min': min(data.v),
629     #          },
630     #    'v': {'max': max(data.u),
631     #          'min': min(data.v),
632     #          },
633     #    }
634    
635     # subset data only to month being processed (see raw2proc.process())
636     i = data['in']
637
638     # data
639     var_data = (
640         ('time', data['time'][i]),
641         ('Sxx', data['Sxx'][i]),
642         ('Sf', data['Sf'][i]),
643         ('Stheta', data['Stheta'][i]),
644         ('Stheta_swell', data['Stheta_swell'][i]),
645         ('Stheta_wind', data['Stheta_wind'][i]),
646         ('Hs', data['Hs'][i]),
647         ('Hs_swell', data['Hs_swell'][i]),
648         ('Hs_wind', data['Hs_wind'][i]),
649         ('Tp', data['Tp'][i]),
650         ('Tp_swell', data['Tp_swell'][i]),
651         ('Tp_wind', data['Tp_wind'][i]),
652         ('Tm', data['Tm'][i]),
653         ('Tm_swell', data['Tm_swell'][i]),
654         ('Tm_wind', data['Tm_wind'][i]),
655         ('Dp', data['Dp'][i]),
656         ('Dp_swell', data['Dp_swell'][i]),
657         ('Dp_wind', data['Dp_wind'][i]),
658         ('Dm', data['Dm'][i]),
659         ('Dm_swell', data['Dm_swell'][i]),
660         ('Dm_wind', data['Dm_wind'][i]),
661        )
662
663     return (global_atts, var_atts, var_data)
664
665 #
Note: See TracBrowser for help on using the browser.