Ejemplo n.º 1
0
	def __getitem__(self, coinc_event_id):
		newxmldoc = ligolw.Document()
		ligolw_elem = newxmldoc.appendChild(ligolw.LIGO_LW())

		# when making these, we can't use .copy() method of Table
		# instances because we need to ensure we have a Table
		# subclass, not a DBTable subclass
		new_process_table = ligolw_elem.appendChild(lsctables.New(lsctables.ProcessTable, self.process_table.columnnamesreal))
		new_process_params_table = ligolw_elem.appendChild(lsctables.New(lsctables.ProcessParamsTable, self.process_params_table.columnnamesreal))
		new_sngl_inspiral_table = ligolw_elem.appendChild(lsctables.New(lsctables.SnglInspiralTable, self.sngl_inspiral_table.columnnamesreal))
		new_coinc_def_table = ligolw_elem.appendChild(lsctables.New(lsctables.CoincDefTable, self.coinc_def_table.columnnamesreal))
		new_coinc_event_table = ligolw_elem.appendChild(lsctables.New(lsctables.CoincTable, self.coinc_event_table.columnnamesreal))
		new_coinc_inspiral_table = ligolw_elem.appendChild(lsctables.New(lsctables.CoincInspiralTable, self.coinc_inspiral_table.columnnamesreal))
		new_coinc_event_map_table = ligolw_elem.appendChild(lsctables.New(lsctables.CoincMapTable, self.coinc_event_map_table.columnnamesreal))
		new_time_slide_table = ligolw_elem.appendChild(lsctables.New(lsctables.TimeSlideTable, self.time_slide_table.columnnamesreal))

		new_coinc_def_table.append(self.coinc_def)
		coincevent = self.coinc_event_index[coinc_event_id]
		new_time_slide_table.extend(self.time_slide_index[coincevent.time_slide_id])

		new_sngl_inspiral_table.extend(self.sngl_inspiral_index[coinc_event_id])
		new_coinc_event_table.append(coincevent)
		new_coinc_event_map_table.extend(self.coinc_event_maps_index[coinc_event_id])
		new_coinc_inspiral_table.append(self.coinc_inspiral_index[coinc_event_id])

		for process_id in set(new_sngl_inspiral_table.getColumnByName("process_id")) | set(new_coinc_event_table.getColumnByName("process_id")) | set(new_time_slide_table.getColumnByName("process_id")):
			# process row is required
			new_process_table.append(self.process_index[process_id])
			try:
				new_process_params_table.extend(self.process_params_index[process_id])
			except KeyError:
				# process_params rows are optional
				pass

		return newxmldoc
def load_injections(inj_file, vetoes, sim_table=False, label=None):
    """Loads injections from PyGRB output file"""

    if label is None:
        logging.info("Loading injections...")
    else:
        logging.info("Loading %s...", label)

    insp_table = glsctables.MultiInspiralTable
    if sim_table:
        insp_table = glsctables.SimInspiralTable

    # Load injections in injection file
    inj_table = load_xml_table(inj_file, insp_table.tableName)

    # Extract injections in time-slid non-vetoed data
    injs = lsctables.New(insp_table, columns=insp_table.loadcolumns)
    injs.extend(inj for inj in inj_table if inj.get_end() not in vetoes)

    if label is None:
        logging.info("%d injections found.", len(injs))
    else:
        logging.info("%d %s found.", len(injs), label)

    return injs
Ejemplo n.º 3
0
def table_to_ligolw(table, tablename):
    """Convert a `astropy.table.Table` to a :class:`ligo.lw.table.Table`
    """
    from ligo.lw import lsctables

    # create new LIGO_LW table
    columns = table.columns.keys()
    cls = lsctables.TableByName[tablename]
    llwcolumns = list(columns)
    for col, llwcols in _get_property_columns(cls, columns).items():
        idx = llwcolumns.index(col)
        llwcolumns.pop(idx)
        for name in llwcols[::-1]:
            llwcolumns.insert(idx, name)
    llwtable = lsctables.New(cls, columns=llwcolumns)

    # map rows across
    for row in table:
        llwrow = llwtable.RowType()
        for name in columns:
            setattr(llwrow, name,
                    to_ligolw_table_type(row[name], llwtable, name))
        llwtable.append(llwrow)

    return llwtable
Ejemplo n.º 4
0
def load_triggers(trig_file, vetoes, ifos):
    """"Loads triggers from PyGRB output file"""
    logging.info("Loading triggers...")

    # Extract time-slides
    multis, slide_dict, _ = \
        MultiInspiralUtils.ReadMultiInspiralTimeSlidesFromFiles([trig_file])
    num_slides = len(slide_dict)
    lsctables.MultiInspiralTable.loadcolumns =\
        [slot for slot in multis[0].__slots__ if hasattr(multis[0], slot)]

    # Extract triggers
    trigs = lsctables.New(lsctables.MultiInspiralTable,
                          columns=lsctables.MultiInspiralTable.loadcolumns)
    logging.info("%d triggers found.", len(trigs))

    # Time-slid vetoes
    for slide_id in range(num_slides):
        slid_vetoes = copy.deepcopy(vetoes)
        for ifo in ifos:
            slid_vetoes[ifo].shift(-slide_dict[slide_id][ifo])

        # Add time-slid triggers
        vets = slid_vetoes.union(slid_vetoes.keys())
        trigs.extend(t for t in multis.veto(vets)
                     if int(t.time_slide_id) == slide_id)

    logging.info("%d triggers found when including timeslides.", len(trigs))

    return trigs
Ejemplo n.º 5
0
    def __init__(self, xmldoc):
        super(ExcessPowerCoincTables, self).__init__(xmldoc)

        # find the multi_burst table or create one if not found
        try:
            self.multibursttable = lsctables.MultiBurstTable.get_table(xmldoc)
        except ValueError:
            self.multibursttable = lsctables.New(
                lsctables.MultiBurstTable,
                ("process_id", "duration", "central_freq", "bandwidth", "snr",
                 "confidence", "amplitude", "coinc_event_id"))
            xmldoc.childNodes[0].appendChild(self.multibursttable)
Ejemplo n.º 6
0
def new_table(tablename, data=None, **new_kw):
    from ligo.lw import lsctables
    from ligo.lw.table import Table

    table = lsctables.New(lsctables.TableByName[Table.TableName(tablename)],
                          **new_kw)
    for dat in data or list():
        row = table.RowType()
        for key, val in dat.items():
            setattr(row, key, val)
        table.append(row)
    return table
