Example #1
0
def get_found_param(injfile, bankfile, trigfile, param, ifo):
    """
    Translates some popular trigger parameters into functions that calculate
    them from an hdf found injection file

    Parameters
    ----------
    injfile: hdf5 File object
        Injection file of format known to ANitz (DOCUMENTME)
    bankfile: hdf5 File object or None
        Template bank file
    trigfile: hdf5 File object or None
        Single-detector trigger file
    param: string
        Parameter to be calculated for the recovered triggers
    ifo: string or None
        Standard ifo name, ex. 'L1'

    Returns
    -------
    [return value]: NumPy array of floats
        The calculated parameter values
    """
    foundtmp = injfile["found_after_vetoes/template_id"][:]
    if trigfile is not None:
        # get the name of the ifo in the injection file, eg "detector_1"
        # and the integer from that name
        ifolabel = [name for name, val in injfile.attrs.items() if \
                    "detector" in name and val == ifo][0]
        foundtrg = injfile["found_after_vetoes/trigger_id" + ifolabel[-1]]
    if bankfile is not None and param in bankfile.keys():
        return bankfile[param][:][foundtmp]
    elif trigfile is not None and param in trigfile[ifo].keys():
        return trigfile[ifo][param][:][foundtrg]
    else:
        b = bankfile
        found_param_dict = {
            "mtotal": (b['mass1'][:] + b['mass2'][:])[foundtmp],
            "mchirp":
            pnutils.mass1_mass2_to_mchirp_eta(b['mass1'][:],
                                              b['mass2'][:])[0][foundtmp],
            "eta":
            pnutils.mass1_mass2_to_mchirp_eta(b['mass1'][:],
                                              b['mass2'][:])[1][foundtmp],
            "effective_spin":
            pnutils.phenomb_chi(b['mass1'][:], b['mass2'][:], b['spin1z'][:],
                                b['spin2z'][:])[foundtmp]
        }

    return found_param_dict[param]
Example #2
0
def get_found_param(injfile, bankfile, trigfile, param, ifo):
    """
    Translates some popular trigger parameters into functions that calculate
    them from an hdf found injection file

    Parameters
    ----------
    injfile: hdf5 File object
        Injection file of format known to ANitz (DOCUMENTME)
    bankfile: hdf5 File object or None
        Template bank file
    trigfile: hdf5 File object or None
        Single-detector trigger file
    param: string
        Parameter to be calculated for the recovered triggers
    ifo: string or None
        Standard ifo name, ex. 'L1'

    Returns
    -------
    [return value]: NumPy array of floats
        The calculated parameter values
    """
    foundtmp = injfile["found_after_vetoes/template_id"][:]
    if trigfile is not None:
        # get the name of the ifo in the injection file, eg "detector_1"
        # and the integer from that name
        ifolabel = [name for name, val in injfile.attrs.items() if \
                    "detector" in name and val == ifo][0]
        foundtrg = injfile["found_after_vetoes/trigger_id" + ifolabel[-1]]
    if bankfile is not None and param in bankfile.keys():
        return bankfile[param][:][foundtmp]
    elif trigfile is not None and param in trigfile[ifo].keys():
        return trigfile[ifo][param][:][foundtrg]
    else:
        b = bankfile
        found_param_dict = {
          "mtotal" : (b['mass1'][:] + b['mass2'][:])[foundtmp],
          "mchirp" : pnutils.mass1_mass2_to_mchirp_eta(b['mass1'][:],
                     b['mass2'][:])[0][foundtmp],
          "eta"    : pnutils.mass1_mass2_to_mchirp_eta(b['mass1'][:],
                     b['mass2'][:])[1][foundtmp],
          "effective_spin" : pnutils.phenomb_chi(b['mass1'][:],
                                                 b['mass2'][:],
                                                 b['spin1z'][:],
                                                 b['spin2z'][:])[foundtmp]
        }

    return found_param_dict[param]
Example #3
0
    def __init__(self, filename, f_lower, sample_rate, minimum_buffer,
                       approximant=None, increment=8, parameters=None,
                       load_compressed=True, load_compressed_now=False, 
                       **kwds):

        self.increment = increment
        self.f_lower = f_lower
        self.filename = filename
        self.sample_rate = sample_rate
        self.minimum_buffer = minimum_buffer

        super(LiveFilterBank, self).__init__(filename, approximant=approximant,
                parameters=parameters, load_compressed=load_compressed,
                load_compressed_now=load_compressed_now, **kwds)

        if not hasattr(self.table, 'template_duration'):
            self.table = self.table.add_fields(numpy.zeros(len(self.table),
                                     dtype=numpy.float32), 'template_duration') 

        from pycbc.pnutils import mass1_mass2_to_mchirp_eta
        self.table = sorted(self.table, key=lambda t: mass1_mass2_to_mchirp_eta(t.mass1, t.mass2)[0])

        self.hash_lookup = {}
        for i, p in enumerate(self.table):
            hash_value =  hash((p.mass1, p.mass2, p.spin1z, p.spin2z))
            self.hash_lookup[hash_value] = i
Example #4
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 : ilwd char
        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, junk = 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
Example #5
0
def get_param(par, args, m1, m2, s1z, s2z):
    """
    Helper function

    Parameters
    ----------
    par : string
        Name of parameter to calculate
    args : Namespace object returned from ArgumentParser instance
        Calling code command line options, used for f_lower value
    m1 : float or array of floats
        First binary component mass (etc.)

    Returns
    -------
    parvals : float or array of floats
        Calculated parameter values
    """
    if par == 'mchirp':
        parvals, _ = pnutils.mass1_mass2_to_mchirp_eta(m1, m2)
    elif par == 'mtotal':
        parvals = m1 + m2
    elif par == 'template_duration':
        # default to SEOBNRv4 duration function
        parvals = pnutils.get_imr_duration(m1, m2, s1z, s2z, args.f_lower,
                                           args.approximant or "SEOBNRv4")
        if args.min_duration:
            parvals += args.min_duration
    elif par in pnutils.named_frequency_cutoffs.keys():
        parvals = pnutils.frequency_cutoff_from_name(par, m1, m2, s1z, s2z)
    else:
        # try asking for a LALSimulation frequency function
        parvals = pnutils.get_freq(par, m1, m2, s1z, s2z)
    return parvals
Example #6
0
def get_param(par, args, m1, m2, s1z, s2z):
    """
    Helper function

    Parameters
    ----------
    par : string
        Name of parameter to calculate
    args : Namespace object returned from ArgumentParser instance
        Calling code command line options, used for f_lower value
    m1 : float or array of floats
        First binary component mass (etc.)

    Returns
    -------
    parvals : float or array of floats
        Calculated parameter values
    """
    if par == 'mchirp':
        parvals, _ = pnutils.mass1_mass2_to_mchirp_eta(m1, m2)
    elif par == 'mtotal':
        parvals = m1 + m2
    elif par == 'template_duration':
        # default to SEOBNRv4 duration function
        parvals = pnutils.get_imr_duration(m1, m2, s1z, s2z, args.f_lower,
                                           args.approximant or "SEOBNRv4")
        if args.min_duration:
            parvals += args.min_duration
    elif par in pnutils.named_frequency_cutoffs.keys():
        parvals = pnutils.frequency_cutoff_from_name(par, m1, m2, s1z, s2z)
    else:
        # try asking for a LALSimulation frequency function
        parvals = pnutils.get_freq(par, m1, m2, s1z, s2z)
    return parvals
Example #7
0
    def read_samples_from_walker(self, variable_arg, nwalker,
                                 thin_start=None, thin_interval=1):
        """ Reads all samples from a specific walker for a parameter.

        Parameters
        -----------
        variable_arg : str
            Name of parameter to get independent samples.
        nwalker : int
            Index of the walker to get samples.
        thin_start : int
            Index of the sample to begin returning samples.
        thin_interval : int
            Interval to accept every i-th sample.

        Returns
        -------
        numpy.array
            Samples from a specific walker for a parameter.
        """

        # default is to skip burn in samples
        thin_start = self.attrs["burn_in_iterations"] if thin_start is None else thin_start

        # derived parameter case for mchirp will calculate mchrip
        # from mass1 and mass2
        if variable_arg == "mchirp" and "mchirp" not in self.keys():
            mass1 = self.read_samples_from_walker("mass1", nwalker,
                                      thin_start=thin_start,
                                      thin_interval=thin_interval)
            mass2 = self.read_samples_from_walker("mass2", nwalker,
                                      thin_start=thin_start,
                                      thin_interval=thin_interval)
            return pnutils.mass1_mass2_to_mchirp_eta(mass1, mass2)[0]

        # derived parameter case for eta will calculate eta
        # from mass1 and mass2
        elif variable_arg == "eta" and "eta" not in self.keys():
            mass1 = self.read_samples_from_walker("mass1", nwalker,
                                      thin_start=thin_start,
                                      thin_interval=thin_interval)
            mass2 = self.read_samples_from_walker("mass2", nwalker,
                                      thin_start=thin_start,
                                      thin_interval=thin_interval)
            return pnutils.mass1_mass2_to_mchirp_eta(mass1, mass2)[1]

        return self[variable_arg]["walker%d"%nwalker][thin_start::thin_interval]
Example #8
0
def outside_mchirp_window(bank, sim, w):
    # template mchirp
    if hasattr(bank, "mchirp"):
        bmchirp = bank.mchirp
    elif hasattr(bank, "mass1") and hasattr(bank, "mass2"):
        bmchirp, eta =\
            pnutils.mass1_mass2_to_mchirp_eta(bank.mass1, bank.mass2)
    elif hasattr(bank, "mtotal") and hasattr(bank, "eta"):
        bmchirp = bank.mtotal * (bank.eta**0.6)
    # signal / injection / proposal mchirp
    if hasattr(sim, "mchirp"):
        smchirp = sim.mchirp
    elif hasattr(sim, "mass1") and hasattr(sim, "mass2"):
        smchirp, eta =\
            pnutils.mass1_mass2_to_mchirp_eta(sim.mass1, sim.mass2)
    elif hasattr(sim, "mtotal") and hasattr(sim, "eta"):
        smchirp = sim.mtotal * (sim.eta**0.6)
    return abs(smchirp - bmchirp) > (w * bmchirp)
