1   
   2   
   3   
   4   
   5   
   6   
   7   
   8   
   9  ''' 
  10  A collection of utilities to assist in printing out information from an xmldoc. 
  11  ''' 
  12   
  13  import sys, re, math 
  14  import time, datetime 
  15   
  16  from glue import iterutils 
  17  from glue.ligolw.utils import print_tables 
  18  from glue.ligolw import ligolw 
  19  from glue.ligolw import table 
  20  from glue.ligolw import lsctables 
  21  from glue import git_version 
  22   
  23  from pylal.xlal.date import XLALGPSToUTC 
  24  try: 
  25      from pylal.xlal.datatypes.ligotimegps import LIGOTimeGPS 
  26  except ImportError: 
  27       
  28      from pylal.xlal.date import LIGOTimeGPS 
  29   
  30   
  31  __author__ = "Collin Capano <cdcapano@physics.syr.edu>" 
  32  __version__ = git_version.id 
  42      if obj.value is None: 
  43          return None 
  44      return ligolwtypes.ToPyType[obj.type or "lstring"](obj.value) 
   45   
  48      """ 
  49      Retrieves canonical columns to print for the given tableName. 
  50      Returns a columnList, row_span and rspan_break lists. 
  51   
  52      @with_sngl: for the loudest_events table, if with_sngl turned on, will print 
  53       sngl_ifo end_times 
  54      """ 
  55      tableName = table.Table.TableName(tableName) 
  56      summTable = table.get_table(xmldoc, tableName ) 
  57       
  58      rankname = [col.getAttribute("Name").split(":")[-1] 
  59          for col in summTable.getElementsByTagName(u'Column') if "rank" in col.getAttribute("Name")][0] 
  60   
  61      if tableName == "loudest_events" and not with_sngl: 
  62          durname = [col.getAttribute("Name").split(":")[-1] 
  63              for col in summTable.getElementsByTagName(u'Column') if "_duration__Px_" in col.getAttribute("Name") 
  64              and not col.getAttribute("Name").split(":")[-1].startswith('sngl_')][0] 
  65          columnList = [ 
  66              rankname, 
  67              'combined_far', 
  68              'fap', 
  69              'fap_1yr', 
  70              'snr', 
  71              'end_time', 
  72              'gps_time_utc__Px_click_for_daily_ihope_xP_', 
  73              'ifos__Px_click_for_elog_xP_', 
  74              'instruments_on', 
  75              'mass', 
  76              'mchirp', 
  77              'mini_followup', 
  78              'omega_scan', 
  79              durname] 
  80          row_span_columns = rspan_break_columns = [durname] 
  81      elif tableName == "loudest_events" and with_sngl: 
  82          durname = [col.getAttribute("Name").split(":")[-1] 
  83              for col in summTable.getElementsByTagName(u'Column') if "_duration__Px_" in col.getAttribute("Name") 
  84              and not col.getAttribute("Name").split(":")[-1].startswith(u'sngl_')][0] 
  85          columnList = [ 
  86              rankname, 
  87              'combined_far', 
  88              'fap', 
  89              'fap_1yr', 
  90              'snr', 
  91              'mass', 
  92              'mchirp', 
  93              'instruments_on', 
  94              'sngl_ifo__Px_click_for_elog_xP_', 
  95              'sngl_end_time', 
  96              'sngl_event_time_utc__Px_click_for_daily_ihope_xP_', 
  97              'mini_followup', 
  98              'omega_scan', 
  99              durname] 
 100          row_span_columns = rspan_break_columns = \ 
 101              [col for col in summTable.columnnames if not col.startswith('sngl_')] 
 102      elif tableName == "selected_found_injections": 
 103          durname = [col.getAttribute("Name").split(":")[-1] 
 104              for col in summTable.getElementsByTagName(u'Column') if "_duration__Px_" in col.getAttribute("Name")][0] 
 105          columnList = [ 
 106              rankname, 
 107              'injected_gps_time', 
 108              'injected_event_time_utc__Px_click_for_daily_ihope_xP_', 
 109              'elogs', 
 110              'mini_followup', 
 111              'omega_scan', 
 112              'sim_tag', 
 113              'injected_decisive_distance', 
 114              'injected_mchirp', 
 115              'injected_mass1', 
 116              'injected_mass2', 
 117              'recovered_match_rank', 
 118              'recovered_ifos', 
 119              'recovered_combined_far', 
 120              'recovered_fap', 
 121              'recovered_fap_1yr', 
 122              'recovered_snr', 
 123              'recovered_gps_time', 
 124              'recovered_mchirp', 
 125              'recovered_mass'] 
 126          row_span_columns = rspan_break_columns = [ 
 127              rankname, 
 128              'injected_gps_time', 
 129              'injected_event_time_utc__Px_click_for_daily_ihope_xP_', 
 130              'elogs', 
 131              'mini_followup', 
 132              'omega_scan', 
 133              'sim_tag', 
 134              'injected_decisive_distance', 
 135              'injected_mchirp', 
 136              'injected_mass1', 
 137              'injected_mass2'] 
 138          if with_sngl: 
 139              row_span_columns.extend( [col for col in summTable.columnnames if col.startswith('recovered_')] ) 
 140      elif tableName == "close_missed_injections": 
 141          columnList = [ 
 142              'rank', 
 143              'decisive_distance', 
 144              'gps_time', 
 145              'injection_time_utc__Px_click_for_daily_ihope_xP_', 
 146              'elogs', 
 147              'mchirp', 
 148              'mass1', 
 149              'mass2', 
 150              'eff_dist_h', 
 151              'eff_dist_l', 
 152              'eff_dist_v', 
 153              'sim_tag', 
 154              'mini_followup', 
 155              'omega_scan' 
 156              ] 
 157          row_span_columns = rspan_break_columns = [] 
 158      else: 
 159           
 160          columnList = [col.getAttribute("Name").split(":")[-1] for col in summTable.getElementsByTagName(u'Column')] 
 161          row_span_columns = rspan_break_columns = [] 
 162           
 163      return columnList, row_span_columns, rspan_break_columns 
  164   
 171      """ 
 172      Figures out what dates daylight savings time starts and ends at a given site on a given year. 
 173      """ 
 174       
 175       
 176      if ("H" in ifo  or "L" in ifo) and year < 2007: 
 177          for ii in range(1,28): 
 178              dst_start = datetime.datetime(year, 4, ii, 2, 0, 0) 
 179              if dst_start.strftime('%A') == 'Sunday': 
 180                  break 
 181          for ii in range(31,0,-1): 
 182              dst_end = datetime.datetime(year, 10, ii, 2, 0, 0) 
 183              if dst_end.strftime('%A') == 'Sunday': 
 184                  break 
 185       
 186       
 187      elif ("H" in ifo  or "L" in ifo) and year >= 2007: 
 188          nn = 1 
 189          for ii in range(1,31): 
 190              dst_start = datetime.datetime(year, 3, ii, 2, 0, 0) 
 191              if dst_start.strftime('%A') == 'Sunday' and nn == 2: 
 192                  break 
 193              elif dst_start.strftime('%A') == 'Sunday': 
 194                  nn += 1 
 195          for ii in range(1,28): 
 196              dst_end = datetime.datetime(year, 11, ii, 2, 0, 0) 
 197              if dst_end.strftime('%A') == 'Sunday': 
 198                  break 
 199       
 200       
 201      elif ("V" in ifo or "G" in ifo): 
 202          for ii in range(31,0,-1): 
 203              dst_start = datetime.datetime(year, 3, ii, 2, 0, 0) 
 204              if dst_start.strftime('%A') == 'Sunday': 
 205                  break 
 206          for ii in range(31,0,-1): 
 207              dst_end = datetime.datetime(year, 10, ii, 2, 0, 0) 
 208              if dst_end.strftime('%A') == 'Sunday': 
 209                  break 
 210      else: 
 211          raise ValueError, "unrecognized ifo %s" % ifo 
 212       
 213      return dst_start, dst_end 
  214           
 217       
 218      utctime = XLALGPSToUTC(LIGOTimeGPS(gpstime, 0)) 
 219      utctime = datetime.datetime(utctime[0],utctime[1],utctime[2],utctime[3],utctime[4],utctime[5],utctime[6]) 
 220       
 221      dst_start, dst_end = get_dst_start_end(ifo, utctime.year) 
 222       
 223      if "H" in ifo: 
 224          toffset = datetime.timedelta(hours=-7) 
 225      elif "L" in ifo: 
 226          toffset = datetime.timedelta(hours=-5) 
 227      elif ("V" in ifo or "G" in ifo): 
 228          toffset = datetime.timedelta(hours=+2) 
 229       
 230      if not (utctime + toffset >= dst_start and utctime + toffset < dst_end): 
 231          toffset = toffset + datetime.timedelta(hours=-1) 
 232   
 233      return utctime + toffset 
  234   
 238   
 239   
 240 -def get_elog_page(ifo, gpstime): 
  241       
 242      if "H" in ifo: 
 243          site_address = "http://ilog.ligo-wa.caltech.edu/ilog/pub/ilog.cgi?group=detector" 
 244      elif "L" in ifo: 
 245          site_address = "http://ilog.ligo-la.caltech.edu/ilog/pub/ilog.cgi?group=detector" 
 246      elif "V" in ifo: 
 247           
 248          site_address = "https://pub3.ego-gw.it/logbook/" 
 249       
 250      site_localtime = get_sitelocaltime_from_gps(ifo, gpstime) 
 251       
 252      if "H" in ifo or "L" in ifo: 
 253          site_address = "%s&date_to_view=%s" % ( site_address, site_localtime.strftime("%m/%d/%Y") ) 
 254   
 255      return site_address 
  256   
 257 -def get_daily_ihope_page(gpstime, pages_location = "https://ldas-jobs.ligo.caltech.edu/~cbc/ihope_daily"): 
  258      utctime = XLALGPSToUTC(LIGOTimeGPS(gpstime, 0)) 
 259      return "%s/%s/%s/" %(pages_location, time.strftime("%Y%m", utctime), time.strftime("%Y%m%d", utctime)) 
  260   
 263      return '<a href="%s"%s>%s</a>' % (address, external and ' rel="external"' or '', link) 
  264   
 265   
 266 -def create_filter( connection, tableName, param_name = None, param_ranges = None,  
 267      exclude_coincs = None, include_only_coincs = None, sim_tag = 'ALLINJ', verbose = False): 
  268      """ 
 269      Strings together param_name, param_ranges, exclude/include_only_coincs, and 
 270      sim_tag options into a filter string that can be stuck in a sqlite WHERE clause. 
 271      """ 
 272      from pylal import ligolw_sqlutils as sqlutils 
 273   
 274      in_this_filter = '' 
 275       
 276       
 277      if param_name is not None: 
 278          param_name = sqlutils.validate_option(param_name) 
 279          param_filters = sqlutils.parse_param_ranges( tableName, param_name,  
 280              param_ranges, verbose = verbose ).get_param_filters() 
 281           
 282           
 283          param_filters = '\n\t\tOR '.join( param_filters ) 
 284          in_this_filter = ''.join([ in_this_filter, '\n\tAND (\n\t\t', param_filters, '\n\t)' ]) 
 285       
 286       
 287      if exclude_coincs is not None: 
 288          exclude_coinc_filters = sqlutils.parse_coinc_options( exclude_coincs,  
 289              verbose = verbose ).get_coinc_filters( coinc_instruments_table = tableName ) 
 290           
 291          exclude_coinc_filters = '\n\t\tOR '.join( exclude_coinc_filters ) 
 292           
 293          in_this_filter = ''.join([ in_this_filter, '\n\tAND NOT (\n\t\t', exclude_coinc_filters, '\n\t)' ])  
 294       
 295       
 296      if include_only_coincs is not None: 
 297          include_coinc_filters = sqlutils.parse_coinc_options( include_only_coincs,  
 298              verbose = verbose ).get_coinc_filters( coinc_instruments_table = tableName ) 
 299           
 300          include_coinc_filters = '\n\t\tOR '.join( include_coinc_filters ) 
 301           
 302          in_this_filter = ''.join([ in_this_filter, '\n\tAND (\n\t\t', include_coinc_filters, '\n\t)' ]) 
 303       
 304       
 305      if sim_tag != 'ALLINJ': 
 306           
 307          sim_map = sqlutils.sim_tag_proc_id_mapper( connection ) 
 308          connection.create_function( 'get_sim_tag', 1, sim_map.get_sim_tag ) 
 309           
 310          sim_filter = '' 
 311          sim_list = sim_tag.split('+') 
 312          for sim_tag in sim_list: 
 313               
 314              sim_tag = sqlutils.validate_option(sim_tag, lower = False).upper() 
 315              if sim_tag not in sim_map.tag_id_map.keys(): 
 316                  raise ValueError, "sim-tag %s not found in database" % sim_tag 
 317               
 318              sim_filter = '\n\t\tOR '.join([ sim_filter, ''.join(['get_sim_tag(experiment_summary.sim_proc_id) == "', sim_tag, '"' ]) ]) 
 319   
 320           
 321          sim_filter = re.sub(r'OR ', '', sim_filter, 1) 
 322          in_this_filter = ''.join([ in_this_filter, '\n\tAND (', sim_filter, '\n\t)' ]) 
 323   
 324       
 325      in_this_filter = re.sub(r'\n\tAND', '', in_this_filter, 1) 
 326   
 327      return in_this_filter 
  328   
 329   
 330   
 331   
 332   
 333   
 334   
 335   
 336 -def printsims(connection, simulation_table, recovery_table, map_label, ranking_stat, rank_by, comparison_datatype, 
 337      sort_by = 'rank', param_name = None, param_ranges = None, exclude_coincs = None, include_only_coincs = None, 
 338      sim_tag = 'ALLINJ', rank_range = None, convert_durations = 's', 
 339      daily_ihope_pages_location = 'https://ldas-jobs.ligo.caltech.edu/~cbc/ihope_daily', verbose = False): 
  340   
 341      from pylal import ligolw_sqlutils as sqlutils 
 342   
 343       
 344      simulation_table = sqlutils.validate_option(simulation_table) 
 345      recovery_table = sqlutils.validate_option(recovery_table) 
 346      ranking_stat = sqlutils.validate_option(ranking_stat) 
 347      rank_by = sqlutils.validate_option(rank_by, lower = False).upper() 
 348      comparison_datatype = sqlutils.validate_option(comparison_datatype) 
 349      convert_durations = sqlutils.validate_option(convert_durations) 
 350       
 351      if rank_by == 'MIN': 
 352          rank_by = 'ASC' 
 353      elif rank_by == 'MAX': 
 354          rank_by = 'DESC' 
 355      elif rank_by != 'ASC' or rank_by != 'DESC': 
 356          raise ValueError, 'rank_by must be MAX (or DESC) or MIN (or ASC)' 
 357   
 358      if not ranking_stat.startswith(recovery_table): 
 359          ranking_stat = '.'.join([recovery_table, ranking_stat]) 
 360   
 361       
 362       
 363       
 364      if 'sim_rec_map' not in sqlutils.get_tables_in_database( connection ): 
 365          sqlutils.create_sim_rec_map_table(connection, simulation_table, recovery_table, map_label, ranking_stat) 
 366       
 367       
 368       
 369       
 370       
 371      if verbose: 
 372          print >> sys.stderr, "Getting statistics for ranking..." 
 373      ranker = sqlutils.rank_stats(recovery_table, ranking_stat, rank_by) 
 374       
 375      rank_filter = ''.join([ 
 376              recovery_table, '''.coinc_event_id NOT IN ( 
 377                  SELECT 
 378                      rec_id 
 379                  FROM 
 380                      sim_rec_map) 
 381              AND 
 382                  experiment_summary.datatype == "''', comparison_datatype, '"']) 
 383       
 384       
 385       
 386      in_this_filter = create_filter(connection, recovery_table, param_name = param_name, param_ranges = param_ranges, 
 387          exclude_coincs = exclude_coincs, include_only_coincs = include_only_coincs, 
 388          sim_tag = comparison_datatype == 'simulation' and sim_tag or 'ALLINJ', 
 389          verbose = False) 
 390      if in_this_filter != '': 
 391          rank_filter = '\n\tAND '.join([ in_this_filter, rank_filter ]) 
 392   
 393      rank_filter = '\n\t'.join([ sqlutils.join_experiment_tables_to_coinc_table(recovery_table), 'WHERE', rank_filter ]) 
 394       
 395      ranker.populate_stats_list(connection, limit = None, filter = rank_filter) 
 396      connection.create_function( 'rank', 1, ranker.get_rank ) 
 397       
 398       
 399       
 400       
 401      in_this_filter = create_filter(connection, recovery_table, param_name = param_name, param_ranges = param_ranges, 
 402          exclude_coincs = exclude_coincs, include_only_coincs = include_only_coincs, sim_tag = sim_tag, 
 403          verbose = verbose) 
 404       
 405       
 406       
 407       
 408       
 409       
 410       
 411       
 412      if in_this_filter != '': 
 413           
 414          in_this_filter = ''.join([ sqlutils.join_experiment_tables_to_coinc_table(recovery_table), "\n    WHERE\n\t", in_this_filter ]) 
 415          sqlscript = ''.join([ """ 
 416              CREATE TEMP TABLE del_ids AS 
 417                  SELECT 
 418                      sim_id AS del_id 
 419                  FROM 
 420                      sim_rec_map 
 421                  WHERE 
 422                      rec_id NOT IN ( 
 423                      SELECT 
 424                          """, recovery_table, """.coinc_event_id 
 425                      FROM 
 426                          """, recovery_table, """ 
 427                      """, in_this_filter, """ 
 428                          AND experiment_summary.datatype == "simulation" 
 429                      ); 
 430           
 431              DELETE FROM 
 432                  sim_rec_map 
 433              WHERE 
 434                  sim_id IN ( 
 435                      SELECT 
 436                          del_id 
 437                      FROM 
 438                          del_ids ); 
 439           
 440              DROP TABLE del_ids;""" ]) 
 441          connection.cursor().executescript(sqlscript) 
 442       
 443       
 444       
 445       
 446       
 447       
 448      def convert_duration( duration ): 
 449          return sqlutils.convert_duration( duration, convert_durations ) 
  450      connection.create_function( 'convert_duration', 1, convert_duration ) 
 451       
 452       
 453      sim_map = sqlutils.sim_tag_proc_id_mapper( connection ) 
 454      connection.create_function( 'get_sim_tag', 1, sim_map.get_sim_tag ) 
 455      
 456       
 457      if rank_range is not None: 
 458          rank_range_parser = sqlutils.parse_param_ranges( 'rank(sim_rec_map', 'ranking_stat)', 
 459              rank_range, verbose = verbose ) 
 460       
 461       
 462       
 463       
 464       
 465       
 466      simulation_table_columns = sqlutils.get_column_names_from_table( connection, simulation_table ) 
 467      recovery_table_columns = sqlutils.get_column_names_from_table( connection, recovery_table ) 
 468       
 469       
 470      injected_cols = [] 
 471      for col in simulation_table_columns: 
 472          if col == 'simulation_id': 
 473              injected_cols.append('simulation_id') 
 474          else: 
 475              injected_cols.append('injected_'+col) 
 476      injected_cols.extend(['injected_decisive_distance','injected_gps_time', 'injected_gps_time_ns', 'injected_event_time_utc__Px_click_for_daily_ihope_xP_']) 
 477       
 478       
 479      recovered_cols = [] 
 480      for col in recovery_table_columns: 
 481          if col == 'coinc_event_id': 
 482              recovered_cols.append(u'coinc_event_id') 
 483          else: 
 484              recovered_cols.append(u'recovered_'+col) 
 485       
 486      column_names = injected_cols + recovered_cols 
 487       
 488      rankname = 'rank_in_' + comparison_datatype.strip().lower() + '_using_' + ranking_stat.split('.')[-1] 
 489      durname = ''.join([ 'simulation', u'_duration__Px_', convert_durations, '_xP_' ]) 
 490      column_names.extend( [ rankname, 'recovered_match_rank', 'instruments_on', 'elogs', durname, 'mini_followup','omega_scan', 'sim_tag' ] ) 
 491       
 492       
 493       
 494       
 495      class tmpSimTable(table.Table): 
 496          tableName = "tmp_sim_table" 
 497          validcolumns = dict([ [col, sqlutils.get_col_type(simulation_table, col)] for col in simulation_table_columns ]) 
 498      class tmpSim(object): 
 499          __slots__ = tmpSimTable.validcolumns.keys() 
 500          def get_gps_time(self, site): 
 501              if '%s_start_time' % site in self.__slots__: 
 502                  return LIGOTimeGPS(getattr(self, '%s_start_time' % site ), getattr(self, '%s_start_time_ns' % site)) 
 503              elif '%s_end_time' % site in self.__slots__: 
 504                  return LIGOTimeGPS(getattr(self, '%s_end_time' % site ), getattr(self, '%s_end_time_ns' % site)) 
 505              else: 
 506                  raise AttributeError, "could not find an injected %s_start_time nor an injected %s_end_time" %(site,site) 
 507          def get_pyvalue(self): 
 508              return generic_get_pyvalue(self) 
 509       
 510      class tmpRecTable(table.Table): 
 511          tableName = "tmp_rec_table" 
 512          validcolumns = dict([ [col, sqlutils.get_col_type(recovery_table, col)] for col in recovery_table_columns ]) 
 513      class tmpRec(object): 
 514          __slots__ = tmpRecTable.validcolumns.keys() 
 515          def get_gps_time(self): 
 516              if 'start_time' in self.__slots__: 
 517                  return LIGOTimeGPS(self.start_time, self.start_time_ns) 
 518              elif 'end_time' in self.__slots__: 
 519                  return LIGOTimeGPS(self.end_time, self.end_time_ns) 
 520              else: 
 521                  raise AttributeError, "could not find a recovered start_time or recovered end_time" 
 522          def get_pyvalue(self): 
 523              return generic_get_pyvalue(self) 
 524       
 525      class SelectedFoundTable(table.Table): 
 526          tableName = "selected_found_injections" 
 527          validcolumns = {} 
 528          for col_name in column_names: 
 529              if 'rank_in_' in col_name: 
 530                  validcolumns[col_name] = "int_4u" 
 531              elif '_duration_' in col_name: 
 532                  validcolumns[col_name] = "real_8" 
 533              elif 'instruments_on' == col_name: 
 534                  validcolumns[col_name] = lsctables.ExperimentTable.validcolumns['instruments'] 
 535              elif col_name == 'injected_start_time' or col_name == 'injected_start_time_ns': 
 536                  validcolumns[col_name] = "int_4s" 
 537              elif col_name == 'injected_gps_time' or col_name == 'injected_gps_time_ns': 
 538                  validcolumns[col_name] = "int_4s" 
 539              elif col_name == 'injected_decisive_distance': 
 540                  validcolumns[col_name] = "real_8" 
 541              elif 'injected_' in col_name or col_name == 'simulation_id': 
 542                  validcolumns[col_name] = sqlutils.get_col_type(simulation_table, re.sub('injected_', '', col_name)) 
 543              elif 'recovered_' in col_name or col_name == 'coinc_event_id': 
 544                  validcolumns[col_name] = sqlutils.get_col_type(recovery_table, re.sub('recovered_', '', col_name)) 
 545               
 546              else: 
 547                  validcolumns[col_name] = "lstring" 
 548           
 549          validcolumns['recovered_fap'] = "real_8" 
 550          validcolumns['recovered_fap_1yr'] = "real_8" 
 551       
 552      class SelectedFound(object): 
 553          __slots__ = SelectedFoundTable.validcolumns.keys() 
 554       
 555          def set_recovered_gps_time(self, gps_time): 
 556              if 'recovered_start_time' in self.__slots__: 
 557                  self.recovered_start_time = gps_time.seconds 
 558                  self.recovered_start_time_ns = gps_time.nanoseconds 
 559              elif 'recovered_end_time' in self.__slots__: 
 560                  self.recovered_end_time = gps_time.seconds 
 561                  self.recovered_end_time_ns = gps_time.nanoseconds 
 562              else: 
 563                  raise AttributeError, "could not find a recovered_start_time or recovered_end_time" 
 564   
 565          def get_recovered_gps_time(self): 
 566              if 'recovered_start_time' in self.__slots__: 
 567                  return LIGOTimeGPS(self.recovered_start_time, self.recovered_start_time_ns) 
 568              elif 'recovered_end_time' in self.__slots__: 
 569                  return LIGOTimeGPS(self.recovered_end_time, self.recovered_end_time_ns) 
 570              else: 
 571                  raise AttributeError, "could not find a recovered_start_time or recovered_end_time" 
 572   
 573          def set_injected_gps_time(self, site, gps_time): 
 574              if 'injected_%s_start_time' % site in self.__slots__: 
 575                  setattr(self, 'injected_%s_start_time' % site, gps_time.seconds) 
 576                  setattr(self, 'injected_%s_start_time_ns' % site, gps_time.nanoseconds) 
 577              elif 'injected_%s_end_time' % site in self.__slots__: 
 578                  setattr(self, 'injected_%s_end_time' % site, gps_time.seconds) 
 579                  setattr(self, 'injected_%s_end_time_ns' % site, gps_time.nanoseconds) 
 580              else: 
 581                  raise AttributeError, "could not find an injected_%s_start_time nor an injected_%s_end_time" %(site,site) 
 582   
 583          def get_injected_gps_time(self, site): 
 584              if 'injected_%s_start_time' % site in self.__slots__: 
 585                  return LIGOTimeGPS(getattr(self, 'injected_%s_start_time' % site ), getattr(self, 'injected_%s_start_time_ns' % site)) 
 586              elif 'injected_%s_end_time' % site in self.__slots__: 
 587                  return LIGOTimeGPS(getattr(self, 'injected_%s_end_time' % site ), getattr(self, 'injected_%s_end_time_ns' % site)) 
 588              else: 
 589                  raise AttributeError, "could not find an injected_%s_start_time nor an injected_%s_end_time" %(site,site) 
 590   
 591          def get_pyvalue(self): 
 592              return generic_get_pyvalue(self) 
 593       
 594       
 595      tmpSimTable.RowType = tmpSim 
 596      tmpRecTable.RowType = tmpRec 
 597      SelectedFoundTable.RowType = SelectedFound 
 598       
 599       
 600       
 601       
 602      tmp_sim_table = lsctables.New(tmpSimTable)  
 603      tmp_rec_table = lsctables.New(tmpRecTable)  
 604      tmp_sftable = lsctables.New(SelectedFoundTable) 
 605      prior_sim_id = '' 
 606      group_rank = None 
 607      current_match_rank = 1 
 608      sqlquery = ''.join([""" 
 609          SELECT 
 610              """, simulation_table, """.*, 
 611              """, recovery_table, """.*, 
 612              get_sim_tag(experiment_summary.sim_proc_id), 
 613              rank(sim_rec_map.ranking_stat), 
 614              NULL AS match_rank, 
 615              experiment.instruments, 
 616              convert_duration(experiment_summary.duration), 
 617              NULL AS mini_followup 
 618          FROM 
 619              sim_rec_map 
 620          JOIN 
 621              """, ', '.join([simulation_table, recovery_table]), """, experiment, experiment_summary, experiment_map ON ( 
 622              sim_rec_map.sim_id == """, simulation_table, """.simulation_id AND 
 623              sim_rec_map.rec_id == """, recovery_table, """.coinc_event_id AND 
 624              sim_rec_map.rec_id == experiment_map.coinc_event_id AND 
 625              experiment_map.experiment_summ_id == experiment_summary.experiment_summ_id AND 
 626              experiment_summary.experiment_id == experiment.experiment_id) 
 627          ORDER BY 
 628              sim_rec_map.sim_id, sim_rec_map.ranking_stat """, rank_by]) 
 629       
 630      if verbose: 
 631          print >> sys.stderr, "Getting coincs..." 
 632          print >> sys.stderr, "SQLite query used is:" 
 633          print >> sys.stderr, sqlquery 
 634       
 635      for values in connection.cursor().execute( sqlquery ).fetchall(): 
 636           
 637          tmp_sim_row = tmpSim() 
 638          tmp_rec_row = tmpRec() 
 639          [ setattr(tmp_sim_row, column, values[ii]) for ii, column in enumerate(simulation_table_columns) ] 
 640          [ setattr(tmp_rec_row, column, values[ii+1+jj]) for jj, column in enumerate(recovery_table_columns) ] 
 641           
 642          this_inj_rank = values[-5] 
 643          this_sim_id = tmp_sim_row.simulation_id 
 644          this_ranking_stat = getattr(tmp_rec_row, ranking_stat.split('.')[-1]) 
 645          if this_sim_id == prior_sim_id and this_ranking_stat != prior_ranking_stat: 
 646              current_match_rank += 1 
 647          elif this_sim_id != prior_sim_id: 
 648              current_match_rank = 1 
 649              group_rank = this_inj_rank 
 650          prior_sim_id = this_sim_id 
 651          prior_ranking_stat = this_ranking_stat  
 652           
 653          if rank_range and rank_range_parser.group_by_param_range(group_rank) is None: 
 654              continue 
 655          on_instruments = lsctables.instrument_set_from_ifos(values[-3]) 
 656          duration = values[-2] 
 657           
 658          sfrow = SelectedFound() 
 659           
 660          setattr(sfrow, rankname, group_rank) 
 661          sfrow.recovered_match_rank = current_match_rank 
 662           
 663          use_this_site = sorted(on_instruments)[0][0].lower() 
 664          injected_time = tmp_sim_row.get_gps_time( use_this_site ) 
 665          sfrow.injected_gps_time = injected_time.seconds 
 666          sfrow.injected_gps_time_ns = injected_time.nanoseconds 
 667          for col in simulation_table_columns: 
 668              if col == "simulation_id": 
 669                  sfrow.simulation_id = tmp_sim_row.simulation_id  
 670              else: 
 671                  setattr(sfrow, 'injected_'+col, getattr( tmp_sim_row, col) ) 
 672           
 673          for col in recovery_table_columns: 
 674              if col == "coinc_event_id": 
 675                  sfrow.coinc_event_id = tmp_rec_row.coinc_event_id 
 676              else: 
 677                  setattr(sfrow, 'recovered_'+col, getattr( tmp_rec_row, col) ) 
 678           
 679          if sfrow.recovered_combined_far is not None: 
 680              t_in_s = float(values[-2]) / sqlutils.convert_duration(1, convert_durations) 
 681              sfrow.recovered_fap = 1 - math.exp(-sqlutils.convert_duration(t_in_s, 'yr') * sfrow.recovered_combined_far) 
 682              sfrow.recovered_fap_1yr = 1 - math.exp(-sfrow.recovered_combined_far) 
 683          else: 
 684              sfrow.recovered_fap = None 
 685              sfrow.recovered_fap_1yr = None 
 686           
 687          elog_pages = [(ifo, get_elog_page(ifo, sfrow.injected_gps_time)) for ifo in on_instruments] 
 688          sfrow.elogs = ','.join([ create_hyperlink(elog[1], elog[0]) for elog in sorted(elog_pages) ]) 
 689           
 690          event_time_utc = format_end_time_in_utc( sfrow.injected_gps_time )  
 691          daily_ihope_address = get_daily_ihope_page(sfrow.injected_gps_time, pages_location = daily_ihope_pages_location) 
 692          sfrow.injected_event_time_utc__Px_click_for_daily_ihope_xP_ = create_hyperlink( daily_ihope_address, event_time_utc )  
 693           
 694          sfrow.instruments_on = ','.join(sorted(on_instruments)) 
 695          sfrow.injected_decisive_distance = sorted([getattr(sfrow, 'injected_eff_dist_%s' % ifo[0].lower()) for ifo in on_instruments])[1] 
 696          sfrow.mini_followup = None 
 697          sfrow.omega_scan = None 
 698          sfrow.sim_tag = values[-6] 
 699          setattr(sfrow, durname, duration) 
 700       
 701           
 702          tmp_sftable.append(sfrow) 
 703       
 704       
 705      sftable = lsctables.New(SelectedFoundTable) 
 706      for sfrow in sorted([ row for row in tmp_sftable ], key = lambda row: getattr(row, sort_by == 'rank' and rankname or sort_by) ): 
 707          if sfrow.simulation_id not in [row.simulation_id for row in sftable]: 
 708              sftable.append(sfrow) 
 709              sftable.extend(sub_row for sub_row in sorted([row for row in tmp_sftable 
 710                  if row.simulation_id == sfrow.simulation_id 
 711                  and row.coinc_event_id != sfrow.coinc_event_id], 
 712                  key = lambda row: row.recovered_match_rank)) 
 713       
 714       
 715      connection.cursor().execute("DROP TABLE sim_rec_map") 
 716       
 717      return sftable 
 718   
 719   
 720   
 721 -def printmissed(connection, simulation_table, recovery_table, map_label, livetime_program, 
 722      param_name = None, param_ranges = None, exclude_coincs = None, include_only_coincs = None, sim_tag = 'ALLINJ', 
 723      limit = None, daily_ihope_pages_location = 'https://ldas-jobs.ligo.caltech.edu/~cbc/ihope_daily', verbose = False): 
  724       
 725      from pylal import ligolw_sqlutils as sqlutils 
 726      from pylal import ligolw_cbc_compute_durations as compute_dur 
 727      from glue import segments 
 728      from glue.ligolw import dbtables 
 729   
 730       
 731      simulation_table = sqlutils.validate_option(simulation_table) 
 732      recovery_table = sqlutils.validate_option(recovery_table) 
 733       
 734       
 735      sim_map = sqlutils.sim_tag_proc_id_mapper( connection ) 
 736      connection.create_function( 'get_sim_tag', 1, sim_map.get_sim_tag ) 
 737   
 738       
 739       
 740       
 741       
 742       
 743      simulation_table_columns = sqlutils.get_column_names_from_table( connection, simulation_table ) 
 744      column_names = simulation_table_columns + \ 
 745          ['rank', 'decisive_distance', 'gps_time', 'gps_time_ns', 'injection_time_utc__Px_click_for_daily_ihope_xP_', 'elogs', 'instruments_on', 'veto_def_name', 'mini_followup','omega_scan', 'sim_tag'] 
 746       
 747       
 748       
 749      class CloseMissedTable(table.Table): 
 750          tableName = "close_missed_injections" 
 751          validcolumns = {} 
 752          for col_name in column_names: 
 753              if 'rank' in col_name: 
 754                  validcolumns[col_name] = "int_4u" 
 755              elif 'instruments_on' == col_name: 
 756                  validcolumns[col_name] = lsctables.ExperimentTable.validcolumns['instruments'] 
 757              elif 'veto_def_name' == col_name: 
 758                  validcolumns[col_name] = lsctables.ExperimentSummaryTable.validcolumns['veto_def_name'] 
 759              elif 'decisive_distance' == col_name: 
 760                  validcolumns[col_name] = sqlutils.get_col_type(simulation_table, 'eff_dist_h') 
 761              elif 'gps_time' == col_name or 'gps_time_ns' == col_name: 
 762                  validcolumns[col_name] = "int_4s" 
 763              elif 'sim_tag' == col_name: 
 764                  validcolumns[col_name] = "lstring" 
 765              else: 
 766                  validcolumns[col_name] = sqlutils.get_col_type(simulation_table, col_name, default = 'lstring') 
  767       
 768      class CloseMissed(object): 
 769          __slots__ = CloseMissedTable.validcolumns.keys() 
 770       
 771          def get_pyvalue(self): 
 772              return generic_get_pyvalue(self) 
 773       
 774       
 775      CloseMissedTable.RowType = CloseMissed 
 776       
 777       
 778      cmtable = lsctables.New(CloseMissedTable) 
 779   
 780       
 781      sqlutils.create_sim_rec_map_table(connection, simulation_table, recovery_table, map_label, None) 
 782       
 783       
 784       
 785       
 786       
 787       
 788       
 789      filter = """ 
 790          WHERE 
 791              simulation_id NOT IN ( 
 792                  SELECT 
 793                      sim_id 
 794                  FROM 
 795                      sim_rec_map )""" 
 796      af = create_filter( connection, simulation_table, param_name = param_name, param_ranges = param_ranges, 
 797              exclude_coincs = None, include_only_coincs = None, sim_tag = sim_tag, verbose = verbose) 
 798      af = re.sub(r'experiment_summary[.]sim_proc_id', 'process_id', af) 
 799      if af != '': 
 800          filter = '\n'.join([ filter, """ 
 801              AND""", af]) 
 802       
 803      if include_only_coincs is not None: 
 804          include_times = [on_instruments for on_instruments, type in 
 805              sqlutils.parse_coinc_options( include_only_coincs, verbose = verbose ).get_coinc_types().items() 
 806              if 'ALL' in type] 
 807      if exclude_coincs is not None: 
 808          exclude_times = [on_instruments for on_instruments, type in 
 809              sqlutils.parse_coinc_options( exclude_coincs, verbose = verbose ).get_coinc_types().items() 
 810              if 'ALL' in type] 
 811   
 812       
 813      sqlquery = """ 
 814          SELECT value 
 815          FROM process_params 
 816          WHERE param == "-userTag" 
 817          GROUP BY value 
 818      """ 
 819      usertags = set(usertag[0] for usertag in connection.cursor().execute(sqlquery) ) 
 820       
 821       
 822      try: 
 823          if "FULL_DATA" in usertags: 
 824              tag = "FULL_DATA" 
 825          else: 
 826              tag = list(usertags)[0] 
 827      except IndexError: 
 828           
 829          tag = "FULL_DATA" 
 830      ifo_segments = compute_dur.get_single_ifo_segments(connection, program_name = livetime_program, usertag = tag) 
 831      if ifo_segments == {}: 
 832          raise ValueError, "Cannot find any analysis segments using %s as a livetime program; cannot get missed injections." % livetime_program 
 833       
 834      if verbose: 
 835          print >> sys.stderr, "Getting all veto category names from the experiment_summary table..." 
 836   
 837      xmldoc = dbtables.get_xml(connection) 
 838       
 839      veto_segments = compute_dur.get_veto_segments(xmldoc, verbose) 
 840   
 841       
 842      zerolag_dict = {} 
 843      for ifo in ifo_segments: 
 844          zerolag_dict[ifo] = 0.0 
 845   
 846       
 847      for veto_def_name, veto_seg_dict in veto_segments.items(): 
 848          post_vetoes_ifosegs = ifo_segments - veto_seg_dict 
 849       
 850           
 851          coinc_segs = compute_dur.get_coinc_segments(post_vetoes_ifosegs, zerolag_dict) 
 852       
 853           
 854           
 855           
 856          sqlquery = """ 
 857              SELECT DISTINCT experiment.instruments 
 858              FROM experiment 
 859                  JOIN experiment_summary ON ( 
 860                      experiment.experiment_id == experiment_summary.experiment_id ) 
 861              WHERE experiment_summary.veto_def_name == :1 
 862          """ 
 863          for on_instruments in connection.cursor().execute(sqlquery, (veto_def_name,)).fetchall(): 
 864              on_instruments = lsctables.instrument_set_from_ifos(on_instruments[0]) 
 865       
 866               
 867              if include_only_coincs is not None and frozenset(on_instruments) not in include_times: 
 868                  continue 
 869              if exclude_coincs is not None and frozenset(on_instruments) in exclude_times: 
 870                  continue 
 871    
 872              on_times = coinc_segs[','.join(sorted(on_instruments))] 
 873               
 874              def is_in_on_time(gps_time, gps_time_ns): 
 875                  return LIGOTimeGPS(gps_time, gps_time_ns) in on_times 
 876               
 877              connection.create_function('is_in_on_time', 2, is_in_on_time) 
 878               
 879               
 880              in_this_filter = filter 
 881               
 882              end_or_start = any('end_time' in c for c in simulation_table_columns) and '_end_time' or '_start_time' 
 883              for instrument in on_instruments: 
 884                  inst_time = instrument.lower()[0] + end_or_start 
 885                  inst_time_ns = inst_time + '_ns'  
 886                  in_this_filter = ''.join([ in_this_filter, 
 887                      '\n\tAND is_in_on_time(', inst_time, ',', inst_time_ns, ')' ]) 
 888        
 889               
 890               
 891               
 892               
 893              def get_decisive_distance( *args ): 
 894                 return sorted(args)[1] 
 895               
 896              connection.create_function('get_decisive_distance', len(on_instruments), get_decisive_distance) 
 897              decisive_distance = ''.join(['get_decisive_distance(', ','.join(['eff_dist_'+inst.lower()[0] for inst in on_instruments]), ')' ]) 
 898               
 899               
 900               
 901               
 902              if verbose: 
 903                  print >> sys.stderr, "Getting statistics for ranking..." 
 904              ranker = sqlutils.rank_stats(simulation_table, decisive_distance, 'ASC') 
 905               
 906              ranker.populate_stats_list(connection, limit = limit, filter = in_this_filter) 
 907              connection.create_function( 'rank', 1, ranker.get_rank ) 
 908               
 909               
 910               
 911               
 912              sqlquery = ''.join([""" 
 913                  SELECT 
 914                      *, 
 915                      get_sim_tag(process_id), 
 916                      """, decisive_distance, """, 
 917                      rank(""", decisive_distance, """) 
 918                  FROM 
 919                      """, simulation_table, """ 
 920                  """, in_this_filter, """ 
 921                      %s""" % (limit is not None and ''.join(['AND rank(', decisive_distance, ') <= ', str(limit)]) or ''), """ 
 922                  ORDER BY 
 923                      rank(""", decisive_distance, """) ASC 
 924                      """]) 
 925               
 926              if verbose: 
 927                  print >> sys.stderr, "Getting injections..." 
 928                  print >> sys.stderr, "SQLite query used is:" 
 929                  print >> sys.stderr, sqlquery 
 930               
 931              for values in connection.cursor().execute( sqlquery ).fetchall(): 
 932                  cmrow = CloseMissed() 
 933                  [ setattr(cmrow, column, values[ii]) for ii, column in enumerate(simulation_table_columns) ] 
 934                  cmrow.decisive_distance = values[-2] 
 935                  cmrow.rank = values[-1] 
 936                  cmrow.instruments_on = lsctables.ifos_from_instrument_set(on_instruments) 
 937                  cmrow.veto_def_name = veto_def_name 
 938                  cmrow.sim_tag = values[-3] 
 939                  cmrow.mini_followup = None 
 940                  cmrow.omega_scan = None 
 941                  cmrow.gps_time = getattr(cmrow, sorted(on_instruments)[0][0].lower() + end_or_start) 
 942                  cmrow.gps_time_ns = getattr(cmrow, sorted(on_instruments)[0][0].lower() + end_or_start + '_ns') 
 943                   
 944                  elog_pages = [(ifo, get_elog_page(ifo, cmrow.gps_time)) for ifo in on_instruments] 
 945                  cmrow.elogs = ','.join([ create_hyperlink(elog[1], elog[0]) for elog in sorted(elog_pages) ]) 
 946                   
 947                  injection_time_utc = format_end_time_in_utc( cmrow.gps_time )  
 948                  daily_ihope_address = get_daily_ihope_page(cmrow.gps_time, pages_location = daily_ihope_pages_location) 
 949                  cmrow.injection_time_utc__Px_click_for_daily_ihope_xP_ = create_hyperlink( daily_ihope_address, injection_time_utc )  
 950               
 951                   
 952                  cmtable.append(cmrow) 
 953   
 954       
 955      connection.cursor().execute("DROP TABLE sim_rec_map") 
 956      
 957      return cmtable 
 958   
 959 -def get_sngl_info(connection, summary_table, sngl_table, daily_ihope_pages_location = 'https://ldas-jobs.ligo.caltech.edu/~cbc/ihope_daily', verbose = False): 
  981   
 982      class Merged(object): 
 983          __slots__ = MergedTable.validcolumns.keys() 
 984          _effective_snr = None 
 985          _new_snr = None 
 986   
 987          def get_sngl_gps_time(self): 
 988              if 'sngl_start_time' in self.__slots__: 
 989                  return self.sngl_start_time 
 990              elif 'sngl_end_time' in self.__slots__: 
 991                  return self.sngl_end_time 
 992              else: 
 993                  raise AttributeError, "could not find a sngl_start_time or sngl_end_time" 
 994   
 995          @property 
 996          def new_snr(self): 
 997              if not self._new_snr: 
 998                  self._new_snr = lsctables.SnglInspiral.get_new_snr(self) 
 999              return self._new_snr 