Ejemplo n.º 7
0
	def __init__(self, xmldoc, coinc_definer_row):
		super(InspiralCoincTables, self).__init__(xmldoc, coinc_definer_row)

		#
		# find the coinc_inspiral table or create one if not found
		#

		try:
			self.coinc_inspiral_table = lsctables.CoincInspiralTable.get_table(xmldoc)
		except ValueError:
			self.coinc_inspiral_table = lsctables.New(lsctables.CoincInspiralTable)
			xmldoc.childNodes[0].appendChild(self.coinc_inspiral_table)
Ejemplo n.º 8
0
def new_doc(comment=None, **kwargs):
    doc = ligolw.Document()
    doc.appendChild(ligolw.LIGO_LW())
    process = ligolw_process.register_to_xmldoc(
        doc,
        program=u"lalapps_gen_timeslides",
        paramdict=kwargs,
        version=__version__,
        cvs_repository=u"lscsoft",
        cvs_entry_time=__date__,
        comment=comment)
    doc.childNodes[0].appendChild(lsctables.New(lsctables.TimeSlideTable))

    return doc, process
Ejemplo n.º 9
0
def table_to_ligolw(table, tablename):
    """Convert a `astropy.table.Table` to a :class:`ligo.lw.table.Table`
    """
    from ligo.lw import lsctables

    # -- work out columns for LIGO_LW table
    # this is overly complicated because of the way that we magically
    # map properties of ligo.lw.table.Table objects to real columns in
    # astropy.table.Table objects, but also because ligo.lw internally
    # combines table names and column names for some columns
    # (e.g. process:process_id)
    columns = table.columns.keys()
    cls = lsctables.TableByName[tablename]
    inst = lsctables.New(cls)
    try:
        columnnamesreal = dict(zip(inst.columnnames, inst.columnnamesreal))
    except AttributeError:  # glue doesn't have these attributes
        columnnamesreal = {}
    llwcolumns = [columnnamesreal.get(n, n) for n in columns]
    for col, llwcols in _get_property_columns(cls, columns).items():
        idx = llwcolumns.index(col)
        llwcolumns.pop(idx)
        for name in llwcols[::-1]:
            llwcolumns.insert(idx, name)

    # create new LIGO_LW table
    llwtable = lsctables.New(cls, columns=llwcolumns)

    # map rows across
    for row in table:
        llwrow = llwtable.RowType()
        for name in columns:
            setattr(llwrow, name,
                    to_ligolw_table_type(row[name], llwtable, name))
        llwtable.append(llwrow)

    return llwtable
Ejemplo n.º 10
0
    def setUp(self):
        available_detectors = get_available_detectors()
        available_detectors = [a[0] for a in available_detectors]
        self.assertTrue('H1' in available_detectors)
        self.assertTrue('L1' in available_detectors)
        self.assertTrue('V1' in available_detectors)
        self.detectors = [Detector(d) for d in ['H1', 'L1', 'V1']]
        self.sample_rate = 4096.
        self.earth_time = lal.REARTH_SI / lal.C_SI

        # create a few random injections
        self.injections = []
        start_time = float(lal.GPSTimeNow())
        taper_choices = ('TAPER_NONE', 'TAPER_START', 'TAPER_END',
                         'TAPER_STARTEND')
        for i, taper in zip(range(20), itertools.cycle(taper_choices)):
            inj = MyInjection()
            inj.end_time = start_time + 40000 * i + \
                    numpy.random.normal(scale=3600)
            random = numpy.random.uniform
            inj.mass1 = random(low=1., high=20.)
            inj.mass2 = random(low=1., high=20.)
            inj.distance = random(low=0.9, high=1.1) * 1e6 * lal.PC_SI
            inj.latitude = numpy.arccos(random(low=-1, high=1))
            inj.longitude = random(low=0, high=2 * lal.PI)
            inj.inclination = numpy.arccos(random(low=-1, high=1))
            inj.polarization = random(low=0, high=2 * lal.PI)
            inj.taper = taper
            self.injections.append(inj)

        # create LIGOLW document
        xmldoc = ligolw.Document()
        xmldoc.appendChild(ligolw.LIGO_LW())

        # create sim inspiral table, link it to document and fill it
        sim_table = lsctables.New(lsctables.SimInspiralTable)
        xmldoc.childNodes[-1].appendChild(sim_table)
        for i in range(len(self.injections)):
            row = sim_table.RowType()
            self.injections[i].fill_sim_inspiral_row(row)
            row.process_id = 0
            row.simulation_id = i
            sim_table.append(row)

        # write document to temp file
        self.inj_file = tempfile.NamedTemporaryFile(suffix='.xml')
        ligolw_utils.write_fileobj(xmldoc, self.inj_file)
Ejemplo n.º 11
0
def load_injections(inj_file, vetoes):
    """"Loads injections from PyGRB output file"""
    logging.info("Loading injections...")

    # Load injection file
    xml_doc = load_xml_file(inj_file)
    multis = lsctables.MultiInspiralTable.get_table(xml_doc)

    # Extract injections
    injs = lsctables.New(lsctables.MultiInspiralTable,
                         columns=lsctables.MultiInspiralTable.loadcolumns)

    # Injections in time-slid non-vetoed data
    injs.extend(t for t in multis if t.get_end() not in vetoes)

    logging.info("%d injections found.", len(injs))

    return injs
Ejemplo n.º 12
0
    def write(filename, samples, write_params=None, static_args=None):
        """Writes the injection samples to the given xml.

        Parameters
        ----------
        filename : str
            The name of the file to write to.
        samples : io.FieldArray
            FieldArray of parameters.
        write_params : list, optional
            Only write the given parameter names. All given names must be keys
            in ``samples``. Default is to write all parameters in ``samples``.
        static_args : dict, optional
            Dictionary mapping static parameter names to values. These are
            written to the ``attrs``.
        """
        xmldoc = ligolw.Document()
        xmldoc.appendChild(ligolw.LIGO_LW())
        simtable = lsctables.New(lsctables.SimInspiralTable)
        xmldoc.childNodes[0].appendChild(simtable)
        if static_args is None:
            static_args = {}
        if write_params is None:
            write_params = samples.fieldnames
        for ii in range(samples.size):
            sim = lsctables.SimInspiral()
            # initialize all elements to None
            for col in sim.__slots__:
                setattr(sim, col, None)
            for field in write_params:
                data = samples[ii][field]
                set_sim_data(sim, field, data)
            # set any static args
            for (field, value) in static_args.items():
                set_sim_data(sim, field, value)
            simtable.append(sim)
        ligolw_utils.write_filename(xmldoc,
                                    filename,
                                    gz=filename.endswith('gz'))
