forked from astropy/astroquery
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsim_result.py
More file actions
115 lines (94 loc) · 3.53 KB
/
sim_result.py
File metadata and controls
115 lines (94 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# Licensed under a 3-clause BSD style license - see LICENSE.rst
import re
import tempfile
import StringIO
from collections import namedtuple
import warnings
from astropy.io.vo.table import parse
from astropy.table import Table
__all__ = ['SimbadResult',
]
error_regex = re.compile(r'(?ms)\[(?P<line>\d+)\]\s?(?P<msg>.+?)(\[|\Z)')
SimbadError = namedtuple('SimbadError', ('line', 'msg'))
VersionInfo = namedtuple('VersionInfo', ('major', 'minor', 'micro', 'patch'))
class SimbadResult(object):
__sections = ('script', 'console', 'error', 'data')
def __init__(self, txt, pedantic=False):
self.__txt = txt
self.__pedantic = pedantic
self.__table = None
self.__stringio = None
self.__indexes = {}
self.exectime = None
self.sim_version = None
self.__split_sections()
self.__parse_console_section()
self.__warn()
self.__file = None
def __split_sections(self):
for section in self.__sections:
match = re.search(r'(?ims)^::%s:+?$(?P<content>.*?)(^::|\Z)' % \
section, self.__txt)
if match:
self.__indexes[section] = (match.start('content'),
match.end('content'))
def __parse_console_section(self):
if self.console is None:
return
m = re.search(r'(?ims)total execution time: ([.\d]+?)\s*?secs',
self.console)
if m:
try:
self.exectime = float(m.group(1))
except:
# TODO: do something useful here.
pass
m = re.search(r'(?ms)SIMBAD(\d) rel (\d)[.](\d+)([^\d^\s])?',
self.console)
if m:
self.sim_version = VersionInfo(*m.groups(None))
def __warn(self):
for error in self.errors:
warnings.warn("Warning: The script line number %i raised "
"the error: %s." %\
(error.line, error.msg))
def __get_section(self, section_name):
if section_name in self.__indexes:
return self.__txt[self.__indexes[section_name][0]:\
self.__indexes[section_name][1]].strip()
@property
def script(self):
return self.__get_section('script')
@property
def console(self):
return self.__get_section('console')
@property
def error_raw(self):
return self.__get_section('error')
@property
def data(self):
return self.__get_section('data')
@property
def errors(self):
result = []
if self.error_raw is None:
return result
for err in error_regex.finditer(self.error_raw):
result.append(SimbadError(int(err.group('line')),
err.group('msg').replace('\n', ' ')))
return result
@property
def nb_errors(self):
if self.error_raw is None:
return 0
return len(self.errors)
@property
def table(self):
if self.__file is None:
self.__file = tempfile.NamedTemporaryFile()
self.__file.write(self.data.encode('utf-8'))
self.__file.flush()
array = parse(self.__file,
pedantic=self.__pedantic).get_first_table().array
self.__table = Table(array)
return self.__table