Raw File
#!/usr/bin/env python

# Copyright (C) 2015 Christopher M. Biwer
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

import argparse
import logging
import numpy
import os, sys
from glue.ligolw import ligolw, lsctables, table, utils
from pycbc.inject import InjectionSet, legacy_approximant_name
from pycbc.types import TimeSeries
from pycbc.waveform import get_td_waveform
from pycbc.detector import get_available_detectors

class DefaultContentHandler(ligolw.LIGOLWContentHandler):
    pass
lsctables.use_in(DefaultContentHandler)

# command line usage
parser = argparse.ArgumentParser(
             usage='pycbc_generate_hwinj_from_xml --injection-file [INJECTION_FILE] --sample-rate [SAMPLE_RATE]',
             description='Generates all the time-domain injections from a LIGOLW \
             sim_inspiral table for H1 and L1. \
             To run the executable you have to specify a LIGOLW XML file \
             that contains a sim_inspiral table (--injection-file) and the sample rate \
             for the generated waveforms (--sample-rate). \
             The output of the code is single-column ASCII files that contain the \
             waveform h(t) time series. The output ASCII files will appear in the \
             current working directory with the standard LIGO naming convetion, \
             eg. H1-HWINJ_CBC_FROM_SIMULATION_ID_X-Y-Z.txt where X is the simulation_id \
             from the sim_inspiral row, Y is the GPS start time of the ASCII waveform file, \
             and Z is the duration of the file in seconds.')

# add command line options
parser.add_argument('--injection-file', type=str, required=True,
             help='Path to the LIGOLW XML file that contains a sim_inspiral table.')
parser.add_argument('--sample-rate', type=int, required=True,
             help='Sample rate that waveforms will be generated.')
parser.add_argument("--tag", type=str, default='hwinjcbcsimid',
                    help="Prefix added to output filenames.")
parser.add_argument('--ifos', nargs='+', default=['H1', 'L1'], required=True,
                    choices=list(zip(*get_available_detectors()))[0],
                    help='List of IFOs to generate injections for.')
# parse command line
opts = parser.parse_args()

# setup log
logging_level = logging.DEBUG
logging.basicConfig(format='%(asctime)s : %(message)s', level=logging_level)

# read in injection LIGOLW XML file
logging.info('Reading injection file')
injections = InjectionSet(opts.injection_file)

# loop over rows in sim_inspiral table
for sim in injections.table:

    # print statement
    logging.info('Begin generating waveform for %s', sim.simulation_id)

    # parse the sim_inspiral waveform column
    name, phase_order = legacy_approximant_name(sim.waveform)

    # get simulation ID for output filename
    sim_id = int(sim.simulation_id)

    # generate the waveform
    # we generate the waveform so we know how many sample points the ASCII file
    # will need to have to contain the full waveform
    logging.info('Getting number of sample points in waveform')
    h_plus, _ = get_td_waveform(sim, approximant=name, phase_order=phase_order,
                    delta_t=1.0/opts.sample_rate)

    # figure out length of the time series to inject waveform into
    pad_seconds = 5
    template_duration_seconds = int( len(h_plus) / opts.sample_rate ) + 1
    start_time = int(sim.geocent_end_time) - template_duration_seconds - pad_seconds
    end_time = int(sim.geocent_end_time) + 1 + pad_seconds
    num_samples = (end_time - start_time) * opts.sample_rate

    # loop over IFOs for writing waveforms to file
    for ifo in opts.ifos:

        # create a time series of zeroes to inject waveform into
        initial_array = numpy.zeros(num_samples, dtype=h_plus.dtype)
        output = TimeSeries(initial_array, delta_t=1.0/opts.sample_rate, epoch=start_time, dtype=h_plus.dtype)

        # inject waveform into time series of zeroes
        logging.info('Injecting %s waveform into timeseries of zeroes', ifo)
        injections.apply(output, ifo, simulation_ids=[sim.simulation_id])

        # set output filename
        txt_filename = opts.tag + str(sim_id) + '_' + str(start_time) + '_' + ifo + '.txt'

        # check if filename does not exist
        if os.path.exists(txt_filename):
            logging.warn('Filename %s already exists and will not be overwritten', txt_filename)
            sys.exit()

        # save waveform as single column ASCII for awgstream to use
        logging.info('Writing strain for %s', ifo)
        numpy.savetxt(txt_filename, output)

# finish
logging.info('Done')
back to top