Ejemplo n.º 13
0
def convert_to_sngl_inspiral_table(params, proc_id):
    '''
    Convert a list of m1,m2,spin1z,spin2z values into a basic sngl_inspiral
    table with mass and spin parameters populated and event IDs assigned

    Parameters
    -----------
    params : iterable
        Each entry in the params iterable should be a sequence of
        [mass1, mass2, spin1z, spin2z] in that order
    proc_id : int
        Process ID to add to each row of the sngl_inspiral table

    Returns
    ----------
    SnglInspiralTable
        Bank of templates in SnglInspiralTable format
    '''
    sngl_inspiral_table = lsctables.New(lsctables.SnglInspiralTable)
    col_names = ['mass1','mass2','spin1z','spin2z']

    for values in params:
        tmplt = return_empty_sngl()

        tmplt.process_id = proc_id
        for colname, value in zip(col_names, values):
            setattr(tmplt, colname, value)
        tmplt.mtotal, tmplt.eta = pnutils.mass1_mass2_to_mtotal_eta(
            tmplt.mass1, tmplt.mass2)
        tmplt.mchirp, _ = pnutils.mass1_mass2_to_mchirp_eta(
            tmplt.mass1, tmplt.mass2)
        tmplt.template_duration = 0 # FIXME
        tmplt.event_id = sngl_inspiral_table.get_next_id()
        sngl_inspiral_table.append(tmplt)

    return sngl_inspiral_table
Ejemplo n.º 14
0
    injections['coa_phase'] = samples['phi_orb']
    injections['polarization'] = samples['polarization']
    injections['spin1x'] = s1x
    injections['spin1y'] = s1y
    injections['spin1z'] = s1z
    injections['spin2x'] = s2x
    injections['spin2y'] = s2y
    injections['spin2z'] = s2z
    injections['amp_order'] = [opts.amporder for i in range(N)]
    injections['numrel_data'] = ["" for _ in range(N)]

    # Create a new XML document
    xmldoc = ligolw.Document()
    xmldoc.appendChild(ligolw.LIGO_LW())
    proc = ligo.lw.utils.process.register_to_xmldoc(doc, sys.argv[0], {})
    sim_table = lsctables.New(lsctables.SimInspiralTable)
    xmldoc.childNodes[0].appendChild(sim_table)

    # Add empty rows to the sim_inspiral table
    for inj in range(N):
        row = sim_table.RowType()
        for slot in row.__slots__:
            setattr(row, slot, 0)
        sim_table.append(row)

    # Fill in IDs
    for i, row in enumerate(sim_table):
        row.process_id = proc.process_id
        row.simulation_id = sim_table.get_next_id()

    # Fill rows
Ejemplo n.º 15
0
def output_sngl_inspiral_table(outputFile, tempBank, metricParams,
                               ethincaParams, programName="", optDict = None,
                               outdoc=None):
    """
    Function that converts the information produced by the various PyCBC bank
    generation codes into a valid LIGOLW XML file containing a sngl_inspiral
    table and outputs to file.

    Parameters
    -----------
    outputFile : string
        Name of the file that the bank will be written to
    tempBank : iterable
        Each entry in the tempBank iterable should be a sequence of
        [mass1,mass2,spin1z,spin2z] in that order.
    metricParams : metricParameters instance
        Structure holding all the options for construction of the metric
        and the eigenvalues, eigenvectors and covariance matrix
        needed to manipulate the space.
    ethincaParams: {ethincaParameters instance, None}
        Structure holding options relevant to the ethinca metric computation
        including the upper frequency cutoff to be used for filtering.
        NOTE: The computation is currently only valid for non-spinning systems
        and uses the TaylorF2 approximant.
    programName (key-word-argument) : string
        Name of the executable that has been run
    optDict (key-word argument) : dictionary
        Dictionary of the command line arguments passed to the program
    outdoc (key-word argument) : ligolw xml document
        If given add template bank to this representation of a xml document and
        write to disk. If not given create a new document.
    """
    if optDict is None:
        optDict = {}
    if outdoc is None:
        outdoc = ligolw.Document()
        outdoc.appendChild(ligolw.LIGO_LW())

    # get IFO to put in search summary table
    ifos = []
    if 'channel_name' in optDict.keys():
        if optDict['channel_name'] is not None:
            ifos = [optDict['channel_name'][0:2]]

    proc = create_process_table(
        outdoc,
        program_name=programName,
        detectors=ifos,
        options=optDict
    )
    proc_id = proc.process_id
    sngl_inspiral_table = convert_to_sngl_inspiral_table(tempBank, proc_id)
    # Calculate Gamma components if needed
    if ethincaParams is not None:
        if ethincaParams.doEthinca:
            for sngl in sngl_inspiral_table:
                # Set tau_0 and tau_3 values needed for the calculation of
                # ethinca metric distances
                (sngl.tau0,sngl.tau3) = pnutils.mass1_mass2_to_tau0_tau3(
                    sngl.mass1, sngl.mass2, metricParams.f0)
                fMax_theor, GammaVals = calculate_ethinca_metric_comps(
                    metricParams, ethincaParams,
                    sngl.mass1, sngl.mass2, spin1z=sngl.spin1z,
                    spin2z=sngl.spin2z, full_ethinca=ethincaParams.full_ethinca)
                # assign the upper frequency cutoff and Gamma0-5 values
                sngl.f_final = fMax_theor
                for i in range(len(GammaVals)):
                    setattr(sngl, "Gamma"+str(i), GammaVals[i])
        # If Gamma metric components are not wanted, assign f_final from an
        # upper frequency cutoff specified in ethincaParams
        elif ethincaParams.cutoff is not None:
            for sngl in sngl_inspiral_table:
                sngl.f_final = pnutils.frequency_cutoff_from_name(
                    ethincaParams.cutoff,
                    sngl.mass1, sngl.mass2, sngl.spin1z, sngl.spin2z)

    # set per-template low-frequency cutoff
    if 'f_low_column' in optDict and 'f_low' in optDict and \
            optDict['f_low_column'] is not None:
        for sngl in sngl_inspiral_table:
            setattr(sngl, optDict['f_low_column'], optDict['f_low'])

    outdoc.childNodes[0].appendChild(sngl_inspiral_table)

    # get times to put in search summary table
    start_time = 0
    end_time = 0
    if 'gps_start_time' in optDict.keys() and 'gps_end_time' in optDict.keys():
        start_time = optDict['gps_start_time']
        end_time = optDict['gps_end_time']

    # make search summary table
    search_summary_table = lsctables.New(lsctables.SearchSummaryTable)
    search_summary = return_search_summary(
        start_time, end_time, len(sngl_inspiral_table), ifos
    )
    search_summary_table.append(search_summary)
    outdoc.childNodes[0].appendChild(search_summary_table)

    # write the xml doc to disk
    ligolw_utils.write_filename(outdoc, outputFile)