Example #9
0
def get_inj_param(injfile, param, ifo):
    """
    Translates some popular injection parameters into functions that calculate
    them from an hdf found injection file

    Parameters
    ----------
    injfile: hdf5 File object
        Injection file of format known to ANitz (DOCUMENTME)
    param: string
        Parameter to be calculated for the injected signals
    ifo: string
        Standard detector name, ex. 'L1'

    Returns
    -------
    [return value]: NumPy array of floats
        The calculated parameter values
    """
    det = pycbc.detector.Detector(ifo)
    time_delay = numpy.vectorize(#lambda dec, ra, t :
                                 det.time_delay_from_earth_center)#(dec, ra, t))

    inj = injfile["injections"]
    if param in inj.keys():
        return inj["injections/"+param]
    inj_param_dict = {
        "mtotal" : inj['mass1'][:] + inj['mass2'][:],
        "mchirp" : pnutils.mass1_mass2_to_mchirp_eta(inj['mass1'][:],
                                                     inj['mass2'][:])[0],
        "eta" : pnutils.mass1_mass2_to_mchirp_eta(inj['mass1'][:],
                                                  inj['mass2'][:])[1],
        "effective_spin" : pnutils.phenomb_chi(inj['mass1'][:],
                                               inj['mass2'][:],
                                               inj['spin1z'][:],
                                               inj['spin2z'][:]),
        "end_time_"+ifo[0].lower() :
            inj['end_time'][:] + time_delay(inj['longitude'][:],
                                            inj['latitude'][:],
                                            inj['end_time'][:]),
    }
    return inj_param_dict[param]
Example #10
0
def get_inj_param(injfile, param, ifo):
    """
    Translates some popular injection parameters into functions that calculate
    them from an hdf found injection file

    Parameters
    ----------
    injfile: hdf5 File object
        Injection file of format known to ANitz (DOCUMENTME)
    param: string
        Parameter to be calculated for the injected signals
    ifo: string
        Standard detector name, ex. 'L1'

    Returns
    -------
    [return value]: NumPy array of floats
        The calculated parameter values
    """
    det = pycbc.detector.Detector(ifo)
    time_delay = numpy.vectorize(  #lambda dec, ra, t :
        det.time_delay_from_earth_center)  #(dec, ra, t))

    inj = injfile["injections"]
    if param in inj.keys():
        return inj["injections/" + param]
    inj_param_dict = {
        "mtotal":
        inj['mass1'][:] + inj['mass2'][:],
        "mchirp":
        pnutils.mass1_mass2_to_mchirp_eta(inj['mass1'][:], inj['mass2'][:])[0],
        "eta":
        pnutils.mass1_mass2_to_mchirp_eta(inj['mass1'][:], inj['mass2'][:])[1],
        "effective_spin":
        pnutils.phenomb_chi(inj['mass1'][:], inj['mass2'][:], inj['spin1z'][:],
                            inj['spin2z'][:]),
        "end_time_" + ifo[0].lower():
        inj['end_time'][:] + time_delay(
            inj['longitude'][:], inj['latitude'][:], inj['end_time'][:]),
    }
    return inj_param_dict[param]
Example #11
0
    def __init__(self, filename, f_lower, sample_rate, minimum_buffer,
                       approximant=None,
                       **kwds):

        self.f_lower = f_lower
        self.filename = filename
        self.sample_rate = sample_rate
        self.minimum_buffer = minimum_buffer

        super(LiveFilterBank, self).__init__(filename, approximant=approximant, **kwds)

        from pycbc.pnutils import mass1_mass2_to_mchirp_eta
        self.table = sorted(self.table, key=lambda t: mass1_mass2_to_mchirp_eta(t.mass1, t.mass2)[0])        
Example #12
0
    def __init__(self, filename, f_lower, sample_rate, minimum_buffer,
                       approximant=None, increment=8,
                       **kwds):

        self.increment = increment
        self.f_lower = f_lower
        self.filename = filename
        self.sample_rate = sample_rate
        self.minimum_buffer = minimum_buffer

        super(LiveFilterBank, self).__init__(filename, approximant=approximant, **kwds)

        from pycbc.pnutils import mass1_mass2_to_mchirp_eta
        self.table = sorted(self.table, key=lambda t: mass1_mass2_to_mchirp_eta(t.mass1, t.mass2)[0])

        self.hash_lookup = {}
        for i, p in enumerate(self.table):
            hash_value =  hash((p.mass1, p.mass2, p.spin1z, p.spin2z))
            self.hash_lookup[hash_value] = i
Example #13
0
    def __init__(self,
                 filename,
                 f_lower,
                 sample_rate,
                 minimum_buffer,
                 approximant=None,
                 **kwds):

        self.f_lower = f_lower
        self.filename = filename
        self.sample_rate = sample_rate
        self.minimum_buffer = minimum_buffer

        super(LiveFilterBank, self).__init__(filename,
                                             approximant=approximant,
                                             **kwds)

        from pycbc.pnutils import mass1_mass2_to_mchirp_eta
        self.table = sorted(
            self.table,
            key=lambda t: mass1_mass2_to_mchirp_eta(t.mass1, t.mass2)[0])
Example #14
0
def _imrphenombfreq(**p):
    import lalinspiral
    params = lalinspiral.InspiralTemplate()
    m1 = p['mass1']
    m2 = p['mass2']

    mc, et = pnutils.mass1_mass2_to_mchirp_eta(m1, m2)
    params.approximant = lalsimulation.IMRPhenomB
    params.fLower = p['f_lower']
    params.eta = et
    params.distance = p['distance'] * lal.PC_SI * 1e6
    params.mass1 = m1
    params.mass2 = m2
    params.spin1[2] = p['spin1z']
    params.spin2[2] = p['spin2z']
    params.startPhase = p['coa_phase']*2 - lal.PI
    params.startTime = 0

    params.tSampling = 8192
    N = int(params.tSampling / p['delta_f'])
    n = N / 2

    # Create temporary memory to hold the results and call the generator
    hpt = zeros(N, dtype=float32)
    hct = zeros(N, dtype=float32)
    hpt=hpt.lal()
    hct=hct.lal()
    lalinspiral.BBHPhenWaveBFreqDomTemplates(hpt, hct, params)

    # Copy the results to a complex frequencyseries format
    hctc = FrequencySeries(zeros(n, dtype=complex64), delta_f=p['delta_f'])
    hptc = FrequencySeries(zeros(n, dtype=complex64), delta_f=p['delta_f'])

    hptc.data += hpt.data[0:n]
    hptc.data[1:n] += hpt.data[N:N-n:-1] * 1j

    hctc.data += hct.data[0:n]
    hctc.data[1:n] += hct.data[N:N-n:-1] * 1j

    return hptc.astype(complex128),  hctc.astype(complex128)
Example #15
0
    def __init__(self,
                 filename,
                 f_lower,
                 sample_rate,
                 minimum_buffer,
                 approximant=None,
                 increment=8,
                 parameters=None,
                 load_compressed=True,
                 load_compressed_now=False,
                 **kwds):

        self.increment = increment
        self.f_lower = f_lower
        self.filename = filename
        self.sample_rate = sample_rate
        self.minimum_buffer = minimum_buffer

        super(LiveFilterBank,
              self).__init__(filename,
                             approximant=approximant,
                             parameters=parameters,
                             load_compressed=load_compressed,
                             load_compressed_now=load_compressed_now,
                             **kwds)

        if not hasattr(self.table, 'template_duration'):
            self.table = self.table.add_fields(
                numpy.zeros(len(self.table), dtype=numpy.float32),
                'template_duration')

        from pycbc.pnutils import mass1_mass2_to_mchirp_eta
        self.table = sorted(
            self.table,
            key=lambda t: mass1_mass2_to_mchirp_eta(t.mass1, t.mass2)[0])

        self.hash_lookup = {}
        for i, p in enumerate(self.table):
            hash_value = hash((p.mass1, p.mass2, p.spin1z, p.spin2z))
            self.hash_lookup[hash_value] = i
Example #16
0
def _imrphenombfreq(**p):
    params = lalinspiral.InspiralTemplate()
    m1 = p['mass1']
    m2 = p['mass2']

    mc, et = pnutils.mass1_mass2_to_mchirp_eta(m1, m2)
    params.approximant = lalsimulation.IMRPhenomB
    params.fLower = p['f_lower']
    params.eta = et
    params.distance = p['distance'] * lal.PC_SI * 1e6
    params.mass1 = m1
    params.mass2 = m2
    params.spin1[2] = p['spin1z']
    params.spin2[2] = p['spin2z']
    params.startPhase = p['coa_phase'] * 2 - lal.PI
    params.startTime = 0

    params.tSampling = 8192
    N = int(params.tSampling / p['delta_f'])
    n = N / 2

    # Create temporary memory to hold the results and call the generator
    hpt = zeros(N, dtype=float32)
    hct = zeros(N, dtype=float32)
    hpt = hpt.lal()
    hct = hct.lal()
    lalinspiral.BBHPhenWaveBFreqDomTemplates(hpt, hct, params)

    # Copy the results to a complex frequencyseries format
    hctc = FrequencySeries(zeros(n, dtype=complex64), delta_f=p['delta_f'])
    hptc = FrequencySeries(zeros(n, dtype=complex64), delta_f=p['delta_f'])

    hptc.data += hpt.data[0:n]
    hptc.data[1:n] += hpt.data[N:N - n:-1] * 1j

    hctc.data += hct.data[0:n]
    hctc.data[1:n] += hct.data[N:N - n:-1] * 1j

    return hptc.astype(complex128), hctc.astype(complex128)
