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

root/sodar/trunk/sodar/formattedData.py

Revision 80 (checked in by cbc, 17 years ago)

Fulfill ticket #20: Compute u,v arrays.

Line 
1 #!/usr/bin/python
2 """
3 Module to handle formatting sodar data samples.
4
5 A list of sample data.
6
7 A sample: formattedDataObject[0] -> dictionary
8
9 A sample header: formattedDataObject[0]['header'] -> dictionary
10
11 A sample body: formattedDataObject[0]['body'] -> list of dictionaries
12
13 Altitude data from a sample: formattedDataObject[0]['body'][0] -> dictionary
14 """
15
16 __author__ = 'Chris Calloway'
17 __email__ = 'cbc@unc.edu'
18 __copyright__ = 'Copyright 2007 UNC-CH Department of Marine Science'
19 __license__ = 'GPL2'
20
21 import rawData
22 import numpy as n
23 import datetime
24
25 class FormattedData(list):
26    
27     """Class to handle formatted daily sodar file data.
28    
29        A list of samples.
30     """
31    
32     def __init__(self, data):
33         """Create formatted sodar daily data."""
34         super(FormattedData, self).__init__()
35         self.extend([sample.data() for sample in data])
36         self._convert()
37         self._stamp()
38         self._timeInterval()
39         self._minAltitude()
40         self._maxAltitude()
41         self._numAltitudes()
42         self._altInterval()
43    
44     def _convert(self):
45         """Convert data to numbers and correct for invalid values."""
46         INVALID = "-9999"
47         for sample in self:
48             # convert header data to integers
49             for key,value in sample['header'].items():
50                 try:
51                     if value == INVALID:
52                         raise ValueError
53                     sample['header'][key] = int(value)
54                 except (ValueError, TypeError):
55                     sample['header'][key] = n.NaN
56             # convert body data to floats
57             for altitude in sample['body']:
58                 for key,value in altitude.items():
59                     try:
60                         if value == INVALID:
61                             raise ValueError
62                         altitude[key] = float(value)
63                     except (ValueError, TypeError):
64                         altitude[key] = n.NaN
65    
66     def _stamp(self):
67         """Add a datetime stamp item to each sample."""
68         for sample in self:
69             header = sample['header']
70             sample['stamp'] = datetime.datetime(header['YEAR'],
71                                                 header['MONTH'],
72                                                 header['DAY'],
73                                                 header['HOUR'],
74                                                 header['MIN'])
75    
76     def _timeInterval(self):
77         """Add a time interval attribute."""
78         intervals = zip([sample['stamp'] for sample in self[:-1]],
79                         [sample['stamp'] for sample in self[1:]])
80         intervals = [interval[1] - interval[0] for interval in intervals]
81         self.timeInterval = min(intervals)
82    
83     def _minAltitude(self):
84         """Add an overall minimum altitude attribute."""
85         altitudes = [sample['body'][0]['ALT'] for sample in self]
86         self.minAltitude = min(altitudes)
87    
88     def _maxAltitude(self):
89         """Add an overall maximum altitude attribute."""
90         altitudes = [sample['body'][-1]['ALT'] for sample in self]
91         self.maxAltitude = max(altitudes)
92    
93     def _numAltitudes(self):
94         """Add an overall maximum number of altitudes attribute"""
95         self.numAltitudes = max([len(sample['body']) for sample in self])
96    
97     def _altInterval(self):
98         """Add an overall altitude interval attribute."""
99         self.altInterval = (self.maxAltitude - self.minAltitude) / \
100                            (self.numAltitudes - 1)
101    
102     def thetas(self):
103         """Create a list of lists of horizontal directional data."""
104         return [[altitude['DIR']
105                  for altitude
106                  in sample['body']]
107                 for sample in self]
108    
109     def radials(self):
110         """Create a list of lists of horizontal radial velocity data."""
111         return [[altitude['SPEED']
112                  for altitude
113                  in sample['body']]
114                 for sample in self]
115    
116     def wComponents(self):
117         """Create a list of lists of vertical velocity data."""
118         return [[altitude['W']
119                  for altitude
120                  in sample['body']]
121                 for sample in self]
122
123
124 def _main():
125     """Process as script from command line."""
126     import urllib2
127     try:
128         rawDataHandle = urllib2.urlopen('http://nemo.isis.unc.edu/'\
129                                         'data/nccoos/level0/dukeforest/sodar/'\
130                                         'store/2007-06/20070601.dat')
131         rawDataString = rawDataHandle.read()
132     except:
133         raise IOError("Failure to read raw test data")
134     rawDataObject = rawData.RawData(rawDataString)
135     formattedDataObject = FormattedData(rawDataObject)
136     print "Time Interval =", formattedDataObject.timeInterval
137     print "Minumum Altitude =", formattedDataObject.minAltitude
138     print "Maximum Altitude =", formattedDataObject.maxAltitude
139     print "Number of Altitudes =", formattedDataObject.numAltitudes
140     print "Altitude Interval =", formattedDataObject.altInterval
141
142 if __name__ == "__main__":
143     _main()
Note: See TracBrowser for help on using the browser.