Ejemplo n.º 16
0
def main(args=None):
    from ligo.lw import lsctables
    from ligo.lw import utils as ligolw_utils
    from ligo.lw import ligolw
    import lal.series
    from scipy import stats

    p = parser()
    args = p.parse_args(args)

    xmldoc = ligolw.Document()
    xmlroot = xmldoc.appendChild(ligolw.LIGO_LW())
    process = register_to_xmldoc(xmldoc, p, args)

    gwcosmo = GWCosmo(
        cosmology.default_cosmology.get_cosmology_from_string(args.cosmology))

    ns_mass_min = 1.0
    ns_mass_max = 2.0
    bh_mass_min = 5.0
    bh_mass_max = 50.0

    ns_astro_spin_min = -0.05
    ns_astro_spin_max = +0.05
    ns_astro_mass_dist = stats.norm(1.33, 0.09)
    ns_astro_spin_dist = stats.uniform(ns_astro_spin_min,
                                       ns_astro_spin_max - ns_astro_spin_min)

    ns_broad_spin_min = -0.4
    ns_broad_spin_max = +0.4
    ns_broad_mass_dist = stats.uniform(ns_mass_min, ns_mass_max - ns_mass_min)
    ns_broad_spin_dist = stats.uniform(ns_broad_spin_min,
                                       ns_broad_spin_max - ns_broad_spin_min)

    bh_astro_spin_min = -0.99
    bh_astro_spin_max = +0.99
    bh_astro_mass_dist = stats.pareto(b=1.3)
    bh_astro_spin_dist = stats.uniform(bh_astro_spin_min,
                                       bh_astro_spin_max - bh_astro_spin_min)

    bh_broad_spin_min = -0.99
    bh_broad_spin_max = +0.99
    bh_broad_mass_dist = stats.reciprocal(bh_mass_min, bh_mass_max)
    bh_broad_spin_dist = stats.uniform(bh_broad_spin_min,
                                       bh_broad_spin_max - bh_broad_spin_min)

    if args.distribution.startswith('bns_'):
        m1_min = m2_min = ns_mass_min
        m1_max = m2_max = ns_mass_max
        if args.distribution.endswith('_astro'):
            x1_min = x2_min = ns_astro_spin_min
            x1_max = x2_max = ns_astro_spin_max
            m1_dist = m2_dist = ns_astro_mass_dist
            x1_dist = x2_dist = ns_astro_spin_dist
        elif args.distribution.endswith('_broad'):
            x1_min = x2_min = ns_broad_spin_min
            x1_max = x2_max = ns_broad_spin_max
            m1_dist = m2_dist = ns_broad_mass_dist
            x1_dist = x2_dist = ns_broad_spin_dist
        else:  # pragma: no cover
            assert_not_reached()
    elif args.distribution.startswith('nsbh_'):
        m1_min = bh_mass_min
        m1_max = bh_mass_max
        m2_min = ns_mass_min
        m2_max = ns_mass_max
        if args.distribution.endswith('_astro'):
            x1_min = bh_astro_spin_min
            x1_max = bh_astro_spin_max
            x2_min = ns_astro_spin_min
            x2_max = ns_astro_spin_max
            m1_dist = bh_astro_mass_dist
            m2_dist = ns_astro_mass_dist
            x1_dist = bh_astro_spin_dist
            x2_dist = ns_astro_spin_dist
        elif args.distribution.endswith('_broad'):
            x1_min = bh_broad_spin_min
            x1_max = bh_broad_spin_max
            x2_min = ns_broad_spin_min
            x2_max = ns_broad_spin_max
            m1_dist = bh_broad_mass_dist
            m2_dist = ns_broad_mass_dist
            x1_dist = bh_broad_spin_dist
            x2_dist = ns_broad_spin_dist
        else:  # pragma: no cover
            assert_not_reached()
    elif args.distribution.startswith('bbh_'):
        m1_min = m2_min = bh_mass_min
        m1_max = m2_max = bh_mass_max
        if args.distribution.endswith('_astro'):
            x1_min = x2_min = bh_astro_spin_min
            x1_max = x2_max = bh_astro_spin_max
            m1_dist = m2_dist = bh_astro_mass_dist
            x1_dist = x2_dist = bh_astro_spin_dist
        elif args.distribution.endswith('_broad'):
            x1_min = x2_min = bh_broad_spin_min
            x1_max = x2_max = bh_broad_spin_max
            m1_dist = m2_dist = bh_broad_mass_dist
            x1_dist = x2_dist = bh_broad_spin_dist
        else:  # pragma: no cover
            assert_not_reached()
    else:  # pragma: no cover
        assert_not_reached()

    dists = (m1_dist, m2_dist, x1_dist, x2_dist)

    # Read PSDs
    psds = list(
        lal.series.read_psd_xmldoc(
            ligolw_utils.load_fileobj(
                args.reference_psd,
                contenthandler=lal.series.PSDContentHandler)).values())

    # Construct mass1, mass2, spin1z, spin2z grid.
    m1 = np.geomspace(m1_min, m1_max, 10)
    m2 = np.geomspace(m2_min, m2_max, 10)
    x1 = np.linspace(x1_min, x1_max, 10)
    x2 = np.linspace(x2_min, x2_max, 10)
    params = m1, m2, x1, x2

    # Calculate the maximum distance on the grid.
    max_z = gwcosmo.get_max_z(psds,
                              args.waveform,
                              args.f_low,
                              args.min_snr,
                              m1,
                              m2,
                              x1,
                              x2,
                              jobs=args.jobs)
    if args.max_distance is not None:
        new_max_z = cosmology.z_at_value(gwcosmo.cosmo.luminosity_distance,
                                         args.max_distance * units.Mpc)
        max_z[max_z > new_max_z] = new_max_z
    max_distance = gwcosmo.sensitive_distance(max_z).to_value(units.Mpc)

    # Find piecewise constant approximate upper bound on distance.
    max_distance = cell_max(max_distance)

    # Calculate V * T in each grid cell
    cdfs = [dist.cdf(param) for param, dist in zip(params, dists)]
    cdf_los = [cdf[:-1] for cdf in cdfs]
    cdfs = [np.diff(cdf) for cdf in cdfs]
    probs = np.prod(np.meshgrid(*cdfs, indexing='ij'), axis=0)
    probs /= probs.sum()
    probs *= 4 / 3 * np.pi * max_distance**3
    volume = probs.sum()
    probs /= volume
    probs = probs.ravel()

    volumetric_rate = args.nsamples / volume * units.year**-1 * units.Mpc**-3

    # Draw random grid cells
    dist = stats.rv_discrete(values=(np.arange(len(probs)), probs))
    indices = np.unravel_index(dist.rvs(size=args.nsamples),
                               max_distance.shape)

    # Draw random intrinsic params from each cell
    cols = {}
    cols['mass1'], cols['mass2'], cols['spin1z'], cols['spin2z'] = [
        dist.ppf(stats.uniform(cdf_lo[i], cdf[i]).rvs(size=args.nsamples))
        for i, dist, cdf_lo, cdf in zip(indices, dists, cdf_los, cdfs)
    ]

    # Swap binary components as needed to ensure that mass1 >= mass2.
    # Note that the .copy() is important.
    # See https://github.com/numpy/numpy/issues/14428
    swap = cols['mass1'] < cols['mass2']
    cols['mass1'][swap], cols['mass2'][swap] = \
        cols['mass2'][swap].copy(), cols['mass1'][swap].copy()
    cols['spin1z'][swap], cols['spin2z'][swap] = \
        cols['spin2z'][swap].copy(), cols['spin1z'][swap].copy()

    # Draw random extrinsic parameters
    cols['distance'] = stats.powerlaw(
        a=3, scale=max_distance[indices]).rvs(size=args.nsamples)
    cols['longitude'] = stats.uniform(0, 2 * np.pi).rvs(size=args.nsamples)
    cols['latitude'] = np.arcsin(stats.uniform(-1, 2).rvs(size=args.nsamples))
    cols['inclination'] = np.arccos(
        stats.uniform(-1, 2).rvs(size=args.nsamples))
    cols['polarization'] = stats.uniform(0, 2 * np.pi).rvs(size=args.nsamples)
    cols['coa_phase'] = stats.uniform(-np.pi,
                                      2 * np.pi).rvs(size=args.nsamples)
    cols['time_geocent'] = stats.uniform(1e9, units.year.to(
        units.second)).rvs(size=args.nsamples)

    # Convert from sensitive distance to redshift and comoving distance.
    # FIXME: Replace this brute-force lookup table with a solver.
    z = np.linspace(0, max_z.max(), 10000)
    ds = gwcosmo.sensitive_distance(z).to_value(units.Mpc)
    dc = gwcosmo.cosmo.comoving_distance(z).to_value(units.Mpc)
    z_for_ds = interp1d(ds, z, kind='cubic', assume_sorted=True)
    dc_for_ds = interp1d(ds, dc, kind='cubic', assume_sorted=True)
    zp1 = 1 + z_for_ds(cols['distance'])
    cols['distance'] = dc_for_ds(cols['distance'])

    # Apply redshift factor to convert from comoving distance and source frame
    # masses to luminosity distance and observer frame masses.
    for key in ['distance', 'mass1', 'mass2']:
        cols[key] *= zp1

    # Populate sim_inspiral table
    sims = xmlroot.appendChild(lsctables.New(lsctables.SimInspiralTable))
    for row in zip(*cols.values()):
        sims.appendRow(**dict(dict.fromkeys(sims.validcolumns, None),
                              process_id=process.process_id,
                              simulation_id=sims.get_next_id(),
                              waveform=args.waveform,
                              f_lower=args.f_low,
                              **dict(zip(cols.keys(), row))))

    # Record process end time.
    process.comment = str(volumetric_rate)
    process.set_end_time_now()

    # Write output file.
    write_fileobj(xmldoc, args.output)