Example #17
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 : ilwd char
        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, junk = 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
Example #18
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.
        padata: PAstroData instance, organizes info relevant to p astro.
        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
        self.basename = None

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

        # P astro calculation
        if 'padata' in kwargs:
            padata = kwargs['padata']
            trigger_data = {
                'mass1': sngl_populated.mass1,
                'mass2': sngl_populated.mass2,
                'spin1z': sngl_populated.spin1z,
                'spin2z': sngl_populated.spin2z,
                'network_snr': network_snrsq**0.5,
                'far': far
            }
            horizons = {ifo: self.psds[ifo].dist for ifo in self.psds}
            self.p_astro, self.p_terr = \
                                  padata.do_pastro_calc(trigger_data, horizons)
        else:
            self.p_astro, self.p_terr = None, None

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

        # Combine p astro and source probs
        if self.p_astro is not None and self.probabilities is not None:
            self.astro_probs = {
                cl: pr * self.p_astro
                for cl, pr in self.probabilities.items()
            }
            self.astro_probs['p_terr'] = self.p_terr
        else:
            self.astro_probs = None

        self.outdoc = outdoc
        self.time = sngl_populated.end
Example #19
0
def get_td_waveform_resp(params):
    """
    Generate time domain data of gw detector response

    This function will produce data of a gw detector response based on a
    numerical relativity waveform.

    Parameters
    ----------
    params: object
        The fields of this object correspond to the kwargs of the
        `pycbc.waveform.get_td_waveform()` method and the positional
        arguments of `pycbc.detector.Detector.antenna_pattern()`. For the later
        the fields should be supplied as `params.ra`, `.dec`, `.polarization`
        and `.geocentric_end_time`

    Returns
    -------
    h_plus: pycbc.Types.TimeSeries
    h_cross: pycbc.Types.TimeSeries
    pats: dictionary
        Dictionary containing 'H1' and 'L1' keys. Each key maps to an object
        of containing the field `.f_plus` and `.f_cross` corresponding to
        the plus and cross antenna patterns for the two ifos 'H1' and 'L1'.
    """

    # # construct waveform string that can be parsed by lalsimulation
    waveform_string = params.approximant
    if not pn_orders[params.order] == -1:
        waveform_string += params.order
    name, phase_order = legacy_approximant_name(waveform_string)

    # Populate additional fields of params object
    params.mchirp, params.eta = pnutils.mass1_mass2_to_mchirp_eta(
        params.mass1, params.mass2)
    params.waveform           = waveform_string
    params.approximant        = name
    params.phase_order        = phase_order

    # generate waveform
    h_plus, h_cross = get_td_waveform(params)

    # Generate antenna patterns for all ifos
    pats = {}
    for ifo in params.instruments:

        # get Detector instance for IFO
        det = Detector(ifo)

        # get antenna pattern
        f_plus, f_cross = det.antenna_pattern(
            params.ra,
            params.dec,
            params.polarization,
            params.geocentric_end_time)

        # Populate antenna patterns with new pattern
        pat         = type('AntennaPattern', (object,), {})
        pat.f_plus  = f_plus
        pat.f_cross = f_cross
        pats[ifo]   = pat

    return h_plus, h_cross, pats
