def add_sim_coinc_coinc(contents, sim, coinc_event_ids, coinc_def_id): """ Create a coinc_event in the coinc table, and add arcs in the coinc_event_map table linking the sim_type row and the list of coinc_event rows to the new coinc_event row. """ coinc = contents.new_coinc(coinc_def_id) coinc.nevents = len(coinc_event_ids) coincmap = lsctables.CoincMap() coincmap.coinc_event_id = coinc.coinc_event_id coincmap.table_name = sim.simulation_id.table_name coincmap.event_id = sim.simulation_id contents.coincmaptable.append(coincmap) for coinc_event_id in coinc_event_ids: coincmap = lsctables.CoincMap() coincmap.coinc_event_id = coinc.coinc_event_id coincmap.table_name = coinc_event_id.table_name coincmap.event_id = coinc_event_id contents.coincmaptable.append(coincmap)
def add_sim_inspiral_coinc(contents, sim, inspirals): """Create a coinc_event in the coinc table, and add arcs in the coinc_event_map table linking the sim_inspiral row and the list of multi_inspiral rows to the new coinc_event row. """ coinc = contents.new_coinc(contents.sb_coinc_def_id) if inspirals: coinc.set_instruments( lsctables.instrument_set_from_ifos(inspirals[0].ifos)) coinc.nevents = len(inspirals) coincmap = lsctables.CoincMap() coincmap.coinc_event_id = coinc.coinc_event_id coincmap.table_name = sim.simulation_id.table_name coincmap.event_id = sim.simulation_id contents.coincmaptable.append(coincmap) for event in inspirals: coincmap = lsctables.CoincMap() coincmap.coinc_event_id = coinc.coinc_event_id coincmap.table_name = event.event_id.table_name coincmap.event_id = event.event_id contents.coincmaptable.append(coincmap)
def add_sim_type_coinc(contents, sim, types): """ Create a coinc_event in the coinc table, and add arcs in the coinc_event_map table linking the sim_type row and the list of sngl_type rows to the new coinc_event row. """ coinc = contents.new_coinc(contents.sb_coinc_def_id) coinc.set_instruments(set(event.ifo for event in types)) coinc.nevents = len(types) coincmap = lsctables.CoincMap() coincmap.coinc_event_id = coinc.coinc_event_id coincmap.table_name = sim.simulation_id.table_name coincmap.event_id = sim.simulation_id contents.coincmaptable.append(coincmap) for event in types: coincmap = lsctables.CoincMap() coincmap.coinc_event_id = coinc.coinc_event_id coincmap.table_name = event.event_id.table_name coincmap.event_id = event.event_id contents.coincmaptable.append(coincmap)
def to_coinc_xml_object(self, file_name): outdoc = ligolw.Document() outdoc.appendChild(ligolw.LIGO_LW()) ifos = list(self.sngl_files.keys()) proc_id = ligolw_process.register_to_xmldoc( outdoc, 'pycbc', {}, ifos=ifos, comment='', version=pycbc_version.git_hash, cvs_repository='pycbc/' + pycbc_version.git_branch, cvs_entry_time=pycbc_version.date).process_id search_summ_table = lsctables.New(lsctables.SearchSummaryTable) coinc_h5file = self.coinc_file.h5file try: start_time = coinc_h5file['segments']['coinc']['start'][:].min() end_time = coinc_h5file['segments']['coinc']['end'][:].max() except KeyError: start_times = [] end_times = [] for ifo_comb in coinc_h5file['segments']: if ifo_comb == 'foreground_veto': continue seg_group = coinc_h5file['segments'][ifo_comb] start_times.append(seg_group['start'][:].min()) end_times.append(seg_group['end'][:].max()) start_time = min(start_times) end_time = max(end_times) num_trigs = len(self.sort_arr) search_summary = return_search_summary(start_time, end_time, num_trigs, ifos) search_summ_table.append(search_summary) outdoc.childNodes[0].appendChild(search_summ_table) sngl_inspiral_table = lsctables.New(lsctables.SnglInspiralTable) coinc_def_table = lsctables.New(lsctables.CoincDefTable) coinc_event_table = lsctables.New(lsctables.CoincTable) coinc_inspiral_table = lsctables.New(lsctables.CoincInspiralTable) coinc_event_map_table = lsctables.New(lsctables.CoincMapTable) time_slide_table = lsctables.New(lsctables.TimeSlideTable) # Set up time_slide table time_slide_id = lsctables.TimeSlideID(0) for ifo in ifos: time_slide_row = lsctables.TimeSlide() time_slide_row.instrument = ifo time_slide_row.time_slide_id = time_slide_id time_slide_row.offset = 0 time_slide_row.process_id = proc_id time_slide_table.append(time_slide_row) # Set up coinc_definer table coinc_def_id = lsctables.CoincDefID(0) coinc_def_row = lsctables.CoincDef() coinc_def_row.search = "inspiral" coinc_def_row.description = \ "sngl_inspiral<-->sngl_inspiral coincidences" coinc_def_row.coinc_def_id = coinc_def_id coinc_def_row.search_coinc_type = 0 coinc_def_table.append(coinc_def_row) bank_col_names = ['mass1', 'mass2', 'spin1z', 'spin2z'] bank_col_vals = {} for name in bank_col_names: bank_col_vals[name] = self.get_bankfile_array(name) coinc_event_names = ['ifar', 'time', 'fap', 'stat'] coinc_event_vals = {} for name in coinc_event_names: if name == 'time': coinc_event_vals[name] = self.get_end_time() else: coinc_event_vals[name] = self.get_coincfile_array(name) sngl_col_names = [ 'snr', 'chisq', 'chisq_dof', 'bank_chisq', 'bank_chisq_dof', 'cont_chisq', 'cont_chisq_dof', 'end_time', 'template_duration', 'coa_phase', 'sigmasq' ] sngl_col_vals = {} for name in sngl_col_names: sngl_col_vals[name] = self.get_snglfile_array_dict(name) sngl_event_count = 0 for idx in range(len(self.sort_arr)): # Set up IDs and mapping values coinc_id = lsctables.CoincID(idx) # Set up sngls # FIXME: As two-ifo is hardcoded loop over all ifos sngl_combined_mchirp = 0 sngl_combined_mtot = 0 net_snrsq = 0 for ifo in ifos: # If this ifo is not participating in this coincidence then # ignore it and move on. if not sngl_col_vals['snr'][ifo][1][idx]: continue event_id = lsctables.SnglInspiralID(sngl_event_count) sngl_event_count += 1 sngl = return_empty_sngl() sngl.event_id = event_id sngl.ifo = ifo net_snrsq += sngl_col_vals['snr'][ifo][0][idx]**2 for name in sngl_col_names: val = sngl_col_vals[name][ifo][0][idx] if name == 'end_time': sngl.set_end(LIGOTimeGPS(val)) else: setattr(sngl, name, val) for name in bank_col_names: val = bank_col_vals[name][idx] setattr(sngl, name, val) sngl.mtotal, sngl.eta = pnutils.mass1_mass2_to_mtotal_eta( sngl.mass1, sngl.mass2) sngl.mchirp, _ = pnutils.mass1_mass2_to_mchirp_eta( sngl.mass1, sngl.mass2) sngl.eff_distance = (sngl.sigmasq)**0.5 / sngl.snr sngl_combined_mchirp += sngl.mchirp sngl_combined_mtot += sngl.mtotal sngl_inspiral_table.append(sngl) # Set up coinc_map entry coinc_map_row = lsctables.CoincMap() coinc_map_row.table_name = 'sngl_inspiral' coinc_map_row.coinc_event_id = coinc_id coinc_map_row.event_id = event_id coinc_event_map_table.append(coinc_map_row) sngl_combined_mchirp = sngl_combined_mchirp / len(ifos) sngl_combined_mtot = sngl_combined_mtot / len(ifos) # Set up coinc inspiral and coinc event tables coinc_event_row = lsctables.Coinc() coinc_inspiral_row = lsctables.CoincInspiral() coinc_event_row.coinc_def_id = coinc_def_id coinc_event_row.nevents = len(ifos) coinc_event_row.instruments = ','.join(ifos) coinc_inspiral_row.set_ifos(ifos) coinc_event_row.time_slide_id = time_slide_id coinc_event_row.process_id = proc_id coinc_event_row.coinc_event_id = coinc_id coinc_inspiral_row.coinc_event_id = coinc_id coinc_inspiral_row.mchirp = sngl_combined_mchirp coinc_inspiral_row.mass = sngl_combined_mtot coinc_inspiral_row.set_end( LIGOTimeGPS(coinc_event_vals['time'][idx])) coinc_inspiral_row.snr = net_snrsq**0.5 coinc_inspiral_row.false_alarm_rate = coinc_event_vals['fap'][idx] coinc_inspiral_row.combined_far = 1. / coinc_event_vals['ifar'][idx] # Transform to Hz coinc_inspiral_row.combined_far = \ coinc_inspiral_row.combined_far / YRJUL_SI coinc_event_row.likelihood = coinc_event_vals['stat'][idx] coinc_inspiral_row.minimum_duration = 0. coinc_event_table.append(coinc_event_row) coinc_inspiral_table.append(coinc_inspiral_row) outdoc.childNodes[0].appendChild(coinc_def_table) outdoc.childNodes[0].appendChild(coinc_event_table) outdoc.childNodes[0].appendChild(coinc_event_map_table) outdoc.childNodes[0].appendChild(time_slide_table) outdoc.childNodes[0].appendChild(coinc_inspiral_table) outdoc.childNodes[0].appendChild(sngl_inspiral_table) ligolw_utils.write_filename(outdoc, file_name)
def lalapps_cbc_injfind(xmldoc, process, search, snglcomparefunc, nearcoinccomparefunc, verbose=False): # # Analyze the document's contents. # if verbose: print >> sys.stderr, "indexing ..." bbdef = { "inspiral": thinca.InspiralCoincDef, "ringdown": ligolw_rinca.RingdownCoincDef }[search] sbdef = { "inspiral": InspiralSICoincDef, "ringdown": RingdownSICoincDef }[search] scndef = { "inspiral": InspiralSCNearCoincDef, "ringdown": RingdownSCNearCoincDef }[search] sngl_type = { "inspiral": lsctables.SnglInspiralTable, "ringdown": lsctables.SnglRingdownTable }[search] sim_type = { "inspiral": lsctables.SimInspiralTable, "ringdown": lsctables.SimRingdownTable }[search] get_sngl_time = { "inspiral": lsctables.SnglInspiral.get_end, "ringdown": lsctables.SnglRingdown.get_start }[search] contents = DocContents(xmldoc=xmldoc, bbdef=bbdef, sbdef=sbdef, scndef=scndef, process=process, sngl_type=sngl_type, sim_type=sim_type, get_sngl_time=get_sngl_time) N = len(contents.simtable) if isinstance(contents.simtable, lsctables.SimInspiralTable): get_sim_time = lsctables.SimInspiral.get_end elif isinstance(contents.simtable, lsctables.SimRingdownTable): get_sim_time = lsctables.SimRingdown.get_start else: raise ValueError, "Unknown sim table" # # Find sim_type <--> sngl_type coincidences. # if verbose: print >> sys.stderr, "constructing %s:" % sbdef.description for n, sim in enumerate(contents.simtable): if verbose: print >> sys.stderr, "\t%.1f%%\r" % (100.0 * n / N), types = find_sngl_type_matches(contents, sim, snglcomparefunc, get_sim_time, get_sngl_time) if types: add_sim_type_coinc(contents, sim, types) if verbose: print >> sys.stderr, "\t100.0%" # # Find sim_type <--> coinc_event coincidences. # if contents.scn_coinc_def_id: if verbose: print >> sys.stderr, "constructing %s:" % (scndef.description) for n, sim in enumerate(contents.simtable): if verbose: print >> sys.stderr, "\t%.1f%%\r" % (100.0 * n / N), coincs = contents.coincs_near_time(get_sim_time(sim), get_sngl_time) coinc_event_ids = find_near_coinc_matches(coincs, sim, nearcoinccomparefunc, get_sim_time, get_sngl_time) if coinc_event_ids: add_sim_coinc_coinc(contents, sim, coinc_event_ids, contents.scn_coinc_def_id) if verbose: print >> sys.stderr, "\t100.0%" # # Find sim_type <--> sim_type mappings # if both a sim_inspiral and sim_ring table # are present. # if verbose: print >> sys.stderr, "Checking for both SimInspiralTable and SimRingdownTable" if isinstance(contents.simtable, lsctables.SimRingdownTable): try: insp_simtable = lsctables.SimInspiralTable.get_table(xmldoc) except ValueError: print >> sys.stderr, "No SimInspiralTable, only SimRingdownTable present" insp_simtable = None if insp_simtable is not None: if verbose: print >> sys.stderr, "found SimInspiralTable, creating maps to SimRingdownTable" # create an index of the sim_ringdown geocent_start_times sim_ring_time_map = dict([[(str(row.process_id), row.geocent_start_time), str(row.simulation_id)] for row in contents.simtable]) # create an index of the sim_ringdown's coinc_event_ids sim_ring_ceid_map = dict([[str(row.event_id), row.coinc_event_id] for row in contents.coincmaptable if row.table_name == "sim_ringdown"]) # cycle over the sim_inspiral table, creating the maps for this_sim_insp in insp_simtable: if (str(this_sim_insp.process_id), this_sim_insp.geocent_end_time) in sim_ring_time_map: this_sim_ring_id = sim_ring_time_map[( str(this_sim_insp.process_id), this_sim_insp.geocent_end_time)] else: continue if str(this_sim_ring_id) in sim_ring_ceid_map: this_ceid = sim_ring_ceid_map[str(this_sim_ring_id)] else: continue # add to the coinc_event_map table new_mapping = lsctables.CoincMap() new_mapping.table_name = "sim_inspiral" new_mapping.event_id = this_sim_insp.simulation_id new_mapping.coinc_event_id = this_ceid contents.coincmaptable.append(new_mapping) # # Restore the original event order. # if verbose: print >> sys.stderr, "finishing ..." contents.sort_triggers_by_id() # # Done. # return xmldoc
def __init__(self, ifos, coinc_results, **kwargs): """Initialize a ligolw xml representation of a zerolag trigger for upload from pycbc live to gracedb. Parameters ---------- ifos: list of strs A list of the ifos pariticipating in this trigger coinc_results: dict of values A dictionary of values. The format is defined in pycbc/events/coinc.py and matches the on disk representation in the hdf file for this time. psds: dict of FrequencySeries Dictionary providing PSD estimates for all involved detectors. low_frequency_cutoff: float Minimum valid frequency for the PSD estimates. followup_data: dict of dicts, optional Dictionary providing SNR time series for each detector, to be used in sky localization with BAYESTAR. The format should be `followup_data['H1']['snr_series']`. More detectors can be present than given in `ifos`. If so, the extra detectors will only be used for sky localization. channel_names: dict of strings, optional Strain channel names for each detector. Will be recorded in the sngl_inspiral table. """ self.template_id = coinc_results['foreground/%s/template_id' % ifos[0]] self.coinc_results = coinc_results self.ifos = ifos # remember if this should be marked as HWINJ self.is_hardware_injection = ('HWINJ' in coinc_results and coinc_results['HWINJ']) if 'followup_data' in kwargs: fud = kwargs['followup_data'] assert len({fud[ifo]['snr_series'].delta_t for ifo in fud}) == 1, \ "delta_t for all ifos do not match" self.snr_series = {ifo: fud[ifo]['snr_series'] for ifo in fud} usable_ifos = fud.keys() followup_ifos = list(set(usable_ifos) - set(ifos)) else: self.snr_series = None usable_ifos = ifos followup_ifos = [] # Set up the bare structure of the xml document outdoc = ligolw.Document() outdoc.appendChild(ligolw.LIGO_LW()) proc_id = ligolw_process.register_to_xmldoc( outdoc, 'pycbc', {}, ifos=usable_ifos, comment='', version=pycbc_version.git_hash, cvs_repository='pycbc/'+pycbc_version.git_branch, cvs_entry_time=pycbc_version.date).process_id # Set up coinc_definer table coinc_def_table = lsctables.New(lsctables.CoincDefTable) coinc_def_id = lsctables.CoincDefID(0) coinc_def_row = lsctables.CoincDef() coinc_def_row.search = "inspiral" coinc_def_row.description = "sngl_inspiral<-->sngl_inspiral coincs" coinc_def_row.coinc_def_id = coinc_def_id coinc_def_row.search_coinc_type = 0 coinc_def_table.append(coinc_def_row) outdoc.childNodes[0].appendChild(coinc_def_table) # Set up coinc inspiral and coinc event tables coinc_id = lsctables.CoincID(0) coinc_event_table = lsctables.New(lsctables.CoincTable) coinc_event_row = lsctables.Coinc() coinc_event_row.coinc_def_id = coinc_def_id coinc_event_row.nevents = len(usable_ifos) coinc_event_row.instruments = ','.join(usable_ifos) coinc_event_row.time_slide_id = lsctables.TimeSlideID(0) coinc_event_row.process_id = proc_id coinc_event_row.coinc_event_id = coinc_id coinc_event_row.likelihood = 0. coinc_event_table.append(coinc_event_row) outdoc.childNodes[0].appendChild(coinc_event_table) # Set up sngls sngl_inspiral_table = lsctables.New(lsctables.SnglInspiralTable) coinc_event_map_table = lsctables.New(lsctables.CoincMapTable) sngl_populated = None network_snrsq = 0 for sngl_id, ifo in enumerate(usable_ifos): sngl = return_empty_sngl(nones=True) sngl.event_id = lsctables.SnglInspiralID(sngl_id) sngl.process_id = proc_id sngl.ifo = ifo names = [n.split('/')[-1] for n in coinc_results if 'foreground/%s' % ifo in n] for name in names: val = coinc_results['foreground/%s/%s' % (ifo, name)] if name == 'end_time': sngl.set_end(lal.LIGOTimeGPS(val)) else: try: setattr(sngl, name, val) except AttributeError: pass if sngl.mass1 and sngl.mass2: sngl.mtotal, sngl.eta = pnutils.mass1_mass2_to_mtotal_eta( sngl.mass1, sngl.mass2) sngl.mchirp, _ = pnutils.mass1_mass2_to_mchirp_eta( sngl.mass1, sngl.mass2) sngl_populated = sngl if sngl.snr: sngl.eff_distance = (sngl.sigmasq)**0.5 / sngl.snr network_snrsq += sngl.snr ** 2.0 if 'channel_names' in kwargs and ifo in kwargs['channel_names']: sngl.channel = kwargs['channel_names'][ifo] sngl_inspiral_table.append(sngl) # Set up coinc_map entry coinc_map_row = lsctables.CoincMap() coinc_map_row.table_name = 'sngl_inspiral' coinc_map_row.coinc_event_id = coinc_id coinc_map_row.event_id = sngl.event_id coinc_event_map_table.append(coinc_map_row) if self.snr_series is not None: snr_series_to_xml(self.snr_series[ifo], outdoc, sngl.event_id) # for subthreshold detectors, respect BAYESTAR's assumptions and checks bayestar_check_fields = ('mass1 mass2 mtotal mchirp eta spin1x ' 'spin1y spin1z spin2x spin2y spin2z').split() subthreshold_sngl_time = numpy.mean( [coinc_results['foreground/{}/end_time'.format(ifo)] for ifo in ifos]) for sngl in sngl_inspiral_table: if sngl.ifo in followup_ifos: for bcf in bayestar_check_fields: setattr(sngl, bcf, getattr(sngl_populated, bcf)) sngl.set_end(lal.LIGOTimeGPS(subthreshold_sngl_time)) outdoc.childNodes[0].appendChild(coinc_event_map_table) outdoc.childNodes[0].appendChild(sngl_inspiral_table) # Set up the coinc inspiral table coinc_inspiral_table = lsctables.New(lsctables.CoincInspiralTable) coinc_inspiral_row = lsctables.CoincInspiral() # This seems to be used as FAP, which should not be in gracedb coinc_inspiral_row.false_alarm_rate = 0 coinc_inspiral_row.minimum_duration = 0. coinc_inspiral_row.set_ifos(usable_ifos) coinc_inspiral_row.coinc_event_id = coinc_id coinc_inspiral_row.mchirp = sngl_populated.mchirp coinc_inspiral_row.mass = sngl_populated.mtotal coinc_inspiral_row.end_time = sngl_populated.end_time coinc_inspiral_row.end_time_ns = sngl_populated.end_time_ns coinc_inspiral_row.snr = network_snrsq ** 0.5 far = 1.0 / (lal.YRJUL_SI * coinc_results['foreground/ifar']) coinc_inspiral_row.combined_far = far coinc_inspiral_table.append(coinc_inspiral_row) outdoc.childNodes[0].appendChild(coinc_inspiral_table) # append the PSDs self.psds = kwargs['psds'] psds_lal = {} for ifo in self.psds: psd = self.psds[ifo] kmin = int(kwargs['low_frequency_cutoff'] / psd.delta_f) fseries = lal.CreateREAL8FrequencySeries( "psd", psd.epoch, kwargs['low_frequency_cutoff'], psd.delta_f, lal.StrainUnit**2 / lal.HertzUnit, len(psd) - kmin) fseries.data.data = psd.numpy()[kmin:] / pycbc.DYN_RANGE_FAC ** 2.0 psds_lal[ifo] = fseries make_psd_xmldoc(psds_lal, outdoc) self.outdoc = outdoc self.time = sngl_populated.get_end()
dt = 1 / sample_rate epoch = sngl_inspiral.end - (len(snr) - 1) / sample_rate snr = np.concatenate((snr[:0:-1].conj(), snr)) snr *= sngl_inspiral.snr * np.exp(1j * sngl_inspiral.coa_phase) snr_series = lal.CreateCOMPLEX16TimeSeries('snr', epoch, 0, dt, lal.StrainUnit, len(snr)) snr_series.data.data[:] = snr elem = lal.series.build_COMPLEX16TimeSeries(snr_series) elem.appendChild( ligolw_param.Param.from_pyvalue(u'event_id', sngl_inspiral.event_id)) out_xmldoc.childNodes[0].appendChild(elem) # Add CoincMap entry. coinc_map = lsctables.CoincMap() coinc_map.coinc_event_id = coinc.coinc_event_id coinc_map.table_name = sngl_inspiral_table.tableName coinc_map.event_id = sngl_inspiral.event_id coinc_map_table.append(coinc_map) # Record process end time. progress.update(-1, 'writing ' + opts.output.name) ligolw_process.set_process_end_time(process) # Write output file. with ligolw_utils.SignalsTrap(): ligolw_utils.write_fileobj(out_xmldoc, opts.output, gz=(os.path.splitext( opts.output.name)[-1] == ".gz"))
def __init__(self, ifos, coinc_results): """Initialize a ligolw xml representation of a zerolag trigger for upload from pycbc live to gracedb. Parameters ---------- ifos: list of strs A list of the ifos pariticipating in this trigger coinc_results: dict of values A dictionary of values. The format is define in pycbc/events/coinc.py and matches the on disk representation in the hdf file for this time. """ # remember if this should be marked as HWINJ self.is_hardware_injection = False if 'HWINJ' in coinc_results: self.is_hardware_injection = True # Set up the bare structure of the xml document outdoc = ligolw.Document() outdoc.appendChild(ligolw.LIGO_LW()) proc_id = ligolw_process.register_to_xmldoc( outdoc, 'pycbc', {}, ifos=ifos, comment='', version=pycbc_version.git_hash, cvs_repository='pycbc/' + pycbc_version.git_branch, cvs_entry_time=pycbc_version.date).process_id # Set up coinc_definer table coinc_def_table = lsctables.New(lsctables.CoincDefTable) coinc_def_id = lsctables.CoincDefID(0) coinc_def_row = lsctables.CoincDef() coinc_def_row.search = "inspiral" coinc_def_row.description = "sngl_inspiral<-->sngl_inspiral coincs" coinc_def_row.coinc_def_id = coinc_def_id coinc_def_row.search_coinc_type = 0 coinc_def_table.append(coinc_def_row) outdoc.childNodes[0].appendChild(coinc_def_table) # Set up coinc inspiral and coinc event tables coinc_id = lsctables.CoincID(0) coinc_event_table = lsctables.New(lsctables.CoincTable) coinc_event_row = lsctables.Coinc() coinc_event_row.coinc_def_id = coinc_def_id coinc_event_row.nevents = len(ifos) coinc_event_row.instruments = ','.join(ifos) coinc_event_row.time_slide_id = lsctables.TimeSlideID(0) coinc_event_row.process_id = proc_id coinc_event_row.coinc_event_id = coinc_id coinc_event_row.likelihood = 0. coinc_event_table.append(coinc_event_row) outdoc.childNodes[0].appendChild(coinc_event_table) # Set up sngls sngl_inspiral_table = lsctables.New(lsctables.SnglInspiralTable) coinc_event_map_table = lsctables.New(lsctables.CoincMapTable) sngl_id = 0 for ifo in ifos: names = [ n.split('/')[-1] for n in coinc_results if 'foreground/%s' % ifo in n ] sngl_id += 1 sngl = return_empty_sngl() sngl.event_id = lsctables.SnglInspiralID(sngl_id) sngl.ifo = ifo for name in names: val = coinc_results['foreground/%s/%s' % (ifo, name)] if name == 'end_time': sngl.set_end(LIGOTimeGPS(val)) else: try: setattr(sngl, name, val) except AttributeError: pass sngl.mtotal, sngl.eta = pnutils.mass1_mass2_to_mtotal_eta( sngl.mass1, sngl.mass2) sngl.mchirp, _ = pnutils.mass1_mass2_to_mchirp_eta( sngl.mass1, sngl.mass2) sngl.eff_distance = (sngl.sigmasq)**0.5 / sngl.snr sngl_inspiral_table.append(sngl) # Set up coinc_map entry coinc_map_row = lsctables.CoincMap() coinc_map_row.table_name = 'sngl_inspiral' coinc_map_row.coinc_event_id = coinc_id coinc_map_row.event_id = sngl.event_id coinc_event_map_table.append(coinc_map_row) outdoc.childNodes[0].appendChild(coinc_event_map_table) outdoc.childNodes[0].appendChild(sngl_inspiral_table) # Set up the coinc inspiral table coinc_inspiral_table = lsctables.New(lsctables.CoincInspiralTable) coinc_inspiral_row = lsctables.CoincInspiral() # This seems to be used as FAP, which should not be in gracedb coinc_inspiral_row.false_alarm_rate = 0 coinc_inspiral_row.minimum_duration = 0. coinc_inspiral_row.set_ifos(ifos) coinc_inspiral_row.coinc_event_id = coinc_id coinc_inspiral_row.mchirp = sngl.mchirp coinc_inspiral_row.mass = sngl.mtotal coinc_inspiral_row.end_time = sngl.end_time coinc_inspiral_row.end_time_ns = sngl.end_time_ns coinc_inspiral_row.snr = coinc_results['foreground/stat'] far = 1.0 / (YRJUL_SI * coinc_results['foreground/ifar']) coinc_inspiral_row.combined_far = far coinc_inspiral_table.append(coinc_inspiral_row) outdoc.childNodes[0].appendChild(coinc_inspiral_table) self.outdoc = outdoc
def __init__(self, ifos, coinc_results, **kwargs): """Initialize a ligolw xml representation of a zerolag trigger for upload from pycbc live to gracedb. Parameters ---------- ifos: list of strs A list of the ifos pariticipating in this trigger coinc_results: dict of values A dictionary of values. The format is defined in pycbc/events/coinc.py and matches the on disk representation in the hdf file for this time. """ self.ifos = ifos if 'followup_ifos' in kwargs and kwargs['followup_ifos'] is not None: self.followup_ifos = kwargs['followup_ifos'] else: self.followup_ifos = [] self.template_id = coinc_results['foreground/%s/template_id' % self.ifos[0]] # remember if this should be marked as HWINJ self.is_hardware_injection = ('HWINJ' in coinc_results) # Set up the bare structure of the xml document outdoc = ligolw.Document() outdoc.appendChild(ligolw.LIGO_LW()) proc_id = ligolw_process.register_to_xmldoc( outdoc, 'pycbc', {}, ifos=ifos, comment='', version=pycbc_version.git_hash, cvs_repository='pycbc/' + pycbc_version.git_branch, cvs_entry_time=pycbc_version.date).process_id # Set up coinc_definer table coinc_def_table = lsctables.New(lsctables.CoincDefTable) coinc_def_id = lsctables.CoincDefID(0) coinc_def_row = lsctables.CoincDef() coinc_def_row.search = "inspiral" coinc_def_row.description = "sngl_inspiral<-->sngl_inspiral coincs" coinc_def_row.coinc_def_id = coinc_def_id coinc_def_row.search_coinc_type = 0 coinc_def_table.append(coinc_def_row) outdoc.childNodes[0].appendChild(coinc_def_table) # Set up coinc inspiral and coinc event tables coinc_id = lsctables.CoincID(0) coinc_event_table = lsctables.New(lsctables.CoincTable) coinc_event_row = lsctables.Coinc() coinc_event_row.coinc_def_id = coinc_def_id coinc_event_row.nevents = len(ifos) coinc_event_row.instruments = ','.join(ifos) coinc_event_row.time_slide_id = lsctables.TimeSlideID(0) coinc_event_row.process_id = proc_id coinc_event_row.coinc_event_id = coinc_id coinc_event_row.likelihood = 0. coinc_event_table.append(coinc_event_row) outdoc.childNodes[0].appendChild(coinc_event_table) # Set up sngls sngl_inspiral_table = lsctables.New(lsctables.SnglInspiralTable) coinc_event_map_table = lsctables.New(lsctables.CoincMapTable) sngl_event_id_map = {} sngl_populated = None for sngl_id, ifo in enumerate(ifos + self.followup_ifos): sngl = return_empty_sngl(nones=True) sngl.event_id = lsctables.SnglInspiralID(sngl_id) sngl_event_id_map[ifo] = sngl.event_id sngl.process_id = proc_id sngl.ifo = ifo names = [ n.split('/')[-1] for n in coinc_results if 'foreground/%s' % ifo in n ] for name in names: val = coinc_results['foreground/%s/%s' % (ifo, name)] if name == 'end_time': sngl.set_end(lal.LIGOTimeGPS(val)) else: try: setattr(sngl, name, val) except AttributeError: pass if sngl.mass1 and sngl.mass2: sngl.mtotal, sngl.eta = pnutils.mass1_mass2_to_mtotal_eta( sngl.mass1, sngl.mass2) sngl.mchirp, _ = pnutils.mass1_mass2_to_mchirp_eta( sngl.mass1, sngl.mass2) sngl_populated = sngl if sngl.snr: sngl.eff_distance = (sngl.sigmasq)**0.5 / sngl.snr sngl_inspiral_table.append(sngl) # Set up coinc_map entry coinc_map_row = lsctables.CoincMap() coinc_map_row.table_name = 'sngl_inspiral' coinc_map_row.coinc_event_id = coinc_id coinc_map_row.event_id = sngl.event_id coinc_event_map_table.append(coinc_map_row) # for subthreshold detectors, respect BAYESTAR's assumptions and checks bayestar_check_fields = ('mass1 mass2 mtotal mchirp eta spin1x ' 'spin1y spin1z spin2x spin2y spin2z').split() subthreshold_sngl_time = numpy.mean( [coinc_results['foreground/%s/end_time' % ifo] for ifo in ifos]) for sngl in sngl_inspiral_table: if sngl.ifo in self.followup_ifos: for bcf in bayestar_check_fields: setattr(sngl, bcf, getattr(sngl_populated, bcf)) sngl.set_end(lal.LIGOTimeGPS(subthreshold_sngl_time)) outdoc.childNodes[0].appendChild(coinc_event_map_table) outdoc.childNodes[0].appendChild(sngl_inspiral_table) # Set up the coinc inspiral table coinc_inspiral_table = lsctables.New(lsctables.CoincInspiralTable) coinc_inspiral_row = lsctables.CoincInspiral() # This seems to be used as FAP, which should not be in gracedb coinc_inspiral_row.false_alarm_rate = 0 coinc_inspiral_row.minimum_duration = 0. coinc_inspiral_row.set_ifos(ifos) coinc_inspiral_row.coinc_event_id = coinc_id coinc_inspiral_row.mchirp = sngl_populated.mchirp coinc_inspiral_row.mass = sngl_populated.mtotal coinc_inspiral_row.end_time = sngl_populated.end_time coinc_inspiral_row.end_time_ns = sngl_populated.end_time_ns coinc_inspiral_row.snr = coinc_results['foreground/stat'] far = 1.0 / (lal.YRJUL_SI * coinc_results['foreground/ifar']) coinc_inspiral_row.combined_far = far coinc_inspiral_table.append(coinc_inspiral_row) outdoc.childNodes[0].appendChild(coinc_inspiral_table) self.outdoc = outdoc self.time = sngl_populated.get_end() # compute SNR time series self.upload_snr_series = kwargs['upload_snr_series'] if self.upload_snr_series: htilde = kwargs['bank'][self.template_id] self.snr_series = {} self.snr_series_psd = {} for ifo in self.ifos + self.followup_ifos: if ifo in ifos: trig_time = coinc_results['foreground/%s/end_time' % ifo] else: trig_time = subthreshold_sngl_time self.snr_series[ifo], self.snr_series_psd[ifo] = \ compute_followup_snr_series( kwargs['data_readers'][ifo], htilde, trig_time) snr_series_to_xml(self.snr_series[ifo], outdoc, sngl_event_id_map[ifo])
def __init__(self, ifos, coinc_results, **kwargs): """Initialize a ligolw xml representation of a zerolag trigger for upload from pycbc live to gracedb. Parameters ---------- ifos: list of strs A list of the ifos pariticipating in this trigger coinc_results: dict of values A dictionary of values. The format is define in pycbc/events/coinc.py and matches the on disk representation in the hdf file for this time. """ self.ifos = ifos self.template_id = coinc_results['foreground/%s/template_id' % self.ifos[0]] # remember if this should be marked as HWINJ self.is_hardware_injection = False if 'HWINJ' in coinc_results: self.is_hardware_injection = True # Set up the bare structure of the xml document outdoc = ligolw.Document() outdoc.appendChild(ligolw.LIGO_LW()) proc_id = ligolw_process.register_to_xmldoc( outdoc, 'pycbc', {}, ifos=ifos, comment='', version=pycbc_version.git_hash, cvs_repository='pycbc/' + pycbc_version.git_branch, cvs_entry_time=pycbc_version.date).process_id # Set up coinc_definer table coinc_def_table = lsctables.New(lsctables.CoincDefTable) coinc_def_id = lsctables.CoincDefID(0) coinc_def_row = lsctables.CoincDef() coinc_def_row.search = "inspiral" coinc_def_row.description = "sngl_inspiral<-->sngl_inspiral coincs" coinc_def_row.coinc_def_id = coinc_def_id coinc_def_row.search_coinc_type = 0 coinc_def_table.append(coinc_def_row) outdoc.childNodes[0].appendChild(coinc_def_table) # Set up coinc inspiral and coinc event tables coinc_id = lsctables.CoincID(0) coinc_event_table = lsctables.New(lsctables.CoincTable) coinc_event_row = lsctables.Coinc() coinc_event_row.coinc_def_id = coinc_def_id coinc_event_row.nevents = len(ifos) coinc_event_row.instruments = ','.join(ifos) coinc_event_row.time_slide_id = lsctables.TimeSlideID(0) coinc_event_row.process_id = proc_id coinc_event_row.coinc_event_id = coinc_id coinc_event_row.likelihood = 0. coinc_event_table.append(coinc_event_row) outdoc.childNodes[0].appendChild(coinc_event_table) # Set up sngls sngl_inspiral_table = lsctables.New(lsctables.SnglInspiralTable) coinc_event_map_table = lsctables.New(lsctables.CoincMapTable) sngl_id = 0 sngl_event_id_map = {} for ifo in ifos: names = [ n.split('/')[-1] for n in coinc_results if 'foreground/%s' % ifo in n ] sngl_id += 1 sngl = return_empty_sngl() sngl.event_id = lsctables.SnglInspiralID(sngl_id) sngl_event_id_map[ifo] = sngl.event_id sngl.ifo = ifo for name in names: val = coinc_results['foreground/%s/%s' % (ifo, name)] if name == 'end_time': sngl.set_end(lal.LIGOTimeGPS(val)) else: try: setattr(sngl, name, val) except AttributeError: pass sngl.mtotal, sngl.eta = pnutils.mass1_mass2_to_mtotal_eta( sngl.mass1, sngl.mass2) sngl.mchirp, _ = pnutils.mass1_mass2_to_mchirp_eta( sngl.mass1, sngl.mass2) sngl.eff_distance = (sngl.sigmasq)**0.5 / sngl.snr sngl_inspiral_table.append(sngl) # Set up coinc_map entry coinc_map_row = lsctables.CoincMap() coinc_map_row.table_name = 'sngl_inspiral' coinc_map_row.coinc_event_id = coinc_id coinc_map_row.event_id = sngl.event_id coinc_event_map_table.append(coinc_map_row) outdoc.childNodes[0].appendChild(coinc_event_map_table) outdoc.childNodes[0].appendChild(sngl_inspiral_table) # Set up the coinc inspiral table coinc_inspiral_table = lsctables.New(lsctables.CoincInspiralTable) coinc_inspiral_row = lsctables.CoincInspiral() # This seems to be used as FAP, which should not be in gracedb coinc_inspiral_row.false_alarm_rate = 0 coinc_inspiral_row.minimum_duration = 0. coinc_inspiral_row.set_ifos(ifos) coinc_inspiral_row.coinc_event_id = coinc_id coinc_inspiral_row.mchirp = sngl.mchirp coinc_inspiral_row.mass = sngl.mtotal coinc_inspiral_row.end_time = sngl.end_time coinc_inspiral_row.end_time_ns = sngl.end_time_ns coinc_inspiral_row.snr = coinc_results['foreground/stat'] far = 1.0 / (lal.YRJUL_SI * coinc_results['foreground/ifar']) coinc_inspiral_row.combined_far = far coinc_inspiral_table.append(coinc_inspiral_row) outdoc.childNodes[0].appendChild(coinc_inspiral_table) self.outdoc = outdoc self.time = sngl.get_end() # compute SNR time series self.upload_snr_series = kwargs['upload_snr_series'] if self.upload_snr_series: data_readers = kwargs['data_readers'] bank = kwargs['bank'] htilde = bank[self.template_id] self.snr_series = {} self.snr_series_psd = {} for ifo in self.ifos: stilde = data_readers[ifo].overwhitened_data(htilde.delta_f) norm = 4.0 * htilde.delta_f / (htilde.sigmasq(stilde.psd)**0.5) qtilde = zeros((len(htilde) - 1) * 2, dtype=htilde.dtype) correlate(htilde, stilde, qtilde) snr = qtilde * 0 ifft(qtilde, snr) valid_end = int(len(qtilde) - data_readers[ifo].trim_padding) valid_start = int(valid_end - data_readers[ifo].blocksize * data_readers[ifo].sample_rate) seg = slice(valid_start, valid_end) snr = snr[seg] snr *= norm delta_t = 1.0 / data_readers[ifo].sample_rate start = data_readers[ifo].start_time snr = TimeSeries(snr, delta_t=delta_t, epoch=start) self.snr_series[ifo] = snr self.snr_series_psd[ifo] = stilde.psd # store the on-source slice of the series into the XML doc snr_onsource_time = coinc_results['foreground/%s/end_time' % ifo] - snr.start_time snr_onsource_dur = lal.REARTH_SI / lal.C_SI onsource_idx = round(snr_onsource_time * snr.sample_rate) onsource_start = onsource_idx - int( snr.sample_rate * snr_onsource_dur / 2) onsource_end = onsource_idx + int( snr.sample_rate * snr_onsource_dur / 2) onsource_slice = slice(onsource_start, onsource_end + 1) snr_lal = snr[onsource_slice].lal() snr_lal.name = 'snr' snr_lal.sampleUnits = '' snr_xml = _build_series(snr_lal, (u'Time', u'Time,Real,Imaginary'), None, 'deltaT', 's') snr_node = outdoc.childNodes[-1].appendChild(snr_xml) eid_param = ligolw_param.new_param( u'event_id', u'ilwd:char', unicode(sngl_event_id_map[ifo])) snr_node.appendChild(eid_param)