Ejemplo n.º 17
0
    def __init__(self, xmldoc, b_b_def, sb_b_def, si_b_def, sb_c_e_def,
                 sb_c_n_def, si_c_e_def, si_c_n_def, process,
                 livetime_program):
        #
        # store the process row
        #

        self.process = process

        #
        # locate the sngl_burst, time_slide and injection tables
        #

        self.snglbursttable = lsctables.SnglBurstTable.get_table(xmldoc)
        try:
            self.simbursttable = lsctables.SimBurstTable.get_table(xmldoc)
        except ValueError:
            self.simbursttable = None
        try:
            self.siminspiraltable = lsctables.SimInspiralTable.get_table(
                xmldoc)
        except ValueError:
            self.siminspiraltable = None
        try:
            timeslidetable = lsctables.TimeSlideTable.get_table(xmldoc)
        except ValueError:
            timeslidetable = None
        if timeslidetable is not None:
            self.offsetvectors = timeslidetable.as_dict()
        else:
            self.offsetvectors = {}

        #
        # store the longest duration of a burst event
        #

        if self.snglbursttable:
            self.longestduration = max(
                self.snglbursttable.getColumnByName("duration"))
        else:
            self.longestduration = 0.0

        #
        # get a segmentlistdict indicating the times when the jobs
        # that produced burst events could have produced output
        #

        self.seglists = ligolw_search_summary.segmentlistdict_fromsearchsummary(
            xmldoc, livetime_program).coalesce()

        #
        # FIXME:  in the future, the sim_inspiral table should
        # indicate time slide at which the injection was done, like
        # the sim_burst table does.  for now, fake it by giving
        # each one a time_slide_id attribute.  this is the only
        # reason why a place-holder class is required for the
        # SimInspiral row type;  that class can be deleted when
        # this is no longer needed
        #

        if self.siminspiraltable is not None:
            time_slide_id = ligolw_time_slide.get_time_slide_id(
                xmldoc, {}.fromkeys(self.seglists, 0.0),
                create_new=process,
                superset_ok=True,
                nonunique_ok=False)
            for sim in self.siminspiraltable:
                sim.time_slide_id = time_slide_id

        #
        # get coinc_definer rows for sim_* <--> sngl_burst coincs
        # for whichever sim_* tables are present; this creates a
        # coinc_definer table if the document doesn't have one
        #

        if self.simbursttable is not None:
            self.sb_b_coinc_def_id = ligolw_coincs.get_coinc_def_id(
                xmldoc,
                sb_b_def.search,
                sb_b_def.search_coinc_type,
                create_new=True,
                description=sb_b_def.description)
        else:
            self.sb_b_coinc_def_id = None
        if self.siminspiraltable is not None:
            self.si_b_coinc_def_id = ligolw_coincs.get_coinc_def_id(
                xmldoc,
                si_b_def.search,
                si_b_def.search_coinc_type,
                create_new=True,
                description=si_b_def.description)
        else:
            self.si_b_coinc_def_id = None

        #
        # get coinc_def_id's for sngl_burst <--> sngl_burst, and
        # both kinds of sim_* <--> coinc_event coincs.  set all to
        # None if this document does not contain any sngl_burst
        # <--> sngl_burst coincs.
        #

        try:
            b_b_coinc_def_id = ligolw_coincs.get_coinc_def_id(
                xmldoc,
                b_b_def.search,
                b_b_def.search_coinc_type,
                create_new=False)
        except KeyError:
            b_b_coinc_def_id = None
            self.sb_c_e_coinc_def_id = None
            self.sb_c_n_coinc_def_id = None
            self.si_c_e_coinc_def_id = None
            self.si_c_n_coinc_def_id = None
        else:
            if self.simbursttable is not None:
                self.sb_c_e_coinc_def_id = ligolw_coincs.get_coinc_def_id(
                    xmldoc,
                    sb_c_e_def.search,
                    sb_c_e_def.search_coinc_type,
                    create_new=True,
                    description=sb_c_e_def.description)
                self.sb_c_n_coinc_def_id = ligolw_coincs.get_coinc_def_id(
                    xmldoc,
                    sb_c_n_def.search,
                    sb_c_n_def.search_coinc_type,
                    create_new=True,
                    description=sb_c_n_def.description)
            else:
                self.sb_c_e_coinc_def_id = None
                self.sb_c_n_coinc_def_id = None
            if self.siminspiraltable is not None:
                self.si_c_e_coinc_def_id = ligolw_coincs.get_coinc_def_id(
                    xmldoc,
                    si_c_e_def.search,
                    si_c_e_def.search_coinc_type,
                    create_new=True,
                    description=si_c_e_def.description)
                self.si_c_n_coinc_def_id = ligolw_coincs.get_coinc_def_id(
                    xmldoc,
                    si_c_n_def.search,
                    si_c_n_def.search_coinc_type,
                    create_new=True,
                    description=si_c_n_def.description)
            else:
                self.si_c_e_coinc_def_id = None
                self.si_c_n_coinc_def_id = None

        #
        # get coinc table, create one if needed
        #

        try:
            self.coinctable = lsctables.CoincTable.get_table(xmldoc)
        except ValueError:
            self.coinctable = lsctables.New(lsctables.CoincTable)
            xmldoc.childNodes[0].appendChild(self.coinctable)
        self.coinctable.sync_next_id()

        #
        # get coinc_map table, create one if needed
        #

        try:
            self.coincmaptable = lsctables.CoincMapTable.get_table(xmldoc)
        except ValueError:
            self.coincmaptable = lsctables.New(lsctables.CoincMapTable)
            xmldoc.childNodes[0].appendChild(self.coincmaptable)

        #
        # index the document
        #

        # index sngl_burst table
        index = dict((row.event_id, row) for row in self.snglbursttable)
        # find IDs of burst<-->burst coincs
        self.coincs = dict((row.coinc_event_id, []) for row in self.coinctable
                           if row.coinc_def_id == b_b_coinc_def_id)
        # construct event list for each burst<-->burst coinc
        for row in self.coincmaptable:
            try:
                self.coincs[row.coinc_event_id].append(index[row.event_id])
            except KeyError:
                pass
        del index
        # sort the event list for each coin by peak time and
        # convert to tuples for speed
        for coinc_event_id, events in self.coincs.items():
            events.sort(key=lambda event: event.peak)
            self.coincs[coinc_event_id] = tuple(events)
        # convert dictionary to a list of (coinc_event_id, events)
        # tuples and create a coinc_event_id to offset vector
        # look-up table
        self.coincs = self.coincs.items()
        self.coincoffsets = dict(
            (row.coinc_event_id, self.offsetvectors[row.time_slide_id])
            for row in self.coinctable if row.coinc_def_id == b_b_coinc_def_id)

        #
        # represent the sngl_burst table as a dictionary indexed by
        # instrument whose values are the event lists for those
        # instruments sorted by peak time.  sort the coincs list by
        # the peak time of the first (earliest) event in each coinc
        # (recall that the event tuple for each coinc has been
        # time-ordered)
        #

        self.snglbursttable = dict(
            (instrument,
             sorted((event for event in self.snglbursttable
                     if event.ifo == instrument),
                    key=lambda event: event.peak))
            for instrument in set(self.snglbursttable.getColumnByName("ifo")))
        self.coincs.sort(
            key=lambda coinc_id_events: coinc_id_events[1][0].peak)