Example #20
0
    def test_get_random_mass(self):
        # Want to do this for a variety of mass combinations
        for i in update_mass_parameters(self):
            curr_min_mass = self.min_total_mass
            curr_max_mass = self.max_total_mass
            try:
                pycbc.tmpltbank.verify_mass_range_options(self, parser=parser)
            except ValueError:
                # Some of the inputs are unphysical and will fail.
                # These cases are known to fail, the inputs are unphysical
                # 35 has inconsistent total mass and eta restrictions
                # 38 Component mass, [upper] chirp mass and [lower] eta limits
                #    rule out the entire space.
                # 41 Same as 38
                # 44 Same as 38
                # 62 From component mass and total mass limits only total masses
                #    between 7 and 7.5 are possible. This range all has eta
                #    lower than the limit of 0.17.
                # 65 Same as 38
                # 68 Same as 38
                # 71 Same as 38
                # 80 Same as 62
                if i in [35,38,41,44,62,65,68,71,80]:
                    continue
                raise

            # Check that if the mass limits have changed, it was right to do so
            # This is not exhaustive, but gets most things
            if not self.min_total_mass == curr_min_mass:
                min_comp_mass = self.min_mass1 + self.min_mass2
                min_eta = self.min_mass1 * self.min_mass2 /\
                           (min_comp_mass * min_comp_mass)
                min_chirp_mass = min_comp_mass * min_eta**(3./5.)
                if self.min_total_mass == min_comp_mass:
                    # Okay, the total mass is changed by the components
                    pass
                elif min_eta < self.min_eta or min_eta > self.max_eta:
                    # Okay, not possible from eta
                    pass
                elif min_chirp_mass < self.min_chirp_mass:
                    # Okay, not possible from chirp mass
                    pass
                else:
                    err_msg = "Minimum total mass changed unexpectedly."
                    print self.min_total_mass, curr_min_mass
                    print self.min_mass1, self.min_mass2, min_comp_mass
                    print min_eta, self.min_eta, self.max_eta
                    print min_chirp_mass, self.min_chirp_mass
                    self.fail(err_msg)
            if not self.max_total_mass == curr_max_mass:
                max_comp_mass = self.max_mass1 + self.max_mass2
                max_eta = self.max_mass1 * self.max_mass2 /\
                           (max_comp_mass * max_comp_mass)
                max_chirp_mass = max_comp_mass * max_eta**(3./5.)
                if self.max_total_mass == max_comp_mass:
                    # Okay, the total mass is changed by the components
                    pass
                elif max_eta < self.min_eta or max_eta > self.max_eta:
                    # Okay, not possible from eta
                    pass
                elif max_chirp_mass > self.max_chirp_mass:
                    # Okay, not possible from chirp mass
                    pass
                else:
                    err_msg = "Maximum total mass changed unexpectedly."
                    self.fail(err_msg)

            massRangeParams = pycbc.tmpltbank.massRangeParameters(\
                                self.min_mass1,\
                                self.max_mass1, self.min_mass2, self.max_mass2,\
                                maxNSSpinMag=self.max_ns_spin_mag,\
                                maxBHSpinMag=self.max_bh_spin_mag,\
                                maxTotMass=self.max_total_mass,\
                                minTotMass=self.min_total_mass,\
                                max_chirp_mass=self.max_chirp_mass,\
                                min_chirp_mass=self.min_chirp_mass,\
                                maxEta=self.max_eta,\
                                minEta=self.min_eta,\
                                ns_bh_boundary_mass=self.ns_bh_boundary_mass)

            # And again with the nsbh flag
            massRangeParams2 = pycbc.tmpltbank.massRangeParameters(\
                                self.min_mass1,\
                                self.max_mass1, self.min_mass2, self.max_mass2,\
                                maxNSSpinMag=self.max_ns_spin_mag,\
                                maxBHSpinMag=self.max_bh_spin_mag,\
                                maxTotMass=self.max_total_mass,\
                                minTotMass=self.min_total_mass,\
                                max_chirp_mass=self.max_chirp_mass,\
                                min_chirp_mass=self.min_chirp_mass,\
                                maxEta=self.max_eta,\
                                minEta=self.min_eta,\
                                nsbhFlag=True)

            mass,eta,beta,sigma,gamma,spin1z,spin2z = \
                      pycbc.tmpltbank.get_random_mass(100000, massRangeParams)
            errMsg = "pycbc.tmpltbank.get_random_mass returns invalid ranges."
            if (mass < self.min_total_mass).any():
                idx = mass.argmin()
                diff = (mass*mass * (1-4*eta))**0.5
                mass1 = (mass + diff)/2.
                mass2 = (mass - diff)/2.
            self.assertTrue(not (mass < self.min_total_mass).any(),msg=errMsg)
            self.assertTrue(not (mass > self.max_total_mass).any(),msg=errMsg)
            # Get individual masses
            diff = (mass*mass * (1-4*eta))**0.5
            mass1 = (mass + diff)/2.
            mass2 = (mass - diff)/2.
            self.assertTrue(not (mass1 > self.max_mass1 * 1.001).any(),
                            msg=errMsg)
            self.assertTrue(not (mass1 < self.min_mass1 * 0.999).any(),
                            msg=errMsg)
            self.assertTrue(not (mass2 > self.max_mass2 * 1.001).any(),
                            msg=errMsg)
            self.assertTrue(not (mass2 < self.min_mass2 * 0.999).any(),
                            msg=errMsg)
            self.assertTrue(not (mass1 < mass2).any(),msg=errMsg)
            # Chirp mass and eta
            mchirp, eta = pnutils.mass1_mass2_to_mchirp_eta(mass1,mass2)
            if self.max_chirp_mass:
                self.assertTrue(not (mchirp > self.max_chirp_mass*1.0001).any(),
                                msg=errMsg)
            if self.min_chirp_mass:
                self.assertTrue(not (mchirp < self.min_chirp_mass*0.9999).any(),
                                msg=errMsg)
            if self.min_eta:
                self.assertTrue(not (eta < self.min_eta*0.9999).any(),
                                msg=errMsg)
                self.assertTrue(not (eta > self.max_eta*1.0001).any(),
                                msg=errMsg)
            nsSpin1 = spin1z[mass1 < self.ns_bh_boundary_mass]
            nsSpin2 = spin2z[mass2 < self.ns_bh_boundary_mass]
            bhSpin1 = spin1z[mass1 > self.ns_bh_boundary_mass]
            bhSpin2 = spin2z[mass2 > self.ns_bh_boundary_mass]
            self.assertTrue(not (abs(nsSpin1) > 0.5).any(), msg=errMsg)
            self.assertTrue(not (abs(nsSpin2) > 0.5).any(), msg=errMsg) 
            self.assertTrue(not (abs(bhSpin1) > 0.9).any(), msg=errMsg)
            self.assertTrue(not (abs(bhSpin2) > 0.9).any(), msg=errMsg)
            # Check that *some* spins are bigger than 0.5
            if len(bhSpin1):
                self.assertTrue((abs(bhSpin1) > 0.5).any(), msg=errMsg)
            if len(bhSpin2):
                self.assertTrue((abs(bhSpin2) > 0.5).any(), msg=errMsg)
            # This can be used to test the boundaries are all applied visually
            # FIXME: This would need to be updated for all of the mass limits
            #pylab.plot(mass1, mass2, 'b.')
            #pylab.plot([3.0,5.0],[3.0,1.0],'r-')
            #pylab.plot([1.7216566400945545,1.9921146662296347,3.4433132801891091,4.01175560949798],[1.1477710933963694,1.0066274466204264,2.2955421867927388,1.002938902374495],'mx')
            #pylab.ylim([0.8,3.0])
            #pylab.xlim([1.5,5.0])
            #pylab.savefig("masses_%d.png" %(idx,))

            # Check nsbh flag
            mass,eta,beta,sigma,gamma,spin1z,spin2z = \
                 pycbc.tmpltbank.get_random_mass(100000, massRangeParams2)
            self.assertTrue(not (abs(spin1z) > 0.9).any(), msg=errMsg)
            self.assertTrue(not (abs(spin2z) > 0.5).any(), msg=errMsg)
            self.assertTrue((abs(spin1z) > 0.5).any(), msg=errMsg)
    """
    xmldoc = ligolw.Document()
    xmldoc.appendChild(ligolw.LIGO_LW())
    for table in tables:
        xmldoc.childNodes[0].appendChild(table)
    return xmldoc

input_bank = 'H1L1-UBERBANK_MAXM100_NS0p05_ER8HMPSD-1126033217-223200.xml.gz'
output_bank = 'H1L1-EDGEBIN_FROM_UBERBANK_ER8HMPSD-1126033217-223200.xml.gz'

xmldoc = utils.load_filename(input_bank, contenthandler=LIGOLWContentHandler,
    gz=True)
all_templates = table.get_table(xmldoc, 'sngl_inspiral')
# get the other tables that are in the document
other_table_names = [y.Name for y in xmldoc.childNodes[0].getElements(
    lambda x: x.tagName == ligolw.Table.tagName) if y.Name != u'sngl_inspiral']
other_tables = [table.get_table(xmldoc, x) for x in other_table_names]

keep_templates = lsctables.New(lsctables.SnglInspiralTable)

# only add templates that fall in the edge bin
for tmplt in all_templates:
    mchirp = pnutils.mass1_mass2_to_mchirp_eta(tmplt.mass1, tmplt.mass2)[0]
    peakfreq = pnutils.get_freq('fSEOBNRv2Peak', tmplt.mass1, tmplt.mass2,
        tmplt.spin1z, tmplt.spin2z)
    if mchirp >= 1.74 and peakfreq < 220.:
        keep_templates.append(tmplt)

outdoc = create_xmldoc(other_tables + [keep_templates])
utils.write_filename(outdoc, output_bank, gz=True)
Example #22
0
def writeHybrid_h5(path_name_part, metadata, approx, sim_name, h1, h1_ts, h2,
                   h2_ts, delta_t, ip2, fp2):
    solar_mass_mpc = MRSUN_SI / ((1 * 10**6) * PC_SI)
    grav_m1 = metadata[0][0]
    grav_m2 = metadata[0][1]
    baryon_m1 = metadata[1][0]
    baryon_m2 = metadata[1][1]
    m1 = metadata[2][0]
    m2 = metadata[2][1]
    s1x = metadata[3][0]
    s1y = metadata[3][1]
    s1z = metadata[3][2]
    s2x = metadata[3][3]
    s2y = metadata[3][4]
    s2z = metadata[3][5]
    LNhatx = metadata[4][0]
    LNhaty = metadata[4][1]
    LNhatz = metadata[4][2]
    n_hatx = 1.0  #metadata[5][0]
    n_haty = 0.0  #metadata[5][1]
    n_hatz = 0.0  #metadata[5][2]
    tidal_1 = metadata[6][0]
    tidal_2 = metadata[6][1]
    type_sim = metadata[7]
    f_low = metadata[8]
    EOS = metadata[9]
    f_low_num = metadata[10]
    M = 300  ## length of the windowing function
    total_mass = grav_m1 + grav_m2  ### used masses are the masses used in the characterization procedure
    ### hybridize numerical (h2) and analytical waveform (h1) at a particular match window length set by fp2
    hybridPN_Num = hy.hybridize(h1,
                                h1_ts,
                                h2,
                                h2_ts,
                                match_i=0,
                                match_f=fp2,
                                delta_t=delta_t,
                                M=M,
                                info=1)
    shift_time = (hybridPN_Num[6], fp2)
    hh_freq = (hybridPN_Num[7], fp2)
    match = hybridPN_Num[0]
    ### path_name_part contains simulation details that must be passed into this function.
    path_name = path_name_part + 'fp2_' + str(fp2) + '.h5'
    f_low_M = f_low * (TWOPI * total_mass * MTSUN_SI)
    with h5py.File(path_name, 'w') as fd:
        mchirp, eta = pnutils.mass1_mass2_to_mchirp_eta(grav_m1, grav_m2)
        fd.attrs['type'] = 'Hybrid:%s' % type_sim
        fd.attrs['hgroup'] = 'Read_CSUF'
        fd.attrs['Format'] = 1
        fd.attrs['Lmax'] = 2
        fd.attrs['approx'] = approx
        fd.attrs['sim_name'] = sim_name
        fd.attrs['f_lower_at_1MSUN'] = f_low
        fd.attrs['eta'] = eta
        fd.attrs['spin1x'] = s1x
        fd.attrs['spin1y'] = s1y
        fd.attrs['spin1z'] = s1z
        fd.attrs['spin2x'] = s2x
        fd.attrs['spin2y'] = s2y
        fd.attrs['spin2z'] = s2z
        fd.attrs['LNhatx'] = LNhatx
        fd.attrs['LNhaty'] = LNhaty
        fd.attrs['LNhatz'] = LNhatz
        fd.attrs['nhatx'] = 1.0  #n_hatx
        fd.attrs['nhaty'] = 0.0  #n_haty
        fd.attrs['nhatz'] = 0.0  #n_hatz
        fd.attrs['mass1'] = m1
        fd.attrs['mass2'] = m2
        fd.attrs['grav_mass1'] = grav_m1
        fd.attrs['grav_mass2'] = grav_m2
        fd.attrs['baryon_mass1'] = baryon_m1
        fd.attrs['baryon_mass2'] = baryon_m2
        fd.attrs['lambda1'] = tidal_1
        fd.attrs['lambda2'] = tidal_2
        fd.attrs['fp1'] = len(h1)
        fd.attrs['ip2'] = ip2
        fd.attrs['hybrid_match'] = match
        fd.attrs['shift_time'] = shift_time
        fd.attrs['hybridize_freq'] = hh_freq
        fd.attrs['EOS'] = EOS
        fd.attrs['f_low_num'] = f_low_num
        gramp = fd.create_group('amp_l2_m2')
        grphase = fd.create_group('phase_l2_m2')
        times = hybridPN_Num[5][0]
        hplus = hybridPN_Num[5][1]
        hcross = hybridPN_Num[5][2]
        massMpc = total_mass * solar_mass_mpc
        hplusMpc = pycbc.types.TimeSeries(hplus / massMpc, delta_t=delta_t)
        hcrossMpc = pycbc.types.TimeSeries(hcross / massMpc, delta_t=delta_t)
        times_M = times / (MTSUN_SI * total_mass)
        HlmAmp = wfutils.amplitude_from_polarizations(hplusMpc, hcrossMpc).data
        HlmPhase = wfutils.phase_from_polarizations(hplusMpc, hcrossMpc).data
        sAmph = romspline.ReducedOrderSpline(times_M,
                                             HlmAmp,
                                             rel=True,
                                             verbose=False)
        sPhaseh = romspline.ReducedOrderSpline(times_M,
                                               HlmPhase,
                                               rel=True,
                                               verbose=False)
        sAmph.write(gramp)
        sPhaseh.write(grphase)
        fd.close()
    ## this function returns the hybridization frequency (hh_freq) and the time shift (shift_time) associated with each hybrid.
    return (shift_time, hh_freq)
Example #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 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()
                    out_left2 = time[l:r] < (time[l:r][idx_mxsnr] - 0.1)
                    out_left = time[l:r][numpy.invert(
                        (out_left1 - out_left2))].shape[0]
                    out_right1 = time[l:r] <= (time[l:r][idx_mxsnr] +
                                               int(args.window))
                    out_right2 = time[l:r] > (time[l:r][idx_mxsnr] + 0.1)
                    out_right = time[l:r][numpy.invert(
                        (out_right1 - out_right2))].shape[0]
                    count_out.append(out_left + out_right)

                    #determining the chirp mass
                    m1_snr = mass1_full[l:r][idx_mxsnr]
                    m2_snr = mass2_full[l:r][idx_mxsnr]
                    m1_new_snr = mass1_full[l:r][idx_mxnewsnr]
                    m2_new_snr = mass2_full[l:r][idx_mxnewsnr]
                    chirp_snr = pnutils.mass1_mass2_to_mchirp_eta(
                        m1_snr, m2_snr)
                    chirp_m.append(chirp_snr)
                    chirp_new_snr = pnutils.mass1_mass2_to_mchirp_eta(
                        m1_new_snr, m2_new_snr)

                    #Calculating delta chirp and ratio of chirp masses
                    delta_chirp.append(
                        log(chirp_snr[0]) - log(chirp_new_snr[0]))
                    ratio_chirp.append(chirp_snr[0] / chirp_new_snr[0])

        for i, (l, r) in enumerate(zip(left_inj, right_inj)):
            logging.info('%s: %2.1f complete', ifo,
                         float(i) / len(right_inj) * 100)
            closest_inj_id = numpy.argmin(abs(time_injc - window_times[i]))
            closest_injt = time_injc[closest_inj_id]
Example #25
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 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.
        """
        followup_ifos = kwargs.get('followup_ifos') or []
        self.template_id = coinc_results['foreground/%s/template_id' % ifos[0]]

        # remember if this should be marked as HWINJ
        self.is_hardware_injection = ('HWINJ' in coinc_results)

        # remember if we want to use a non-standard gracedb server
        self.gracedb_server = kwargs.get('gracedb_server')

        # compute SNR time series if needed, and figure out which of
        # the followup detectors are usable
        subthreshold_sngl_time = numpy.mean(
                [coinc_results['foreground/%s/end_time' % ifo]
                 for ifo in ifos])
        self.upload_snr_series = kwargs.get('upload_snr_series')
        usable_ifos = []
        if self.upload_snr_series:
            self.snr_series = {}
            self.snr_series_psd = {}
            htilde = kwargs['bank'][self.template_id]
            for ifo in ifos + followup_ifos:
                if ifo in ifos:
                    trig_time = coinc_results['foreground/%s/end_time' % ifo]
                else:
                    trig_time = subthreshold_sngl_time
                # NOTE we only check the state/DQ of followup IFOs here.
                # IFOs producing the coincidence are assumed to also
                # produce valid SNR series.
                snr_series, snr_series_psd = compute_followup_snr_series(
                        kwargs['data_readers'][ifo], htilde, trig_time,
                        check_state=(ifo in followup_ifos))
                if snr_series is not None:
                    self.snr_series[ifo] = snr_series
                    self.snr_series_psd[ifo] = snr_series_psd
                    usable_ifos.append(ifo)
        else:
            usable_ifos = 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
        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
            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.upload_snr_series:
                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()
        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 = 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()
