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

root/sodar/trunk/sodar/formattedData.py

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

Saving refactored changes.

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