gstlal 1.13.0
Loading...
Searching...
No Matches
gstlal_spectrum_movie
Go to the documentation of this file.
1#!/usr/bin/env python3
2#
3# Copyright (C) 2010 Kipp Cannon
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the
7# Free Software Foundation; either version 2 of the License, or (at your
8# option) any later version.
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13# Public License for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc.,
17# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19
21
22#
23# =============================================================================
24#
25# Preamble
26#
27# =============================================================================
28#
29
30
31from optparse import OptionParser
32
33import gi
34gi.require_version('Gst', '1.0')
35from gi.repository import GObject, Gst
36
37from gstlal import simplehandler
38from gstlal import pipeparts
39from gstlal import datasource
40
41
42from ligo import segments
43
44
45#
46# =============================================================================
47#
48# Command Line
49#
50# =============================================================================
51#
52
53
54def parse_command_line():
55 parser = OptionParser(
56 description = "%prog generates an animated view of the PSD measured from h(t). The video can be shown on the screen or saved to a OGG Theora movie file. Example:\n\n%prog \\\n\t--frame-cache \"/home/kipp/scratch_local/874100000-20000/cache/874100000-20000.cache\" \\\n\t--instrument \"H1\" \\\n\t--channel-name \"LSC-STRAIN\" \\\n\t--gps-start-time 874100000.0 \\\n\t--gps-end-time 874120000.0 \\\n\t--psd-fft-length 8.0 \\\n\t--psd-zero-pad-length 0.0 \\\n\t--average-length 64.0 \\\n\t--median-samples 3 \\\n\t--frame-rate 10/1 \\\n\t--output spectrum_movie.ogm \\\n\t--verbose"
57 )
58 # generic "source" options
59 datasource.append_options(parser)
60 parser.add_option("--sample-rate", metavar = "Hz", type = "float", default = 8192.0, help = "Downsample the data to this sample rate. Default = 8192 Hz.")
61 parser.add_option("--psd-fft-length", metavar = "seconds", type = "float", default = 8.0, help = "Set the length of the FFT windows used to measure the PSD (optional).")
62 parser.add_option("--psd-zero-pad-length", metavar = "seconds", type = "float", default = 0.0, help = "Set the length of zero-padding in the FFT windows used to measure the PSD (optional).")
63 parser.add_option("--average-length", metavar = "seconds", type = "float", default = 64.0, help = "Set the time scale for the running mean (optional). Default = 64.0.")
64 parser.add_option("--median-samples", metavar = "samples", type = "int", default = 5, help = "Set the number of samples in the median history (optional). Default = 5.")
65 parser.add_option("--f-min", metavar = "Hz", type = "float", default = 10.0, help = "Set the lower bound of the spectrum plot's horizontal axis. Default = 10.0.")
66 parser.add_option("--f-max", metavar = "Hz", type = "float", default = 4000.0, help = "Set the upper bound of the spectrum plot's horizontal axis. Default = 4000.0.")
67 parser.add_option("--output", metavar = "filename", help = "Set the name of the movie file to write (optional). The default is to display the video on screen.")
68 parser.add_option("-v", "--verbose", action = "store_true", help = "Be verbose (optional).")
69
70 options, filenames = parser.parse_args()
71
72 if options.f_max <= options.f_min:
73 raise ValueError("--f-max must be >= --f-min")
74
75 return options, filenames
76
77
78#
79# =============================================================================
80#
81# Main
82#
83# =============================================================================
84#
85
86
87#
88# parse command line
89#
90
91
92options, filenames = parse_command_line()
93
94
95#
96# parse the generic "source" options, check for inconsistencies is done inside
97# the class init method
98#
99
100
101gw_data_source_info = datasource.DataSourceInfo.from_optparse(options)
102if len(gw_data_source_info.channel_dict) != 1:
103 raise ValueError("can only specify one channel, one instrument")
104instrument, = gw_data_source_info.channel_dict.keys()
105
106
107#
108# build pipeline
109#
110
111
112def build_pipeline(pipeline, head, sample_rate, psd_fft_length, psd_zero_pad_length, average_length, median_samples, input_tuple, verbose = False):
113 f_min, f_max = input_tuple
114 head = pipeparts.mkresample(pipeline, head, quality = 9)
115 head = pipeparts.mkcapsfilter(pipeline, head, "audio/x-raw, rate=%d" % sample_rate)
116 head = pipeparts.mkwhiten(pipeline, head, fft_length = psd_fft_length, zero_pad = psd_zero_pad_length, average_samples = int(round(average_length / (psd_fft_length / 2) - 1)), median_samples = median_samples)
117 pipeparts.mkfakesink(pipeline, head)
118 head = pipeparts.mkqueue(pipeline, head.get_static_pad("mean-psd"), max_size_buffers = 4)
119
120 head = pipeparts.mkspectrumplot(pipeline, head, f_min = f_min, f_max = f_max)
121 head = pipeparts.mkcapsfilter(pipeline, head, "video/x-raw-rgb, width=768, height=320")
122 return head
123
124
125#
126# construct and run pipeline
127#
128
129
130mainloop = GObject.MainLoop()
131pipeline = Gst.Pipeline(name="spectrum-movie")
132handler = simplehandler.Handler(mainloop, pipeline)
133
134
135head, _, _, _ = datasource.mkbasicsrc(pipeline, gw_data_source_info, instrument, verbose = options.verbose)
136head = build_pipeline(
137 pipeline,
138 head,
139 options.sample_rate,
140 options.psd_fft_length,
141 options.psd_zero_pad_length,
142 options.average_length,
143 options.median_samples,
144 (options.f_min, options.f_max),
145 verbose = options.verbose
146)
147if options.output is not None:
148 pipeparts.mkogmvideosink(pipeline, head, options.output, verbose = options.verbose)
149else:
150 pipeparts.mkvideosink(pipeline, pipeparts.mkcolorspace(pipeline, head))
151
152
153#
154# process segment
155#
156
157
158if pipeline.set_state(Gst.State.PLAYING) == Gst.StateChangeReturn.FAILURE:
159 raise RuntimeError("pipeline failed to enter PLAYING state")
160mainloop.run()
161
162
163#
164# done
165#