Example #26
0
    def test_get_random_mass(self):
        # Want to do this for a variety of mass combinations
        for i in update_mass_parameters(self):
            curr_min_mass = self.min_total_mass
            curr_max_mass = self.max_total_mass
            try:
                pycbc.tmpltbank.verify_mass_range_options(self, parser=parser)
            except ValueError:
                # Some of the inputs are unphysical and will fail.
                # These cases are known to fail, the inputs are unphysical
                # 35 has inconsistent total mass and eta restrictions
                # 38 Component mass, [upper] chirp mass and [lower] eta limits
                #    rule out the entire space.
                # 41 Same as 38
                # 44 Same as 38
                # 62 From component mass and total mass limits only total masses
                #    between 7 and 7.5 are possible. This range all has eta
                #    lower than the limit of 0.17.
                # 65 Same as 38
                # 68 Same as 38
                # 71 Same as 38
                # 80 Same as 62
                if i in [35,38,41,44,62,65,68,71,80]:
                    continue
                raise

            # Check that if the mass limits have changed, it was right to do so
            # This is not exhaustive, but gets most things
            if not self.min_total_mass == curr_min_mass:
                min_comp_mass = self.min_mass1 + self.min_mass2
                min_eta = self.min_mass1 * self.min_mass2 /\
                           (min_comp_mass * min_comp_mass)
                min_chirp_mass = min_comp_mass * min_eta**(3./5.)
                if self.min_total_mass == min_comp_mass:
                    # Okay, the total mass is changed by the components
                    pass
                elif min_eta < self.min_eta or min_eta > self.max_eta:
                    # Okay, not possible from eta
                    pass
                elif min_chirp_mass < self.min_chirp_mass:
                    # Okay, not possible from chirp mass
                    pass
                else:
                    err_msg = "Minimum total mass changed unexpectedly."
                    print(self.min_total_mass, curr_min_mass)
                    print(self.min_mass1, self.min_mass2, min_comp_mass)
                    print(min_eta, self.min_eta, self.max_eta)
                    print(min_chirp_mass, self.min_chirp_mass)
                    self.fail(err_msg)
            if not self.max_total_mass == curr_max_mass:
                max_comp_mass = self.max_mass1 + self.max_mass2
                max_eta = self.max_mass1 * self.max_mass2 /\
                           (max_comp_mass * max_comp_mass)
                max_chirp_mass = max_comp_mass * max_eta**(3./5.)
                if self.max_total_mass == max_comp_mass:
                    # Okay, the total mass is changed by the components
                    pass
                elif max_eta < self.min_eta or max_eta > self.max_eta:
                    # Okay, not possible from eta
                    pass
                elif max_chirp_mass > self.max_chirp_mass:
                    # Okay, not possible from chirp mass
                    pass
                else:
                    err_msg = "Maximum total mass changed unexpectedly."
                    self.fail(err_msg)

            massRangeParams = pycbc.tmpltbank.massRangeParameters(\
                                self.min_mass1,\
                                self.max_mass1, self.min_mass2, self.max_mass2,\
                                maxNSSpinMag=self.max_ns_spin_mag,\
                                maxBHSpinMag=self.max_bh_spin_mag,\
                                maxTotMass=self.max_total_mass,\
                                minTotMass=self.min_total_mass,\
                                max_chirp_mass=self.max_chirp_mass,\
                                min_chirp_mass=self.min_chirp_mass,\
                                maxEta=self.max_eta,\
                                minEta=self.min_eta,\
                                ns_bh_boundary_mass=self.ns_bh_boundary_mass)

            # And again with the nsbh flag
            massRangeParams2 = pycbc.tmpltbank.massRangeParameters(\
                                self.min_mass1,\
                                self.max_mass1, self.min_mass2, self.max_mass2,\
                                maxNSSpinMag=self.max_ns_spin_mag,\
                                maxBHSpinMag=self.max_bh_spin_mag,\
                                maxTotMass=self.max_total_mass,\
                                minTotMass=self.min_total_mass,\
                                max_chirp_mass=self.max_chirp_mass,\
                                min_chirp_mass=self.min_chirp_mass,\
                                maxEta=self.max_eta,\
                                minEta=self.min_eta,\
                                nsbhFlag=True)

            mass1, mass2, spin1z, spin2z = \
                 pycbc.tmpltbank.get_random_mass(100000, massRangeParams)
            mass = mass1 + mass2
            errMsg = "pycbc.tmpltbank.get_random_mass returns invalid ranges."
            self.assertTrue(not (mass < self.min_total_mass).any(),msg=errMsg)
            self.assertTrue(not (mass > self.max_total_mass).any(),msg=errMsg)
            self.assertTrue(not (mass1 > self.max_mass1 * 1.001).any(),
                            msg=errMsg)
            self.assertTrue(not (mass1 < self.min_mass1 * 0.999).any(),
                            msg=errMsg)
            self.assertTrue(not (mass2 > self.max_mass2 * 1.001).any(),
                            msg=errMsg)
            self.assertTrue(not (mass2 < self.min_mass2 * 0.999).any(),
                            msg=errMsg)
            self.assertTrue(not (mass1 < mass2).any(),msg=errMsg)
            # Chirp mass and eta
            mchirp, eta = pnutils.mass1_mass2_to_mchirp_eta(mass1,mass2)
            if self.max_chirp_mass:
                self.assertTrue(not (mchirp > self.max_chirp_mass*1.0001).any(),
                                msg=errMsg)
            if self.min_chirp_mass:
                self.assertTrue(not (mchirp < self.min_chirp_mass*0.9999).any(),
                                msg=errMsg)
            if self.min_eta:
                self.assertTrue(not (eta < self.min_eta*0.9999).any(),
                                msg=errMsg)
                self.assertTrue(not (eta > self.max_eta*1.0001).any(),
                                msg=errMsg)
            nsSpin1 = spin1z[mass1 < self.ns_bh_boundary_mass]
            nsSpin2 = spin2z[mass2 < self.ns_bh_boundary_mass]
            bhSpin1 = spin1z[mass1 > self.ns_bh_boundary_mass]
            bhSpin2 = spin2z[mass2 > self.ns_bh_boundary_mass]
            self.assertTrue(not (abs(nsSpin1) > 0.5).any(), msg=errMsg)
            self.assertTrue(not (abs(nsSpin2) > 0.5).any(), msg=errMsg)
            self.assertTrue(not (abs(bhSpin1) > 0.9).any(), msg=errMsg)
            self.assertTrue(not (abs(bhSpin2) > 0.9).any(), msg=errMsg)
            # Check that *some* spins are bigger than 0.5
            if len(bhSpin1):
                self.assertTrue((abs(bhSpin1) > 0.5).any(), msg=errMsg)
            if len(bhSpin2):
                self.assertTrue((abs(bhSpin2) > 0.5).any(), msg=errMsg)

            # Check nsbh flag
            mass1, mass2, spin1z, spin2z = \
                 pycbc.tmpltbank.get_random_mass(100000, massRangeParams2)
            self.assertTrue(not (abs(spin1z) > 0.9).any(), msg=errMsg)
            self.assertTrue(not (abs(spin2z) > 0.5).any(), msg=errMsg)
            self.assertTrue((abs(spin1z) > 0.5).any(), msg=errMsg)
Example #27
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 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)
Example #28
0
    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
Example #29
0
best_chirp_mass = np.zeros(len(results_data))

sigma_best_match = np.zeros(len(results_data))
sigma_best_mass = np.zeros(len(results_data))
sigma_best_chirp_mass = np.zeros(len(results_data))

best_a1dotL = np.zeros(len(results_data))
best_a2dotL = np.zeros(len(results_data))

