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

root/sodar/trunk/sodar/formattedData.py

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

Saving work. show() throws numerix exception, though. Cutting tag on this changeset for debug demo puposes.

Exception (Using stock Enthon 1.0.0 on Win XP) looks like:

  File "C:\Python24\lib\site-packages\matplotlib\numerix\__init__.py", line 97, in angle
    return arctan2(a.imag, a.real)
ValueError: math domain error
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         rawDataHandle.close()
133     except:
134         raise IOError("Failure to read raw test data")
135     rawDataObject = rawData.RawData(rawDataString)
136     formattedDataObject = FormattedData(rawDataObject)
137     print "Time Interval =", formattedDataObject.timeInterval
138     print "Minumum Altitude =", formattedDataObject.minAltitude
139     print "Maximum Altitude =", formattedDataObject.maxAltitude
140     print "Number of Altitudes =", formattedDataObject.numAltitudes
141     print "Altitude Interval =", formattedDataObject.altInterval
142
143 if __name__ == "__main__":
144     _main()
Note: See TracBrowser for help on using the browser.