Package glue :: Package ligolw :: Module types
[hide private]
[frames] | no frames]

Source Code for Module glue.ligolw.types

  1  # Copyright (C) 2006--2013,2016  Kipp Cannon 
  2  # 
  3  # This program is free software; you can redistribute it and/or modify it 
  4  # under the terms of the GNU General Public License as published by the 
  5  # Free Software Foundation; either version 3 of the License, or (at your 
  6  # option) any later version. 
  7  # 
  8  # This program is distributed in the hope that it will be useful, but 
  9  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 10  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General 
 11  # Public License for more details. 
 12  # 
 13  # You should have received a copy of the GNU General Public License along 
 14  # with this program; if not, write to the Free Software Foundation, Inc., 
 15  # 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. 
 16   
 17   
 18  # 
 19  # ============================================================================= 
 20  # 
 21  #                                   Preamble 
 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:  # python < 3 
 78      long 
 79  except NameError:  # python >= 3 
 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  #                               Type Categories 
 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  #                         Output Format Look-up Table 
129  # 
130  # ============================================================================= 
131  # 
132   
133   
134 -def string_format_func(s):
135 """ 136 Function used internally to format string data for output to XML. 137 Escapes back-slashes and quotes, and wraps the resulting string in 138 quotes. 139 """ 140 return u"\"%s\"" % six.text_type(s).replace(u"\\", u"\\\\").replace(u"\"", u"\\\"")
141 142
143 -def blob_format_func(b):
144 """ 145 Function used internally to format binary data. Base64-encodes the 146 data and wraps the resulting string in quotes. 147 """ 148 return u"\"%s\"" % base64.standard_b64encode(b)
149 150
151 -def mk_complex_format_func(fmt):
152 """ 153 Function used internally to generate functions to format complex 154 valued data. 155 """ 156 fmt = fmt + u"+i" + fmt 157 def complex_format_func(z): 158 return fmt % (z.real, z.imag)
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 # Conversion To And From Native Python Types 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
229 -class FromPyTypeCls(dict):
230 - def __getitem__(self, key):
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 # Conversion To and From Native Numpy Types 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 # Conversion To and From Native Database Types 310 # 311 # ============================================================================= 312 # 313 314 315 # 316 # SQL does not support complex numbers. Documents containing 317 # complex-valued table columns cannot be stored in SQL databases at this 318 # time. 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