best_mass_ratio = np.zeros(len(results_data))

for d,data in enumerate(results_data):

    results_file = os.path.join(data[0], data[0]+'_'+sys.argv[2]+'.pickle')
    injected_mass[d] = float(data[1])+float(data[2])
    injected_chirp_mass[d], injected_eta  = pnutils.mass1_mass2_to_mchirp_eta(
            float(data[1]),float(data[2]))
    injected_a1z[d] = float(data[3])
    injected_a2z[d] = float(data[4])

    matches, masses, inclinations, config, simulations, _, _, _ = pickle.load(
            open(results_file, 'rb'))


    # Label figures according to the pickle file
    if opts.user_tag is None:
        user_tag=results_file.replace('.pickle','')

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Manipulation and derived FOMs
    #
Example #30
0
File: hdf.py Project: cmbiwer/pycbc
 def mchirp(self):
     mchirp, _ = pnutils.mass1_mass2_to_mchirp_eta(
         self.mass1, self.mass2)
     return mchirp
Example #31
0
    def to_coinc_xml_object(self, file_name):
        # FIXME: This function will only work with two ifos!!

        outdoc = ligolw.Document()
        outdoc.appendChild(ligolw.LIGO_LW())

        ifos = [ifo for ifo in 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
        start_time = coinc_h5file["segments"]["coinc"]["start"][:].min()
        end_time = coinc_h5file["segments"]["coinc"]["end"][:].max()
        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", "time1", "fap", "stat"]
        coinc_event_vals = {}
        for name in coinc_event_names:
            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)

        for idx, coinc_idx in enumerate(self.sort_arr):
            # Set up IDs and mapping values
            curr_tmplt_id = self.template_id[idx]
            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
            for ifo in ifos:
                sngl_id = self.trig_id[ifo][idx]
                event_id = lsctables.SnglInspiralID(sngl_id)
                sngl = return_empty_sngl()
                sngl.event_id = event_id
                sngl.ifo = ifo
                curr_sngl_file = self.sngl_files[ifo].h5file[ifo]
                for name in sngl_col_names:
                    val = sngl_col_vals[name][ifo][idx]
                    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, junk = 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["time1"][idx]))
            coinc_inspiral_row.snr = coinc_event_vals["stat"][idx]
            coinc_inspiral_row.false_alarm_rate = coinc_event_vals["fap"][idx]
            coinc_inspiral_row.combined_far = 1.0 / coinc_event_vals["ifar"][idx]
            # Transform to Hz
            coinc_inspiral_row.combined_far = coinc_inspiral_row.combined_far / YRJUL_SI
            coinc_event_row.likelihood = 0.0
            coinc_inspiral_row.minimum_duration = 0.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)
Example #32
0
 def mchirp(self):
     mchirp, _ = pnutils.mass1_mass2_to_mchirp_eta(self.mass1, self.mass2)
     return mchirp
Example #33
0
    def test_get_random_mass(self):
        # Want to do this for a variety of mass combinations
        for i in update_mass_parameters(self):
            curr_min_mass = self.min_total_mass
            curr_max_mass = self.max_total_mass
            try:
                pycbc.tmpltbank.verify_mass_range_options(self, parser=parser)
            except ValueError:
                # Some of the inputs are unphysical and will fail.
                # These cases are known to fail, the inputs are unphysical
                # 35 has inconsistent total mass and eta restrictions
                # 38 Component mass, [upper] chirp mass and [lower] eta limits
                #    rule out the entire space.
                # 41 Same as 38
                # 44 Same as 38
                # 62 From component mass and total mass limits only total masses
                #    between 7 and 7.5 are possible. This range all has eta
                #    lower than the limit of 0.17.
                # 65 Same as 38
                # 68 Same as 38
                # 71 Same as 38
                # 80 Same as 62
                if i in [35, 38, 41, 44, 62, 65, 68, 71, 80]:
                    continue
                raise

            # Check that if the mass limits have changed, it was right to do so
            # This is not exhaustive, but gets most things
            if (curr_min_mass is None) or \
                    not math.isclose(self.min_total_mass, curr_min_mass,
                                     rel_tol=1e-06):
                min_comp_mass = self.min_mass1 + self.min_mass2
                min_eta = self.min_mass1 * self.min_mass2 /\
                           (min_comp_mass * min_comp_mass)
                min_chirp_mass = min_comp_mass * min_eta**(3. / 5.)
                if (min_comp_mass is not None) and \
                        math.isclose(self.min_total_mass, min_comp_mass,
                                     rel_tol=1e-06):
                    # Okay, the total mass is changed by the components
                    pass
                elif (self.min_eta and min_eta < self.min_eta) or \
                        (self.max_eta and min_eta > self.max_eta):
                    # Okay, not possible from eta
                    pass
                elif self.min_chirp_mass and \
                        min_chirp_mass < self.min_chirp_mass:
                    # Okay, not possible from chirp mass
                    pass
                else:
                    err_msg = "Minimum total mass changed unexpectedly."
                    self.fail(err_msg)
            if (curr_max_mass is None) or \
                    not math.isclose(self.max_total_mass, curr_max_mass,
                                 rel_tol=1e-06):
                max_comp_mass = self.max_mass1 + self.max_mass2
                max_eta = self.max_mass1 * self.max_mass2 /\
                           (max_comp_mass * max_comp_mass)
                max_chirp_mass = max_comp_mass * max_eta**(3. / 5.)
                if (max_comp_mass is not None) and \
                        math.isclose(self.max_total_mass, max_comp_mass,
                                     rel_tol=1e-06):
                    # Okay, the total mass is changed by the components
                    pass
                elif (self.min_eta and max_eta < self.min_eta) or\
                        (self.max_eta and max_eta > self.max_eta):
                    # Okay, not possible from eta
                    pass
                elif self.max_chirp_mass and \
                        max_chirp_mass > self.max_chirp_mass:
                    # Okay, not possible from chirp mass
                    pass
                else:
                    err_msg = "Maximum total mass changed unexpectedly."
                    self.fail(err_msg)

            massRangeParams = pycbc.tmpltbank.massRangeParameters(\
                                self.min_mass1,\
                                self.max_mass1, self.min_mass2, self.max_mass2,\
                                maxNSSpinMag=self.max_ns_spin_mag,\
                                maxBHSpinMag=self.max_bh_spin_mag,\
                                maxTotMass=self.max_total_mass,\
                                minTotMass=self.min_total_mass,\
                                max_chirp_mass=self.max_chirp_mass,\
                                min_chirp_mass=self.min_chirp_mass,\
                                maxEta=self.max_eta,\
                                minEta=self.min_eta,\
                                ns_bh_boundary_mass=self.ns_bh_boundary_mass)

            # And again with the nsbh flag
            massRangeParams2 = pycbc.tmpltbank.massRangeParameters(\
                                self.min_mass1,\
                                self.max_mass1, self.min_mass2, self.max_mass2,\
                                maxNSSpinMag=self.max_ns_spin_mag,\
                                maxBHSpinMag=self.max_bh_spin_mag,\
                                maxTotMass=self.max_total_mass,\
                                minTotMass=self.min_total_mass,\
                                max_chirp_mass=self.max_chirp_mass,\
                                min_chirp_mass=self.min_chirp_mass,\
                                maxEta=self.max_eta,\
                                minEta=self.min_eta,\
                                nsbhFlag=True)

            mass1, mass2, spin1z, spin2z = \
                 pycbc.tmpltbank.get_random_mass(100000, massRangeParams)
            mass = mass1 + mass2
            errMsg = "pycbc.tmpltbank.get_random_mass returns invalid ranges."
            self.assertTrue(not (mass < self.min_total_mass).any(), msg=errMsg)
            self.assertTrue(not (mass > self.max_total_mass).any(), msg=errMsg)
            self.assertTrue(not (mass1 > self.max_mass1 * 1.001).any(),
                            msg=errMsg)
            self.assertTrue(not (mass1 < self.min_mass1 * 0.999).any(),
                            msg=errMsg)
            self.assertTrue(not (mass2 > self.max_mass2 * 1.001).any(),
                            msg=errMsg)
            self.assertTrue(not (mass2 < self.min_mass2 * 0.999).any(),
                            msg=errMsg)
            self.assertTrue(not (mass1 < mass2).any(), msg=errMsg)
            # Chirp mass and eta
            mchirp, eta = pnutils.mass1_mass2_to_mchirp_eta(mass1, mass2)
            if self.max_chirp_mass:
                self.assertTrue(
                    not (mchirp > self.max_chirp_mass * 1.0001).any(),
                    msg=errMsg)
            if self.min_chirp_mass:
                self.assertTrue(
                    not (mchirp < self.min_chirp_mass * 0.9999).any(),
                    msg=errMsg)
            if self.min_eta:
                self.assertTrue(not (eta < self.min_eta * 0.9999).any(),
                                msg=errMsg)
                self.assertTrue(not (eta > self.max_eta * 1.0001).any(),
                                msg=errMsg)
            nsSpin1 = spin1z[mass1 < self.ns_bh_boundary_mass]
            nsSpin2 = spin2z[mass2 < self.ns_bh_boundary_mass]
            bhSpin1 = spin1z[mass1 > self.ns_bh_boundary_mass]
            bhSpin2 = spin2z[mass2 > self.ns_bh_boundary_mass]
            self.assertTrue(not (abs(nsSpin1) > 0.5).any(), msg=errMsg)
            self.assertTrue(not (abs(nsSpin2) > 0.5).any(), msg=errMsg)
            self.assertTrue(not (abs(bhSpin1) > 0.9).any(), msg=errMsg)
            self.assertTrue(not (abs(bhSpin2) > 0.9).any(), msg=errMsg)
            # Check that *some* spins are bigger than 0.5
            if len(bhSpin1):
                self.assertTrue((abs(bhSpin1) > 0.5).any(), msg=errMsg)
            if len(bhSpin2):
                self.assertTrue((abs(bhSpin2) > 0.5).any(), msg=errMsg)

            # Check nsbh flag
            mass1, mass2, spin1z, spin2z = \
                 pycbc.tmpltbank.get_random_mass(100000, massRangeParams2)
            self.assertTrue(not (abs(spin1z) > 0.9).any(), msg=errMsg)
            self.assertTrue(not (abs(spin2z) > 0.5).any(), msg=errMsg)
            self.assertTrue((abs(spin1z) > 0.5).any(), msg=errMsg)