Ejemplo n.º 18
0
def create_bank_xml(flow,
                    fhigh,
                    band,
                    duration,
                    level=0,
                    ndof=1,
                    frequency_overlap=0,
                    detector=None,
                    units=utils.EXCESSPOWER_UNIT_SCALE['Hz']):
    """
	Create a bank of sngl_burst XML entries. This file is then used by the trigger generator to do trigger generation. Takes in the frequency parameters and filter duration and returns an ligolw entity with a sngl_burst Table which can be saved to a file.
	"""

    xmldoc = ligolw.Document()
    xmldoc.appendChild(ligolw.LIGO_LW())
    bank = lsctables.New(lsctables.SnglBurstTable, [
        "peak_time_ns", "start_time_ns", "stop_time_ns", "process_id", "ifo",
        "peak_time", "start_time", "stop_time", "duration", "time_lag",
        "peak_frequency", "search", "central_freq", "channel", "amplitude",
        "snr", "confidence", "chisq", "chisq_dof", "flow", "fhigh",
        "bandwidth", "tfvolume", "hrss", "event_id"
    ])
    bank.sync_next_id()

    # The first frequency band actually begins at flow, so we offset the
    # central frequency accordingly
    if level == 0:  # Hann windows
        edge = band / 2
        cfreq = flow + band
    else:  # Tukey windows
        edge = band / 2**(level + 1)
        # The sin^2 tapering comes from the Hann windows, so we need to know
        # how far they extend to account for the overlap at the ends
        cfreq = flow + edge + (band / 2)

    while cfreq + edge + band / 2 <= fhigh:
        row = bank.RowType()
        row.search = u"gstlal_excesspower"
        row.duration = duration * ndof
        row.bandwidth = band
        row.peak_frequency = cfreq
        row.central_freq = cfreq
        # This actually marks the 50 % overlap point
        row.flow = cfreq - band / 2.0
        # This actually marks the 50 % overlap point
        row.fhigh = cfreq + band / 2.0
        row.ifo = detector
        row.chisq_dof = 2 * band * row.duration
        row.duration *= units

        # Stuff that doesn't matter, yet
        row.peak_time_ns = 0
        row.peak_time = 0
        row.start_time_ns = 0
        row.start_time = 0
        row.stop_time_ns = 0
        row.stop_time = 0
        row.tfvolume = 0
        row.time_lag = 0
        row.amplitude = 0
        row.hrss = 0
        row.snr = 0
        row.chisq = 0
        row.confidence = 0
        row.event_id = bank.get_next_id()
        row.channel = "awesome full of GW channel"
        row.process_id = ilwd.ilwdchar(u"process:process_id:0")

        bank.append(row)
        #cfreq += band #band is half the full width of the window, so this is 50% overlap
        cfreq += band * (1 - frequency_overlap)

    xmldoc.childNodes[0].appendChild(bank)
    return xmldoc
