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

root/sodar/branches/scintec-branch/sodar/scintec/maindata.py

Revision 262 (checked in by cbc, 14 years ago)

Create maindata.Observation class.

Line 
1 """
2 Module to handle Scintec sodar .mnd files.
3
4 >>> from sodar.scintec import maindata
5 """
6
7 __author__ = 'Chris Calloway'
8 __email__ = 'cbc@chriscalloway.org'
9 __copyright__ = 'Copyright 2009 UNC-CH Department of Marine Science'
10 __license__ = 'GPL2'
11
12 class MainData(list):
13     """
14     Contain data from a Scintec sodar .mnd file.
15    
16     Parse a known good .mnd file:
17     >>> main_data = MainData(good_mnd)
18    
19     Parse the format header:
20     >>> len(main_data._format_header)
21     4
22     >>> main_data._format_header[0]
23     'FORMAT-1'
24    
25     Parse the file header after the format header:
26     >>> len(main_data._file_header_body)
27     26
28     >>> main_data._file_header_body[1]
29     '# file information'
30    
31     Parse the profile data:
32     >>> len(main_data)
33     48
34    
35     Parse the first profile:
36     >>> len(main_data[0])
37     39
38     >>> main_data[0].timestamp
39     '2009-11-17 00:30:00 00:30:00'
40     >>> main_data[0].variables == ['z', 'speed', 'dir', 'W',
41     ...                            'sigW', 'bck', 'error']
42     True
43     >>> main_data[0][0] == {'z':'10', 'speed':'99.99', 'dir':'999.9',
44     ...                     'W':'-0.05', 'sigW':'0.40', 'bck':'5.46E+03',
45     ...                     'error':'0'}
46     True
47     >>> main_data[0][-1] == {'z':'200', 'speed':'99.99', 'dir':'999.9',
48     ...                      'W':'-0.07', 'sigW':'99.99', 'bck':'9.99E+37',
49     ...                      'error':'0'}
50     True
51    
52     Parse the last profile:
53     >>> len(main_data[-1])
54     39
55     >>> main_data[-1].timestamp
56     '2009-11-18 00:00:00 00:30:00'
57     >>> main_data[-1].variables == ['z', 'speed', 'dir', 'W',
58     ...                             'sigW', 'bck', 'error']
59     True
60     >>> main_data[-1][0] == {'z':'10', 'speed':'99.99', 'dir':'999.9',
61     ...                     'W':'-0.32', 'sigW':'99.99', 'bck':'9.99E+37',
62     ...                     'error':'0'}
63     True
64     >>> main_data[-1][-1] == {'z':'200', 'speed':'15.05', 'dir':'71.8',
65     ...                      'W':'-0.19', 'sigW':'0.53', 'bck':'9.99E+37',
66     ...                      'error':'0'}
67     True
68     """
69    
70     def __init__(self, mnd, *args):
71         """
72         Parse main daily Scintec sodar .mnd file.
73        
74         MainData(mnd[,file_name[,file_path]]) -> <MainData object>
75        
76         Where:
77          
78             mnd is a str object containing the complete contents read from a
79             Scintec .mnd daily sodar file including all line endings,
80            
81             file_name is an optional str object representing a file name for
82             a file which contains the referenced .mnd daily sodar file,
83            
84             file_path is an optional str object representing the path to
85             file_name.
86        
87         Parse a known good .mnd file:
88        
89         >>> main_data = MainData(good_mnd)
90         >>> main_data = MainData(good_mnd,good_name)
91         >>> main_data.file_name == good_name
92         True
93         >>> main_data = MainData(good_mnd,good_name,good_path)
94         >>> main_data.file_name == good_name
95         True
96         >>> main_data.file_path == good_path
97         True
98         """
99        
100         super(MainData, self).__init__()
101        
102         self.file_name = ''
103         self.file_path = ''
104        
105         try:
106             self.file_name = str(args[0])
107             self.file_path = str(args[1])
108         except IndexError:
109             pass
110        
111         self._blocks = [self._block.strip()
112                       for self._block in mnd.split('\n\n')
113                       if self._block.strip()]
114         self._format_header = [self._line.strip()
115                               for self._line in self._blocks[0].split('\n')
116                               if self._line.strip()]
117         self._file_header_body = [self._line.strip()
118                                   for self._line in self._blocks[1].split('\n')
119                                   if self._line.strip()]
120         self.extend([Profile([self._line.strip()
121                               for self._line in self._block.split('\n')
122                               if self._line.strip()])
123                      for self._block in self._blocks[2:]])
124         del self._blocks, self._block, self._line
125
126 class Profile(list):
127     """
128     Contain data for single profile from a Scintec sodar .mnd file.
129    
130     Parse a known good profile block:
131     >>> profile = Profile(good_profile)
132     >>> profile.timestamp
133     '2009-11-17 00:30:00 00:30:00'
134     >>> profile.variables == ['z', 'speed', 'dir', 'W',
135     ...                       'sigW', 'bck', 'error']
136     True
137     >>> profile[0] == {'z':'10', 'speed':'99.99', 'dir':'999.9',
138     ...                'W':'-0.05', 'sigW':'0.40', 'bck':'5.46E+03',
139     ...                'error':'0'}
140     True
141     >>> profile[-1] == {'z':'200', 'speed':'99.99', 'dir':'999.9',
142     ...                 'W':'-0.07', 'sigW':'99.99', 'bck':'9.99E+37',
143     ...                 'error':'0'}
144     True
145     """
146    
147     def __init__(self, profile_block):
148         """
149         Parse a profile block from a main daily Scintec sodar .mnd file.
150        
151         Profile(profile_data) -> <Profile object>
152        
153         Where:
154          
155             profile_block is a list of str objects containing all the lines
156             from a single profile in a Scintec .mnd daily sodar file.
157
158         Parse a known good profile block:
159         >>> profile = Profile(good_profile)
160         >>> profile.timestamp
161         '2009-11-17 00:30:00 00:30:00'
162         >>> profile.variables == ['z', 'speed', 'dir', 'W',
163         ...                       'sigW', 'bck', 'error']
164         True
165         >>> profile[0] == {'z':'10', 'speed':'99.99', 'dir':'999.9',
166         ...                'W':'-0.05', 'sigW':'0.40', 'bck':'5.46E+03',
167         ...                'error':'0'}
168         True
169         >>> profile[-1] == {'z':'200', 'speed':'99.99', 'dir':'999.9',
170         ...                 'W':'-0.07', 'sigW':'99.99', 'bck':'9.99E+37',
171         ...                 'error':'0'}
172         True
173         """
174        
175         super(Profile, self).__init__()
176        
177         self.timestamp = profile_block[0]
178         self.variables = profile_block[1].split()[1:]
179         self.extend([Observation(observation.split(),self.variables)
180                      for observation in profile_block[2:]])
181
182 class Observation(dict):
183     """
184     Contain data for single observation from a Scintec sodar .mnd files.
185    
186     Parse a known good observation:
187     >>> observation = Observation(good_observation,good_variables)
188     >>> observation == {'z':'10', 'speed':'99.99', 'dir':'999.9',
189     ...                 'W':'-0.05', 'sigW':'0.40', 'bck':'5.46E+03',
190     ...                 'error':'0'}
191     True
192     """
193    
194     def __init__(self,data,variables):
195         """
196         Parse an observation from a main daily Scintec sodar .mnd file.
197        
198         Observation(data,variables) -> <Observation object>
199        
200         Where:
201          
202             data is a list of str object representing variable values,
203            
204             variables is a list of str objects representing variable labels.
205        
206         Parse a known good observation:
207         >>> observation = Observation(good_observation,good_variables)
208         >>> observation == {'z':'10', 'speed':'99.99', 'dir':'999.9',
209         ...                 'W':'-0.05', 'sigW':'0.40', 'bck':'5.46E+03',
210         ...                 'error':'0'}
211         True
212         """
213
214         super(Observation, self).__init__()
215        
216         self.update(dict(zip(variables,data)))
217
218 def _test():
219     """
220     Run module tests in script mode.
221    
222     >>> from sodar.scintec.maindata import _test
223     """
224    
225     import doctest
226     from sodar.tests import suite
227     mnd_path,mnd_file,mnd,profile,variables,observation = \
228         suite.setUpGoodMndData()
229     doctest.testmod(extraglobs=dict(good_mnd=mnd,
230                                     good_name=mnd_file,
231                                     good_path=mnd_path,
232                                     good_profile=profile,
233                                     good_variables=variables,
234                                     good_observation=observation),
235                     optionflags=doctest.NORMALIZE_WHITESPACE)
236
237 if __name__ == "__main__":
238     _test()
Note: See TracBrowser for help on using the browser.