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 Definitions of type strings found in LIGO Light Weight XML files.
29
30 Notes. To guarantee that a double-precision floating-point number can be
31 reconstructed exactly from its representation as a decimal number, one must
32 use 17 decimal digits; for single-precision, the number is 9. Python uses
33 only double-precision numbers, but LIGO Light Weight XML allows for
34 single-precision values, so I provide distinct format specifiers for those
35 cases here. In both cases, I have elected to use 1 fewer digits than are
36 required to uniquely reconstruct the number: the XML written by this
37 library is lossy. I made this choice to reduce the file size, for example
38
39 >>> "%.17g" % 0.1
40 '0.10000000000000001'
41
42 while
43
44 >>> "%.16g" % 0.1
45 '0.1'
46
47 In this worst case, storing full precision increases the size of the XML by
48 more than an order of magnitude. If you wish to make a different choice
49 for your files, for example if you wish your XML files to be lossless,
50 simply include the lines
51
52 glue.ligolw.types.FormatFunc.update({
53 "real_4": u"%.9g".__mod__,
54 "real_8": u"%.17g".__mod__,
55 "float": u"%.9g".__mod__,
56 "double": u"%.17g".__mod__,
57 u"complex_8": glue.ligolw.types.mk_complex_format_func(u"%.9g"),
58 u"complex_16": glue.ligolw.types.mk_complex_format_func(u"%.17g")
59 })
60
61 anywhere in your code, but before you write the document to a file.
62
63 References:
64
65 - http://docs.sun.com/source/806-3568/ncg_goldberg.html
66 """
67
68
69 import base64
70
71
72 from glue import git_version
73 from . import ilwd
74 import six
75
76
77 try:
78 long
79 except NameError:
80 long = int
81
82
83 __author__ = "Kipp Cannon <kipp.cannon@ligo.org>"
84 __version__ = "git id %s" % git_version.id
85 __date__ = git_version.date
86
87
88
89
90
91
92
93
94
95
96
97 IDTypes = set([u"ilwd:char", u"ilwd:char_u"])
98 """LIGO Light-Weight XML type strings for ID-like data."""
99
100 BlobTypes = set([u"blob", u"ilwd:char_u"])
101 """LIGO Light-Weight XML type strings for binary blob-like data."""
102
103 StringTypes = set([u"char_s", u"char_v", u"lstring", u"string", u"ilwd:char"])
104 """LIGO Light-Weight XML type strings for string-like data."""
105
106 IntTypes = set([u"int_2s", u"int_2u", u"int_4s", u"int_4u", u"int_8s", u"int_8u", u"int"])
107 """LIGO Light-Weight XML type strings for integer-like data."""
108
109 FloatTypes = set([u"real_4", u"real_8", u"float", u"double"])
110 """LIGO Light-Weight XML type strings for floating-point-like data."""
111
112 ComplexTypes = set([u"complex_8", u"complex_16"])
113 """LIGO Light-Weight XML type strings for complex-like data."""
114
115 NumericTypes = IntTypes | FloatTypes | ComplexTypes
116 """LIGO Light-Weight XML type strings for number-like data."""
117
118 TimeTypes = set([u"GPS", u"Unix", u"ISO-8601"])
119 """LIGO Light-Weight XML type strings for time-like data."""
120
121 Types = BlobTypes | StringTypes | NumericTypes | TimeTypes
122 """All valid LIGO Light-Weight XML type strings."""
123
124
125
126
127
128
129
130
131
132
133
141
142
149
150
159 return complex_format_func
160
161
162 FormatFunc = {
163 u"char_s": string_format_func,
164 u"char_v": string_format_func,
165 u"ilwd:char": u"\"%s\"".__mod__,
166 u"ilwd:char_u": blob_format_func,
167 u"blob": blob_format_func,
168 u"lstring": string_format_func,
169 u"string": string_format_func,
170 u"int_2s": u"%d".__mod__,
171 u"int_2u": u"%u".__mod__,
172 u"int_4s": u"%d".__mod__,
173 u"int_4u": u"%u".__mod__,
174 u"int_8s": u"%d".__mod__,
175 u"int_8u": u"%u".__mod__,
176 u"int": u"%d".__mod__,
177 u"real_4": u"%.8g".__mod__,
178 u"real_8": u"%.16g".__mod__,
179 u"float": u"%.8g".__mod__,
180 u"double": u"%.16g".__mod__,
181 u"complex_8": mk_complex_format_func(u"%.8g"),
182 u"complex_16": mk_complex_format_func(u"%.16g")
183 }
184 """
185 Look-up table mapping LIGO Light-Weight XML data type strings to functions
186 for formating Python data for output. This table is used universally by
187 glue.ligolw XML writing codes.
188 """
189
190
191
192
193
194
195
196
197
198
199
200 ToPyType = {
201 u"char_s": six.text_type,
202 u"char_v": six.text_type,
203 u"ilwd:char": ilwd.ilwdchar,
204 u"ilwd:char_u": lambda s: memoryview(base64.b64decode(s)),
205 u"blob": lambda s: memoryview(base64.b64decode(s)),
206 u"lstring": six.text_type,
207 u"string": six.text_type,
208 u"int_2s": int,
209 u"int_2u": int,
210 u"int_4s": int,
211 u"int_4u": int,
212 u"int_8s": int,
213 u"int_8u": int,
214 u"int": int,
215 u"real_4": float,
216 u"real_8": float,
217 u"float": float,
218 u"double": float,
219 u"complex_8": lambda s: complex(*map(float, s.split(u"+i"))),
220 u"complex_16": lambda s: complex(*map(float, s.split(u"+i")))
221 }
222 """
223 Look-up table mapping LIGO Light-Weight XML data type strings to functions
224 for parsing Python data from input. This table is used universally by
225 glue.ligolw XML parsing codes.
226 """
227
228
231 try:
232 return super(FromPyTypeCls, self).__getitem__(key)
233 except KeyError:
234 for test_key, val in six.iteritems(self):
235 if issubclass(key, test_key):
236 return val
237 raise
238
239
240 FromPyType = FromPyTypeCls({
241 ilwd._ilwd.ilwdchar: u"ilwd:char",
242 memoryview: u"blob",
243 str: u"lstring",
244 six.text_type: u"lstring",
245 bool: u"int_4s",
246 int: u"int_8s",
247 long: u"int_8s",
248 float: u"real_8",
249 complex: u"complex_16"
250 })
251 """
252 Look-up table used to guess LIGO Light-Weight XML data type strings from
253 Python types. This table is used when auto-generating XML from Python
254 objects.
255 """
256
257
258
259
260
261
262
263
264
265
266
267 ToNumPyType = {
268 u"int_2s": "int16",
269 u"int_2u": "uint16",
270 u"int_4s": "int32",
271 u"int_4u": "uint32",
272 u"int_8s": "int64",
273 u"int_8u": "uint64",
274 u"int": "int32",
275 u"real_4": "float32",
276 u"real_8": "float64",
277 u"float": "float32",
278 u"double": "float64",
279 u"complex_8": "complex64",
280 u"complex_16": "complex128"
281 }
282 """
283 Look-up table mapping LIGO Light-Weight XML data type strings to numpy
284 array type strings. Used by glue.ligolw array reading codes.
285 """
286
287
288 FromNumPyType = {
289 "int16": u"int_2s",
290 "uint16": u"int_2u",
291 "int32": u"int_4s",
292 "uint32": u"int_4u",
293 "int64": u"int_8s",
294 "uint64": u"int_8u",
295 "float32": u"real_4",
296 "float64": u"real_8",
297 "complex64": u"complex_8",
298 "complex128": u"complex_16"
299 }
300 """
301 Look-up table mapping numpy array type strings to LIGO Light-Weight XML
302 data type strings. Uesd by glue.ligolw array writing codes.
303 """
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 ToMySQLType = {
323 u"char_s": "CHAR(20)",
324 u"char_v": "VARCHAR(64)",
325 u"ilwd:char": "VARCHAR(64)",
326 u"ilwd:char_u": "BLOB",
327 u"blob": "BLOB",
328 u"lstring": "VARCHAR(255)",
329 u"string": "VARCHAR(255)",
330 u"int_2s": "SMALLINT",
331 u"int_2u": "SMALLINT",
332 u"int_4s": "INTEGER",
333 u"int_4u": "INTEGER",
334 u"int_8s": "BIGINT",
335 u"int_8u": "BIGINT",
336 u"int": "INTEGER",
337 u"real_4": "FLOAT",
338 u"real_8": "DOUBLE",
339 u"float": "FLOAT",
340 u"double": "DOUBLE"
341 }
342 """
343 Look-up table mapping LIGO Light-Weight XML data type strings to MySQL
344 column types. Used by XML --> MySQL conversion codes.
345 """
346
347
348 ToSQLiteType = {
349 u"char_s": "TEXT",
350 u"char_v": "TEXT",
351 u"ilwd:char": "TEXT",
352 u"ilwd:char_u": "BLOB",
353 u"blob": "BLOB",
354 u"lstring": "TEXT",
355 u"string": "TEXT",
356 u"int_2s": "INTEGER",
357 u"int_2u": "INTEGER",
358 u"int_4s": "INTEGER",
359 u"int_4u": "INTEGER",
360 u"int_8s": "INTEGER",
361 u"int_8u": "INTEGER",
362 u"int": "INTEGER",
363 u"real_4": "REAL",
364 u"real_8": "REAL",
365 u"float": "REAL",
366 u"double": "REAL"
367 }
368 """
369 Look-up table mapping LIGO Light-Weight XML data type strings to SQLite
370 column types. Used by XML --> SQLite conversion codes.
371 """
372
373
374 FromSQLiteType = {
375 "BLOB": u"blob",
376 "TEXT": u"lstring",
377 "STRING": u"lstring",
378 "INTEGER": u"int_4s",
379 "REAL": u"real_8"
380 }
381 """
382 Look-up table used to guess LIGO Light-Weight XML data type strings from
383 SQLite column types. Used when auto-generating XML from the contents of an
384 SQLite database.
385 """
386