Ejemplo n.º 19
0
    injections['q'] = q
    try:
        injections['hrss'] = samples['hrss']
    except:
        injections['hrss'] = np.exp(samples['loghrss'])
    injections['ra'] = samples['ra']
    injections['dec'] = samples['dec']
    injections['psi'] = samples['psi']

    # Create a new XML document
    xmldoc = ligolw.Document()
    xmldoc.appendChild(ligolw.LIGO_LW())
    proc = ligo.lw.utils.process.register_to_xmldoc(doc, sys.argv[0], {})

    #create timeslide table and set offsets to 0
    timeslide_table = lsctables.New(lsctables.TimeSlideTable)
    timeslide_id = timeslide_table.append_offsetvector(
        {
            'H1': 0,
            'V1': 0,
            'L1': 0,
            'H2': 0
        }, proc)

    sim_table = lsctables.New(lsctables.SimBurstTable)
    xmldoc.childNodes[0].appendChild(timeslide_table)
    xmldoc.childNodes[0].appendChild(sim_table)

    # Add empty rows to the sim_inspiral table
    for inj in range(N):
        row = sim_table.RowType()
Ejemplo n.º 20
0
	def __init__(self, xmldoc, bbdef, sbdef, scedef, scndef, process, end_time_bisect_window):
		#
		# store the process row
		#

		self.process = process

		#
		# locate the sngl_inspiral and sim_inspiral tables
		#

		self.snglinspiraltable = lsctables.SnglInspiralTable.get_table(xmldoc)
		self.siminspiraltable = lsctables.SimInspiralTable.get_table(xmldoc)

		#
		# get the offset vectors from the document
		#

		self.offsetvectors = lsctables.TimeSlideTable.get_table(xmldoc).as_dict()

		#
		# construct the zero-lag time slide needed to cover the
		# instruments listed in all the triggers, then determine
		# its ID (or create it if needed)
		#
		# FIXME:  in the future, the sim_inspiral table should
		# indicate time slide at which the injection was done
		#

		self.tisi_id = ligolw_time_slide.get_time_slide_id(xmldoc, {}.fromkeys(self.snglinspiraltable.getColumnByName("ifo"), 0.0), create_new = process, superset_ok = True, nonunique_ok = True)

		#
		# get coinc_definer row for sim_inspiral <--> sngl_inspiral
		# coincs; this creates a coinc_definer table if the
		# document doesn't have one
		#

		self.sb_coinc_def_id = ligolw_coincs.get_coinc_def_id(xmldoc, sbdef.search, sbdef.search_coinc_type, create_new = True, description = sbdef.description)

		#
		# get coinc_def_id's for sngl_inspiral <--> sngl_inspiral, and
		# both kinds of sim_inspiral <--> coinc_event coincs.  set all
		# to None if this document does not contain any sngl_inspiral
		# <--> sngl_inspiral coincs.
		#

		try:
			ii_coinc_def_id = ligolw_coincs.get_coinc_def_id(xmldoc, bbdef.search, bbdef.search_coinc_type, create_new = False)
		except KeyError:
			ii_coinc_def_id = None
			self.sce_coinc_def_id = None
			self.scn_coinc_def_id = None
		else:
			self.sce_coinc_def_id = ligolw_coincs.get_coinc_def_id(xmldoc, scedef.search, scedef.search_coinc_type, create_new = True, description = scedef.description)
			self.scn_coinc_def_id = ligolw_coincs.get_coinc_def_id(xmldoc, scndef.search, scndef.search_coinc_type, create_new = True, description = scndef.description)

		#
		# get coinc table, create one if needed
		#

		try:
			self.coinctable = lsctables.CoincTable.get_table(xmldoc)
		except ValueError:
			self.coinctable = lsctables.New(lsctables.CoincTable)
			xmldoc.childNodes[0].appendChild(self.coinctable)
		self.coinctable.sync_next_id()

		#
		# get coinc_map table, create one if needed
		#

		try:
			self.coincmaptable = lsctables.CoincMapTable.get_table(xmldoc)
		except ValueError:
			self.coincmaptable = lsctables.New(lsctables.CoincMapTable)
			xmldoc.childNodes[0].appendChild(self.coincmaptable)

		#
		# index the document
		#
		# FIXME:  inspiral<-->inspiral coincs should be organized by time
		# slide ID, but since injections are only done at zero lag
		# for now this is ignored.
		#

		# index the sngl_inspiral table
		index = dict((row.event_id, row) for row in self.snglinspiraltable)
		# find IDs of inspiral<-->inspiral coincs
		self.sngls = dict((row.coinc_event_id, []) for row in self.coinctable if row.coinc_def_id == ii_coinc_def_id)
		# construct event list for each inspiral<-->inspiral coinc
		for row in self.coincmaptable:
			try:
				self.sngls[row.coinc_event_id].append(index[row.event_id])
			except KeyError:
				pass
		del index
		# construct a sngl-->coincs look-up table
		self.coincs = dict((event.event_id, set()) for events in self.sngls.values() for event in events)
		for row in self.coincmaptable:
			if row.event_id in self.coincs and row.coinc_event_id in self.sngls:
				self.coincs[row.event_id].add(row.coinc_event_id)
		# create a coinc_event_id to offset vector look-up table
		self.coincoffsets = dict((row.coinc_event_id, self.offsetvectors[row.time_slide_id]) for row in self.coinctable if row.coinc_def_id == ii_coinc_def_id)

		#
		# sort sngl_inspiral table by end time
		#

		self.snglinspiraltable.sort(key = lambda row: row.end)

		#
		# set the window for inspirals_near_endtime().  this window
		# is the amount of time such that if an injection's end
		# time and a inspiral event's end time differ by more than
		# this it is *impossible* for them to match one another.
		#

		self.end_time_bisect_window = lsctables.LIGOTimeGPS(end_time_bisect_window)
Ejemplo n.º 21
0
#

try:
    lsctables.SimBurstTable.get_table(xmldoc)
except ValueError:
    # no sim_burst table in document
    pass
else:
    raise ValueError(
        "%s contains a sim_burst table.  this program isn't smart enough to deal with that."
        % options.time_slide_xml)

sim_burst_tbl = xmldoc.childNodes[-1].appendChild(
    lsctables.New(lsctables.SimBurstTable, [
        "process:process_id", "simulation_id", "time_slide:time_slide_id",
        "waveform", "waveform_number", "ra", "dec", "psi", "time_geocent_gps",
        "time_geocent_gps_ns", "duration", "frequency", "bandwidth",
        "egw_over_rsquared", "pol_ellipse_angle", "pol_ellipse_e"
    ]))

#
# populate the sim_burst table with pixels
#

if options.verbose:
    print("time-frequency tiles have %g degrees of freedom" %
          (2. * options.delta_t * options.delta_f),
          file=sys.stderr)