1000    
1001          @new_snr.setter 
1002          def new_snr(self): 
1003              err_msg = "The new_snr property cannot be set directly." 
1004              raise ValueError(err_msg) 
1005   
1006          @property 
1007          def effective_snr(self): 
1008              if not self._effective_snr: 
1009                  self._effective_snr = \ 
1010                                   lsctables.SnglInspiral.get_effective_snr(self) 
1011              return self._new_snr 
1012   
1013          @new_snr.setter 
1014          def effective_snr(self): 
1015              err_msg = "The effective_snr property cannot be set directly."  
1016              raise ValueError(err_msg)   
1017   
1018          def get_pyvalue(self): 
1019              return printutils.generic_get_pyvalue() 
1020   
1021       
1022      MergedTable.RowType = Merged 
1023   
1024       
1025       
1026       
1027      mtable = lsctables.New(MergedTable) 
1028   
1029      sqlquery = "CREATE TEMP TABLE select_ceids (coinc_event_id)" 
1030      connection.cursor().execute(sqlquery) 
1031      sqlquery = "INSERT INTO select_ceids (coinc_event_id) VALUES (?)" 
1032      connection.cursor().executemany(sqlquery, [(row.coinc_event_id,) for row in summary_table]) 
1033   
1034      sqlquery = ''.join([""" 
1035          SELECT 
1036              select_ceids.coinc_event_id, 
1037              """, sngl_table, """.* 
1038          FROM 
1039              """, sngl_table, ''' 
1040          JOIN 
1041              select_ceids, coinc_event_map 
1042          ON 
1043              select_ceids.coinc_event_id == coinc_event_map.coinc_event_id AND 
1044              coinc_event_map.table_name == "''', sngl_table, """" AND 
1045              coinc_event_map.event_id == """, sngl_table, """.event_id 
1046          """]) 
1047      if verbose: 
1048          print >> sys.stderr, "SQLite Query Used is:" 
1049          print >> sys.stderr, sqlquery 
1050      for data in connection.cursor().execute(sqlquery).fetchall(): 
1051          mrow = Merged() 
1052          data = list(data) 
1053          mrow.coinc_event_id = data.pop(0) 
1054           
1055          for sngl_col, value in zip(sngl_table_cols, data): 
1056              setattr(mrow, 'sngl_'+sngl_col, value) 
1057           
1058          [setattr(mrow, col, getattr(lcindex[mrow.coinc_event_id], col)) 
1059              for col in lcindex[mrow.coinc_event_id].__slots__ if col != 'coinc_event_id'] 
1060           
1061          gps_time_utc = format_end_time_in_utc( mrow.get_sngl_gps_time() ) 
1062          daily_ihope_address = get_daily_ihope_page(mrow.get_sngl_gps_time(), pages_location = daily_ihope_pages_location) 
1063          mrow.sngl_event_time_utc__Px_click_for_daily_ihope_xP_ = create_hyperlink( daily_ihope_address, gps_time_utc ) 
1064           
1065          mrow.sngl_ifo__Px_click_for_elog_xP_ = create_hyperlink( get_elog_page(mrow.sngl_ifo, mrow.get_sngl_gps_time()), mrow.sngl_ifo ) 
1066           
1067          mtable.append(mrow) 
1068   
1069       
1070      connection.cursor().execute('DROP TABLE select_ceids') 
1071   
1072      return mtable 
1073