Example #34
0
 def eta(self):
     _, eta = pnutils.mass1_mass2_to_mchirp_eta(self.mass1, self.mass2)
     return eta
Example #35
0
        times, strainVal1, strainVal2 = np.loadtxt(datafile,
                                                   usecols=(0, 1, 2),
                                                   unpack=True)

        # run conversion functions for correct PyCBC conventions
        grav_mass1, grav_mass2 = convert_mass(massFormat, grav_mass1,
                                              grav_mass2, total_grav_mass)
        strainVal1, strainVal2 = convert_strain(strainFormat, strainVal1,
                                                strainVal2, total_grav_mass)
        times = convert_time(timeFormat, times, total_grav_mass)

        with h5py.File(h5file, 'w') as fd:

            # Set metadata
            # still need to add values for love number, radius, lambda, etc.
            mchirp, eta = pnutils.mass1_mass2_to_mchirp_eta(
                grav_mass1, grav_mass2)
            fd.attrs.create('NR_group', 'CSUF_GWPAC_NS')
            fd.attrs.create('sim_name', 'Deitrich')
            fd.attrs.create('EOS', 'ALF2')
            hashtag = hashlib.md5()
            fd.attrs.create('type', 'BNS')
            hashtag.update(fd.attrs['type'])
            fd.attrs.create('hashtag', hashtag.digest())
            fd.attrs.create('Format', 1)
            fd.attrs.create('f_lower_at_1MSUN', f_lower)
            fd.attrs.create('eta', eta)
            fd.attrs.create('spin1x', spin1x)
            fd.attrs.create('spin1y', spin1y)
            fd.attrs.create('spin1z', spin1z)
            fd.attrs.create('spin2x', spin2x)
            fd.attrs.create('spin2y', spin2y)
Example #36
0
    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
Example #37
0
 def eta(self):
     mchirp, eta = pnutils.mass1_mass2_to_mchirp_eta(self.mass1, self.mass2)
     return eta
Example #38
0
    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)
Example #39
0
            elif ((spin1z != 0) or (spin2z != 0)):
                simtype = 'aligned-spin'
            else:
                spinval = False

            # calculate the value for mean_anomaly (assuming this hasn't been calculated)
            # 0 is default for low eccentricity values (<= .001)
            mean_anom = 0
            if (id_eccentricity > .001):
                # default value for when it hasn't been properly calculated
                mean_anom = -1

            # create all relevant attributes for converted .h5 file

            # default Format 1 attributes
            mchirp, eta = pnutils.mass1_mass2_to_mchirp_eta(
                id_mass_starA, id_mass_starB)
            hashtag = hashlib.md5()
            fd.attrs.create('Format', 1)
            fd.attrs.create('type', 'BNS')
            fd.attrs.create('name', 'CoRe:' + database_key)
            fd.attrs.create('alternative-names', simulation_name)
            fd.attrs.create('NR-group', 'CoRe')
            fd.attrs.create('NR-code', id_code + ', ' + evolution_code)
            fd.attrs.create('modification-date', '')
            fd.attrs.create('point-of-contact-email',
                            '*****@*****.**')
            fd.attrs.create('simulation-type', simtype)
            fd.attrs.create('INSPIRE-bibtex-keys', reference_bibkeys)
            fd.attrs.create('license', 'public')
            fd.attrs.create('Lmax', lmax)
            fd.attrs.create('files-in-error-series', '')
def get_params(file):
    """
    Read waveform meta data from hdf5 file
    """

    f = h5py.File(file, "r")

    # Metadata parameters:
    params = {}

    params["eta"] = float(f.attrs["eta"])

    params["spin1x"] = float(f.attrs["spin1x"])
    params["spin1y"] = float(f.attrs["spin1y"])
    params["spin1z"] = float(f.attrs["spin1z"])
    params["spin2x"] = float(f.attrs["spin2x"])
    params["spin2y"] = float(f.attrs["spin2y"])
    params["spin2z"] = float(f.attrs["spin2z"])

    params["Mmin30Hz"] = float(f.attrs["f_lower_at_1MSUN"]) / 30.0

    mass1, mass2 = pnutils.mtotal_eta_to_mass1_mass2(params["Mmin30Hz"], params["eta"])

    params["Mchirpmin30Hz"], _ = pnutils.mass1_mass2_to_mchirp_eta(mass1, mass2)

    params["q"] = mass1 / mass2

    # --- Derived spin configuration
    params["a1"] = np.linalg.norm([params["spin1x"], params["spin1y"], params["spin1z"]])
    params["a2"] = np.linalg.norm([params["spin2x"], params["spin2y"], params["spin2z"]])

    params["a1dotL"], vec = nrbu.a_with_L(params["spin1x"], params["spin1y"], params["spin1z"])
    params["a1crossL"] = np.linalg.norm(vec)

    params["a2dotL"], vec = nrbu.a_with_L(params["spin2x"], params["spin2y"], params["spin2z"])
    params["a2crossL"] = np.linalg.norm(vec)

    params["theta_a12"] = nrbu.spin_angle(
        params["spin1x"], params["spin1y"], params["spin1z"], params["spin2x"], params["spin2y"], params["spin2z"]
    )

    params["SeffdotL"], vec = nrbu.effspin_with_L(
        params["q"],
        params["spin1x"],
        params["spin1y"],
        params["spin1z"],
        params["spin2x"],
        params["spin2y"],
        params["spin2z"],
    )
    params["SeffcrossL"] = np.linalg.norm(vec)

    params["SdotL"], params["theta_SdotL"] = nrbu.totspin_dot_L(
        params["q"],
        params["spin1x"],
        params["spin1y"],
        params["spin1z"],
        params["spin2x"],
        params["spin2y"],
        params["spin2z"],
    )

    params["wavefile"] = os.path.abspath(file)

    return params
Example #41
0
    def to_coinc_xml_object(self, file_name):
        # FIXME: This function will only work with two ifos!!

        outdoc = ligolw.Document()
        outdoc.appendChild(ligolw.LIGO_LW())

        ifos = [ifo for ifo in 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
        start_time = coinc_h5file['segments']['coinc']['start'][:].min()
        end_time = coinc_h5file['segments']['coinc']['end'][:].max()
        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', 'time1', 'fap', 'stat']
        coinc_event_vals = {}
        for name in coinc_event_names:
            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)

        for idx in xrange(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
            for ifo in ifos:
                sngl_id = self.trig_id[ifo][idx]
                event_id = lsctables.SnglInspiralID(sngl_id)
                sngl = return_empty_sngl()
                sngl.event_id = event_id
                sngl.ifo = ifo
                for name in sngl_col_names:
                    val = sngl_col_vals[name][ifo][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['time1'][idx]))
            coinc_inspiral_row.snr = coinc_event_vals['stat'][idx]
            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 = 0.
            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)
Example #42
0
Hlm = pwave.construct_Hlm(*quadrupole_data[1:])

wavelen = len(Hlm['l=2, m=2'])
times = np.arange(0, wavelen * delta_t, delta_t)
times_M = times / (lal.MTSUN_SI * total_mass)
# GEOMETERIZE  HLM (might be already!) see line 241+ of pmns_waveform.py

l = 2
with h5py.File(eos + '_' + mass + '.h5', 'w') as fd:

    #
    # Set metadata
    #

    mchirp, eta = pnutils.mass1_mass2_to_mchirp_eta(mass1, mass2)
    fd.attrs.create('NR_group', 'Bauswein')
    fd.attrs.create(
        'name',
        'Bauswein:BNS:%s' % (waveform_data.eos + '_' + waveform_data.mass +
                             '_' + waveform_data.viscosity))
    hashtag = hashlib.md5()
    hashtag.update(fd.attrs['name'])
    fd.attrs.create('hashtag', hashtag.digest())
    fd.attrs.create('f_lower_at_1MSUN', f_lower)
    fd.attrs.create('eta', eta)
    fd.attrs.create('LNhatx', 0.0)
    fd.attrs.create('LNhaty', 0.0)
    fd.attrs.create('LNhatz', 0.0)
    fd.attrs.create('lnhatx', 0.0)
    fd.attrs.create('lnhaty', 0.0)