for n, filename in enumerate(filenames, 1):
    if options.verbose:
        print("%d/%d: loading %s ..." % (n, len(filenames), filename),
Ejemplo n.º 22
0
def make_exttrig_file(cp, ifos, sci_seg, out_dir):
    '''
    Make an ExtTrig xml file containing information on the external trigger

    Parameters
    ----------
    cp : pycbc.workflow.configuration.WorkflowConfigParser object
    The parsed configuration options of a pycbc.workflow.core.Workflow.

    ifos : str
    String containing the analysis interferometer IDs.

    sci_seg : ligo.segments.segment
    The science segment for the analysis run.

    out_dir : str
    The output directory, destination for xml file.

    Returns
    -------
    xml_file : pycbc.workflow.File object
    The xml file with external trigger information.

    '''
    # Initialise objects
    xmldoc = ligolw.Document()
    xmldoc.appendChild(ligolw.LIGO_LW())
    tbl = lsctables.New(lsctables.ExtTriggersTable)
    cols = tbl.validcolumns
    xmldoc.childNodes[-1].appendChild(tbl)
    row = tbl.appendRow()

    # Add known attributes for this GRB
    setattr(row, "event_ra", float(cp.get("workflow", "ra")))
    setattr(row, "event_dec", float(cp.get("workflow", "dec")))
    setattr(row, "start_time", int(cp.get("workflow", "trigger-time")))
    setattr(row, "event_number_grb", str(cp.get("workflow", "trigger-name")))

    # Fill in all empty rows
    for entry in cols.keys():
        if hasattr(row, entry):
            continue
        if cols[entry] in ['real_4', 'real_8']:
            setattr(row, entry, 0.)
        elif cols[entry] in ['int_4s', 'int_8s']:
            setattr(row, entry, 0)
        elif cols[entry] == 'lstring':
            setattr(row, entry, '')
        elif entry == 'process_id':
            row.process_id = 0
        elif entry == 'event_id':
            row.event_id = 0
        else:
            raise ValueError("Column %s not recognized" % entry)

    # Save file
    xml_file_name = "triggerGRB%s.xml" % str(cp.get("workflow",
                                                    "trigger-name"))
    xml_file_path = os.path.join(out_dir, xml_file_name)
    utils.write_filename(xmldoc, xml_file_path)
    xml_file_url = urljoin("file:", pathname2url(xml_file_path))
    xml_file = File(ifos, xml_file_name, sci_seg, file_url=xml_file_url)
    xml_file.add_pfn(xml_file_url, site="local")

    return xml_file
Ejemplo n.º 23
0
    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 participating 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.
        high_frequency_cutoff: float, optional
            Maximum frequency considered for the PSD estimates. Default None.
        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.
        mc_area_args: dict of dicts, optional
            Dictionary providing arguments to be used in source probability
            estimation with pycbc/mchirp_area.py
        """
        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'])

        # Check if we need to apply a time offset (this may be permerger)
        self.time_offset = 0
        rtoff = 'foreground/{}/time_offset'.format(ifos[0])
        if rtoff in coinc_results:
            self.time_offset = coinc_results[rtoff]

        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))

            for ifo in self.snr_series:
                self.snr_series[ifo].start_time += self.time_offset
        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())

        # FIXME is it safe (in terms of downstream operations) to let
        # `program_name` default to the actual script name?
        proc_id = create_process_table(outdoc,
                                       program_name='pycbc',
                                       detectors=usable_ifos).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':
                    val += self.time_offset
                    sngl.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)

        # set merger time to the average of the ifo peaks
        self.merger_time = numpy.mean([
            coinc_results['foreground/{}/end_time'.format(ifo)] for ifo in ifos
        ]) + self.time_offset

        # for subthreshold detectors, respect BAYESTAR's assumptions and checks
        bayestar_check_fields = ('mass1 mass2 mtotal mchirp eta spin1x '
                                 'spin1y spin1z spin2x spin2y spin2z').split()
        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.end = lal.LIGOTimeGPS(self.merger_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.instruments = tuple(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)

        # source probabilities estimation
        if 'mc_area_args' in kwargs:
            eff_distances = [sngl.eff_distance for sngl in sngl_inspiral_table]
            probabilities = calc_probabilities(coinc_inspiral_row.mchirp,
                                               coinc_inspiral_row.snr,
                                               min(eff_distances),
                                               kwargs['mc_area_args'])
            self.probabilities = probabilities
        else:
            self.probabilities = None

        self.outdoc = outdoc
        self.time = sngl_populated.end
Ejemplo n.º 24
0
def write_simplified_sngl_inspiral_table(m1,
                                         m2,
                                         s1x,
                                         s1y,
                                         s1z,
                                         s2x,
                                         s2y,
                                         s2z,
                                         instrument,
                                         approximant,
                                         filename=None):
    """Writing a simplified sngl_inspiral_table containing only one template.

	Args:
		m1 (float): mass1.
		m2 (float): mass2.
		s1x (float): spin 1 x-axis.
		s1y (float): spin 1 y-axis.
		s1z (float): spin 1 z-axis.
		s2x (float): spin 2 x-axis.
		s2y (float): spin 2 y-axis.
		s2z (float): spin 2 z-axis.
		instrument (str): The instrument for the template.
		approximant (str): The approximant used to simulate the waveform.
		filename (str, default=None): The output filename.

	Return:
		The file object representing the xmldoc.

	"""
    # Check if it is valid approximant
    templates.gstlal_valid_approximant(approximant)

    xmldoc = ligolw.Document()
    root = xmldoc.appendChild(ligolw.LIGO_LW())

    table = lsctables.New(lsctables.SnglInspiralTable)
    rows = table.RowType()

    # set all slots to impossible/dummy value
    for t, c in zip(table.columntypes, table.columnnames):
        if t == u"real_4" or t == u"real_8":
            rows.__setattr__(c, 0)
        elif t == u"int_4s" or t == u"int_8s":
            rows.__setattr__(c, 0)
        elif t == u"lstring":
            rows.__setattr__(c, "")
        else:
            rows.__setattr__(c, None)

    rows.mass1 = m1
    rows.mass2 = m2
    rows.mtotal = m1 + m2
    rows.mchirp = (m1 * m2)**0.6 / (m1 + m2)**0.2
    rows.spin1x = s1x
    rows.spin1y = s1y
    rows.spin1z = s1z
    rows.spin2x = s2x
    rows.spin2y = s2y
    rows.spin2z = s2z
    rows.ifo = instrument

    table.append(rows)
    root.appendChild(table)

    #FIXME: do something better than this
    root.appendChild(
        ligolw_param.Param.from_pyvalue("approximant", approximant))

    if filename is not None:
        ligolw_utils.write_filename(xmldoc,
                                    filename,
                                    gz=filename.endswith("gz"))

    return xmldoc