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

Source Code for Module glue.ligolw.lsctables

   1  # Copyright (C) 2006--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  LSC Table definitions.  These must be kept synchronized with the official 
  29  definitions in the LDAS CVS repository at 
  30  http://www.ldas-sw.ligo.caltech.edu/cgi-bin/cvsweb.cgi/ldas/dbms/db2/sql. 
  31  Maintenance of the table definitions is left to the conscience of 
  32  interested users. 
  33  """ 
  34   
  35   
  36  import math 
  37  import numpy 
  38  import warnings 
  39  from xml import sax 
  40   
  41   
  42  from glue import git_version 
  43  from glue import iterutils 
  44  from glue import offsetvector 
  45  from glue import segments 
  46  import lal 
  47  from lal import LIGOTimeGPS 
  48  from . import ligolw 
  49  from . import table 
  50  from . import types as ligolwtypes 
  51  from . import ilwd 
  52   
  53   
  54  __author__ = "Kipp Cannon <kipp.cannon@ligo.org>" 
  55  __version__ = "git id %s" % git_version.id 
  56  __date__ = git_version.date 
57 58 59 # 60 # ============================================================================= 61 # 62 # Convenience Functions 63 # 64 # ============================================================================= 65 # 66 67 68 -def New(cls, columns = None, **kwargs):
69 """ 70 Construct a pre-defined LSC table. The optional columns argument 71 is a sequence of the names of the columns the table should be 72 constructed with. If columns = None, then the table is constructed 73 with all valid columns (use columns = [] to create a table with no 74 columns). 75 76 Example: 77 78 >>> import sys 79 >>> tbl = New(ProcessTable, [u"process_id", u"start_time", u"end_time", u"comment"]) 80 >>> tbl.write(sys.stdout) # doctest: +NORMALIZE_WHITESPACE 81 <Table Name="process:table"> 82 <Column Type="ilwd:char" Name="process:process_id"/> 83 <Column Type="int_4s" Name="process:start_time"/> 84 <Column Type="int_4s" Name="process:end_time"/> 85 <Column Type="lstring" Name="process:comment"/> 86 <Stream Delimiter="," Type="Local" Name="process:table"> 87 </Stream> 88 </Table> 89 """ 90 new = cls(sax.xmlreader.AttributesImpl({u"Name": cls.TableName.enc(cls.tableName)}), **kwargs) 91 colnamefmt = new.Name + u":%s" 92 if columns is not None: 93 for key in sorted(columns): 94 if key not in new.validcolumns: 95 raise ligolw.ElementError("invalid Column '%s' for Table '%s'" % (key, new.Name)) 96 new.appendChild(table.Column(sax.xmlreader.AttributesImpl({u"Name": colnamefmt % key, u"Type": new.validcolumns[key]}))) 97 else: 98 for key, value in sorted(new.validcolumns.items()): 99 new.appendChild(table.Column(sax.xmlreader.AttributesImpl({u"Name": colnamefmt % key, u"Type": value}))) 100 new._end_of_columns() 101 new.appendChild(table.TableStream(sax.xmlreader.AttributesImpl({u"Name": new.getAttribute(u"Name"), u"Delimiter": table.TableStream.Delimiter.default, u"Type": table.TableStream.Type.default}))) 102 return new
103
104 105 -def HasNonLSCTables(elem):
106 """ 107 Return True if the document tree below elem contains non-LSC 108 tables, otherwise return False. 109 """ 110 return any(t.Name not in TableByName for t in elem.getElementsByTagName(ligolw.Table.tagName))
111
112 113 -class instrumentsproperty(object):
114 - def __init__(self, name):
115 self.name = name
116 117 @staticmethod
118 - def get(ifos):
119 """ 120 Parse the values stored in the "ifos" and "instruments" 121 columns found in many tables. This function is mostly for 122 internal use by the .instruments properties of the 123 corresponding row classes. The mapping from input to 124 output is as follows (rules are applied in order): 125 126 input is None --> output is None 127 128 input contains "," --> output is set of strings split on 129 "," with leading and trailing whitespace stripped from each 130 piece and empty strings removed from the set 131 132 input contains "+" --> output is set of strings split on 133 "+" with leading and trailing whitespace stripped from each 134 piece and empty strings removed from the set 135 136 else, after stripping input of leading and trailing 137 whitespace, 138 139 input has an even length greater than two --> output is set 140 of two-character pieces 141 142 input is a non-empty string --> output is a set containing 143 input as single value 144 145 else output is an empty set. 146 147 NOTE: the complexity of this algorithm is a consequence of 148 there being several conventions in use for encoding a set 149 of instruments into one of these columns; it has been 150 proposed that L.L.W. documents standardize on the 151 comma-delimited variant of the encodings recognized by this 152 function, and for this reason the inverse function, 153 instrumentsproperty.set(), implements that encoding only. 154 155 NOTE: to force a string containing an even number of 156 characters to be interpreted as a single instrument name 157 and not to be be split into two-character pieces, add a "," 158 character to the end to force the comma-delimited decoding 159 to be used. instrumentsproperty.set() does this for you. 160 161 Example: 162 163 >>> print(instrumentsproperty.get(None)) 164 None 165 >>> instrumentsproperty.get(u"") 166 set([]) 167 >>> instrumentsproperty.get(u" , ,,") 168 set([]) 169 >>> instrumentsproperty.get(u"H1") 170 set([u'H1']) 171 >>> instrumentsproperty.get(u"SWIFT") 172 set([u'SWIFT']) 173 >>> instrumentsproperty.get(u"H1L1") 174 set([u'H1', u'L1']) 175 >>> instrumentsproperty.get(u"H1L1,") 176 set([u'H1L1']) 177 >>> instrumentsproperty.get(u"H1,L1") 178 set([u'H1', u'L1']) 179 >>> instrumentsproperty.get(u"H1+L1") 180 set([u'H1', u'L1']) 181 """ 182 if ifos is None: 183 return None 184 if u"," in ifos: 185 result = set(ifo.strip() for ifo in ifos.split(u",")) 186 result.discard(u"") 187 return result 188 if u"+" in ifos: 189 result = set(ifo.strip() for ifo in ifos.split(u"+")) 190 result.discard(u"") 191 return result 192 ifos = ifos.strip() 193 if len(ifos) > 2 and not len(ifos) % 2: 194 # if ifos is a string with an even number of 195 # characters greater than two, split it into 196 # two-character pieces. FIXME: remove this when 197 # the inspiral codes don't write ifos strings like 198 # this anymore 199 return set(ifos[n:n+2] for n in range(0, len(ifos), 2)) 200 if ifos: 201 return set([ifos]) 202 return set()
203 204 @staticmethod
205 - def set(instruments):
206 """ 207 Convert an iterable of instrument names into a value 208 suitable for storage in the "ifos" column found in many 209 tables. This function is mostly for internal use by the 210 .instruments properties of the corresponding row classes. 211 The input can be None or an iterable of zero or more 212 instrument names, none of which may be zero-length, consist 213 exclusively of spaces, or contain "," or "+" characters. 214 The output is a single string containing the unique 215 instrument names concatenated using "," as a delimiter. 216 instruments will only be iterated over once and so can be a 217 generator expression. Whitespace is allowed in instrument 218 names but might not be preserved. Repeated names will not 219 be preserved. 220 221 NOTE: in the special case that there is 1 instrument name 222 in the iterable and it has an even number of characters > 2 223 in it, the output will have a "," appended in order to 224 force instrumentsproperty.get() to parse the string back 225 into a single instrument name. This is a special case 226 included temporarily to disambiguate the encoding until all 227 codes have been ported to the comma-delimited encoding. 228 This behaviour will be discontinued at that time. DO NOT 229 WRITE CODE THAT RELIES ON THIS! You have been warned. 230 231 Example: 232 233 >>> print(instrumentsproperty.set(None)) 234 None 235 >>> instrumentsproperty.set(()) 236 u'' 237 >>> instrumentsproperty.set((u"H1",)) 238 u'H1' 239 >>> instrumentsproperty.set((u"H1",u"H1",u"H1")) 240 u'H1' 241 >>> instrumentsproperty.set((u"H1",u"L1")) 242 u'H1,L1' 243 >>> instrumentsproperty.set((u"SWIFT",)) 244 u'SWIFT' 245 >>> instrumentsproperty.set((u"H1L1",)) 246 u'H1L1,' 247 """ 248 if instruments is None: 249 return None 250 _instruments = sorted(set(instrument.strip() for instrument in instruments)) 251 # safety check: refuse to accept blank names, or names 252 # with commas or pluses in them as they cannot survive the 253 # encode/decode process 254 if not all(_instruments) or any(u"," in instrument or u"+" in instrument for instrument in _instruments): 255 raise ValueError(instruments) 256 if len(_instruments) == 1 and len(_instruments[0]) > 2 and not len(_instruments[0]) % 2: 257 # special case disambiguation. FIXME: remove when 258 # everything uses the comma-delimited encoding 259 return u"%s," % _instruments[0] 260 return u",".join(_instruments)
261
262 - def __get__(self, obj, type = None):
263 return self.get(getattr(obj, self.name))
264
265 - def __set__(self, obj, instruments):
266 setattr(obj, self.name, self.set(instruments))
267 268 269 instrument_set_from_ifos = instrumentsproperty.get 270 ifos_from_instrument_set = instrumentsproperty.set
271 272 273 -class gpsproperty(object):
274 """ 275 Descriptor used internally to implement LIGOTimeGPS-valued 276 properties. 277 """
278 - def __init__(self, s_name, ns_name):
279 self.s_name = s_name 280 self.ns_name = ns_name
281 282 posinf = 0x7FFFFFFF, 0xFFFFFFFF 283 neginf = 0xFFFFFFFF, 0xFFFFFFFF 284
285 - def __get__(self, obj, type = None):
286 s = getattr(obj, self.s_name) 287 ns = getattr(obj, self.ns_name) 288 if s is None and ns is None: 289 return None 290 if (s, ns) == self.posinf: 291 return segments.PosInfinity 292 if (s, ns) == self.neginf: 293 return segments.NegInfinity 294 return LIGOTimeGPS(s, ns)
295
296 - def __set__(self, obj, gps):
297 if gps is None: 298 s = ns = None 299 elif isinstance(gps, segments.infinity) or math.isinf(gps): 300 if gps > 0: 301 s, ns = self.posinf 302 elif gps < 0: 303 s, ns = self.neginf 304 else: 305 raise ValueError(gps) 306 else: 307 try: 308 s = gps.gpsSeconds 309 ns = gps.gpsNanoSeconds 310 except AttributeError: 311 # try converting and going again 312 return self.__set__(obj, LIGOTimeGPS(gps)) 313 if abs(ns) > 999999999: 314 raise ValueError("denormalized LIGOTimeGPS not allowed") 315 setattr(obj, self.s_name, s) 316 setattr(obj, self.ns_name, ns)
317
318 319 -class gpsproperty_with_gmst(gpsproperty):
320 - def __init__(self, s_name, ns_name, gmst_name):
321 super(gpsproperty_with_gmst, self).__init__(s_name, ns_name) 322 self.gmst_name = gmst_name
323
324 - def __set__(self, obj, gps):
325 super(gpsproperty_with_gmst, self).__set__(obj, gps) 326 if gps is None: 327 setattr(obj, self.gmst_name, None) 328 else: 329 # re-retrieve the value in case it required type 330 # conversion 331 gps = self.__get__(obj) 332 setattr(obj, self.gmst_name, lal.GreenwichMeanSiderealTime(gps))
333
334 335 -class segmentproperty(object):
336 """ 337 Descriptor used internally to expose pairs of GPS-valued properties 338 as segment-valued properties. 339 """
340 - def __init__(self, start_name, stop_name):
341 self.start = start_name 342 self.stop = stop_name
343
344 - def __get__(self, obj, type = None):
345 start = getattr(obj, self.start) 346 stop = getattr(obj, self.stop) 347 if start is None and stop is None: 348 return None 349 return segments.segment(start, stop)
350
351 - def __set__(self, obj, seg):
352 if seg is None: 353 start = stop = None 354 else: 355 start, stop = seg 356 setattr(obj, self.start, start) 357 setattr(obj, self.stop, stop)
358 359 360 # 361 # ============================================================================= 362 # 363 # process:table 364 # 365 # ============================================================================= 366 # 367 368 369 ProcessID = ilwd.get_ilwdchar_class(u"process", u"process_id")
370 371 372 -class ProcessTable(table.Table):
373 tableName = "process" 374 validcolumns = { 375 "program": "lstring", 376 "version": "lstring", 377 "cvs_repository": "lstring", 378 "cvs_entry_time": "int_4s", 379 "comment": "lstring", 380 "is_online": "int_4s", 381 "node": "lstring", 382 "username": "lstring", 383 "unix_procid": "int_4s", 384 "start_time": "int_4s", 385 "end_time": "int_4s", 386 "jobid": "int_4s", 387 "domain": "lstring", 388 "ifos": "lstring", 389 "process_id": "ilwd:char" 390 } 391 constraints = "PRIMARY KEY (process_id)" 392 next_id = ProcessID(0) 393
394 - def get_ids_by_program(self, program):
395 """ 396 Return a set containing the process IDs from rows whose 397 program string equals the given program. 398 """ 399 return set(row.process_id for row in self if row.program == program)
400
401 402 -class Process(table.Table.RowType):
403 """ 404 Example: 405 406 >>> x = Process() 407 >>> x.instruments = (u"H1", u"L1") 408 >>> x.ifos 409 u'H1,L1' 410 >>> x.instruments 411 set([u'H1', u'L1']) 412 """ 413 __slots__ = tuple(ProcessTable.validcolumns.keys()) 414 415 instruments = instrumentsproperty("ifos") 416
417 - def get_ifos(self):
418 """ 419 Return a set of the instruments for this row. 420 """ 421 return self.instruments
422
423 - def set_ifos(self, instruments):
424 """ 425 Serialize a sequence of instruments into the ifos 426 attribute. The instrument names must not contain the "," 427 character. 428 """ 429 self.instruments = instruments
430 431 432 ProcessTable.RowType = Process 433 434 435 # 436 # ============================================================================= 437 # 438 # lfn:table 439 # 440 # ============================================================================= 441 # 442 443 444 LfnID = ilwd.get_ilwdchar_class(u"lfn", u"lfn_id")
445 446 447 -class LfnTable(table.Table):
448 tableName = "lfn" 449 validcolumns = { 450 "process_id": "ilwd:char", 451 "lfn_id": "ilwd:char", 452 "name": "lstring", 453 "comment": "lstring", 454 "start_time": "int_4s", 455 "end_time": "int_4s" 456 } 457 constraints = "PRIMARY KEY (lfn_id)" 458 next_id = LfnID(0)
459
460 461 -class Lfn(table.Table.RowType):
462 __slots__ = tuple(LfnTable.validcolumns.keys())
463 464 465 LfnTable.RowType = Lfn
466 467 468 # 469 # ============================================================================= 470 # 471 # process_params:table 472 # 473 # ============================================================================= 474 # 475 476 477 -class ProcessParamsTable(table.Table):
478 tableName = "process_params" 479 validcolumns = { 480 "program": "lstring", 481 "process_id": "ilwd:char", 482 "param": "lstring", 483 "type": "lstring", 484 "value": "lstring" 485 } 486 # FIXME: these constraints break ID remapping in the DB backend. 487 # an index is used instead. switch back to the constraints when I 488 # can figure out how not to break remapping. 489 #constraints = "PRIMARY KEY (process_id, param)" 490 how_to_index = { 491 "pp_pip_index": ("process_id", "param"), 492 } 493
494 - def append(self, row):
495 if row.type is not None and row.type not in ligolwtypes.Types: 496 raise ligolw.ElementError("unrecognized type '%s'" % row.type) 497 table.Table.append(self, row)
498
499 500 -class ProcessParams(table.Table.RowType):
501 """ 502 Example: 503 504 >>> x = ProcessParams() 505 >>> x.pyvalue = u"test" 506 >>> x.type 507 u'lstring' 508 >>> x.value 509 u'test' 510 >>> x.pyvalue 511 u'test' 512 >>> x.pyvalue = 6. 513 >>> x.type 514 u'real_8' 515 >>> x.value 516 u'6' 517 >>> x.pyvalue 518 6.0 519 >>> x.pyvalue = None 520 >>> print(x.type) 521 None 522 >>> print(x.value) 523 None 524 >>> print(x.pyvalue) 525 None 526 >>> x.pyvalue = True 527 >>> x.type 528 u'int_4s' 529 >>> x.value 530 u'1' 531 >>> x.pyvalue 532 1 533 """ 534 __slots__ = tuple(ProcessParamsTable.validcolumns.keys()) 535 536 @property
537 - def pyvalue(self):
538 if self.value is None: 539 return None 540 try: 541 parsefunc = ligolwtypes.ToPyType[self.type] 542 except KeyError: 543 raise ValueError("invalid type '%s'" % self.type) 544 return parsefunc(self.value)
545 546 @pyvalue.setter
547 - def pyvalue(self, value):
548 if value is None: 549 self.type = self.value = None 550 else: 551 try: 552 self.type = ligolwtypes.FromPyType[type(value)] 553 except KeyError: 554 raise ValueError("type not supported: %s" % repr(type(value))) 555 self.value = value if self.type in ligolwtypes.StringTypes else ligolwtypes.FormatFunc[self.type](value)
556 557 558 ProcessParamsTable.RowType = ProcessParams
559 560 561 # 562 # ============================================================================= 563 # 564 # search_summary:table 565 # 566 # ============================================================================= 567 # 568 569 570 -class SearchSummaryTable(table.Table):
571 tableName = "search_summary" 572 validcolumns = { 573 "process_id": "ilwd:char", 574 "shared_object": "lstring", 575 "lalwrapper_cvs_tag": "lstring", 576 "lal_cvs_tag": "lstring", 577 "comment": "lstring", 578 "ifos": "lstring", 579 "in_start_time": "int_4s", 580 "in_start_time_ns": "int_4s", 581 "in_end_time": "int_4s", 582 "in_end_time_ns": "int_4s", 583 "out_start_time": "int_4s", 584 "out_start_time_ns": "int_4s", 585 "out_end_time": "int_4s", 586 "out_end_time_ns": "int_4s", 587 "nevents": "int_4s", 588 "nnodes": "int_4s" 589 } 590 how_to_index = { 591 "ss_pi_index": ("process_id",), 592 } 593
594 - def get_inlist(self):
595 """ 596 Return a segmentlist object describing the times spanned by 597 the input segments of all rows in the table. 598 599 Note: the result is not coalesced, the segmentlist 600 contains the segments as they appear in the table. 601 """ 602 return segments.segmentlist(row.in_segment for row in self)
603
604 - def get_outlist(self):
605 """ 606 Return a segmentlist object describing the times spanned by 607 the output segments of all rows in the table. 608 609 Note: the result is not coalesced, the segmentlist 610 contains the segments as they appear in the table. 611 """ 612 return segments.segmentlist(row.out_segment for row in self)
613
614 - def get_in_segmentlistdict(self, process_ids = None):
615 """ 616 Return a segmentlistdict mapping instrument to in segment 617 list. If process_ids is a sequence of process IDs, then 618 only rows with matching IDs are included otherwise all rows 619 are included. 620 621 Note: the result is not coalesced, each segmentlist 622 contains the segments listed for that instrument as they 623 appeared in the table. 624 """ 625 seglists = segments.segmentlistdict() 626 for row in self: 627 ifos = row.instruments or (None,) 628 if process_ids is None or row.process_id in process_ids: 629 seglists.extend(dict((ifo, segments.segmentlist([row.in_segment])) for ifo in ifos)) 630 return seglists
631
632 - def get_out_segmentlistdict(self, process_ids = None):
633 """ 634 Return a segmentlistdict mapping instrument to out segment 635 list. If process_ids is a sequence of process IDs, then 636 only rows with matching IDs are included otherwise all rows 637 are included. 638 639 Note: the result is not coalesced, each segmentlist 640 contains the segments listed for that instrument as they 641 appeared in the table. 642 """ 643 seglists = segments.segmentlistdict() 644 for row in self: 645 ifos = row.instruments or (None,) 646 if process_ids is None or row.process_id in process_ids: 647 seglists.extend(dict((ifo, segments.segmentlist([row.out_segment])) for ifo in ifos)) 648 return seglists
649
650 651 -class SearchSummary(table.Table.RowType):
652 """ 653 Example: 654 655 >>> x = SearchSummary() 656 >>> x.instruments = (u"H1", u"L1") 657 >>> x.ifos 658 u'H1,L1' 659 >>> x.instruments 660 set([u'H1', u'L1']) 661 >>> x.in_start = x.out_start = LIGOTimeGPS(0) 662 >>> x.in_end = x.out_end = LIGOTimeGPS(10) 663 >>> x.in_segment 664 segment(LIGOTimeGPS(0, 0), LIGOTimeGPS(10, 0)) 665 >>> x.out_segment 666 segment(LIGOTimeGPS(0, 0), LIGOTimeGPS(10, 0)) 667 >>> x.in_segment = x.out_segment = None 668 >>> print(x.in_segment) 669 None 670 >>> print(x.out_segment) 671 None 672 """ 673 __slots__ = tuple(SearchSummaryTable.validcolumns.keys()) 674 675 instruments = instrumentsproperty("ifos") 676 677 in_start = gpsproperty("in_start_time", "in_start_time_ns") 678 in_end = gpsproperty("in_end_time", "in_end_time_ns") 679 out_start = gpsproperty("out_start_time", "out_start_time_ns") 680 out_end = gpsproperty("out_end_time", "out_end_time_ns") 681 682 in_segment = segmentproperty("in_start", "in_end") 683 out_segment = segmentproperty("out_start", "out_end") 684
685 - def get_ifos(self):
686 """ 687 Return a set of the instruments for this row. 688 """ 689 return self.instruments
690
691 - def set_ifos(self, instruments):
692 """ 693 Serialize a sequence of instruments into the ifos 694 attribute. The instrument names must not contain the "," 695 character. 696 """ 697 self.instruments = instruments
698
699 - def get_in(self):
700 """ 701 Get the input segment. 702 """ 703 return self.in_segment
704
705 - def set_in(self, seg):
706 """ 707 Set the input segment. 708 """ 709 self.in_segment = seg
710
711 - def get_out(self):
712 """ 713 Get the output segment. 714 """ 715 return self.out_segment
716
717 - def set_out(self, seg):
718 """ 719 Set the output segment. 720 """ 721 self.out_segment = seg
722 723 724 SearchSummaryTable.RowType = SearchSummary 725 726 727 # 728 # ============================================================================= 729 # 730 # search_summvars:table 731 # 732 # ============================================================================= 733 # 734 735 736 SearchSummVarsID = ilwd.get_ilwdchar_class(u"search_summvars", u"search_summvar_id")
737 738 739 -class SearchSummVarsTable(table.Table):
740 tableName = "search_summvars" 741 validcolumns = { 742 "process_id": "ilwd:char", 743 "search_summvar_id": "ilwd:char", 744 "name": "lstring", 745 "string": "lstring", 746 "value": "real_8" 747 } 748 constraints = "PRIMARY KEY (search_summvar_id)" 749 next_id = SearchSummVarsID(0)
750
751 752 -class SearchSummVars(table.Table.RowType):
753 __slots__ = tuple(SearchSummVarsTable.validcolumns.keys())
754 755 756 SearchSummVarsTable.RowType = SearchSummVars 757 758 759 # 760 # ============================================================================= 761 # 762 # experiment:table 763 # 764 # ============================================================================= 765 # 766 767 768 ExpDefID = ilwd.get_ilwdchar_class(u"experiment", u"experiment_id")
769 770 771 -class ExperimentTable(table.Table):
772 tableName = "experiment" 773 validcolumns = { 774 "experiment_id": "ilwd:char", 775 "search_group": "lstring", 776 "search": "lstring", 777 "lars_id": "lstring", 778 "instruments": "lstring", 779 "gps_start_time": "int_4s", 780 "gps_end_time": "int_4s", 781 "comments": "lstring" 782 } 783 constraints = "PRIMARY KEY (experiment_id)" 784 next_id = ExpDefID(0) 785
786 - def get_expr_id(self, search_group, search, lars_id, instruments, gps_start_time, gps_end_time, comments = None):
787 """ 788 Return the expr_def_id for the row in the table whose 789 values match the givens. 790 If a matching row is not found, returns None. 791 792 @search_group: string representing the search group (e.g., cbc) 793 @serach: string representing search (e.g., inspiral) 794 @lars_id: string representing lars_id 795 @instruments: the instruments; must be a python set 796 @gps_start_time: string or int representing the gps_start_time of the experiment 797 @gps_end_time: string or int representing the gps_end_time of the experiment 798 """ 799 # create string from instrument set 800 instruments = ifos_from_instrument_set(instruments) 801 802 # look for the ID 803 for row in self: 804 if (row.search_group, row.search, row.lars_id, row.instruments, row.gps_start_time, row.gps_end_time, row.comments) == (search_group, search, lars_id, instruments, gps_start_time, gps_end_time, comments): 805 # found it 806 return row.experiment_id 807 808 # experiment not found in table 809 return None
810
811 - def write_new_expr_id(self, search_group, search, lars_id, instruments, gps_start_time, gps_end_time, comments = None):
812 """ 813 Creates a new def_id for the given arguments and returns it. 814 If an entry already exists with these, will just return that id. 815 816 @search_group: string representing the search group (e.g., cbc) 817 @serach: string representing search (e.g., inspiral) 818 @lars_id: string representing lars_id 819 @instruments: the instruments; must be a python set 820 @gps_start_time: string or int representing the gps_start_time of the experiment 821 @gps_end_time: string or int representing the gps_end_time of the experiment 822 """ 823 824 # check if id already exists 825 check_id = self.get_expr_id( search_group, search, lars_id, instruments, gps_start_time, gps_end_time, comments = comments ) 826 if check_id: 827 return check_id 828 829 # experiment not found in table 830 row = self.RowType() 831 row.experiment_id = self.get_next_id() 832 row.search_group = search_group 833 row.search = search 834 row.lars_id = lars_id 835 row.instruments = ifos_from_instrument_set(instruments) 836 row.gps_start_time = gps_start_time 837 row.gps_end_time = gps_end_time 838 row.comments = comments 839 self.append(row) 840 841 # return new ID 842 return row.experiment_id
843
844 - def get_row_from_id(self, experiment_id):
845 """ 846 Returns row in matching the given experiment_id. 847 """ 848 row = [row for row in self if row.experiment_id == experiment_id] 849 if len(row) > 1: 850 raise ValueError("duplicate ids in experiment table") 851 if len(row) == 0: 852 raise ValueError("id '%s' not found in table" % experiment_id) 853 854 return row[0]
855
856 857 -class Experiment(table.Table.RowType):
858 __slots__ = tuple(ExperimentTable.validcolumns.keys()) 859
860 - def get_instruments(self):
861 """ 862 Return a set of the instruments for this row. 863 """ 864 return instrument_set_from_ifos(self.instruments)
865
866 - def set_instruments(self, instruments):
867 """ 868 Serialize a sequence of instruments into the ifos 869 attribute. The instrument names must not contain the "," 870 character. 871 """ 872 self.instruments = ifos_from_instrument_set(instruments)
873 874 875 ExperimentTable.RowType = Experiment 876 877 878 # 879 # ============================================================================= 880 # 881 # experiment_summary:table 882 # 883 # ============================================================================= 884 # 885 886 887 ExpSummID = ilwd.get_ilwdchar_class(u"experiment_summary", u"experiment_summ_id")
888 889 890 -class ExperimentSummaryTable(table.Table):
891 tableName = "experiment_summary" 892 validcolumns = { 893 "experiment_summ_id": "ilwd:char", 894 "experiment_id": "ilwd:char", 895 "time_slide_id": "ilwd:char", 896 "veto_def_name": "lstring", 897 "datatype": "lstring", 898 "sim_proc_id": "ilwd:char", 899 "duration": "int_4s", 900 "nevents": "int_4u" 901 } 902 constraints = "PRIMARY KEY (experiment_summ_id)" 903 how_to_index = { 904 "es_ei_index": ("experiment_id",), 905 "es_dt_index": ("datatype",) 906 } 907 next_id = ExpSummID(0) 908 909 datatypes = ['slide', 'all_data', 'playground', 'exclude_play', 'simulation'] 910 911
912 - def as_id_dict(self):
913 """ 914 Return table as a dictionary mapping experiment_id, time_slide_id, 915 veto_def_name, and sim_proc_id (if it exists) to the expr_summ_id. 916 """ 917 d = {} 918 for row in self: 919 if row.experiment_id not in d: 920 d[row.experiment_id] = {} 921 if (row.time_slide_id, row.veto_def_name, row.datatype, row.sim_proc_id) in d[row.experiment_id]: 922 # entry already exists, raise error 923 raise KeyError("duplicate entries in experiment_summary table") 924 d[row.experiment_id][(row.time_slide_id, row.veto_def_name, row.datatype, row.sim_proc_id)] = row.experiment_summ_id 925 926 return d
927
928 - def get_expr_summ_id(self, experiment_id, time_slide_id, veto_def_name, datatype, sim_proc_id = None):
929 """ 930 Return the expr_summ_id for the row in the table whose experiment_id, 931 time_slide_id, veto_def_name, and datatype match the given. If sim_proc_id, 932 will retrieve the injection run matching that sim_proc_id. 933 If a matching row is not found, returns None. 934 """ 935 936 # look for the ID 937 for row in self: 938 if (row.experiment_id, row.time_slide_id, row.veto_def_name, row.datatype, row.sim_proc_id) == (experiment_id, time_slide_id, veto_def_name, datatype, sim_proc_id): 939 # found it 940 return row.experiment_summ_id 941 942 # if get to here, experiment not found in table 943 return None
944
945 - def write_experiment_summ(self, experiment_id, time_slide_id, veto_def_name, datatype, sim_proc_id = None ):
946 """ 947 Writes a single entry to the experiment_summ table. This can be used 948 for either injections or non-injection experiments. However, it is 949 recommended that this only be used for injection experiments; for 950 non-injection experiments write_experiment_summ_set should be used to 951 ensure that an entry gets written for every time-slide performed. 952 """ 953 # check if entry alredy exists; if so, return value 954 check_id = self.get_expr_summ_id(experiment_id, time_slide_id, veto_def_name, datatype, sim_proc_id = sim_proc_id) 955 if check_id: 956 return check_id 957 958 row = self.RowType() 959 row.experiment_summ_id = self.get_next_id() 960 row.experiment_id = experiment_id 961 row.time_slide_id = time_slide_id 962 row.veto_def_name = veto_def_name 963 row.datatype = datatype 964 row.sim_proc_id = sim_proc_id 965 row.nevents = None 966 row.duration = None 967 self.append(row) 968 969 return row.experiment_summ_id
970
971 - def write_non_injection_summary(self, experiment_id, time_slide_dict, veto_def_name, write_all_data = True, write_playground = True, write_exclude_play = True, return_dict = False):
972 """ 973 Method for writing a new set of non-injection experiments to the experiment 974 summary table. This ensures that for every entry in the 975 experiment table, an entry for every slide is added to 976 the experiment_summ table, rather than just an entry for slides that 977 have events in them. Default is to write a 3 rows for zero-lag: one for 978 all_data, playground, and exclude_play. (If all of these are set to false, 979 will only slide rows.) 980 981 Note: sim_proc_id is hard-coded to None because time-slides 982 are not performed with injections. 983 984 @experiment_id: the experiment_id for this experiment_summary set 985 @time_slide_dict: the time_slide table as a dictionary; used to figure out 986 what is zero-lag and what is slide 987 @veto_def_name: the name of the vetoes applied 988 @write_all_data: if set to True, writes a zero-lag row who's datatype column 989 is set to 'all_data' 990 @write_playground: same, but datatype is 'playground' 991 @write_exclude_play: same, but datatype is 'exclude_play' 992 @return_dict: if set to true, returns an id_dict of the table 993 """ 994 for slide_id in time_slide_dict: 995 # check if it's zero_lag or not 996 if not any( time_slide_dict[slide_id].values() ): 997 if write_all_data: 998 self.write_experiment_summ( experiment_id, slide_id, veto_def_name, 'all_data', sim_proc_id = None ) 999 if write_playground: 1000 self.write_experiment_summ( experiment_id, slide_id, veto_def_name, 'playground', sim_proc_id = None ) 1001 if write_exclude_play: 1002 self.write_experiment_summ( experiment_id, slide_id, veto_def_name, 'exclude_play', sim_proc_id = None ) 1003 else: 1004 self.write_experiment_summ( experiment_id, slide_id, veto_def_name, 'slide', sim_proc_id = None ) 1005 1006 if return_dict: 1007 return self.as_id_dict()
1008 1009
1010 - def add_nevents(self, experiment_summ_id, num_events, add_to_current = True):
1011 """ 1012 Add num_events to the nevents column in a specific entry in the table. If 1013 add_to_current is set to False, will overwrite the current nevents entry in 1014 the row with num_events. Otherwise, default is to add num_events to 1015 the current value. 1016 1017 Note: Can subtract events by passing a negative number to num_events. 1018 """ 1019 for row in self: 1020 if row.experiment_summ_id != experiment_summ_id: 1021 continue 1022 if row.nevents is None: 1023 row.nevents = 0 1024 if add_to_current: 1025 row.nevents += num_events 1026 return row.nevents 1027 else: 1028 row.nevents = num_events 1029 return row.nevents 1030 1031 # if get to here, couldn't find experiment_summ_id in the table 1032 raise ValueError("'%s' could not be found in the table" % (str(experiment_summ_id)))
1033
1034 1035 -class ExperimentSummary(table.Table.RowType):
1036 __slots__ = tuple(ExperimentSummaryTable.validcolumns.keys())
1037 1038 1039 ExperimentSummaryTable.RowType = ExperimentSummary
1040 1041 1042 # 1043 # ============================================================================= 1044 # 1045 # experiment_map:table 1046 # 1047 # ============================================================================= 1048 # 1049 1050 1051 -class ExperimentMapTable(table.Table):
1052 tableName = "experiment_map" 1053 validcolumns = { 1054 "experiment_summ_id": "ilwd:char", 1055 "coinc_event_id": "ilwd:char", 1056 } 1057 how_to_index = { 1058 "em_esi_index": ("experiment_summ_id",), 1059 "em_cei_index": ("coinc_event_id",) 1060 } 1061
1062 - def get_experiment_summ_ids( self, coinc_event_id ):
1063 """ 1064 Gets all the experiment_summ_ids that map to a given coinc_event_id. 1065 """ 1066 experiment_summ_ids = [] 1067 for row in self: 1068 if row.coinc_event_id == coinc_event_id: 1069 experiment_summ_ids.append(row.experiment_summ_id) 1070 if len(experiment_summ_ids) == 0: 1071 raise ValueError("'%s' could not be found in the experiment_map table" % coinc_event_id) 1072 return experiment_summ_ids
1073
1074 1075 -class ExperimentMap(table.Table.RowType):
1076 __slots__ = tuple(ExperimentMapTable.validcolumns.keys())
1077 1078 1079 ExperimentMapTable.RowType = ExperimentMap 1080 1081 1082 # 1083 # ============================================================================= 1084 # 1085 # gds_trigger:table 1086 # 1087 # ============================================================================= 1088 # 1089 1090 1091 GDSTriggerID = ilwd.get_ilwdchar_class(u"gds_trigger", u"event_id")
1092 1093 -class GDSTriggerTable(table.Table):
1094 tableName = "gds_trigger" 1095 validcolumns = { 1096 "creator_db": "int_4s", 1097 "process_id": "ilwd:char_u", 1098 "filter_id": "ilwd:char", 1099 "name": "lstring", 1100 "subtype": "lstring", 1101 "ifo": "lstring", 1102 "start_time": "int_4s", 1103 "start_time_ns": "int_4s", 1104 "duration": "real_4", 1105 "priority": "int_4s", 1106 "disposition": "int_4s", 1107 "size": "real_4", 1108 "significance": "real_4", 1109 "frequency": "real_4", 1110 "bandwidth": "real_4", 1111 "time_peak": "real_4", 1112 "time_average": "real_4", 1113 "time_sigma": "real_4", 1114 "freq_peak": "real_4", 1115 "freq_average": "real_4", 1116 "freq_sigma": "real_4", 1117 "noise_power": "real_4", 1118 "signal_power": "real_4", 1119 "pixel_count": "int_4s", 1120 "confidence": "real_4", 1121 "binarydata": "ilwd:char_u", 1122 "binarydata_length": "int_4s", 1123 "event_id": "ilwd:char" 1124 } 1125 constraints = "PRIMARY KEY (event_id)" 1126 next_id = GDSTriggerID(0) 1127 interncolumns = ("process_id", "ifo", "subtype")
1128
1129 1130 -class GDSTrigger(table.Table.RowType):
1131 __slots__ = tuple(GDSTriggerTable.validcolumns.keys()) 1132 1133 # 1134 # Tile properties 1135 # 1136
1137 - def get_start(self):
1138 return LIGOTimeGPS(self.start_time, self.start_time_ns)
1139
1140 - def set_start(self, gps):
1141 self.start_time, self.start_time_ns = gps.seconds, gps.nanoseconds
1142
1143 - def get_stop(self):
1144 return LIGOTimeGPS(self.start_time, self.start_time_ns) + self.duration
1145
1146 - def get_peak(self):
1147 return LIGOTimeGPS(self.time_peak, self.time_peak)
1148
1149 - def set_peak(self, gps):
1150 self.time_peak, self.peak_time_ns = gps.seconds, gps.nanoseconds
1151
1152 - def get_period(self):
1153 start = LIGOTimeGPS(self.start_time, self.start_time_ns) 1154 return segments.segment(start, start + self.duration)
1155
1156 - def set_period(self, period):
1157 self.start_time, self.start_time_ns = period[0].seconds, period[0].nanoseconds 1158 self.duration = float(abs(period))
1159
1160 - def get_band(self):
1161 low = self.frequency 1162 return segments.segment(low, low + self.bandwidth)
1163
1164 - def set_band(self, band):
1165 self.frequency = band[0] 1166 self.bandwidth = abs(band)
1167 1168 GDSTriggerTable.RowType = GDSTrigger 1169 1170 1171 # 1172 # ============================================================================= 1173 # 1174 # sngl_burst:table 1175 # 1176 # ============================================================================= 1177 # 1178 1179 1180 SnglBurstID = ilwd.get_ilwdchar_class(u"sngl_burst", u"event_id")
1181 1182 1183 -class SnglBurstTable(table.Table):
1184 tableName = "sngl_burst" 1185 validcolumns = { 1186 "creator_db": "int_4s", 1187 "process_id": "ilwd:char", 1188 "filter_id": "ilwd:char", 1189 "ifo": "lstring", 1190 "search": "lstring", 1191 "channel": "lstring", 1192 "start_time": "int_4s", 1193 "start_time_ns": "int_4s", 1194 "stop_time": "int_4s", 1195 "stop_time_ns": "int_4s", 1196 "duration": "real_4", 1197 "flow": "real_4", 1198 "fhigh": "real_4", 1199 "central_freq": "real_4", 1200 "bandwidth": "real_4", 1201 "amplitude": "real_4", 1202 "snr": "real_4", 1203 "confidence": "real_4", 1204 "chisq": "real_8", 1205 "chisq_dof": "real_8", 1206 "tfvolume": "real_4", 1207 "hrss": "real_4", 1208 "time_lag": "real_4", 1209 "peak_time": "int_4s", 1210 "peak_time_ns": "int_4s", 1211 "peak_frequency": "real_4", 1212 "peak_strain": "real_4", 1213 "peak_time_error": "real_4", 1214 "peak_frequency_error": "real_4", 1215 "peak_strain_error": "real_4", 1216 "ms_start_time": "int_4s", 1217 "ms_start_time_ns": "int_4s", 1218 "ms_stop_time": "int_4s", 1219 "ms_stop_time_ns": "int_4s", 1220 "ms_duration": "real_4", 1221 "ms_flow": "real_4", 1222 "ms_fhigh": "real_4", 1223 "ms_bandwidth": "real_4", 1224 "ms_hrss": "real_4", 1225 "ms_snr": "real_4", 1226 "ms_confidence": "real_4", 1227 "param_one_name": "lstring", 1228 "param_one_value": "real_8", 1229 "param_two_name": "lstring", 1230 "param_two_value": "real_8", 1231 "param_three_name": "lstring", 1232 "param_three_value": "real_8", 1233 "event_id": "ilwd:char" 1234 } 1235 constraints = "PRIMARY KEY (event_id)" 1236 next_id = SnglBurstID(0) 1237 interncolumns = ("process_id", "ifo", "search", "channel") 1238
1239 - def get_column(self, column):
1240 """@returns: an array of column values for each row in the table 1241 1242 @param column: 1243 name of column to return 1244 @returntype: 1245 numpy.ndarray 1246 """ 1247 if column.lower() == 'q': 1248 return self.get_q 1249 else: 1250 return self.getColumnByName(column).asarray()
1251
1252 - def get_peak(self):
1253 """@returns: the peak time of each row in the table 1254 @returntype: numpy.ndarray 1255 """ 1256 return numpy.asarray([row.get_peak() for row in self])
1257
1258 - def get_start(self):
1259 """@returns: the start time of each row in the table 1260 @returntype: numpy.ndarray 1261 """ 1262 return numpy.asarray([row.get_start() for row in self])
1263
1264 - def get_ms_start(self):
1265 """@returns: the start time of the most significant tile for 1266 each row in the table 1267 @returntype: numpy.ndarray 1268 """ 1269 return numpy.asarray([row.get_ms_start() for row in self])
1270
1271 - def get_stop(self):
1272 """@returns: the stop time of each row in the table 1273 @returntype: numpy.ndarray 1274 """ 1275 return numpy.asarray([row.get_stop() for row in self])
1276
1277 - def get_ms_stop(self):
1278 """@returns: the stop time of the most significant tile for 1279 each row in the table 1280 @returntype: numpy.ndarray 1281 """ 1282 return numpy.asarray([row.get_ms_stop() for row in self])
1283
1284 - def get_q(self):
1285 """@returns: the Q of each row in the table 1286 @returntype: numpy.ndarray 1287 """ 1288 return numpy.asarray([row.get_q() for row in self])
1289
1290 - def get_z(self):
1291 """@returns: the Z (Omega-Pipeline energy) of each row in the 1292 table 1293 @returntype: numpy.ndarray 1294 """ 1295 return numpy.asarray([row.get_z() for row in self])
1296
1297 - def get_period(self):
1298 """@returns: the period segment of each row in the table 1299 @returntype: glue.segments.segmentlist 1300 """ 1301 return segments.segmentlist([row.get_period() for row in self])
1302
1303 - def get_ms_period(self):
1304 """@returns: the period segment for the most significant tile 1305 of each row in the table 1306 @returntype: glue.segments.segmentlist 1307 """ 1308 return segments.segmentlist([row.get_ms_period() for row in self])
1309
1310 - def get_band(self):
1311 """@returns: the frequency band of each row in the table 1312 @returntype: glue.segments.segmentlist 1313 """ 1314 return segments.segmentlist([row.get_band() for row in self])
1315
1316 - def get_ms_band(self):
1317 """@returns: the frequency band of the most significant tile 1318 for each row in the table 1319 """ 1320 return segments.segmentlist([row.get_ms_band() for row in self])
1321
1322 - def veto(self, seglist):
1323 """@returns: those rows of the table that don't lie within a 1324 given seglist 1325 """ 1326 keep = self.copy() 1327 for row in self: 1328 time = row.get_peak() 1329 if time not in seglist: 1330 keep.append(row) 1331 return keep
1332
1333 - def vetoed(self, seglist):
1334 """@returns: those rows of the table that lie within a given 1335 seglist 1336 """ 1337 vetoed = self.copy() 1338 for row in self: 1339 time = row.get_peak() 1340 if time in seglist: 1341 vetoed.append(row) 1342 return vetoed
1343
1344 - def veto_seglistdict(self, seglistdict):
1345 keep = self.copy() 1346 for row in self: 1347 time = row.get_peak() 1348 if time not in seglistdict[row.ifo]: 1349 keep.append(row) 1350 return keep
1351
1352 - def vetoed_seglistdict(self, seglistdict):
1353 vetoed = self.copy() 1354 for row in self: 1355 time = row.get_peak() 1356 if time in seglistdict[row.ifo]: 1357 vetoed.append(row) 1358 return vetoed
1359
1360 1361 -class SnglBurst(table.Table.RowType):
1362 __slots__ = tuple(SnglBurstTable.validcolumns.keys()) 1363 1364 # 1365 # Tile properties 1366 # 1367 1368 start = gpsproperty("start_time", "start_time_ns") 1369 stop = gpsproperty("stop_time", "stop_time_ns") 1370 peak = gpsproperty("peak_time", "peak_time_ns") 1371 1372 @property
1373 - def period(self):
1374 start = self.start 1375 try: 1376 stop = self.stop 1377 except AttributeError: 1378 stop = None 1379 # special case: use duration if stop is not recorded 1380 if start is not None and stop is None and self.duration is not None: 1381 stop = start + self.duration 1382 if start is None and stop is None: 1383 return None 1384 return segments.segment(start, stop)
1385 1386 @period.setter
1387 - def period(self, seg):
1388 if seg is None: 1389 self.start = self.stop = self.duration = None 1390 else: 1391 self.start, self.stop = seg 1392 self.duration = float(abs(seg))
1393 1394 @property
1395 - def band(self):
1396 if self.central_freq is None and self.bandwidth is None: 1397 return None 1398 return segments.segment(self.central_freq - self.bandwidth / 2., self.central_freq + self.bandwidth / 2.)
1399 1400 @band.setter
1401 - def band(self, seg):
1402 if seg is None: 1403 try: 1404 self.flow = self.fhigh = None 1405 except AttributeError: 1406 # not in LAL C version 1407 pass 1408 self.central_freq = self.bandwidth = None 1409 else: 1410 try: 1411 self.flow, self.fhigh = seg 1412 except AttributeError: 1413 # not in LAL C version 1414 pass 1415 self.central_freq = sum(seg) / 2. 1416 self.bandwidth = abs(seg)
1417 1418 # 1419 # "Most significant pixel" properties 1420 # 1421 1422 ms_start = gpsproperty("ms_start_time", "ms_start_time_ns") 1423 ms_stop = gpsproperty("ms_stop_time", "ms_stop_time_ns") 1424 ms_peak = gpsproperty("ms_peak_time", "ms_peak_time_ns") 1425 1426 @property
1427 - def ms_period(self):
1428 start = self.ms_start 1429 stop = self.ms_stop 1430 # special case: use duration if stop is not recorded 1431 if start is not None and stop is None and self.ms-duration is not None: 1432 stop = start + self.ms_duration 1433 if start is None and stop is None: 1434 return None 1435 return segments.segment(start, stop)
1436 1437 @ms_period.setter
1438 - def ms_period(self, seg):
1439 if seg is None: 1440 self.ms_start = self.ms_stop = self.ms_duration = None 1441 else: 1442 self.ms_start, self.ms_stop = seg 1443 self.ms_duration = float(abs(seg))
1444 1445 @property
1446 - def ms_band(self):
1447 if self.ms_flow is None and self.ms_bandwidth is None: 1448 return None 1449 return segments.segment(self.ms_flow, self.ms_flow + self.ms_bandwidth)
1450 1451 @ms_band.setter
1452 - def ms_band(self, seg):
1453 if seg is None: 1454 self.ms_bandwidth = self.ms_flow = self.ms_fhigh = None 1455 else: 1456 self.ms_flow, self.ms_fhigh = seg 1457 self.ms_bandwidth = abs(seg)
1458 1459 # legacy compatibility. DO NOT USE 1460
1461 - def get_start(self):
1462 return self.start
1463
1464 - def set_start(self, gps):
1465 self.start = gps
1466
1467 - def get_stop(self):
1468 return self.stop
1469
1470 - def set_stop(self, gps):
1471 self.stop = gps
1472
1473 - def get_peak(self):
1474 return self.peak
1475
1476 - def set_peak(self, gps):
1477 self.peak = gps
1478
1479 - def get_period(self):
1480 return self.period
1481
1482 - def set_period(self, period):
1483 self.period = period
1484
1485 - def get_band(self):
1486 return self.band
1487
1488 - def set_band(self, band):
1489 self.band = band
1490
1491 - def get_ms_start(self):
1492 return self.ms_start
1493
1494 - def set_ms_start(self, gps):
1495 self.ms_start = gps
1496
1497 - def get_ms_stop(self):
1498 return self.ms_stop
1499
1500 - def set_ms_stop(self, gps):
1501 self.ms_stop = gps
1502
1503 - def get_ms_period(self):
1504 return self.ms_period
1505
1506 - def set_ms_period(self, period):
1507 self.ms_period = period
1508
1509 - def get_ms_band(self):
1510 return self.ms_band
1511
1512 - def set_ms_band(self, band):
1513 self.ms_band = band
1514 1515 # 1516 # Omega-Pipeline properties 1517 # 1518
1519 - def get_q(self):
1520 return self.duration * 2 * numpy.pi**(1/2.) * self.central_freq
1521
1522 - def get_z(self):
1523 return self.snr ** 2 / 2.
1524 1525 1526 SnglBurstTable.RowType = SnglBurst
1527 1528 1529 # 1530 # ============================================================================= 1531 # 1532 # multi_burst:table 1533 # 1534 # ============================================================================= 1535 # 1536 1537 1538 # 1539 # FIXME: I think extra columns have been added here that aren't in other 1540 # places where this table is defined. 1541 # 1542 1543 1544 -class MultiBurstTable(table.Table):
1545 tableName = "multi_burst" 1546 validcolumns = { 1547 "creator_db": "int_4s", 1548 "process_id": "ilwd:char", 1549 "filter_id": "ilwd:char", 1550 "ifos": "lstring", 1551 "start_time": "int_4s", 1552 "start_time_ns": "int_4s", 1553 "duration": "real_4", 1554 "peak_time": "int_4s", 1555 "peak_time_ns": "int_4s", 1556 "central_freq": "real_4", 1557 "bandwidth": "real_4", 1558 "amplitude": "real_4", 1559 "snr": "real_4", 1560 "confidence": "real_4", 1561 "false_alarm_rate": "real_4", 1562 "ligo_axis_ra": "real_4", 1563 "ligo_axis_dec": "real_4", 1564 "ligo_angle": "real_4", 1565 "ligo_angle_sig": "real_4", 1566 "coinc_event_id": "ilwd:char" 1567 } 1568 # FIXME: like some other tables here, this table should have the 1569 # constraint that the coinc_event_id column is a primary key. this 1570 # breaks ID reassignment in ligolw_sqlite, so until that is fixed 1571 # the constraint is being replaced with an index. 1572 #constraints = "PRIMARY KEY (coinc_event_id)" 1573 how_to_index = { 1574 "mb_cei_index": ("coinc_event_id",) 1575 }
1576
1577 1578 -class MultiBurst(table.Table.RowType):
1579 __slots__ = tuple(MultiBurstTable.validcolumns.keys()) 1580 1581 instruments = instrumentsproperty("ifos") 1582 1583 start = gpsproperty("start_time", "start_time_ns") 1584 peak = gpsproperty("peak_time", "peak_time_ns") 1585 1586 @property
1587 - def period(self):
1588 start = self.start 1589 if start is None and self.duration is None: 1590 return None 1591 return segments.segment(start, start + self.duration)
1592 1593 @period.setter
1594 - def period(self, seg):
1595 if seg is None: 1596 self.start = self.duration = None 1597 else: 1598 self.start = seg[0] 1599 self.duration = float(abs(seg))
1600 1601 @property
1602 - def band(self):
1603 if self.central_freq is None and self.bandwidth is None: 1604 return None 1605 return segments.segment(self.central_freq - self.bandwidth / 2., self.central_freq + self.bandwidth / 2.)
1606 1607 @band.setter
1608 - def band(self, seg):
1609 if seg is None: 1610 self.central_freq = self.bandwidth = None 1611 else: 1612 self.central_freq = sum(seg) / 2. 1613 self.bandwidth = abs(seg)
1614 1615 # legacy compatibility. DO NOT USE 1616
1617 - def get_ifos(self):
1618 return self.instruments
1619
1620 - def set_ifos(self, instruments):
1622
1623 - def get_peak(self):
1624 return self.peak
1625
1626 - def set_peak(self, gps):
1627 self.peak = gps
1628 1629 1630 MultiBurstTable.RowType = MultiBurst 1631 1632 1633 # 1634 # ============================================================================= 1635 # 1636 # sngl_inspiral:table 1637 # 1638 # ============================================================================= 1639 # 1640 1641 1642 SnglInspiralID = ilwd.get_ilwdchar_class(u"sngl_inspiral", u"event_id")
1643 1644 1645 -class SnglInspiralTable(table.Table):
1646 tableName = "sngl_inspiral" 1647 validcolumns = { 1648 "process_id": "ilwd:char", 1649 "ifo": "lstring", 1650 "search": "lstring", 1651 "channel": "lstring", 1652 "end_time": "int_4s", 1653 "end_time_ns": "int_4s", 1654 "end_time_gmst": "real_8", 1655 "impulse_time": "int_4s", 1656 "impulse_time_ns": "int_4s", 1657 "template_duration": "real_8", 1658 "event_duration": "real_8", 1659 "amplitude": "real_4", 1660 "eff_distance": "real_4", 1661 "coa_phase": "real_4", 1662 "mass1": "real_4", 1663 "mass2": "real_4", 1664 "mchirp": "real_4", 1665 "mtotal": "real_4", 1666 "eta": "real_4", 1667 "kappa": "real_4", 1668 "chi": "real_4", 1669 "tau0": "real_4", 1670 "tau2": "real_4", 1671 "tau3": "real_4", 1672 "tau4": "real_4", 1673 "tau5": "real_4", 1674 "ttotal": "real_4", 1675 "psi0": "real_4", 1676 "psi3": "real_4", 1677 "alpha": "real_4", 1678 "alpha1": "real_4", 1679 "alpha2": "real_4", 1680 "alpha3": "real_4", 1681 "alpha4": "real_4", 1682 "alpha5": "real_4", 1683 "alpha6": "real_4", 1684 "beta": "real_4", 1685 "f_final": "real_4", 1686 "snr": "real_4", 1687 "chisq": "real_4", 1688 "chisq_dof": "int_4s", 1689 "bank_chisq": "real_4", 1690 "bank_chisq_dof": "int_4s", 1691 "cont_chisq": "real_4", 1692 "cont_chisq_dof": "int_4s", 1693 "sigmasq": "real_8", 1694 "rsqveto_duration": "real_4", 1695 "Gamma0": "real_4", 1696 "Gamma1": "real_4", 1697 "Gamma2": "real_4", 1698 "Gamma3": "real_4", 1699 "Gamma4": "real_4", 1700 "Gamma5": "real_4", 1701 "Gamma6": "real_4", 1702 "Gamma7": "real_4", 1703 "Gamma8": "real_4", 1704 "Gamma9": "real_4", 1705 "spin1x": "real_4", 1706 "spin1y": "real_4", 1707 "spin1z": "real_4", 1708 "spin2x": "real_4", 1709 "spin2y": "real_4", 1710 "spin2z": "real_4", 1711 "event_id": "ilwd:char" 1712 } 1713 constraints = "PRIMARY KEY (event_id)" 1714 # FIXME: lal uses an ID of 0 to indicate "no valid ID has been 1715 # set", so we start at 1 for safety, but eventually that should be 1716 # fixed in LAL and then this can be put back to 0 for cleanliness. 1717 next_id = SnglInspiralID(1) 1718 interncolumns = ("process_id", "ifo", "search", "channel") 1719
1720 - def get_column(self,column,fac=250.,index=6.):
1721 if column == 'reduced_chisq': 1722 return self.get_reduced_chisq() 1723 if column == 'reduced_bank_chisq': 1724 return self.get_reduced_bank_chisq() 1725 if column == 'reduced_cont_chisq': 1726 return self.get_reduced_cont_chisq() 1727 if column == 'snr_over_chi': 1728 return self.get_snr_over_chi() 1729 if column == 'effective_snr': 1730 return self.get_effective_snr(fac=fac) 1731 if column == 'new_snr': 1732 return self.get_new_snr(index=index) 1733 if column == 'lvS5stat': 1734 return self.get_lvS5stat() 1735 elif column == 'chirp_eff_distance': 1736 return self.get_chirp_eff_dist() 1737 else: 1738 return self.getColumnByName(column).asarray()
1739
1740 - def get_end(self):
1741 return [row.get_end() for row in self]
1742
1743 - def get_reduced_chisq(self):
1744 return self.get_column('chisq') / (2*self.get_column('chisq_dof') - 2)
1745
1746 - def get_reduced_bank_chisq(self):
1747 return self.get_column('bank_chisq') / self.get_column('bank_chisq_dof')
1748
1749 - def get_reduced_cont_chisq(self):
1750 return self.get_column('cont_chisq') / self.get_column('cont_chisq_dof')
1751
1752 - def get_effective_snr(self, fac=250.0):
1753 snr = self.get_column('snr') 1754 rchisq = self.get_column('reduced_chisq') 1755 return snr/ (1 + snr**2/fac)**(0.25) / rchisq**(0.25)
1756
1757 - def get_bank_effective_snr(self, fac=250.0):
1758 snr = self.get_column('snr') 1759 rchisq = self.get_column('reduced_bank_chisq') 1760 return snr/ (1 + snr**2/fac)**(0.25) / rchisq**(0.25)
1761
1762 - def get_cont_effective_snr(self, fac=250.0):
1763 snr = self.get_column('snr') 1764 rchisq = self.get_column('reduced_cont_chisq') 1765 return snr/ (1 + snr**2/fac)**(0.25) / rchisq**(0.25)
1766
1767 - def get_new_snr(self, index=6.0):
1768 # kwarg 'index' is assigned to the parameter chisq_index 1769 # nhigh gives the asymptotic large rho behaviour of d (ln chisq) / d (ln rho) 1770 # for fixed new_snr eg nhigh = 2 -> chisq ~ rho^2 at large rho 1771 snr = self.get_column('snr') 1772 rchisq = self.get_column('reduced_chisq') 1773 nhigh = 2. 1774 newsnr = snr/ (0.5*(1+rchisq**(index/nhigh)))**(1./index) 1775 numpy.putmask(newsnr, rchisq < 1, snr) 1776 return newsnr
1777
1778 - def get_bank_new_snr(self, index=6.0):
1779 snr = self.get_column('snr') 1780 rchisq = self.get_column('reduced_bank_chisq') 1781 nhigh = 2. 1782 banknewsnr = snr/ (0.5*(1+rchisq**(index/nhigh)))**(1./index) 1783 numpy.putmask(banknewsnr, rchisq < 1, snr) 1784 return banknewsnr
1785
1786 - def get_cont_new_snr(self, index=6.0):
1787 snr = self.get_column('snr') 1788 rchisq = self.get_column('reduced_cont_chisq') 1789 nhigh = 2. 1790 contnewsnr = snr/ (0.5*(1+rchisq**(index/nhigh)))**(1./index) 1791 numpy.putmask(contnewsnr, rchisq < 1, snr) 1792 return contnewsnr
1793
1794 - def get_chirp_eff_dist(self, ref_mass=1.4):
1795 mchirp = self.get_column('mchirp') 1796 eff_dist = self.get_column('eff_distance') 1797 return SnglInspiral.chirp_distance(eff_dist, mchirp, ref_mass)
1798
1799 - def get_snr_over_chi(self):
1800 return self.get_column('snr')/self.get_column('chisq')**(1./2)
1801
1802 - def get_lvS5stat(self):
1803 return self.get_column('beta')
1804
1805 - def ifocut(self, ifo, inplace=False):
1806 """ 1807 Return a SnglInspiralTable with rows from self having IFO equal 1808 to the given ifo. If inplace, modify self directly, else create 1809 a new table and fill it. 1810 """ 1811 if inplace: 1812 iterutils.inplace_filter(lambda row: row.ifo == ifo, self) 1813 return self 1814 else: 1815 ifoTrigs = self.copy() 1816 ifoTrigs.extend([row for row in self if row.ifo == ifo]) 1817 return ifoTrigs
1818
1819 - def veto(self,seglist):
1820 vetoed = self.copy() 1821 keep = self.copy() 1822 for row in self: 1823 time = row.get_end() 1824 if time in seglist: 1825 vetoed.append(row) 1826 else: 1827 keep.append(row) 1828 return keep
1829
1830 - def vetoed(self, seglist):
1831 """ 1832 Return the inverse of what veto returns, i.e., return the triggers 1833 that lie within a given seglist. 1834 """ 1835 vetoed = self.copy() 1836 keep = self.copy() 1837 for row in self: 1838 time = row.get_end() 1839 if time in seglist: 1840 vetoed.append(row) 1841 else: 1842 keep.append(row) 1843 return vetoed
1844
1845 - def veto_seglistdict(self, seglistdict):
1846 vetoed = self.copy() 1847 keep = self.copy() 1848 for row in self: 1849 time = row.get_end() 1850 if time in seglistdict[row.ifo]: 1851 vetoed.append(row) 1852 else: 1853 keep.append(row) 1854 return keep
1855
1856 - def vetoed_seglistdict(self, seglistdict):
1857 vetoed = self.copy() 1858 keep = self.copy() 1859 for row in self: 1860 time = row.get_end() 1861 if time in seglistdict[row.ifo]: 1862 vetoed.append(row) 1863 else: 1864 keep.append(row) 1865 return vetoed
1866
1867 - def getslide(self,slide_num):
1868 """ 1869 Return the triggers with a specific slide number. 1870 @param slide_num: the slide number to recover (contained in the event_id) 1871 """ 1872 slideTrigs = self.copy() 1873 slideTrigs.extend(row for row in self if row.get_slide_number() == slide_num) 1874 return slideTrigs
1875
1876 1877 -class SnglInspiral(table.Table.RowType):
1878 __slots__ = tuple(SnglInspiralTable.validcolumns.keys()) 1879 1880 @staticmethod
1881 - def chirp_distance(dist, mchirp, ref_mass=1.4):
1882 return dist * (2.**(-1./5) * ref_mass / mchirp)**(5./6)
1883 1884 # 1885 # Properties 1886 # 1887 1888 end = gpsproperty("end_time", "end_time_ns") 1889 1890 @property
1891 - def spin1(self):
1892 if self.spin1x is None and self.spin1y is None and self.spin1z is None: 1893 return None 1894 return numpy.array((self.spin1x, self.spin1y, self.spin1z), dtype = "double")
1895 1896 @spin1.setter
1897 - def spin1(self, spin):
1898 if spin is None: 1899 self.spin1x, self.spin1y, self.spin1z = None, None, None 1900 else: 1901 self.spin1x, self.spin1y, self.spin1z = spin
1902 1903 @property
1904 - def spin2(self):
1905 if self.spin2x is None and self.spin2y is None and self.spin2z is None: 1906 return None 1907 return numpy.array((self.spin2x, self.spin2y, self.spin2z), dtype = "double")
1908 1909 @spin2.setter
1910 - def spin2(self, spin):
1911 if spin is None: 1912 self.spin2x, self.spin2y, self.spin2z = None, None, None 1913 else: 1914 self.spin2x, self.spin2y, self.spin2z = spin
1915 1916 # 1917 # Methods 1918 # 1919
1920 - def get_reduced_chisq(self):
1921 return float(self.chisq)/ (2*self.chisq_dof - 2)
1922
1923 - def get_reduced_bank_chisq(self):
1924 return float(self.bank_chisq)/ self.bank_chisq_dof
1925
1926 - def get_reduced_cont_chisq(self):
1927 return float(self.cont_chisq)/ self.cont_chisq_dof
1928
1929 - def get_effective_snr(self,fac=250.0):
1930 return self.snr/ (1 + self.snr**2/fac)**(0.25)/ self.get_reduced_chisq()**0.25
1931
1932 - def get_bank_effective_snr(self,fac=250.0):
1933 return self.snr/ (1 + self.snr**2/fac)**(0.25)/ self.get_reduced_bank_chisq()**0.25
1934
1935 - def get_cont_effective_snr(self,fac=250.0):
1936 return self.snr/ (1 + self.snr**2/fac)**(0.25)/ self.get_reduced_cont_chisq()**0.25
1937
1938 - def get_new_snr(self,index=6.0):
1939 rchisq = self.get_reduced_chisq() 1940 nhigh = 2. 1941 if rchisq > 1.: 1942 return self.snr/ ((1+rchisq**(index/nhigh))/2)**(1./index) 1943 else: 1944 return self.snr
1945
1946 - def get_bank_new_snr(self,index=6.0):
1947 rchisq = self.get_reduced_bank_chisq() 1948 nhigh = 2. 1949 if rchisq > 1.: 1950 return self.snr/ ((1+rchisq**(index/nhigh))/2)**(1./index) 1951 else: 1952 return self.snr
1953
1954 - def get_cont_new_snr(self,index=6.0):
1955 rchisq = self.get_reduced_cont_chisq() 1956 nhigh = 2. 1957 if rchisq > 1.: 1958 return self.snr/ ((1+rchisq**(index/nhigh))/2)**(1./index) 1959 else: 1960 return self.snr
1961
1962 - def get_far(self):
1963 return self.alpha
1964
1965 - def get_ifar(self):
1966 if self.alpha < 0.000000001: 1967 self.alpha = 0.000000001 1968 return 1./self.alpha
1969
1970 - def get_lvS5stat(self):
1971 return self.beta
1972 1973 # FIXME: how are two inspiral events defined to be the same?
1974 - def __eq__(self, other):
1975 return not ( 1976 cmp(self.ifo, other.ifo) or 1977 cmp(self.end, other.end) or 1978 cmp(self.mass1, other.mass1) or 1979 cmp(self.mass2, other.mass2) or 1980 cmp(self.spin1, other.spin1) or 1981 cmp(self.spin2, other.spin2) or 1982 cmp(self.search, other.search) 1983 )
1984 1985 # 1986 # Legacy 1987 # 1988
1989 - def get_end(self):
1990 return self.end
1991
1992 - def set_end(self, gps):
1993 self.end = gps
1994 1995 1996 SnglInspiralTable.RowType = SnglInspiral
1997 1998 1999 # 2000 # ============================================================================= 2001 # 2002 # coinc_inspiral:table 2003 # 2004 # ============================================================================= 2005 # 2006 2007 2008 -class CoincInspiralTable(table.Table):
2009 tableName = "coinc_inspiral" 2010 validcolumns = { 2011 "coinc_event_id": "ilwd:char", 2012 "ifos": "lstring", 2013 "end_time": "int_4s", 2014 "end_time_ns": "int_4s", 2015 "mass": "real_8", 2016 "mchirp": "real_8", 2017 "minimum_duration": "real_8", 2018 "snr": "real_8", 2019 "false_alarm_rate": "real_8", 2020 "combined_far": "real_8" 2021 } 2022 # FIXME: like some other tables here, this table should have the 2023 # constraint that the coinc_event_id column is a primary key. this 2024 # breaks ID reassignment in ligolw_sqlite, so until that is fixed 2025 # the constraint is being replaced with an index. 2026 #constraints = "PRIMARY KEY (coinc_event_id)" 2027 how_to_index = { 2028 "ci_cei_index": ("coinc_event_id",) 2029 } 2030 interncolumns = ("coinc_event_id", "ifos")
2031
2032 2033 -class CoincInspiral(table.Table.RowType):
2034 """ 2035 Example: 2036 2037 >>> x = CoincInspiral() 2038 >>> x.instruments = (u"H1", u"L1") 2039 >>> x.ifos 2040 u'H1,L1' 2041 >>> x.instruments 2042 set([u'H1', u'L1']) 2043 >>> x.end = LIGOTimeGPS(10) 2044 >>> x.end 2045 LIGOTimeGPS(10, 0) 2046 >>> x.end = None 2047 >>> print(x.end) 2048 None 2049 """ 2050 __slots__ = tuple(CoincInspiralTable.validcolumns.keys()) 2051 2052 instruments = instrumentsproperty("ifos") 2053 2054 end = gpsproperty("end_time", "end_time_ns") 2055
2056 - def get_end(self):
2057 return self.end
2058
2059 - def set_end(self, gps):
2060 self.end = gps
2061
2062 - def get_ifos(self):
2063 return self.instruments
2064
2065 - def set_ifos(self, ifos):
2066 self.instruments = ifos
2067 2068 2069 CoincInspiralTable.RowType = CoincInspiral 2070 2071 2072 # 2073 # ============================================================================= 2074 # 2075 # sngl_ringdown:table 2076 # 2077 # ============================================================================= 2078 # 2079 2080 2081 SnglRingdownID = ilwd.get_ilwdchar_class(u"sngl_ringdown", u"event_id")
2082 2083 2084 -class SnglRingdownTable(table.Table):
2085 tableName = "sngl_ringdown" 2086 validcolumns = { 2087 "process_id": "ilwd:char", 2088 "ifo": "lstring", 2089 "channel": "lstring", 2090 "start_time": "int_4s", 2091 "start_time_ns": "int_4s", 2092 "start_time_gmst": "real_8", 2093 "frequency": "real_4", 2094 "quality": "real_4", 2095 "phase": "real_4", 2096 "mass": "real_4", 2097 "spin": "real_4", 2098 "epsilon": "real_4", 2099 "num_clust_trigs": "int_4s", 2100 "ds2_H1H2": "real_4", 2101 "ds2_H1L1": "real_4", 2102 "ds2_H1V1": "real_4", 2103 "ds2_H2L1": "real_4", 2104 "ds2_H2V1": "real_4", 2105 "ds2_L1V1": "real_4", 2106 "amplitude": "real_4", 2107 "snr": "real_4", 2108 "eff_dist": "real_4", 2109 "sigma_sq": "real_8", 2110 "event_id": "ilwd:char" 2111 } 2112 constraints = "PRIMARY KEY (event_id)" 2113 next_id = SnglRingdownID(0) 2114 interncolumns = ("process_id", "ifo", "channel") 2115
2116 - def get_start(self):
2117 return [row.get_start() for row in self]
2118
2119 2120 -class SnglRingdown(table.Table.RowType):
2121 __slots__ = tuple(SnglRingdownTable.validcolumns.keys()) 2122
2123 - def get_start(self):
2124 return LIGOTimeGPS(self.start_time, self.start_time_ns)
2125
2126 - def set_start(self, gps):
2127 self.start_time, self.start_time_ns = gps.seconds, gps.nanoseconds
2128
2129 - def get_id_parts(self):
2130 """ 2131 Return the three pieces of the int_8s-style event_id. 2132 """ 2133 int_event_id = int(self.event_id) 2134 a = int_event_id // 1000000000 2135 slidenum = (int_event_id % 1000000000) // 100000 2136 b = int_event_id % 100000 2137 return int(a), int(slidenum), int(b)
2138 2139 2140 SnglRingdownTable.RowType = SnglRingdown
2141 2142 2143 # 2144 # ============================================================================= 2145 # 2146 # coinc_ringdown:table 2147 # 2148 # ============================================================================= 2149 # 2150 2151 2152 -class CoincRingdownTable(table.Table):
2153 tableName = "coinc_ringdown" 2154 validcolumns = { 2155 "coinc_event_id": "ilwd:char", 2156 "ifos": "lstring", 2157 "start_time": "int_4s", 2158 "start_time_ns": "int_4s", 2159 "frequency": "real_8", 2160 "quality": "real_8", 2161 "mass": "real_8", 2162 "spin": "real_8", 2163 "snr": "real_8", 2164 "choppedl_snr": "real_8", 2165 "snr_sq": "real_8", 2166 "eff_coh_snr": "real_8", 2167 "null_stat": "real_8", 2168 "kappa": "real_8", 2169 "snr_ratio": "real_8", 2170 "false_alarm_rate": "real_8", 2171 "combined_far": "real_8" 2172 } 2173 # constraints = "PRIMARY KEY (coinc_event_id)" 2174 how_to_index = { 2175 "cr_cei_index": ("coinc_event_id",) 2176 } 2177 interncolumns = ("coinc_event_id", "ifos")
2178
2179 2180 -class CoincRingdown(table.Table.RowType):
2181 __slots__ = tuple(CoincRingdownTable.validcolumns.keys()) 2182
2183 - def get_start(self):
2184 return LIGOTimeGPS(self.start_time, self.start_time_ns)
2185
2186 - def set_start(self, gps):
2187 self.start_time, self.start_time_ns = gps.seconds, gps.nanoseconds
2188
2189 - def set_ifos(self, ifos):
2191
2192 - def get_ifos(self):
2193 return instrument_set_from_ifos(self.ifos)
2194 2195 2196 CoincRingdownTable.RowType = CoincRingdown 2197 2198 2199 # 2200 # ============================================================================= 2201 # 2202 # multi_inspiral:table 2203 # 2204 # ============================================================================= 2205 # 2206 2207 2208 MultiInspiralID = ilwd.get_ilwdchar_class(u"multi_inspiral", u"event_id")
2209 2210 2211 -class MultiInspiralTable(table.Table):
2212 tableName = "multi_inspiral" 2213 validcolumns = { 2214 "process_id": "ilwd:char", 2215 "ifos": "lstring", 2216 "search": "lstring", 2217 "end_time": "int_4s", 2218 "end_time_ns": "int_4s", 2219 "end_time_gmst": "real_8", 2220 "impulse_time": "int_4s", 2221 "impulse_time_ns": "int_4s", 2222 "amplitude": "real_4", 2223 "distance": "real_4", 2224 "eff_dist_h1": "real_4", 2225 "eff_dist_h2": "real_4", 2226 "eff_dist_l": "real_4", 2227 "eff_dist_g": "real_4", 2228 "eff_dist_t": "real_4", 2229 "eff_dist_v": "real_4", 2230 "eff_dist_h1h2": "real_4", 2231 "coa_phase": "real_4", 2232 "mass1": "real_4", 2233 "mass2": "real_4", 2234 "mchirp": "real_4", 2235 "eta": "real_4", 2236 "chi": "real_4", 2237 "kappa": "real_4", 2238 "tau0": "real_4", 2239 "tau2": "real_4", 2240 "tau3": "real_4", 2241 "tau4": "real_4", 2242 "tau5": "real_4", 2243 "ttotal": "real_4", 2244 "snr": "real_4", 2245 "snr_dof": "int_4s", 2246 "chisq": "real_4", 2247 "chisq_dof": "int_4s", 2248 "bank_chisq": "real_4", 2249 "bank_chisq_dof": "int_4s", 2250 "cont_chisq": "real_4", 2251 "cont_chisq_dof": "int_4s", 2252 "trace_snr": "real_4", 2253 "snr_h1": "real_4", 2254 "snr_h2": "real_4", 2255 "snr_l": "real_4", 2256 "snr_g": "real_4", 2257 "snr_t": "real_4", 2258 "snr_v": "real_4", 2259 "amp_term_1": "real_4", 2260 "amp_term_2": "real_4", 2261 "amp_term_3": "real_4", 2262 "amp_term_4": "real_4", 2263 "amp_term_5": "real_4", 2264 "amp_term_6": "real_4", 2265 "amp_term_7": "real_4", 2266 "amp_term_8": "real_4", 2267 "amp_term_9": "real_4", 2268 "amp_term_10": "real_4", 2269 "sigmasq_h1": "real_8", 2270 "sigmasq_h2": "real_8", 2271 "sigmasq_l": "real_8", 2272 "sigmasq_g": "real_8", 2273 "sigmasq_t": "real_8", 2274 "sigmasq_v": "real_8", 2275 "chisq_h1": "real_4", 2276 "chisq_h2": "real_4", 2277 "chisq_l": "real_4", 2278 "chisq_g": "real_4", 2279 "chisq_t": "real_4", 2280 "chisq_v": "real_4", 2281 "sngl_chisq_dof": "int_4s", 2282 "bank_chisq_h1": "real_4", 2283 "bank_chisq_h2": "real_4", 2284 "bank_chisq_l": "real_4", 2285 "bank_chisq_g": "real_4", 2286 "bank_chisq_t": "real_4", 2287 "bank_chisq_v": "real_4", 2288 "sngl_bank_chisq_dof": "int_4s", 2289 "cont_chisq_h1": "real_4", 2290 "cont_chisq_h2": "real_4", 2291 "cont_chisq_l": "real_4", 2292 "cont_chisq_g": "real_4", 2293 "cont_chisq_t": "real_4", 2294 "cont_chisq_v": "real_4", 2295 "sngl_cont_chisq_dof": "int_4s", 2296 "ra": "real_4", 2297 "dec": "real_4", 2298 "ligo_angle": "real_4", 2299 "ligo_angle_sig": "real_4", 2300 "inclination": "real_4", 2301 "polarization": "real_4", 2302 "null_statistic": "real_4", 2303 "null_stat_h1h2": "real_4", 2304 "null_stat_degen": "real_4", 2305 "event_id": "ilwd:char", 2306 "h1quad_re": "real_4", 2307 "h1quad_im": "real_4", 2308 "h2quad_re": "real_4", 2309 "h2quad_im": "real_4", 2310 "l1quad_re": "real_4", 2311 "l1quad_im": "real_4", 2312 "g1quad_re": "real_4", 2313 "g1quad_im": "real_4", 2314 "t1quad_re": "real_4", 2315 "t1quad_im": "real_4", 2316 "v1quad_re": "real_4", 2317 "v1quad_im": "real_4", 2318 "coh_snr_h1h2": "real_4", 2319 "cohSnrSqLocal": "real_4", 2320 "autoCorrCohSq": "real_4", 2321 "crossCorrCohSq": "real_4", 2322 "autoCorrNullSq": "real_4", 2323 "crossCorrNullSq": "real_4", 2324 "ampMetricEigenVal1": "real_8", 2325 "ampMetricEigenVal2": "real_8", 2326 "time_slide_id": "ilwd:char" 2327 } 2328 constraints = "PRIMARY KEY (event_id)" 2329 next_id = MultiInspiralID(0) 2330 interncolumns = ("process_id", "ifos", "search") 2331 instrument_id = {"G1":"g", "H1":"h1", "H2":"h2", "L1":"l", "T1":"t", 2332 "V1":"v"} 2333
2334 - def get_column(self,column):
2335 if column == 'bestnr': 2336 return self.get_bestnr() 2337 elif column == 'new_snr': 2338 return self.get_new_snr() 2339 elif column == "null_snr": 2340 return self.get_null_snr() 2341 elif column == 'coinc_snr': 2342 return self.get_coinc_snr() 2343 elif column == 'reduced_chisq': 2344 return self.get_reduced_chisq() 2345 elif column == 'reduced_bank_chisq': 2346 return self.get_reduced_bank_chisq() 2347 elif column == 'reduced_cont_chisq': 2348 return self.get_reduced_cont_chisq() 2349 elif column == "reduced_chisq_h1": 2350 return self.get_reduced_sngl_chisq(ifo="hl") 2351 elif column == "reduced_chisq_h2": 2352 return self.get_reduced_sngl_chisq(ifo="h2") 2353 elif column == "reduced_chisq_l": 2354 return self.get_reduced_sngl_chisq(ifo="l") 2355 elif column == "reduced_chisq_v": 2356 return self.get_reduced_sngl_chisq(ifo="v") 2357 else: 2358 return self.getColumnByName(column).asarray()
2359
2360 - def get_coinc_snr(self):
2361 if len(self): 2362 return (numpy.asarray(list(self.get_sngl_snrs().values()))\ 2363 **2).sum(axis=0)**(1./2.) 2364 else: 2365 return numpy.array([])
2366
2367 - def get_end(self):
2368 return [row.get_end() for row in self]
2369
2370 - def get_new_snr(self, index=4.0,nhigh = 3.0, column='chisq'):
2371 # kwarg 'index' is assigned to the parameter chisq_index 2372 # nhigh gives the asymptotic large rho behaviour of 2373 # d (ln chisq) / d (ln rho) 2374 # for fixed new_snr eg nhigh = 2 -> chisq ~ rho^2 at large rho 2375 snr = self.get_column('snr') 2376 rchisq = self.get_column('reduced_%s' % column) 2377 newsnr = snr/ (0.5*(1+rchisq**(index/nhigh)))**(1./index) 2378 numpy.putmask(newsnr, rchisq < 1, snr) 2379 return newsnr
2380
2381 - def get_null_snr(self):
2382 """ 2383 Get the coherent Null SNR for each row in the table. 2384 """ 2385 null_snr_sq = self.get_coinc_snr()**2 - self.get_column('snr')**2 2386 null_snr_sq[null_snr_sq < 0] = 0. 2387 return null_snr_sq**(1./2.)
2388
2389 - def get_coinc_chisq(self):
2390 """@returns the coincident chisq for each row in the table 2391 """ 2392 if len(self): 2393 return (numpy.asarray(list(self.get_sngl_chisqs().values()))\ 2394 **2).sum(axis=0)**(1./2.) 2395 else: 2396 return numpy.array([])
2397
2398 - def get_reduced_coinc_chisq(self):
2399 """@returns the coincident chisq per degree of freedom for each 2400 row in the table 2401 """ 2402 dof = float(len(self) and self[0].sngl_chisq_dof or 1) 2403 return self.get_coinc_chisq()/dof
2404
2405 - def get_null_chisq(self):
2406 """@returns the coherent null chisq for each row in the table 2407 """ 2408 null_chisq_sq = (self.get_reduced_coinc_chisq() - 2409 self.get_reduced_chisq()) 2410 null_chisq_sq[null_chisq_sq < 0] = 0. 2411 return null_chisq_sq
2412
2413 - def get_sigmasq(self, instrument):
2414 """ 2415 Get the single-detector SNR of the given instrument for each 2416 row in the table. 2417 """ 2418 return self.get_column('sigmasq_%s' 2419 % self.instrument_id[instrument.upper()])
2420
2421 - def get_sigmasqs(self, instruments=None):
2422 """ 2423 Return dictionary of single-detector sigmas for each row in the 2424 table. 2425 """ 2426 if len(self): 2427 if not instruments: 2428 instruments = list(map(str, \ 2429 instrument_set_from_ifos(self[0].ifos))) 2430 return dict((ifo, self.get_sigmasq(ifo))\ 2431 for ifo in instruments) 2432 else: 2433 return dict()
2434 2435
2436 - def get_sngl_snr(self, instrument):
2437 """ 2438 Get the single-detector SNR of the given instrument for each 2439 row in the table. 2440 """ 2441 return self.get_column('snr_%s'\ 2442 % self.instrument_id[instrument.upper()])
2443
2444 - def get_sngl_snrs(self, instruments=None):
2445 """ 2446 Get the single-detector SNRs for each row in the table. 2447 """ 2448 if len(self) and instruments is None: 2449 instruments = list(map(str, \ 2450 instrument_set_from_ifos(self[0].ifos))) 2451 elif instruments is None: 2452 instruments = [] 2453 return dict((ifo, self.get_sngl_snr(ifo))\ 2454 for ifo in instruments)
2455
2456 - def get_sngl_chisq(self, instrument):
2457 """ 2458 Get the single-detector \chi^2 of the given instrument for each 2459 row in the table. 2460 """ 2461 return self.get_column('chisq_%s'\ 2462 % self.instrument_id[instrument.upper()])
2463
2464 - def get_sngl_chisqs(self, instruments=None):
2465 """ 2466 Get the single-detector \chi^2 for each row in the table. 2467 """ 2468 if len(self) and instruments is None: 2469 instruments = list(map(str, \ 2470 instrument_set_from_ifos(self[0].ifos))) 2471 elif instruments is None: 2472 instruments = [] 2473 return dict((ifo, self.get_sngl_chisq(ifo))\ 2474 for ifo in instruments)
2475
2476 - def get_sngl_bank_chisq(self, instrument):
2477 """ 2478 Get the single-detector \chi^2 of the given instrument for each 2479 row in the table. 2480 """ 2481 return self.get_column('bank_chisq_%s'\ 2482 % self.instrument_id[instrument.upper()])
2483
2484 - def get_sngl_bank_chisqs(self, instruments=None):
2485 """ 2486 Get the single-detector \chi^2 for each row in the table. 2487 """ 2488 if len(self) and instruments is None: 2489 instruments = list(map(str, \ 2490 instrument_set_from_ifos(self[0].ifos))) 2491 elif instruments is None: 2492 instruments = [] 2493 return dict((ifo, self.get_sngl_bank_chisq(ifo))\ 2494 for ifo in instruments)
2495
2496 - def get_sngl_cont_chisq(self, instrument):
2497 """ 2498 Get the single-detector \chi^2 of the given instrument for each 2499 row in the table. 2500 """ 2501 return self.get_column('cont_chisq_%s'\ 2502 % self.instrument_id[instrument.upper()])
2503
2504 - def get_sngl_cont_chisqs(self, instruments=None):
2505 """ 2506 Get the single-detector \chi^2 for each row in the table. 2507 """ 2508 if len(self) and instruments is None: 2509 instruments = list(map(str, \ 2510 instrument_set_from_ifos(self[0].ifos))) 2511 elif instruments is None: 2512 instruments = [] 2513 return dict((ifo, self.get_sngl_cont_chisq(ifo))\ 2514 for ifo in instruments)
2515
2516 - def get_bestnr(self, index=4.0, nhigh=3.0, null_snr_threshold=4.25,\ 2517 null_grad_thresh=20., null_grad_val = 1./5.):
2518 """ 2519 Get the BestNR statistic for each row in the table 2520 """ 2521 return [row.get_bestnr(index=index, nhigh=nhigh, 2522 null_snr_threshold=null_snr_threshold, 2523 null_grad_thresh=null_grad_thresh, 2524 null_grad_val=null_grad_val) 2525 for row in self]
2526
2527 - def getstat(self):
2528 return self.get_column('snr')
2529
2530 - def veto(self,seglist):
2531 vetoed = self.copy() 2532 keep = self.copy() 2533 for row in self: 2534 time = row.get_end() 2535 if time in seglist: 2536 vetoed.append(row) 2537 else: 2538 keep.append(row) 2539 return keep
2540
2541 - def vetoed(self, seglist):
2542 """ 2543 Return the inverse of what veto returns, i.e., return the triggers 2544 that lie within a given seglist. 2545 """ 2546 vetoed = self.copy() 2547 keep = self.copy() 2548 for row in self: 2549 time = row.get_end() 2550 if time in seglist: 2551 vetoed.append(row) 2552 else: 2553 keep.append(row) 2554 return vetoed
2555
2556 - def getslide(self,slide_num):
2557 """ 2558 Return the triggers with a specific slide number. 2559 @param slide_num: the slide number to recover (contained in the event_id) 2560 """ 2561 slideTrigs = self.copy() 2562 slideTrigs.extend(row for row in self if row.get_slide_number() == slide_num) 2563 return slideTrigs
2564
2565 - def get_reduced_chisq(self):
2566 """@returns the chisq per degree of freedom for each row in 2567 this table 2568 """ 2569 return self.get_column('chisq') / self.get_column('chisq_dof')
2570
2571 - def get_reduced_bank_chisq(self):
2572 """@returns the bank chisq per degree of freedom for each row in 2573 this table 2574 """ 2575 return self.get_column('bank_chisq') / self.get_column('bank_chisq_dof')
2576
2577 - def get_reduced_cont_chisq(self):
2578 """@returns the auto (continuous) chisq per degree of freedom 2579 for each row in this table 2580 """ 2581 return self.get_column('cont_chisq') / self.get_column('cont_chisq_dof')
2582
2583 - def get_reduced_sngl_chisq(self, instrument):
2584 """@returns the single-detector chisq per degree of freedom for 2585 each row in this table 2586 """ 2587 return (self.get_column("chisq_%s" 2588 % self.instrument_id[instrument.upper()]) / 2589 self.get_column("sngl_chisq_dof"))
2590
2591 - def get_sngl_new_snr(self, ifo, column="chisq", index=4.0, nhigh = 3.0):
2592 column = column.lower() 2593 if column == "chisq": 2594 rchisq = self.get_reduced_sngl_chisq(ifo) 2595 elif column == "bank_chisq": 2596 rchisq = self.get_reduced_sngl_bank_chisq(ifo) 2597 elif column == "cont_chisq": 2598 rchisq = self.get_reduced_cont_chisq() 2599 else: 2600 rchisq = getattr(self, column) / getattr(self, "%s_dof" % column) 2601 snr = self.get_column('snr') 2602 newsnr = snr/ (0.5*(1+rchisq**(index/nhigh)))**(1./index) 2603 numpy.putmask(newsnr, rchisq < 1, snr) 2604 return newsnr
2605
2606 2607 -class MultiInspiral(table.Table.RowType):
2608 __slots__ = tuple(MultiInspiralTable.validcolumns.keys()) 2609 instrument_id = MultiInspiralTable.instrument_id 2610
2611 - def get_reduced_chisq(self):
2612 return self.chisq / self.chisq_dof
2613
2614 - def get_reduced_bank_chisq(self):
2615 return self.bank_chisq / self.bank_chisq_dof
2616
2617 - def get_reduced_cont_chisq(self):
2618 return self.cont_chisq / self.cont_chisq_dof
2619
2620 - def get_reduced_sngl_chisq(self, instrument):
2621 return (getattr(self, 2622 "chisq_%s" % self.instrument_id[instrument.upper()]) / 2623 getattr(self, "sngl_chisq_dof"))
2624
2625 - def get_reduced_sngl_bank_chisq(self, instrument):
2626 return (getattr(self, ("bank_chisq_%s" 2627 % self.instrument_id[instrument.upper()])) / 2628 getattr(self, "sngl_bank_chisq_dof"))
2629
2630 - def get_reduced_sngl_cont_chisq(self, instrument):
2631 return (getattr(self, ("cont_chisq_%s" 2632 % self.instrument_id[instrument.upper()])) / 2633 getattr(self, "sngl_bank_chisq_dof"))
2634 2635
2636 - def get_end(self):
2637 return LIGOTimeGPS(self.end_time, self.end_time_ns)
2638
2639 - def get_ifos(self):
2640 """ 2641 Return a set of the instruments for this row. 2642 """ 2643 return instrument_set_from_ifos(self.ifos)
2644
2645 - def get_coinc_snr(self):
2646 """ 2647 Get the coincident SNR for this row. 2648 """ 2649 return (numpy.asarray(list(self.get_sngl_snrs().values()))**2)\ 2650 .sum()**(1./2.)
2651
2652 - def get_coinc_chisq(self):
2653 """@returns the coincident chisq for this row 2654 """ 2655 return ((numpy.asarray(list(self.get_sngl_chisqs().values()))**2) 2656 .sum()**(1./2.))
2657
2658 - def get_reduced_coinc_chisq(self):
2659 """@returns the coincident chisq per degree of freedom for this row 2660 """ 2661 return self.get_coinc_chisq()/self.sngl_chisq_dof
2662
2663 - def get_new_snr(self, index=4.0, nhigh = 3.0, column='chisq'):
2664 column = column.lower() 2665 if column == "chisq": 2666 rchisq = self.get_reduced_chisq() 2667 elif column == "bank_chisq": 2668 rchisq = self.get_reduced_bank_chisq() 2669 elif column == "cont_chisq": 2670 rchisq = self.get_reduced_cont_chisq() 2671 else: 2672 rchisq = getattr(self, column) / getattr(self, "%s_dof" % column) 2673 if rchisq > 1.: 2674 return self.snr /\ 2675 ((1+rchisq**(index/nhigh))/2)**(1./index) 2676 else: 2677 return self.snr
2678
2679 - def get_sngl_new_snr(self, ifo, column="chisq", index=4.0, nhigh = 3.0):
2680 column = column.lower() 2681 if column == "chisq": 2682 rchisq = self.get_reduced_sngl_chisq(ifo) 2683 elif column == "bank_chisq": 2684 rchisq = self.get_reduced_sngl_bank_chisq(ifo) 2685 elif column == "cont_chisq": 2686 rchisq = self.get_reduced_sngl_cont_chisq(ifo) 2687 if rchisq > 1.: 2688 return self.get_sngl_snr(ifo) /\ 2689 ((1+rchisq**(index/nhigh))/2)**(1./index) 2690 else: 2691 return self.snr
2692 2693
2694 - def get_sngl_new_snrs(self, column="chisq", index=4.0, nhigh = 3.0):
2695 """@returns a dictionary of single-detector newSNRs for this row. 2696 """ 2697 return dict((ifo, 2698 self.get_sngl_new_snr(ifo, column=column, index=index, nhigh=nhigh)) for 2699 ifo in instrument_set_from_ifos(self.ifos))
2700 2701
2702 - def get_null_snr(self):
2703 """ 2704 Get the coherent Null SNR for this row. 2705 """ 2706 null_snr_sq = (numpy.asarray(list(self.get_sngl_snrs().values()))**2)\ 2707 .sum() - self.snr**2 2708 if null_snr_sq < 0: 2709 return 0 2710 else: 2711 return null_snr_sq**(1./2.)
2712
2713 - def get_null_chisq(self):
2714 """@returns the coherent null chisq for this row 2715 """ 2716 null_chisq_sq = (self.get_reduced_coinc_chisq() - 2717 self.get_reduced_chisq()) 2718 if null_chisq_sq < 0: 2719 return 0 2720 else: 2721 return null_chisq_sq
2722
2723 - def get_sngl_snr(self, instrument):
2724 """ 2725 Get the single-detector SNR for the given instrument for this 2726 row 2727 """ 2728 return getattr(self, "snr_%s" % self.instrument_id[instrument.upper()])
2729 2730
2731 - def get_sngl_snrs(self):
2732 """ 2733 Return a dictionary of single-detector SNRs for this row. 2734 """ 2735 return dict((ifo, self.get_sngl_snr(ifo)) for ifo in\ 2736 instrument_set_from_ifos(self.ifos))
2737
2738 - def get_sngl_chisq(self, instrument):
2739 """@returns the single-detector chisq for the given instrument 2740 for this row 2741 """ 2742 return getattr(self, 2743 "chisq_%s" % self.instrument_id[instrument.upper()])
2744 2745
2746 - def get_sngl_chisqs(self):
2747 """@returns a dictionary of single-detector chisqs for this row. 2748 """ 2749 return dict((ifo, self.get_sngl_chisq(ifo)) for ifo in 2750 instrument_set_from_ifos(self.ifos))
2751
2752 - def set_ifos(self, instruments):
2753 """ 2754 Serialize a sequence of instruments into the ifos 2755 attribute. The instrument names must not contain the "," 2756 character. 2757 """ 2758 self.ifos = ifos_from_instrument_set(instruments)
2759
2760 - def get_id_parts(self):
2761 """ 2762 Return the three pieces of the int_8s-style event_id. 2763 """ 2764 int_event_id = int(self.event_id) 2765 a = int_event_id // 1000000000 2766 slidenum = (int_event_id % 1000000000) // 100000 2767 b = int_event_id % 100000 2768 return int(a), int(slidenum), int(b)
2769
2770 - def get_slide_number(self):
2771 """ 2772 Return the slide-number for this trigger 2773 """ 2774 a, slide_number, b = self.get_id_parts() 2775 if slide_number > 5000: 2776 slide_number = 5000 - slide_number 2777 return slide_number
2778
2779 - def get_bestnr(self, index=4.0, nhigh=3.0, null_snr_threshold=4.25,\ 2780 null_grad_thresh=20., null_grad_val = 1./5.):
2781 """ 2782 Return the BestNR statistic for this row. 2783 """ 2784 # weight SNR by chisq 2785 bestnr = self.get_new_snr(index=index, nhigh=nhigh, 2786 column="chisq") 2787 if len(self.get_ifos()) < 3: 2788 return bestnr 2789 # recontour null SNR threshold for higher SNRs 2790 if self.snr > null_grad_thresh: 2791 null_snr_threshold += (self.snr - null_grad_thresh) * null_grad_val 2792 # weight SNR by null SNR 2793 if self.get_null_snr() > null_snr_threshold: 2794 bestnr /= 1 + self.get_null_snr() - null_snr_threshold 2795 return bestnr
2796 2797 2798 MultiInspiralTable.RowType = MultiInspiral 2799 2800 2801 # 2802 # ============================================================================= 2803 # 2804 # sim_inspiral:table 2805 # 2806 # ============================================================================= 2807 # 2808 2809 2810 SimInspiralID = ilwd.get_ilwdchar_class(u"sim_inspiral", u"simulation_id")
2811 2812 2813 -class SimInspiralTable(table.Table):
2814 tableName = "sim_inspiral" 2815 validcolumns = { 2816 "process_id": "ilwd:char", 2817 "waveform": "lstring", 2818 "geocent_end_time": "int_4s", 2819 "geocent_end_time_ns": "int_4s", 2820 "h_end_time": "int_4s", 2821 "h_end_time_ns": "int_4s", 2822 "l_end_time": "int_4s", 2823 "l_end_time_ns": "int_4s", 2824 "g_end_time": "int_4s", 2825 "g_end_time_ns": "int_4s", 2826 "t_end_time": "int_4s", 2827 "t_end_time_ns": "int_4s", 2828 "v_end_time": "int_4s", 2829 "v_end_time_ns": "int_4s", 2830 "end_time_gmst": "real_8", 2831 "source": "lstring", 2832 "mass1": "real_4", 2833 "mass2": "real_4", 2834 "mchirp": "real_4", 2835 "eta": "real_4", 2836 "distance": "real_4", 2837 "longitude": "real_4", 2838 "latitude": "real_4", 2839 "inclination": "real_4", 2840 "coa_phase": "real_4", 2841 "polarization": "real_4", 2842 "psi0": "real_4", 2843 "psi3": "real_4", 2844 "alpha": "real_4", 2845 "alpha1": "real_4", 2846 "alpha2": "real_4", 2847 "alpha3": "real_4", 2848 "alpha4": "real_4", 2849 "alpha5": "real_4", 2850 "alpha6": "real_4", 2851 "beta": "real_4", 2852 "spin1x": "real_4", 2853 "spin1y": "real_4", 2854 "spin1z": "real_4", 2855 "spin2x": "real_4", 2856 "spin2y": "real_4", 2857 "spin2z": "real_4", 2858 "theta0": "real_4", 2859 "phi0": "real_4", 2860 "f_lower": "real_4", 2861 "f_final": "real_4", 2862 "eff_dist_h": "real_4", 2863 "eff_dist_l": "real_4", 2864 "eff_dist_g": "real_4", 2865 "eff_dist_t": "real_4", 2866 "eff_dist_v": "real_4", 2867 "numrel_mode_min": "int_4s", 2868 "numrel_mode_max": "int_4s", 2869 "numrel_data": "lstring", 2870 "amp_order": "int_4s", 2871 "taper": "lstring", 2872 "bandpass": "int_4s", 2873 "simulation_id": "ilwd:char" 2874 } 2875 constraints = "PRIMARY KEY (simulation_id)" 2876 next_id = SimInspiralID(0) 2877 interncolumns = ("process_id", "waveform", "source") 2878
2879 - def get_column(self,column):
2880 if column == 'chirp_dist' or column == 'chirp_distance': 2881 return self.get_chirp_dist() 2882 # be strict about formatting of chirp eff distance 2883 if column[0:14] == 'chirp_eff_dist' and column[14:16] in ['_h','_l','_g','_t','_v'] and len(column) == 16: 2884 site = column[-1] 2885 return self.get_chirp_eff_dist(site) 2886 elif column == 'spin1': 2887 return self.get_spin_mag(1) 2888 elif column == 'spin2': 2889 return self.get_spin_mag(2) 2890 elif column == 'total_mass' or column == 'mtotal': 2891 m1=self.getColumnByName('mass1').asarray() 2892 m2=self.getColumnByName('mass2').asarray() 2893 return m1+m2 2894 else: 2895 return self.getColumnByName(column).asarray()
2896
2897 - def get_chirp_dist(self,ref_mass=1.4):
2898 mchirp = self.get_column('mchirp') 2899 dist = self.get_column('distance') 2900 return SnglInspiral.chirp_distance(dist, mchirp, ref_mass)
2901
2902 - def get_chirp_eff_dist(self,site,ref_mass=1.4):
2903 mchirp = self.get_column('mchirp') 2904 eff_dist = self.get_column('eff_dist_' + site) 2905 return SnglInspiral.chirp_distance(eff_dist, mchirp, ref_mass)
2906
2907 - def get_spin_mag(self,objectnumber):
2908 sx = self.get_column('spin' + str(objectnumber) + 'x') 2909 sy = self.get_column('spin' + str(objectnumber) + 'y') 2910 sz = self.get_column('spin' + str(objectnumber) + 'z') 2911 return (sx**2 + sy**2 + sz**2)**(0.5)
2912
2913 - def veto(self,seglist,site=None):
2914 keep = self.copy() 2915 keep.extend(row for row in self if row.get_end(site) not in seglist) 2916 return keep
2917
2918 - def veto(self,seglist):
2919 vetoed = self.copy() 2920 keep = self.copy() 2921 for row in self: 2922 time = row.get_end() 2923 if time in seglist: 2924 vetoed.append(row) 2925 else: 2926 keep.append(row) 2927 return keep
2928
2929 - def vetoed(self, seglist):
2930 """ 2931 Return the inverse of what veto returns, i.e., return the triggers 2932 that lie within a given seglist. 2933 """ 2934 vetoed = self.copy() 2935 keep = self.copy() 2936 for row in self: 2937 time = row.get_end() 2938 if time in seglist: 2939 vetoed.append(row) 2940 else: 2941 keep.append(row) 2942 return vetoed
2943
2944 - def get_end(self, site=None):
2945 return numpy.asarray([row.get_end(site=site) for row in self])
2946
2947 2948 -class SimInspiral(table.Table.RowType):
2949 """ 2950 Example: 2951 2952 >>> x = SimInspiral() 2953 >>> x.ra_dec = 0., 0. 2954 >>> x.ra_dec 2955 (0.0, 0.0) 2956 >>> x.ra_dec = None 2957 >>> print(x.ra_dec) 2958 None 2959 >>> x.time_geocent = None 2960 >>> print(x.time_geocent) 2961 None 2962 >>> print(x.end_time_gmst) 2963 None 2964 >>> x.time_geocent = LIGOTimeGPS(6e8) 2965 >>> print(x.time_geocent) 2966 600000000 2967 >>> print(x.end_time_gmst) 2968 -2238.39417156 2969 """ 2970 __slots__ = tuple(SimInspiralTable.validcolumns.keys()) 2971 2972 time_geocent = gpsproperty_with_gmst("geocent_end_time", "geocent_end_time_ns", "end_time_gmst") 2973 2974 @property
2975 - def ra_dec(self):
2976 if self.longitude is None and self.latitude is None: 2977 return None 2978 return self.longitude, self.latitude
2979 2980 @ra_dec.setter
2981 - def ra_dec(self, radec):
2982 if radec is None: 2983 self.longitude = self.latitude = None 2984 else: 2985 self.longitude, self.latitude = radec
2986 2987 @property
2988 - def spin1(self):
2989 if self.spin1x is None and self.spin1y is None and self.spin1z is None: 2990 return None 2991 return numpy.array((self.spin1x, self.spin1y, self.spin1z), dtype = "double")
2992 2993 @spin1.setter
2994 - def spin1(self, spin):
2995 if spin is None: 2996 self.spin1x, self.spin1y, self.spin1z = None, None, None 2997 else: 2998 self.spin1x, self.spin1y, self.spin1z = spin
2999 3000 @property
3001 - def spin2(self):
3002 if self.spin2x is None and self.spin2y is None and self.spin2z is None: 3003 return None 3004 return numpy.array((self.spin2x, self.spin2y, self.spin2z), dtype = "double")
3005 3006 @spin2.setter
3007 - def spin2(self, spin):
3008 if spin is None: 3009 self.spin2x, self.spin2y, self.spin2z = None, None, None 3010 else: 3011 self.spin2x, self.spin2y, self.spin2z = spin
3012
3013 - def time_at_instrument(self, instrument, offsetvector):
3014 """ 3015 Return the "time" of the injection, delay corrected for the 3016 displacement from the geocentre to the given instrument. 3017 3018 NOTE: this method does not account for the rotation of the 3019 Earth that occurs during the transit of the plane wave from 3020 the detector to the geocentre. That is, it is assumed the 3021 Earth is in the same orientation with respect to the 3022 celestial sphere when the wave passes through the detector 3023 as when it passes through the geocentre. The Earth rotates 3024 by about 1.5 urad during the 21 ms it takes light to travel 3025 the radius of the Earth, which corresponds to 10 m of 3026 displacement at the equator, or 33 light-ns. Therefore, 3027 the failure to do a proper retarded time calculation here 3028 results in errors as large as 33 ns. This is insignificant 3029 for burst searches, but be aware that this approximation is 3030 being made if the return value is used in other contexts. 3031 """ 3032 # the offset is subtracted from the time of the injection. 3033 # injections are done this way so that when the triggers 3034 # that result from an injection have the offset vector 3035 # added to their times the triggers will form a coinc 3036 t_geocent = self.time_geocent - offsetvector[instrument] 3037 ra, dec = self.ra_dec 3038 return t_geocent + lal.TimeDelayFromEarthCenter(lal.cached_detector_by_prefix[instrument].location, ra, dec, t_geocent)
3039
3040 - def get_time_geocent(self):
3041 # FIXME: delete this method 3042 warnings.warn("SimInspiral.get_time_geocent() is deprecated. use SimInspiral.time_geocent instead", DeprecationWarning) 3043 return self.time_geocent
3044
3045 - def set_time_geocent(self, gps):
3046 # FIXME: delete this method 3047 warnings.warn("SimInspiral.set_time_geocent() is deprecated. use SimInspiral.time_geocent instead", DeprecationWarning) 3048 self.time_geocent = gps
3049
3050 - def get_ra_dec(self):
3051 # FIXME: delete this method 3052 warnings.warn("SimInspiral.get_ra_dec() is deprecated. use SimInspiral.ra_dec instead", DeprecationWarning) 3053 return self.ra_dec
3054
3055 - def get_end(self, site = None):
3056 # FIXME: delete this method 3057 warnings.warn("SimInspiral.get_end() is deprecated. use SimInspiral.time_geocent or SimInspiral.time_at_instrument() instead", DeprecationWarning) 3058 if site is None: 3059 return self.time_geocent 3060 else: 3061 return LIGOTimeGPS(getattr(self, "%s_end_time" % site.lower()), getattr(self, "%s_end_time_ns" % site.lower()))
3062
3063 - def get_eff_dist(self, instrument):
3064 return getattr(self, "eff_dist_%s" % instrument[0].lower())
3065
3066 - def get_chirp_eff_dist(self, instrument, ref_mass = 1.4):
3067 return SnglInspiral.chirp_distance(self.get_eff_dist(instrument), self.mchirp, ref_mass)
3068
3069 - def get_spin_mag(self, objectnumber):
3070 s = getattr(self, "spin%d" % objectnumber) 3071 return math.sqrt(numpy.dot(s, s))
3072 3073 3074 SimInspiralTable.RowType = SimInspiral 3075 3076 3077 # 3078 # ============================================================================= 3079 # 3080 # sim_burst:table 3081 # 3082 # ============================================================================= 3083 # 3084 3085 3086 SimBurstID = ilwd.get_ilwdchar_class(u"sim_burst", u"simulation_id")
3087 3088 3089 -class SimBurstTable(table.Table):
3090 tableName = "sim_burst" 3091 validcolumns = { 3092 "process_id": "ilwd:char", 3093 "waveform": "lstring", 3094 "ra": "real_8", 3095 "dec": "real_8", 3096 "psi": "real_8", 3097 "time_geocent_gps": "int_4s", 3098 "time_geocent_gps_ns": "int_4s", 3099 "time_geocent_gmst": "real_8", 3100 "duration": "real_8", 3101 "frequency": "real_8", 3102 "bandwidth": "real_8", 3103 "q": "real_8", 3104 "pol_ellipse_angle": "real_8", 3105 "pol_ellipse_e": "real_8", 3106 "amplitude": "real_8", 3107 "hrss": "real_8", 3108 "egw_over_rsquared": "real_8", 3109 "waveform_number": "int_8u", 3110 "time_slide_id": "ilwd:char", 3111 "simulation_id": "ilwd:char" 3112 } 3113 constraints = "PRIMARY KEY (simulation_id)" 3114 next_id = SimBurstID(0) 3115 interncolumns = ("process_id", "waveform")
3116
3117 3118 -class SimBurst(table.Table.RowType):
3119 """ 3120 Example: 3121 3122 >>> x = SimBurst() 3123 >>> x.ra_dec = 0., 0. 3124 >>> x.ra_dec 3125 (0.0, 0.0) 3126 >>> x.ra_dec = None 3127 >>> print(x.ra_dec) 3128 None 3129 >>> x.time_geocent = None 3130 >>> print(x.time_geocent) 3131 None 3132 >>> print(x.time_geocent_gmst) 3133 None 3134 >>> x.time_geocent = LIGOTimeGPS(6e8) 3135 >>> print(x.time_geocent) 3136 600000000 3137 >>> print(x.time_geocent_gmst) 3138 -2238.39417156 3139 """ 3140 __slots__ = tuple(SimBurstTable.validcolumns.keys()) 3141 3142 time_geocent = gpsproperty_with_gmst("time_geocent_gps", "time_geocent_gps_ns", "time_geocent_gmst") 3143 3144 @property
3145 - def ra_dec(self):
3146 if self.ra is None and self.dec is None: 3147 return None 3148 return self.ra, self.dec
3149 3150 @ra_dec.setter
3151 - def ra_dec(self, radec):
3152 if radec is None: 3153 self.ra = self.dec = None 3154 else: 3155 self.ra, self.dec = radec
3156
3157 - def time_at_instrument(self, instrument, offsetvector):
3158 """ 3159 Return the "time" of the injection, delay corrected for the 3160 displacement from the geocentre to the given instrument. 3161 3162 NOTE: this method does not account for the rotation of the 3163 Earth that occurs during the transit of the plane wave from 3164 the detector to the geocentre. That is, it is assumed the 3165 Earth is in the same orientation with respect to the 3166 celestial sphere when the wave passes through the detector 3167 as when it passes through the geocentre. The Earth rotates 3168 by about 1.5 urad during the 21 ms it takes light to travel 3169 the radius of the Earth, which corresponds to 10 m of 3170 displacement at the equator, or 33 light-ns. Therefore, 3171 the failure to do a proper retarded time calculation here 3172 results in errors as large as 33 ns. This is insignificant 3173 for burst searches, but be aware that this approximation is 3174 being made if the return value is used in other contexts. 3175 """ 3176 # the offset is subtracted from the time of the injection. 3177 # injections are done this way so that when the triggers 3178 # that result from an injection have the offset vector 3179 # added to their times the triggers will form a coinc 3180 t_geocent = self.time_geocent - offsetvector[instrument] 3181 ra, dec = self.ra_dec 3182 return t_geocent + lal.TimeDelayFromEarthCenter(lal.cached_detector_by_prefix[instrument].location, ra, dec, t_geocent)
3183
3184 - def get_time_geocent(self):
3185 return self.time_geocent
3186
3187 - def set_time_geocent(self, gps):
3188 self.time_geocent = gps
3189
3190 - def get_ra_dec(self):
3191 return self.ra_dec
3192
3193 - def get_end(self, site = None):
3194 """ 3195 Do not use this method: use .time_at_instrument() if that's what you want, or use .time_geocent if that's what you want. 3196 3197 Also ... this doesn't return the *end time*, it returns the *PEAK TIME*. You've been warned. 3198 """ 3199 if site is None: 3200 return self.time_geocent 3201 instrument = site + "1" # ugh ... 3202 return self.time_at_instrument(instrument, {instrument: 0.0})
3203 3204 SimBurstTable.RowType = SimBurst 3205 3206 3207 # 3208 # ============================================================================= 3209 # 3210 # sim_ringdown:table 3211 # 3212 # ============================================================================= 3213 # 3214 3215 3216 SimRingdownID = ilwd.get_ilwdchar_class(u"sim_ringdown", u"simulation_id")
3217 3218 3219 -class SimRingdownTable(table.Table):
3220 tableName = "sim_ringdown" 3221 validcolumns = { 3222 "process_id": "ilwd:char", 3223 "waveform": "lstring", 3224 "coordinates": "lstring", 3225 "geocent_start_time": "int_4s", 3226 "geocent_start_time_ns": "int_4s", 3227 "h_start_time": "int_4s", 3228 "h_start_time_ns": "int_4s", 3229 "l_start_time": "int_4s", 3230 "l_start_time_ns": "int_4s", 3231 "v_start_time": "int_4s", 3232 "v_start_time_ns": "int_4s", 3233 "start_time_gmst": "real_8", 3234 "longitude": "real_4", 3235 "latitude": "real_4", 3236 "distance": "real_4", 3237 "inclination": "real_4", 3238 "polarization": "real_4", 3239 "frequency": "real_4", 3240 "quality": "real_4", 3241 "phase": "real_4", 3242 "mass": "real_4", 3243 "spin": "real_4", 3244 "epsilon": "real_4", 3245 "amplitude": "real_4", 3246 "eff_dist_h": "real_4", 3247 "eff_dist_l": "real_4", 3248 "eff_dist_v": "real_4", 3249 "hrss": "real_4", 3250 "hrss_h": "real_4", 3251 "hrss_l": "real_4", 3252 "hrss_v": "real_4", 3253 "simulation_id": "ilwd:char" 3254 } 3255 constraints = "PRIMARY KEY (simulation_id)" 3256 next_id = SimRingdownID(0) 3257 interncolumns = ("process_id", "waveform", "coordinates")
3258
3259 3260 -class SimRingdown(table.Table.RowType):
3261 __slots__ = tuple(SimRingdownTable.validcolumns.keys()) 3262
3263 - def get_start(self, site = None):
3264 if not site: 3265 return LIGOTimeGPS(self.geocent_start_time, self.geocent_start_time_ns) 3266 else: 3267 site = site[0].lower() 3268 return LIGOTimeGPS(getattr(self, site + '_start_time'), getattr(self, site + '_start_time_ns'))
3269 3270 3271 SimRingdownTable.RowType = SimRingdown 3272 3273 3274 # 3275 # ============================================================================= 3276 # 3277 # summ_value:table 3278 # 3279 # ============================================================================= 3280 # 3281 3282 3283 SummValueID = ilwd.get_ilwdchar_class(u"summ_value", u"summ_value_id")
3284 3285 3286 -class SummValueTable(table.Table):
3287 tableName = "summ_value" 3288 validcolumns = { 3289 "summ_value_id": "ilwd:char", 3290 "program": "lstring", 3291 "process_id": "ilwd:char", 3292 "frameset_group": "lstring", 3293 "segment_def_id": "ilwd:char", 3294 "start_time": "int_4s", 3295 "start_time_ns": "int_4s", 3296 "end_time": "int_4s", 3297 "end_time_ns": "int_4s", 3298 "ifo": "lstring", 3299 "name": "lstring", 3300 "value": "real_4", 3301 "error": "real_4", 3302 "intvalue": "int_4s", 3303 "comment": "lstring" 3304 } 3305 constraints = "PRIMARY KEY (summ_value_id)" 3306 next_id = SummValueID(0) 3307 interncolumns = ("program", "process_id", "ifo", "name", "comment")
3308
3309 3310 -class SummValue(table.Table.RowType):
3311 """ 3312 Example: 3313 3314 >>> x = SummValue() 3315 >>> x.instruments = (u"H1", u"L1") 3316 >>> x.ifo 3317 u'H1,L1' 3318 >>> x.instruments 3319 set([u'H1', u'L1']) 3320 >>> x.start = LIGOTimeGPS(0) 3321 >>> x.end = LIGOTimeGPS(10) 3322 >>> x.segment 3323 segment(LIGOTimeGPS(0, 0), LIGOTimeGPS(10, 0)) 3324 >>> x.segment = None 3325 >>> print(x.segment) 3326 None 3327 """ 3328 __slots__ = tuple(SummValueTable.validcolumns.keys()) 3329 3330 instruments = instrumentsproperty("ifo") 3331 3332 start = gpsproperty("start_time", "start_time_ns") 3333 end = gpsproperty("end_time", "end_time_ns") 3334 segment = segmentproperty("start", "end")
3335 3336 3337 SummValueTable.RowType = SummValue 3338 3339 3340 # 3341 # ============================================================================= 3342 # 3343 # sim_inst_params:table 3344 # 3345 # ============================================================================= 3346 # 3347 3348 3349 SimInstParamsID = ilwd.get_ilwdchar_class(u"sim_inst_params", u"simulation_id")
3350 3351 3352 -class SimInstParamsTable(table.Table):
3353 tableName = "sim_inst_params" 3354 validcolumns = { 3355 "simulation_id": "ilwd:char", 3356 "name": "lstring", 3357 "comment": "lstring", 3358 "value": "real_8" 3359 } 3360 next_id = SimInstParamsID(0)
3361
3362 3363 -class SimInstParams(table.Table.RowType):
3364 __slots__ = tuple(SimInstParamsTable.validcolumns.keys())
3365 3366 3367 SimInstParamsTable.RowType = SimInstParams
3368 3369 3370 # 3371 # ============================================================================= 3372 # 3373 # stochastic:table 3374 # 3375 # ============================================================================= 3376 # 3377 3378 3379 -class StochasticTable(table.Table):
3380 tableName = "stochastic" 3381 validcolumns = { 3382 "process_id": "ilwd:char", 3383 "ifo_one": "lstring", 3384 "ifo_two": "lstring", 3385 "channel_one": "lstring", 3386 "channel_two": "lstring", 3387 "start_time": "int_4s", 3388 "start_time_ns": "int_4s", 3389 "duration": "int_4s", 3390 "duration_ns": "int_4s", 3391 "f_min": "real_8", 3392 "f_max": "real_8", 3393 "cc_stat": "real_8", 3394 "cc_sigma": "real_8" 3395 }
3396
3397 3398 -class Stochastic(table.Table.RowType):
3399 __slots__ = tuple(StochasticTable.validcolumns.keys())
3400 3401 3402 StochasticTable.RowType = Stochastic
3403 3404 3405 # 3406 # ============================================================================= 3407 # 3408 # stochsumm:table 3409 # 3410 # ============================================================================= 3411 # 3412 3413 3414 -class StochSummTable(table.Table):
3415 tableName = "stochsumm" 3416 validcolumns = { 3417 "process_id": "ilwd:char", 3418 "ifo_one": "lstring", 3419 "ifo_two": "lstring", 3420 "channel_one": "lstring", 3421 "channel_two": "lstring", 3422 "start_time": "int_4s", 3423 "start_time_ns": "int_4s", 3424 "end_time": "int_4s", 3425 "end_time_ns": "int_4s", 3426 "f_min": "real_8", 3427 "f_max": "real_8", 3428 "y_opt": "real_8", 3429 "error": "real_8" 3430 }
3431
3432 3433 -class StochSumm(table.Table.RowType):
3434 __slots__ = tuple(StochSummTable.validcolumns.keys())
3435 3436 3437 StochSummTable.RowType = StochSumm
3438 3439 3440 # 3441 # ============================================================================= 3442 # 3443 # external_trigger:table 3444 # 3445 # ============================================================================= 3446 # 3447 3448 3449 # FIXME: this table is completely different from the official definition. 3450 # Someone *HAS* to sort this out. 3451 3452 3453 -class ExtTriggersTable(table.Table):
3454 tableName = "external_trigger" 3455 validcolumns = { 3456 "process_id": "ilwd:char", 3457 "det_alts": "lstring", 3458 "det_band": "lstring", 3459 "det_fluence": "lstring", 3460 "det_fluence_int": "lstring", 3461 "det_name": "lstring", 3462 "det_peak": "lstring", 3463 "det_peak_int": "lstring", 3464 "det_snr": "lstring", 3465 "email_time": "int_4s", 3466 "event_dec": "real_4", 3467 "event_dec_err": "real_4", 3468 "event_epoch": "lstring", 3469 "event_err_type": "lstring", 3470 "event_ra": "real_4", 3471 "event_ra_err": "real_4", 3472 "start_time": "int_4s", 3473 "start_time_ns": "int_4s", 3474 "event_type": "lstring", 3475 "event_z": "real_4", 3476 "event_z_err": "real_4", 3477 "notice_comments": "lstring", 3478 "notice_id": "lstring", 3479 "notice_sequence": "lstring", 3480 "notice_time": "int_4s", 3481 "notice_type": "lstring", 3482 "notice_url": "lstring", 3483 "obs_fov_dec": "real_4", 3484 "obs_fov_dec_width": "real_4", 3485 "obs_fov_ra": "real_4", 3486 "obs_fov_ra_width": "real_4", 3487 "obs_loc_ele": "real_4", 3488 "obs_loc_lat": "real_4", 3489 "obs_loc_long": "real_4", 3490 "ligo_fave_lho": "real_4", 3491 "ligo_fave_llo": "real_4", 3492 "ligo_delay": "real_4", 3493 "event_number_gcn": "int_4s", 3494 "event_number_grb": "lstring", 3495 "event_status": "int_4s" 3496 }
3497
3498 3499 -class ExtTriggers(table.Table.RowType):
3500 __slots__ = tuple(ExtTriggersTable.validcolumns.keys())
3501 3502 3503 ExtTriggersTable.RowType = ExtTriggers 3504 3505 3506 # 3507 # ============================================================================= 3508 # 3509 # filter:table 3510 # 3511 # ============================================================================= 3512 # 3513 3514 3515 FilterID = ilwd.get_ilwdchar_class(u"filter", u"filter_id")
3516 3517 3518 -class FilterTable(table.Table):
3519 tableName = "filter" 3520 validcolumns = { 3521 "process_id": "ilwd:char", 3522 "program": "lstring", 3523 "start_time": "int_4s", 3524 "filter_name": "lstring", 3525 "filter_id": "ilwd:char", 3526 "param_set": "int_4s", 3527 "comment": "lstring" 3528 } 3529 constraints = "PRIMARY KEY (filter_id)" 3530 next_id = FilterID(0)
3531
3532 3533 -class Filter(table.Table.RowType):
3534 __slots__ = tuple(FilterTable.validcolumns.keys())
3535 3536 3537 FilterTable.RowType = Filter 3538 3539 3540 # 3541 # ============================================================================= 3542 # 3543 # segment:table 3544 # 3545 # ============================================================================= 3546 # 3547 3548 3549 SegmentID = ilwd.get_ilwdchar_class(u"segment", u"segment_id")
3550 3551 3552 -class SegmentTable(table.Table):
3553 tableName = "segment" 3554 validcolumns = { 3555 "creator_db": "int_4s", 3556 "process_id": "ilwd:char", 3557 "segment_id": "ilwd:char", 3558 "start_time": "int_4s", 3559 "start_time_ns": "int_4s", 3560 "end_time": "int_4s", 3561 "end_time_ns": "int_4s", 3562 "segment_def_id": "ilwd:char", 3563 "segment_def_cdb": "int_4s" 3564 } 3565 constraints = "PRIMARY KEY (segment_id)" 3566 next_id = SegmentID(0) 3567 interncolumns = ("process_id",)
3568
3569 3570 -class Segment(table.Table.RowType):
3571 """ 3572 Example: 3573 3574 >>> x = Segment() 3575 >>> x.start = LIGOTimeGPS(0) 3576 >>> x.end = LIGOTimeGPS(10) 3577 >>> x.segment 3578 segment(LIGOTimeGPS(0, 0), LIGOTimeGPS(10, 0)) 3579 >>> x.segment = None 3580 >>> print(x.segment) 3581 None 3582 >>> print(x.start) 3583 None 3584 >>> # non-LIGOTimeGPS times are converted to LIGOTimeGPS 3585 >>> x.segment = (20, 30.125) 3586 >>> x.end 3587 LIGOTimeGPS(30, 125000000) 3588 >>> # initialization from a tuple or with arguments 3589 >>> Segment((20, 30)).segment 3590 segment(LIGOTimeGPS(20, 0), LIGOTimeGPS(30, 0)) 3591 >>> Segment(20, 30).segment 3592 segment(LIGOTimeGPS(20, 0), LIGOTimeGPS(30, 0)) 3593 >>> # use as a segment object in segmentlist operations 3594 >>> from glue import segments 3595 >>> x = segments.segmentlist([Segment(0, 10), Segment(20, 30)]) 3596 >>> abs(x) 3597 LIGOTimeGPS(20, 0) 3598 >>> y = segments.segmentlist([Segment(5, 15), Segment(25, 35)]) 3599 >>> abs(x & y) 3600 LIGOTimeGPS(10, 0) 3601 >>> abs(x | y) 3602 LIGOTimeGPS(30, 0) 3603 >>> 8.0 in x 3604 True 3605 >>> 12 in x 3606 False 3607 >>> Segment(2, 3) in x 3608 True 3609 >>> Segment(2, 12) in x 3610 False 3611 >>> segments.segment(2, 3) in x 3612 True 3613 >>> segments.segment(2, 12) in x 3614 False 3615 >>> # make sure results are segment table row objects 3616 >>> segments.segmentlist(map(Segment, x & y)) # doctest: +ELLIPSIS 3617 [<glue.ligolw.lsctables.Segment object at 0x...>, <glue.ligolw.lsctables.Segment object at 0x...>] 3618 3619 This implementation uses a non-standard extension to encode 3620 infinite values for boundaries: the second and nanosecond 3621 components are both set to 0x7FFFFFFF or 0xFFFFFFFF to indicate 3622 positive resp. negative infinity. For this reason, "denormalized" 3623 LIGOTimeGPS objects (objects whose nanoseconds fields contain 3624 values exceeding +/-999999999) are disallowed for use with this 3625 class. 3626 3627 Example: 3628 3629 >>> x = Segment() 3630 >>> # OK 3631 >>> x.start = -segments.infinity() 3632 >>> # also OK 3633 >>> x.start = float("-inf") 3634 >>> # infinite boundaries always returned as segments.infinity 3635 >>> # instances 3636 >>> x.start 3637 -infinity 3638 >>> x.end = float("+inf") 3639 >>> x.segment 3640 segment(-infinity, infinity) 3641 """ 3642 __slots__ = tuple(SegmentTable.validcolumns.keys()) 3643 3644 start = gpsproperty("start_time", "start_time_ns") 3645 end = gpsproperty("end_time", "end_time_ns") 3646 segment = segmentproperty("start", "end") 3647
3648 - def get(self):
3649 """ 3650 Return the segment described by this row. 3651 """ 3652 return self.segment
3653
3654 - def set(self, segment):
3655 """ 3656 Set the segment described by this row. 3657 """ 3658 self.segment = segment
3659 3660 # emulate a glue.segments.segment object 3661
3662 - def __abs__(self):
3663 return abs(self.segment)
3664
3665 - def __cmp__(self, other):
3666 return cmp(self.segment, other)
3667
3668 - def __contains__(self, other):
3669 return other in self.segment
3670
3671 - def __getitem__(self, i):
3672 return self.segment[i]
3673
3674 - def __init__(self, *args):
3675 if args: 3676 try: 3677 # first try unpacking arguments 3678 self.segment = args 3679 except ValueError: 3680 # didn't work, try unpacking 0th argument 3681 self.segment, = args
3682
3683 - def __len__(self):
3684 return len(self.segment)
3685
3686 - def __nonzero__(self):
3687 return bool(self.segment)
3688 3689 3690 SegmentTable.RowType = Segment 3691 3692 3693 # 3694 # ============================================================================= 3695 # 3696 # segment_definer:table 3697 # 3698 # ============================================================================= 3699 # 3700 3701 3702 SegmentDefID = ilwd.get_ilwdchar_class(u"segment_definer", u"segment_def_id")
3703 3704 3705 -class SegmentDefTable(table.Table):
3706 tableName = "segment_definer" 3707 validcolumns = { 3708 "creator_db": "int_4s", 3709 "process_id": "ilwd:char", 3710 "segment_def_id": "ilwd:char", 3711 "ifos": "lstring", 3712 "name": "lstring", 3713 "version": "int_4s", 3714 "comment": "lstring", 3715 "insertion_time": "int_4s" 3716 } 3717 constraints = "PRIMARY KEY (segment_def_id)" 3718 next_id = SegmentDefID(0) 3719 interncolumns = ("process_id",)
3720
3721 3722 -class SegmentDef(table.Table.RowType):
3723 """ 3724 Example: 3725 3726 >>> x = SegmentDef() 3727 >>> x.instruments = (u"H1", u"L1") 3728 >>> x.ifos 3729 u'H1,L1' 3730 >>> x.instruments 3731 set([u'H1', u'L1']) 3732 """ 3733 __slots__ = tuple(SegmentDefTable.validcolumns.keys()) 3734 3735 instruments = instrumentsproperty("ifos") 3736
3737 - def get_ifos(self):
3738 """ 3739 Return a set of the instruments for this row. 3740 """ 3741 return self.instruments
3742
3743 - def set_ifos(self, instruments):
3744 """ 3745 Serialize a sequence of instruments into the ifos 3746 attribute. The instrument names must not contain the "," 3747 character. 3748 """ 3749 self.instruments = instruments
3750 3751 3752 SegmentDefTable.RowType = SegmentDef 3753 3754 3755 # 3756 # ============================================================================= 3757 # 3758 # segment_summary:table 3759 # 3760 # ============================================================================= 3761 # 3762 3763 3764 SegmentSumID = ilwd.get_ilwdchar_class(u"segment_summary", u"segment_sum_id")
3765 3766 3767 -class SegmentSumTable(table.Table):
3768 tableName = "segment_summary" 3769 validcolumns = { 3770 "creator_db": "int_4s", 3771 "process_id": "ilwd:char", 3772 "segment_sum_id": "ilwd:char", 3773 "start_time": "int_4s", 3774 "start_time_ns": "int_4s", 3775 "end_time": "int_4s", 3776 "end_time_ns": "int_4s", 3777 "comment": "lstring", 3778 "segment_def_id": "ilwd:char", 3779 "segment_def_cdb": "int_4s" 3780 } 3781 constraints = "PRIMARY KEY (segment_sum_id)" 3782 next_id = SegmentSumID(0) 3783 interncolumns = ("process_id","segment_def_id") 3784
3785 - def get(self, segment_def_id = None):
3786 """ 3787 Return a segmentlist object describing the times spanned by 3788 the segments carrying the given segment_def_id. If 3789 segment_def_id is None then all segments are returned. 3790 3791 Note: the result is not coalesced, the segmentlist 3792 contains the segments as they appear in the table. 3793 """ 3794 if segment_def_id is None: 3795 return segments.segmentlist(row.segment for row in self) 3796 return segments.segmentlist(row.segment for row in self if row.segment_def_id == segment_def_id)
3797
3798 3799 -class SegmentSum(Segment):
3800 __slots__ = tuple(SegmentSumTable.validcolumns.keys())
3801 3802 3803 SegmentSumTable.RowType = SegmentSum 3804 3805 3806 3807 # 3808 # ============================================================================= 3809 # 3810 # time_slide:table 3811 # 3812 # ============================================================================= 3813 # 3814 3815 3816 TimeSlideID = ilwd.get_ilwdchar_class(u"time_slide", u"time_slide_id")
3817 3818 3819 -class TimeSlideTable(table.Table):
3820 tableName = "time_slide" 3821 validcolumns = { 3822 "process_id": "ilwd:char", 3823 "time_slide_id": "ilwd:char", 3824 "instrument": "lstring", 3825 "offset": "real_8" 3826 } 3827 constraints = "PRIMARY KEY (time_slide_id, instrument)" 3828 next_id = TimeSlideID(0) 3829 interncolumns = ("process_id", "time_slide_id", "instrument") 3830
3831 - def as_dict(self):
3832 """ 3833 Return a ditionary mapping time slide IDs to offset 3834 dictionaries. 3835 """ 3836 d = {} 3837 for row in self: 3838 if row.time_slide_id not in d: 3839 d[row.time_slide_id] = offsetvector.offsetvector() 3840 if row.instrument in d[row.time_slide_id]: 3841 raise KeyError("'%s': duplicate instrument '%s'" % (row.time_slide_id, row.instrument)) 3842 d[row.time_slide_id][row.instrument] = row.offset 3843 return d
3844
3845 - def append_offsetvector(self, offsetvect, process):
3846 """ 3847 Append rows describing an instrument --> offset mapping to 3848 this table. offsetvect is a dictionary mapping instrument 3849 to offset. process should be the row in the process table 3850 on which the new time_slide table rows will be blamed (or 3851 any object with a process_id attribute). The return value 3852 is the time_slide_id assigned to the new rows. 3853 """ 3854 time_slide_id = self.get_next_id() 3855 for instrument, offset in offsetvect.items(): 3856 row = self.RowType() 3857 row.process_id = process.process_id 3858 row.time_slide_id = time_slide_id 3859 row.instrument = instrument 3860 row.offset = offset 3861 self.append(row) 3862 return time_slide_id
3863
3864 - def get_time_slide_id(self, offsetdict, create_new = None, superset_ok = False, nonunique_ok = False):
3865 """ 3866 Return the time_slide_id corresponding to the offset vector 3867 described by offsetdict, a dictionary of instrument/offset 3868 pairs. 3869 3870 If the optional create_new argument is None (the default), 3871 then the table must contain a matching offset vector. The 3872 return value is the ID of that vector. If the table does 3873 not contain a matching offset vector then KeyError is 3874 raised. 3875 3876 If the optional create_new argument is set to a Process 3877 object (or any other object with a process_id attribute), 3878 then if the table does not contain a matching offset vector 3879 a new one will be added to the table and marked as having 3880 been created by the given process. The return value is the 3881 ID of the (possibly newly created) matching offset vector. 3882 3883 If the optional superset_ok argument is False (the default) 3884 then an offset vector in the table is considered to "match" 3885 the requested offset vector only if they contain the exact 3886 same set of instruments. If the superset_ok argument is 3887 True, then an offset vector in the table is considered to 3888 match the requested offset vector as long as it provides 3889 the same offsets for the same instruments as the requested 3890 vector, even if it provides offsets for other instruments 3891 as well. 3892 3893 More than one offset vector in the table might match the 3894 requested vector. If the optional nonunique_ok argument is 3895 False (the default), then KeyError will be raised if more 3896 than one offset vector in the table is found to match the 3897 requested vector. If the optional nonunique_ok is True 3898 then the return value is the ID of one of the matching 3899 offset vectors selected at random. 3900 """ 3901 # look for matching offset vectors 3902 if superset_ok: 3903 ids = [id for id, slide in self.as_dict().items() if offsetdict == dict((instrument, offset) for instrument, offset in slide.items() if instrument in offsetdict)] 3904 else: 3905 ids = [id for id, slide in self.as_dict().items() if offsetdict == slide] 3906 if len(ids) > 1: 3907 # found more than one 3908 if nonunique_ok: 3909 # and that's OK 3910 return ids[0] 3911 # and that's not OK 3912 raise KeyError("%s not unique" % repr(offsetdict)) 3913 if len(ids) == 1: 3914 # found one 3915 return ids[0] 3916 # offset vector not found in table 3917 if create_new is None: 3918 # and that's not OK 3919 raise KeyError("%s not found" % repr(offsetdict)) 3920 # that's OK, create new vector, return its ID 3921 return self.append_offsetvector(offsetdict, create_new)
3922
3923 3924 -class TimeSlide(table.Table.RowType):
3925 __slots__ = tuple(TimeSlideTable.validcolumns.keys())
3926 3927 3928 TimeSlideTable.RowType = TimeSlide 3929 3930 3931 # 3932 # ============================================================================= 3933 # 3934 # coinc_definer:table 3935 # 3936 # ============================================================================= 3937 # 3938 3939 3940 CoincDefID = ilwd.get_ilwdchar_class(u"coinc_definer", u"coinc_def_id")
3941 3942 3943 -class CoincDefTable(table.Table):
3944 tableName = "coinc_definer" 3945 validcolumns = { 3946 "coinc_def_id": "ilwd:char", 3947 "search": "lstring", 3948 "search_coinc_type": "int_4u", 3949 "description": "lstring" 3950 } 3951 constraints = "PRIMARY KEY (coinc_def_id)" 3952 next_id = CoincDefID(0) 3953 how_to_index = { 3954 "cd_ssct_index": ("search", "search_coinc_type") 3955 } 3956
3957 - def get_coinc_def_id(self, search, search_coinc_type, create_new = True, description = None):
3958 """ 3959 Return the coinc_def_id for the row in the table whose 3960 search string and search_coinc_type integer have the values 3961 given. If a matching row is not found, the default 3962 behaviour is to create a new row and return the ID assigned 3963 to the new row. If, instead, create_new is False then 3964 KeyError is raised when a matching row is not found. The 3965 optional description parameter can be used to set the 3966 description string assigned to the new row if one is 3967 created, otherwise the new row is left with no description. 3968 """ 3969 # look for the ID 3970 rows = [row for row in self if (row.search, row.search_coinc_type) == (search, search_coinc_type)] 3971 if len(rows) > 1: 3972 raise ValueError("(search, search coincidence type) = ('%s', %d) is not unique" % (search, search_coinc_type)) 3973 if len(rows) > 0: 3974 return rows[0].coinc_def_id 3975 3976 # coinc type not found in table 3977 if not create_new: 3978 raise KeyError((search, search_coinc_type)) 3979 row = self.RowType() 3980 row.coinc_def_id = self.get_next_id() 3981 row.search = search 3982 row.search_coinc_type = search_coinc_type 3983 row.description = description 3984 self.append(row) 3985 3986 # return new ID 3987 return row.coinc_def_id
3988
3989 3990 -class CoincDef(table.Table.RowType):
3991 __slots__ = tuple(CoincDefTable.validcolumns.keys())
3992 3993 3994 CoincDefTable.RowType = CoincDef 3995 3996 3997 # 3998 # ============================================================================= 3999 # 4000 # coinc_event:table 4001 # 4002 # ============================================================================= 4003 # 4004 4005 4006 CoincID = ilwd.get_ilwdchar_class(u"coinc_event", u"coinc_event_id")
4007 4008 4009 -class CoincTable(table.Table):
4010 tableName = "coinc_event" 4011 validcolumns = { 4012 "process_id": "ilwd:char", 4013 "coinc_def_id": "ilwd:char", 4014 "coinc_event_id": "ilwd:char", 4015 "time_slide_id": "ilwd:char", 4016 "instruments": "lstring", 4017 "nevents": "int_4u", 4018 "likelihood": "real_8" 4019 } 4020 constraints = "PRIMARY KEY (coinc_event_id)" 4021 next_id = CoincID(0) 4022 interncolumns = ("process_id", "coinc_def_id", "time_slide_id", "instruments") 4023 how_to_index = { 4024 "ce_cdi_index": ("coinc_def_id",), 4025 "ce_tsi_index": ("time_slide_id",) 4026 }
4027
4028 4029 -class Coinc(table.Table.RowType):
4030 __slots__ = tuple(CoincTable.validcolumns.keys()) 4031 4032 insts = instrumentsproperty("instruments") 4033
4034 - def get_instruments(self):
4035 return self.insts
4036
4037 - def set_instruments(self, instruments):
4038 self.insts = instruments
4039 4040 4041 CoincTable.RowType = Coinc
4042 4043 4044 # 4045 # ============================================================================= 4046 # 4047 # coinc_event_map:table 4048 # 4049 # ============================================================================= 4050 # 4051 4052 4053 -class CoincMapTable(table.Table):
4054 tableName = "coinc_event_map" 4055 validcolumns = { 4056 "coinc_event_id": "ilwd:char", 4057 "table_name": "char_v", 4058 "event_id": "ilwd:char" 4059 } 4060 interncolumns = ("table_name",) 4061 how_to_index = { 4062 "cem_tn_ei_index": ("table_name", "event_id"), 4063 "cem_cei_index": ("coinc_event_id",) 4064 }
4065
4066 4067 -class CoincMap(table.Table.RowType):
4068 __slots__ = tuple(CoincMapTable.validcolumns.keys())
4069 4070 4071 CoincMapTable.RowType = CoincMap 4072 4073 4074 # 4075 # ============================================================================= 4076 # 4077 # dq_list Table 4078 # 4079 # ============================================================================= 4080 # 4081 4082 4083 DQSpecListID = ilwd.get_ilwdchar_class(u"dq_list", u"dq_list_id") 4084 DQSpecListRowID = ilwd.get_ilwdchar_class(u"dq_list", u"dq_list_row_id")
4085 4086 4087 -class DQSpecListTable(table.Table):
4088 tableName = "dq_list" 4089 validcolumns = { 4090 "dq_list_id": "ilwd:char", 4091 "dq_list_row_id": "ilwd:char", 4092 "instrument": "lstring", 4093 "flag": "lstring", 4094 "low_window": "real_8", 4095 "high_window": "real_8" 4096 } 4097 constraints = "PRIMARY KEY (dq_list_id, dq_list_row_id)" 4098 next_id = DQSpecListID(0)
4099
4100 4101 -class DQSpec(table.Table.RowType):
4102 __slots__ = tuple(DQSpecListTable.validcolumns.keys()) 4103
4104 - def apply_to_segmentlist(self, seglist):
4105 """ 4106 Apply our low and high windows to the segments in a 4107 segmentlist. 4108 """ 4109 for i, seg in enumerate(seglist): 4110 seglist[i] = seg.__class__(seg[0] - self.low_window, seg[1] + self.high_window)
4111 4112 4113 DQSpecListTable.RowType = DQSpec 4114 4115 4116 # 4117 # ============================================================================= 4118 # 4119 # ligolw_mon:table 4120 # 4121 # ============================================================================= 4122 # 4123 4124 4125 LIGOLWMonID = ilwd.get_ilwdchar_class(u"ligolw_mon", u"event_id")
4126 4127 4128 -class LIGOLWMonTable(table.Table):
4129 tableName = "ligolw_mon" 4130 validcolumns = { 4131 "creator_db": "int_4s", 4132 "process_id": "ilwd:char", 4133 "time": "int_4s", 4134 "time_ns": "int_4s", 4135 "amplitude": "real_8", 4136 "confidence": "real_8", 4137 "frequency": "real_8", 4138 "event_id": "ilwd:char", 4139 "insertion_time": "int_4s" 4140 } 4141 constraints = "PRIMARY KEY (event_id)" 4142 next_id = LIGOLWMonID(0)
4143
4144 4145 -class LIGOLWMon(table.Table.RowType):
4146 __slots__ = tuple(LIGOLWMonTable.validcolumns.keys()) 4147
4148 - def get_time(self):
4149 return LIGOTimeGPS(self.time, self.time_ns)
4150
4151 - def set_time(self, gps):
4152 self.time, self.time_ns = gps.seconds, gps.nanoseconds
4153 4154 4155 LIGOLWMonTable.RowType = LIGOLWMon
4156 4157 4158 # 4159 # ============================================================================= 4160 # 4161 # veto_definer:table 4162 # 4163 # ============================================================================= 4164 # 4165 4166 4167 -class VetoDefTable(table.Table):
4168 tableName = "veto_definer" 4169 validcolumns = { 4170 "process_id": "ilwd:char", 4171 "ifo": "lstring", 4172 "name": "lstring", 4173 "version": "int_4s", 4174 "category": "int_4s", 4175 "start_time": "int_4s", 4176 "end_time": "int_4s", 4177 "start_pad": "int_4s", 4178 "end_pad": "int_4s", 4179 "comment": "lstring" 4180 } 4181 interncolumns = ("process_id","ifo")
4182
4183 4184 -class VetoDef(table.Table.RowType):
4185 __slots__ = tuple(VetoDefTable.validcolumns.keys())
4186 4187 4188 VetoDefTable.RowType = VetoDef 4189 4190 4191 # 4192 # ============================================================================= 4193 # 4194 # summ_mime:table 4195 # 4196 # ============================================================================= 4197 # 4198 4199 4200 SummMimeID = ilwd.get_ilwdchar_class(u"summ_mime", u"summ_mime_id")
4201 4202 4203 -class SummMimeTable(table.Table):
4204 tableName = "summ_mime" 4205 validcolumns = { 4206 "origin": "lstring", 4207 "process_id": "ilwd:char", 4208 "filename": "lstring", 4209 "submitter": "lstring", 4210 "frameset_group": "lstring", 4211 "segment_def_id": "ilwd:char", 4212 "start_time": "int_4s", 4213 "start_time_ns": "int_4s", 4214 "end_time": "int_4s", 4215 "end_time_ns": "int_4s", 4216 "channel": "lstring", 4217 "descrip": "lstring", 4218 "mimedata": "blob", 4219 "mimedata_length": "int_4s", 4220 "mimetype": "lstring", 4221 "comment": "lstring", 4222 "summ_mime_id": "ilwd:char" 4223 } 4224 constraints = "PRIMARY KEY (summ_mime_id)" 4225 next_id = SummMimeID(0)
4226
4227 4228 -class SummMime(table.Table.RowType):
4229 __slots__ = tuple(SummMimeTable.validcolumns.keys()) 4230
4231 - def get_start(self):
4232 return LIGOTimeGPS(self.start_time, self.start_time_ns)
4233
4234 - def set_start(self, gps):
4235 self.start_time, self.start_time_ns = gps.seconds, gps.nanoseconds
4236
4237 - def get_end(self):
4238 return LIGOTimeGPS(self.end_time, self.end_time_ns)
4239
4240 - def set_end(self, gps):
4241 self.end_time, self.end_time_ns = gps.seconds, gps.nanoseconds
4242 4243 4244 SummMimeTable.RowType = SummMime
4245 4246 4247 # 4248 # ============================================================================= 4249 # 4250 # time_slide_segment_map:table 4251 # 4252 # ============================================================================= 4253 # 4254 4255 4256 -class TimeSlideSegmentMapTable(table.Table):
4257 tableName = "time_slide_segment_map" 4258 validcolumns = { 4259 "segment_def_id": "ilwd:char", 4260 "time_slide_id": "ilwd:char", 4261 }
4262
4263 4264 -class TimeSlideSegmentMap(table.Table.RowType):
4265 __slots__ = tuple(TimeSlideSegmentMapTable.validcolumns.keys())
4266 4267 4268 TimeSlideSegmentMapTable.RowType = TimeSlideSegmentMap 4269 4270 4271 # 4272 # ============================================================================= 4273 # 4274 # Table Metadata 4275 # 4276 # ============================================================================= 4277 # 4278 4279 4280 # 4281 # Table name ---> table type mapping. 4282 # 4283 4284 4285 TableByName = { 4286 CoincDefTable.tableName: CoincDefTable, 4287 CoincInspiralTable.tableName: CoincInspiralTable, 4288 CoincMapTable.tableName: CoincMapTable, 4289 CoincRingdownTable.tableName: CoincRingdownTable, 4290 CoincTable.tableName: CoincTable, 4291 DQSpecListTable.tableName: DQSpecListTable, 4292 ExperimentMapTable.tableName: ExperimentMapTable, 4293 ExperimentSummaryTable.tableName: ExperimentSummaryTable, 4294 ExperimentTable.tableName: ExperimentTable, 4295 ExtTriggersTable.tableName: ExtTriggersTable, 4296 FilterTable.tableName: FilterTable, 4297 GDSTriggerTable.tableName: GDSTriggerTable, 4298 LfnTable.tableName: LfnTable, 4299 LIGOLWMonTable.tableName: LIGOLWMonTable, 4300 MultiBurstTable.tableName: MultiBurstTable, 4301 MultiInspiralTable.tableName: MultiInspiralTable, 4302 ProcessParamsTable.tableName: ProcessParamsTable, 4303 ProcessTable.tableName: ProcessTable, 4304 SearchSummaryTable.tableName: SearchSummaryTable, 4305 SearchSummVarsTable.tableName: SearchSummVarsTable, 4306 SegmentDefTable.tableName: SegmentDefTable, 4307 SegmentSumTable.tableName: SegmentSumTable, 4308 SegmentTable.tableName: SegmentTable, 4309 SimBurstTable.tableName: SimBurstTable, 4310 SimInspiralTable.tableName: SimInspiralTable, 4311 SimInstParamsTable.tableName: SimInstParamsTable, 4312 SimRingdownTable.tableName: SimRingdownTable, 4313 SnglBurstTable.tableName: SnglBurstTable, 4314 SnglInspiralTable.tableName: SnglInspiralTable, 4315 SnglRingdownTable.tableName: SnglRingdownTable, 4316 StochasticTable.tableName: StochasticTable, 4317 StochSummTable.tableName: StochSummTable, 4318 SummValueTable.tableName: SummValueTable, 4319 SummMimeTable.tableName: SummMimeTable, 4320 TimeSlideSegmentMapTable.tableName: TimeSlideSegmentMapTable, 4321 TimeSlideTable.tableName: TimeSlideTable, 4322 VetoDefTable.tableName: VetoDefTable 4323 }
4324 4325 4326 -def reset_next_ids(classes):
4327 """ 4328 For each class in the list, if the .next_id attribute is not None 4329 (meaning the table has an ID generator associated with it), set 4330 .next_id to 0. This has the effect of reseting the ID generators, 4331 and is useful in applications that process multiple documents and 4332 add new rows to tables in those documents. Calling this function 4333 between documents prevents new row IDs from growing continuously 4334 from document to document. There is no need to do this, it's 4335 purpose is merely aesthetic, but it can be confusing to open a 4336 document and find process ID 300 in the process table and wonder 4337 what happened to the other 299 processes. 4338 4339 Example: 4340 4341 >>> reset_next_ids(TableByName.values()) 4342 """ 4343 for cls in classes: 4344 cls.reset_next_id()
4345
4346 4347 # 4348 # ============================================================================= 4349 # 4350 # Content Handler 4351 # 4352 # ============================================================================= 4353 # 4354 4355 4356 # 4357 # Override portions of a ligolw.LIGOLWContentHandler class 4358 # 4359 4360 4361 -def use_in(ContentHandler):
4362 """ 4363 Modify ContentHandler, a sub-class of 4364 glue.ligolw.LIGOLWContentHandler, to cause it to use the Table 4365 classes defined in this module when parsing XML documents. 4366 4367 Example: 4368 4369 >>> from glue.ligolw import ligolw 4370 >>> class MyContentHandler(ligolw.LIGOLWContentHandler): 4371 ... pass 4372 ... 4373 >>> use_in(MyContentHandler) 4374 <class 'glue.ligolw.lsctables.MyContentHandler'> 4375 """ 4376 ContentHandler = table.use_in(ContentHandler) 4377 4378 def startTable(self, parent, attrs, __orig_startTable = ContentHandler.startTable): 4379 name = table.Table.TableName(attrs[u"Name"]) 4380 if name in TableByName: 4381 return TableByName[name](attrs) 4382 return __orig_startTable(self, parent, attrs)
4383 4384 ContentHandler.startTable = startTable 4385 4386 return ContentHandler 4387