Index: sodar/trunk/sodar/data.py =================================================================== --- sodar/trunk/sodar/data.py (revision 59) +++ sodar/trunk/sodar/data.py (revision 60) @@ -6,11 +6,37 @@ """ +import re + class Data(object): - """Split sodar daily file data into samples""" + """Daily sodar file data (a collection of samples)""" def __init__(self,data): - import re - dataPattern = re.compile('\$') # samples in file are terminated by $ - samples = dataPattern.split(data) - self.samples = [sample for sample in samples if sample] + object.__init__(self) + # samples in file are terminated by $ + self.samples = [Sample(sample) for sample in [sample.strip() for sample in data.split('$')] if sample] + +class Sample(object): + """A single sample from daily sodar file data (a header and a body)""" + def __init__(self,sample): + object.__init__(self) + # first three groups of lines are the header; rest is body + samplePattern = re.compile(r'''(?P
.*?\n\n.*?\n\n.*?\n\n) + (?P.*$) + ''',re.DOTALL | re.VERBOSE) + self.__dict__.update(samplePattern.match(sample.strip()).groupdict()) + # fix for missing keys + self.header = Header(self.header) + +class Header(object): + """A sodar data sample header (a collection of sample-wide parameters)""" + def __init__(self,header): + object.__init__(self) + headerLines = [headerLine.strip() for headerLine in header.split('\n') if headerLine] + # every other line contains parameter names; every other line contains parameter values + parametersPairs = [(headerLine,headerLines[headerLines.index(headerLine)+1]) for headerLine in headerLines[::2]] + for parameterNames,parameterValues in parametersPairs: + # parameter names must be valid Python identifiers for named groups matching + parameterNames = [parameterName.strip('#') for parameterName in parameterNames.split()] + parameterPattern = re.compile(r'(?P<'+'>\S+)\s+(?P<'.join(parameterNames)+'>.*$)') + self.__dict__.update(parameterPattern.match(parameterValues).groupdict()) def __main():