30from optparse
import OptionParser
36from igwn_ligolw
import ligolw
37from igwn_ligolw
import lsctables
38from igwn_ligolw
import utils
as ligolw_utils
39from igwn_ligolw.utils
import process
as ligolw_process
43from lalburst
import git_version
49 for key, value
in kwargs.items():
50 setattr(self, key, value)
53 return self.time_geocent_gps.gpsNanoSeconds
54lsctables.SimBurst = lsctables.SimBurstTable.RowType = SimBurst
57__author__ =
"Kipp Cannon <kipp.cannon@ligo.org>"
58__version__ =
"git id %s" % git_version.id
59__date__ = git_version.date
72 parser = OptionParser(
73 version =
"Name: %%prog\n%s" % git_version.verbose_msg,
74 usage =
"%prog [options] filename",
75 description =
"Convert an image into a LIGO Light-Weight XML file containing a list of sine-Gaussian burst injections. When injected into data, the injections will cause a waterfall plot to display the image."
77 parser.add_option(
"-l",
"--f-low", metavar =
"Hz", type =
"float", default = 64.0, help =
"Set the low-frequency limit of the tiling in Hertz (default = 64).")
78 parser.add_option(
"-d",
"--delta-f", metavar =
"Hz", type =
"float", default = 16.0, help =
"Set the bandwidth of the pixels in Hertz (default = 16). Must be > 0. The product of --delta-f and --delta-t must be at least 2/pi.")
79 parser.add_option(
"-t",
"--delta-t", metavar =
"s", type =
"float", default = 1.0 / 16, help =
"Set the duration of the pixels in seconds (default = 1/16). Must be > 0. The product of --delta-f and --delta-t must be at least 2/pi.")
80 parser.add_option(
"-f",
"--overlap-fraction", metavar =
"fraction", type =
"float", default = 0.25, help =
"Set the fraction by which adjacent tiles overlap (default = 0.25). The pixels centres are spaced (1 - --overlap-fraction) * --delta-f apart in the frequency domain. The value must be in the range [0, 1).")
81 parser.add_option(
"-H",
"--height", metavar =
"pixels", type =
"int", default = 64, help =
"Set the number of pixles in the frequency domain (default = 64). The image will be scaled to this vertical size, and the number of pixels in the time domain (horizontal size) will be fixed by the image aspect ratio.")
82 parser.add_option(
"-o",
"--output", metavar =
"filename", help =
"Set the name of the output file (default = stdout).")
83 parser.add_option(
"-s",
"--gps-start-time", metavar =
"seconds", help =
"Set the start time of the tiling in GPS seconds (required).")
84 parser.add_option(
"--sample-rate", metavar =
"Hz", type =
"int", default = 16384, help =
"Set the sample rate in Hertz of the data into which the injections will be placed (default = 16384). This information is required in order to normalize each pixel accurately. If the wrong value is used, the result will be the addition of noise to the image. The highest frequency pixel must have a centre frequency < 1/2 this frequency.")
85 parser.add_option(
"-n",
"--hrss-scale", metavar =
"hrss", type =
"float", default = 1e-20, help =
"Set the single-pixel hrss (root-sum-square strain) corresponding to \"white\" (default = 1e-20).")
86 parser.add_option(
"-v",
"--verbose", action =
"store_true", help =
"Be verbose.")
87 parser.add_option(
"-T",
"--time-slide-xml", metavar =
"filename", help =
"Associate injections with the first time slide ID in this XML file (required).")
88 options, filenames = parser.parse_args()
91 options.options_dict =
dict(options.__dict__)
93 if options.gps_start_time
is None:
94 raise ValueError(
"missing required option --gps-start-time")
95 if not 0. < options.delta_f:
96 raise ValueError(
"--delta-f must be > 0")
97 if not 0. < options.delta_t:
98 raise ValueError(
"--delta-t must be > 0")
99 if options.delta_f * options.delta_t < 2. / math.pi:
100 raise ValueError(
"the product of --delta-t and --delta-f must be >= 2/pi")
101 if not (0. <= options.overlap_fraction < 1.):
102 raise ValueError(
"--overlap-fraction must be in [0, 1)")
103 if options.f_low + options.height * (1. - options.overlap_fraction) * options.delta_f >= options.sample_rate / 2.:
104 raise ValueError(
"total waveform bandwidth exceeds Nyquist frequency")
105 if options.time_slide_xml
is None:
106 raise ValueError(
"missing required option time-slide-xml")
109 options.gps_start_time = lsctables.LIGOTimeGPS(options.gps_start_time)
111 return options, filenames
131xmldoc = ligolw_utils.load_filename(options.time_slide_xml, verbose = options.verbose)
139process = ligolw_process.register_to_xmldoc(xmldoc,
"lalburst_inj_pic", options.options_dict, version = git_version.version)
147time_slide_table = lsctables.TimeSlideTable.get_table(xmldoc)
148time_slide_id = time_slide_table[0].time_slide_id
150 print(
"associating injections with time slide (%d) %s" % (time_slide_id, time_slide_table.as_dict()[time_slide_id]), file = sys.stderr)
159 lsctables.SimBurstTable.get_table(xmldoc)
164 raise ValueError(
"%s contains a sim_burst table. this program isn't smart enough to deal with that." % options.time_slide_xml)
166sim_burst_tbl = xmldoc.childNodes[-1].appendChild(lsctables.SimBurstTable.new([
"process:process_id",
"simulation_id",
"time_slide:time_slide_id",
"waveform",
"waveform_number",
"ra",
"dec",
"psi",
"time_geocent_gps",
"time_geocent_gps_ns",
"duration",
"frequency",
"bandwidth",
"egw_over_rsquared",
"pol_ellipse_angle",
"pol_ellipse_e"]))
175 print(
"time-frequency tiles have %g degrees of freedom" % (2. * options.delta_t * options.delta_f), file = sys.stderr)
177for n, filename
in enumerate(filenames, 1):
179 print(
"%d/%d: loading %s ..." % (n, len(filenames), filename), file = sys.stderr)
180 img = Image.open(filename)
182 width, height = img.size
183 width, height = int(round(width * options.height / float(height))), options.height
185 print(
"converting to %dx%d grayscale ... " % (width, height), file = sys.stderr)
186 img = img.resize((width, height)).convert(
"L")
188 progress = tqdm(desc =
"computing pixels", total = width * height, disable =
not options.verbose)
189 for i
in range(width):
190 for j
in range(height):
202 hrss = options.hrss_scale * img.getpixel((i, height - 1 - j)) / 255.0
209 row = lsctables.SimBurst(
211 process_id = process.process_id,
212 simulation_id = sim_burst_tbl.get_next_id(),
213 time_slide_id = time_slide_id,
224 pol_ellipse_angle = 0.,
227 time_geocent_gps = options.gps_start_time + i * options.delta_t * (1.0 - options.overlap_fraction),
228 frequency = options.f_low + j * options.delta_f * (1.0 - options.overlap_fraction),
229 bandwidth = options.delta_f,
230 duration = options.delta_t,
237 egw_over_rsquared = 1.
242 row.egw_over_rsquared *= hrss / lalsimulation.MeasureHrss(*lalburst.GenerateSimBurst(row, 1.0 / options.sample_rate))
245 sim_burst_tbl.append(row)
254ligolw_utils.write_filename(xmldoc, options.output, verbose = options.verbose)
def time_geocent_gps_ns(self)
def __init__(self, **kwargs)