Example #43
0
    def test_get_random_mass(self):
        # Want to do this for a variety of mass combinations
        for i in update_mass_parameters(self):
            curr_min_mass = self.min_total_mass
            curr_max_mass = self.max_total_mass
            try:
                pycbc.tmpltbank.verify_mass_range_options(self, parser=parser)
            except ValueError:
                # Some of the inputs are unphysical and will fail.
                # These cases are known to fail, the inputs are unphysical
                # 35 has inconsistent total mass and eta restrictions
                # 38 Component mass, [upper] chirp mass and [lower] eta limits
                #    rule out the entire space.
                # 41 Same as 38
                # 44 Same as 38
                # 62 From component mass and total mass limits only total masses
                #    between 7 and 7.5 are possible. This range all has eta
                #    lower than the limit of 0.17.
                # 65 Same as 38
                # 68 Same as 38
                # 71 Same as 38
                # 80 Same as 62
                if i in [35, 38, 41, 44, 62, 65, 68, 71, 80]:
                    continue
                raise

            # Check that if the mass limits have changed, it was right to do so
            # This is not exhaustive, but gets most things
            if not self.min_total_mass == curr_min_mass:
                min_comp_mass = self.min_mass1 + self.min_mass2
                min_eta = self.min_mass1 * self.min_mass2 /\
                           (min_comp_mass * min_comp_mass)
                min_chirp_mass = min_comp_mass * min_eta**(3. / 5.)
                if self.min_total_mass == min_comp_mass:
                    # Okay, the total mass is changed by the components
                    pass
                elif min_eta < self.min_eta or min_eta > self.max_eta:
                    # Okay, not possible from eta
                    pass
                elif min_chirp_mass < self.min_chirp_mass:
                    # Okay, not possible from chirp mass
                    pass
                else:
                    err_msg = "Minimum total mass changed unexpectedly."
                    print(self.min_total_mass, curr_min_mass)
                    print(self.min_mass1, self.min_mass2, min_comp_mass)
                    print(min_eta, self.min_eta, self.max_eta)
                    print(min_chirp_mass, self.min_chirp_mass)
                    self.fail(err_msg)
            if not self.max_total_mass == curr_max_mass:
                max_comp_mass = self.max_mass1 + self.max_mass2
                max_eta = self.max_mass1 * self.max_mass2 /\
                           (max_comp_mass * max_comp_mass)
                max_chirp_mass = max_comp_mass * max_eta**(3. / 5.)
                if self.max_total_mass == max_comp_mass:
                    # Okay, the total mass is changed by the components
                    pass
                elif max_eta < self.min_eta or max_eta > self.max_eta:
                    # Okay, not possible from eta
                    pass
                elif max_chirp_mass > self.max_chirp_mass:
                    # Okay, not possible from chirp mass
                    pass
                else:
                    err_msg = "Maximum total mass changed unexpectedly."
                    self.fail(err_msg)

            massRangeParams = pycbc.tmpltbank.massRangeParameters(\
                                self.min_mass1,\
                                self.max_mass1, self.min_mass2, self.max_mass2,\
                                maxNSSpinMag=self.max_ns_spin_mag,\
                                maxBHSpinMag=self.max_bh_spin_mag,\
                                maxTotMass=self.max_total_mass,\
                                minTotMass=self.min_total_mass,\
                                max_chirp_mass=self.max_chirp_mass,\
                                min_chirp_mass=self.min_chirp_mass,\
                                maxEta=self.max_eta,\
                                minEta=self.min_eta,\
                                ns_bh_boundary_mass=self.ns_bh_boundary_mass)

            # And again with the nsbh flag
            massRangeParams2 = pycbc.tmpltbank.massRangeParameters(\
                                self.min_mass1,\
                                self.max_mass1, self.min_mass2, self.max_mass2,\
                                maxNSSpinMag=self.max_ns_spin_mag,\
                                maxBHSpinMag=self.max_bh_spin_mag,\
                                maxTotMass=self.max_total_mass,\
                                minTotMass=self.min_total_mass,\
                                max_chirp_mass=self.max_chirp_mass,\
                                min_chirp_mass=self.min_chirp_mass,\
                                maxEta=self.max_eta,\
                                minEta=self.min_eta,\
                                nsbhFlag=True)

            mass1, mass2, spin1z, spin2z = \
                 pycbc.tmpltbank.get_random_mass(100000, massRangeParams)
            mass = mass1 + mass2
            errMsg = "pycbc.tmpltbank.get_random_mass returns invalid ranges."
            self.assertTrue(not (mass < self.min_total_mass).any(), msg=errMsg)
            self.assertTrue(not (mass > self.max_total_mass).any(), msg=errMsg)
            self.assertTrue(not (mass1 > self.max_mass1 * 1.001).any(),
                            msg=errMsg)
            self.assertTrue(not (mass1 < self.min_mass1 * 0.999).any(),
                            msg=errMsg)
            self.assertTrue(not (mass2 > self.max_mass2 * 1.001).any(),
                            msg=errMsg)
            self.assertTrue(not (mass2 < self.min_mass2 * 0.999).any(),
                            msg=errMsg)
            self.assertTrue(not (mass1 < mass2).any(), msg=errMsg)
            # Chirp mass and eta
            mchirp, eta = pnutils.mass1_mass2_to_mchirp_eta(mass1, mass2)
            if self.max_chirp_mass:
                self.assertTrue(
                    not (mchirp > self.max_chirp_mass * 1.0001).any(),
                    msg=errMsg)
            if self.min_chirp_mass:
                self.assertTrue(
                    not (mchirp < self.min_chirp_mass * 0.9999).any(),
                    msg=errMsg)
            if self.min_eta:
                self.assertTrue(not (eta < self.min_eta * 0.9999).any(),
                                msg=errMsg)
                self.assertTrue(not (eta > self.max_eta * 1.0001).any(),
                                msg=errMsg)
            nsSpin1 = spin1z[mass1 < self.ns_bh_boundary_mass]
            nsSpin2 = spin2z[mass2 < self.ns_bh_boundary_mass]
            bhSpin1 = spin1z[mass1 > self.ns_bh_boundary_mass]
            bhSpin2 = spin2z[mass2 > self.ns_bh_boundary_mass]
            self.assertTrue(not (abs(nsSpin1) > 0.5).any(), msg=errMsg)
            self.assertTrue(not (abs(nsSpin2) > 0.5).any(), msg=errMsg)
            self.assertTrue(not (abs(bhSpin1) > 0.9).any(), msg=errMsg)
            self.assertTrue(not (abs(bhSpin2) > 0.9).any(), msg=errMsg)
            # Check that *some* spins are bigger than 0.5
            if len(bhSpin1):
                self.assertTrue((abs(bhSpin1) > 0.5).any(), msg=errMsg)
            if len(bhSpin2):
                self.assertTrue((abs(bhSpin2) > 0.5).any(), msg=errMsg)
            # This can be used to test the boundaries are all applied visually
            # FIXME: This would need to be updated for all of the mass limits
            #pylab.plot(mass1, mass2, 'b.')
            #pylab.plot([3.0,5.0],[3.0,1.0],'r-')
            #pylab.plot([1.7216566400945545,1.9921146662296347,3.4433132801891091,4.01175560949798],[1.1477710933963694,1.0066274466204264,2.2955421867927388,1.002938902374495],'mx')
            #pylab.ylim([0.8,3.0])
            #pylab.xlim([1.5,5.0])
            #pylab.savefig("masses_%d.png" %(idx,))

            # Check nsbh flag
            mass1, mass2, spin1z, spin2z = \
                 pycbc.tmpltbank.get_random_mass(100000, massRangeParams2)
            self.assertTrue(not (abs(spin1z) > 0.9).any(), msg=errMsg)
            self.assertTrue(not (abs(spin2z) > 0.5).any(), msg=errMsg)
            self.assertTrue((abs(spin1z) > 0.5).any(), msg=errMsg)
Example #44
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 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
        followup_ifos = kwargs.get('followup_ifos') or []
        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)

        # compute SNR time series
        subthreshold_sngl_time = numpy.mean(
            [coinc_results['foreground/%s/end_time' % ifo] for ifo in ifos])
        self.upload_snr_series = kwargs.get('upload_snr_series')
        if self.upload_snr_series:
            self.snr_series = {}
            self.snr_series_psd = {}
            htilde = kwargs['bank'][self.template_id]
            for ifo in ifos + followup_ifos:
                if ifo in ifos:
                    trig_time = coinc_results['foreground/%s/end_time' % ifo]
                else:
                    trig_time = subthreshold_sngl_time
                # NOTE we only check the state/DQ of followup IFOs here.
                # IFOs producing the coincidence are assumed to also
                # produce valid SNR series.
                snr_series, snr_series_psd = compute_followup_snr_series(
                    kwargs['data_readers'][ifo],
                    htilde,
                    trig_time,
                    check_state=(ifo in followup_ifos))
                if snr_series is not None:
                    self.snr_series[ifo] = snr_series
                    self.snr_series_psd[ifo] = snr_series_psd

        # Set up sngls
        sngl_inspiral_table = lsctables.New(lsctables.SnglInspiralTable)
        coinc_event_map_table = lsctables.New(lsctables.CoincMapTable)

        sngl_populated = None
        for sngl_id, ifo in enumerate(ifos + followup_ifos):
            if self.upload_snr_series and ifo not in self.snr_series:
                # SNR series could not be computed, so skip this
                continue

            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
            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.upload_snr_series and ifo in self.snr_series:
                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()
        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(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()
Example #45
0
File: live.py Project: tdent/pycbc
    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]]

        # 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()
        elif ((spin1z != 0) or (spin2z != 0)):
            simtype = 'aligned-spin'
        else:
            spinval = False

        # calculate the value for mean_anomaly (assuming this hasn't been calculated)
        # 0 is default for low eccentricity values (<= .001)
        mean_anom = 0
        if (eccentricity > .001):
            # default value for when it hasn't been properly calculated
            mean_anom = -1

        # create all relevant attributes for converted .h5 file

        # default Format 1 attributes
        mchirp, eta = pnutils.mass1_mass2_to_mchirp_eta(
            initial_mass1, initial_mass2)
        hashtag = hashlib.md5()
        fd.attrs.create('Format', 1)
        fd.attrs.create('type', 'BBH')
        fd.attrs.create('name', simulation_name)
        fd.attrs.create('alternative-names', alternative_names)
        fd.attrs.create('NR-group', 'SXS')
        fd.attrs.create('NR-code', 'SpEC')
        fd.attrs.create('modification-date', '')
        fd.attrs.create('point-of-contact-email', '')
        fd.attrs.create('simulation-type', '')
        fd.attrs.create('INSPIRE-bibtex-keys', '')
        fd.attrs.create('license', 'public')
        fd.attrs.create('Lmax', lmax)
        fd.attrs.create('files-in-error-series', '')
        fd.attrs.create('comparable-simulation', '')