Changeset 73
- Timestamp:
- 09/14/07 17:46:37
- Files:
-
- sodar/trunk/sodar/processedData.py (modified) (6 diffs)
- sodar/trunk/sodar/rawData.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
sodar/trunk/sodar/processedData.py
r72 r73 3 3 Classes to handle processed sodar data samples. 4 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. 5 12 """ 6 13 … … 16 23 class ProcessedData(list): 17 24 18 """Processed daily sodar file data.""" 25 """Processed daily sodar file data. 26 27 A list of rawData.Sample deep copies. 28 """ 19 29 20 30 def __init__(self, data): 21 31 """Prepare raw sodar daily data for analysis.""" 22 32 super(ProcessedData, self).__init__() 23 self. data = data33 self.extend([sample.data() for sample in data]) 24 34 self._normalize() 25 35 26 36 def _normalize(self): 27 37 """Clean up data for analysis.""" 28 self._copy()29 38 self._convert() 30 39 self._stamp() … … 43 52 # compute plotting parameters 44 53 45 def _copy(self):46 """Create a deep copy as a list of Sample copies."""47 self.extend([sample._copy() for sample in self.data])48 49 54 def _convert(self): 50 """Convert to numbers and correct for invalid values."""55 """Convert data to numbers and correct for invalid values.""" 51 56 INVALID = "-9999" 52 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 53 67 for altitude in sample['body']: 54 68 for key,value in altitude.items(): … … 57 71 raise ValueError 58 72 altitude[key] = float(value) 59 except (ValueError, TypeError , KeyError):73 except (ValueError, TypeError): 60 74 altitude[key] = n.NaN 61 for key,value in sample['header'].items():62 try:63 if value == INVALID:64 raise ValueError65 sample['header'][key] = int(value)66 except (ValueError, TypeError, KeyError):67 sample['header'][key] = n.NaN68 75 69 76 def _stamp(self): 70 """Add a datetime stamp to each sample."""77 """Add a datetime stamp item to each sample.""" 71 78 for sample in self: 72 79 try: … … 85 92 [sample['stamp'] for sample in self[1:]]) 86 93 intervals = [interval[1] - interval[0] for interval in intervals] 87 accumulator = {} 88 for interval in intervals: 89 if interval in accumulator: 90 accumulator[interval] += 1 91 else: 92 accumulator[interval] = 1 93 maxVotes = max(accumulator.values()) 94 for key,value in accumulator.items(): 95 if value == maxVotes: 96 self.sampleInterval = key 97 break 98 self.sampleInterval = getattr(self, 99 'sampleInterval', 100 datetime.timedelta.resolution) 94 intervals = [interval for interval in intervals if interval] 95 intervals = [interval for interval in intervals 96 if interval != datetime.datetime.min] 97 try: 98 self.interval = min(intervals) 99 except ValueError: 100 self.interval = datetime.datetime.min 101 101 102 102 def _minimumAltitude(self): … … 142 142 def _main(): 143 143 """Process as script from command line.""" 144 pass 144 import urllib2 145 try: 146 rawDataHandle = urllib2.urlopen('http://nemo.isis.unc.edu/'\ 147 'data/nccoos/level0/dukeforest/sodar/'\ 148 'store/2007-06/20070601.dat') 149 rawDataString = rawDataHandle.read() 150 except: 151 raise IOError("Failure to read raw test data") 152 rawDataObject = rawData.RawData(rawDataString) 153 processedDataObject = ProcessedData(rawDataObject) 145 154 146 155 if __name__ == "__main__": sodar/trunk/sodar/rawData.py
r72 r73 15 15 16 16 Each Sample object has attributes for a Header and Body object. The Samples 17 within a RawData object may also be accessed by time using a string of the format18 YYYY-MM-DD-HH-MM as in index on the RawData object to return the first matching 19 Sample in the RawData object:17 within a RawData object may also be accessed by time using a string of the 18 format YYYY-MM-DD-HH-MM as in index on the RawData object to return the first 19 matching Sample in the RawData object: 20 20 21 21 rawDataObject[0] # the first Sample object of the day … … 94 94 year,month,day,hour,minute = index.split('-') 95 95 except ValueError: 96 raise ValueError('RawData index by date must be "YYYY-MM-DD-HH-MM"') 96 raise ValueError('RawData index by date must be '\ 97 '"YYYY-MM-DD-HH-MM"') 97 98 except AttributeError: 98 raise AttributeError('RawData index by date must be "YYYY-MM-DD-HH-MM"') 99 raise AttributeError('RawData index by date must be '\ 100 '"YYYY-MM-DD-HH-MM"') 99 101 for sample in self: 100 102 try: … … 140 142 raise IndexError('Sample index out of range') 141 143 142 def _copy(self):143 """Create a deep copy as a dictionary of header and body copies."""144 return {'header':self.header. _copy(),145 'body':self.body. _copy()}144 def data(self): 145 """Create a deep copy as a dictionary of header and body data.""" 146 return {'header':self.header.data(), 147 'body':self.body.data()} 146 148 147 149 … … 169 171 " ".join(headerLines[1::2]).split()))) 170 172 171 def _copy(self):172 """Create a shallow copy as a dictionary."""173 def data(self): 174 """Create a shallow copy of the data as a dictionary.""" 173 175 return self.copy() 174 176 … … 217 219 raise IndexError('Body index, out of range') 218 220 219 def _copy(self):220 """Create a deep copy as a list of dictionaries."""221 def data(self): 222 """Create a deep copy of the data as a list of dictionaries.""" 221 223 return [altitude.copy() for altitude in self] 222 224 … … 226 228 import urllib2 227 229 try: 228 rawDataHandle = urllib2.urlopen('http://nemo.isis.unc.edu/data/nccoos/level0/dukeforest/sodar/store/2007-06/20070601.dat') 230 rawDataHandle = urllib2.urlopen('http://nemo.isis.unc.edu/'\ 231 'data/nccoos/level0/dukeforest/sodar/'\ 232 'store/2007-06/20070601.dat') 229 233 rawDataString = rawDataHandle.read() 230 234 except: