1"""Module for producing source elements
7from typing
import List, Tuple, Union, Iterable, Optional
9from ligo
import segments
11from gstlal.pipeparts
import pipetools, transform, filters, mux
12from gstlal.utilities
import laltools
14BYTE_ORDER =
'LE' if sys.byteorder ==
"little" else 'BE'
18 """Enumeration of test waveforms
21 [1] https://gstreamer.freedesktop.org/documentation/audiotestsrc/index.html?gi-language=python#GstAudioTestSrcWave
39 """Enumeration of NDS channel types
42 Implementation: gstlal-ugly/gst/nds/ndssrc.c
48 SecondTrend =
's-trend'
49 MinuteTrend =
'm-trend'
54 """A class that manages the task of watching for and connecting to new
55 source pads by name. The inputs are an element, the name of the
56 source pad to watch for on that element, and the sink pad (on a
57 different element) to which the source pad should be linked when it
60 The "pad-added" signal of the element will be used to watch for new
61 pads, and if the "no-more-pads" signal is emitted by the element
62 before the requested pad has appeared ValueError is raised.
65 def __init__(self, element, srcpadname, sinkpad):
66 no_more_pads_handler_id = element.connect(
"no-more-pads", self.
no_more_pads, srcpadname)
67 assert no_more_pads_handler_id > 0
68 pad_added_data = [srcpadname, sinkpad, no_more_pads_handler_id]
69 pad_added_handler_id = element.connect(
"pad-added", self.
pad_added, pad_added_data)
70 assert pad_added_handler_id > 0
71 pad_added_data.append(pad_added_handler_id)
74 def pad_added(element, pad, src_sink_ids):
75 srcpadname, sinkpad, no_more_pads_handler_id, pad_added_handler_id = src_sink_ids
76 if pad.get_name() == srcpadname:
77 element.handler_disconnect(no_more_pads_handler_id)
78 element.handler_disconnect(pad_added_handler_id)
82 def no_more_pads(element, srcpadname):
83 raise ValueError(
"<%s>: no pad named '%s'" % (element.get_name(), srcpadname))
86def fake_ligo(pipeline: pipetools.Pipeline, instrument: str =
None, channel_name: str =
None, blocksize: int = 16384 * 8 * 1) -> pipetools.Element:
91 Gst.Pipeline, the pipeline to which the new element will be added
97 int, default 16384 * 8 * 1, Number of samples in each outgoing buffer
100 Implementation gstlal/gst/python/lal_fakeligosrc.py
105 properties = {
"blocksize": blocksize}
106 properties.update((name, val)
for name, val
in ((
"instrument", instrument), (
"channel_name", channel_name))
if val
is not None)
107 return pipetools.make_element_with_src(pipeline,
None,
"lal_fakeligosrc", **properties)
110def fake_aligo(pipeline: pipetools.Pipeline, instrument: str =
None, channel_name: str =
None, blocksize: int = 16384 * 8 * 1) -> pipetools.Element:
111 """Fake Advanced LIGO Source
115 Gst.Pipeline, the pipeline to which the new element will be added
121 int, default 16384 * 8 * 1, Number of samples in each outgoing buffer
124 Implementation gstlal/gst/python/lal_fakeadvligosrc.py
129 properties = {
"blocksize": blocksize}
130 properties.update((name, val)
for name, val
in ((
"instrument", instrument), (
"channel_name", channel_name))
if val
is not None)
131 return pipetools.make_element_with_src(pipeline,
None,
"lal_fakeadvligosrc", **properties)
134def fake_avirgo(pipeline: pipetools.Pipeline, instrument: str =
None, channel_name: str =
None, blocksize: int = 16384 * 8 * 1) -> pipetools.Element:
135 """Fake Advanced Virgo Source
139 Gst.Pipeline, the pipeline to which the new element will be added
145 int, default 16384 * 8 * 1, Number of samples in each outgoing buffer
148 Implementation gstlal/gst/python/lal_fakeadvvirgosrc.py
153 properties = {
"blocksize": blocksize}
154 if instrument
is not None:
155 properties[
"instrument"] = instrument
156 if channel_name
is not None:
157 properties[
"channel_name"] = channel_name
158 return pipetools.make_element_with_src(pipeline,
None,
"lal_fakeadvvirgosrc", **properties)
162def segment(pipeline: pipetools.Pipeline, segment_list: List[Tuple[pipetools.TimeGPS, pipetools.TimeGPS]], blocksize: int = 4096 * 1 * 1,
163 invert_output: bool =
False) -> pipetools.Element:
164 """The output is a buffer of boolean values specifying when a list of segments are on and off.
168 Gst.Pipeline, the pipeline to which the new element will be added
170 Iterable[Tuple[TimeGPS, TimeGPS]], list of segment start / stop times
172 int, default blocksize is 4096 seconds of unsigned integers at 1 Hz, e.g. segments without nanoseconds
174 bool, default False, False = output is high in segments (default), True = output is low in segments
177 Implementation: gstlal/gst/lal/gstlal_segmentsrc.c
182 return pipetools.make_element_with_src(pipeline,
None,
"lal_segmentsrc", blocksize=blocksize,
183 segment_list=segments.segmentlist(segments.segment(a.ns(), b.ns())
for a, b
in segment_list),
184 invert_output=invert_output)
188def cache(pipeline: pipetools.Pipeline, location: str, use_mmap: bool =
True, **properties) -> pipetools.Element:
189 """Retrieve frame files from locations recorded in a LAL cache file.
193 Gst.Pipeline, the pipeline to which the new element will be added
195 str, Path to LAL cache file.
197 bool, default True, if True Use mmap() instead of read()
201 Implementation: gstlal/gst/lal/gstlal_cachesrc.c
206 return pipetools.make_element_with_src(pipeline,
None,
"lal_cachesrc", location=location, use_mmap=use_mmap, **properties)
209def lvshm(pipeline: pipetools.Pipeline, shm_name: str, **properties) -> pipetools.Element:
210 """LIGO-Virgo shared memory frame file source element
214 Gst.Pipeline, the pipeline to which the new element will be added
216 str, Shared memory partition name. Suggestions: LHO_Data, LLO_Data, VIRGO_Data
220 Implementation: gstlal-ugly/gst/gds/lvshmsrc.cc
225 return pipetools.make_element_with_src(pipeline,
None,
"gds_lvshmsrc", shm_name=shm_name, **properties)
227def devshm(pipeline: pipetools.Pipeline, shm_dirname: str, **properties) -> pipetools.Element:
228 """LIGO-Virgo /dev/shm frame file source element
232 Gst.Pipeline, the pipeline to which the new element will be added
234 str, Shared memory directory name (full path). Suggestion: /dev/shm/kafka/L1_O3ReplayMDC
238 Implementation: gstlal-ugly/gst/gds/devshmsrc.cc
243 return pipetools.make_element_with_src(pipeline,
None,
"gds_devshmsrc", shm_dirname=shm_dirname, **properties)
246def framexmit(pipeline: pipetools.Pipeline, multicast_group: str =
'0.0.0.0', port: int = 0, **properties) -> pipetools.Element:
247 """FrameXMIT based source element
251 Gst.Pipeline, the pipeline to which the new element will be added
253 str, default "0.0.0.0", The address of multicast group to join. If no multicast address is supplied, the receiver will listen for
254 UDP/IP broadcast transmissions at the specified port.
256 int, default 0, The local port on which to receive broadcasts (0 = allocate). These ports can be reused by multiple applications.
260 Implementation: gstlal-ugly/gst/gds/framexmitsrc.cc
265 return pipetools.make_element_with_src(pipeline,
None,
"gds_framexmitsrc", multicast_group=multicast_group, port=port, **properties)
268def nds(pipeline: pipetools.Pipeline, host: str, instrument: str, channel_name: str, channel_type: str, blocksize: int = 16384 * 8 * 1, port: int = 31200) -> pipetools.Element:
269 """NDS-based src element
273 Gst.Pipeline, the pipeline to which the new element will be added
275 str, NDS1 or NDS2 remote host name or IP address
277 str, name of instrument
279 str, Name of the desired NDS channel.
281 str, Type of the desired NDS channel.
283 int, default 16384 * 8 * 1, blocksize
285 int, NDS1 or NDS2 remote host port
288 Implementation: gstlal-ugly/gst/nds/ndssrc.c
295 return pipetools.make_element_with_src(pipeline,
None,
"ndssrc", blocksize=blocksize, port=port, host=host, channel_name=
"%s:%s" % (instrument, channel_name),
296 channel_type=channel_type)
300def audio_test(pipeline: pipetools.Pipeline, freq: float = 440, volume: float = 0.8, wave: int = AudioTestWaveform.Sine, samples_per_buffer: int = 1024,
301 **properties) -> pipetools.Element:
302 """AudioTestSrc can be used to generate basic audio signals. It support several different waveforms and
303 allows to set the base frequency and volume. Some waveforms might use additional properties.
307 Gst.Pipeline, the pipeline to which the new element will be added
309 float, Frequency of test signal. The sample rate needs to be at least 2 times higher.
311 float, default 0.8, Volume of test signal
313 int, default 0, the type of waveform to produce. Options are:
317 triangle (3) – Triangle
318 silence (4) – Silence
319 white-noise (5) – White uniform noise
320 pink-noise (6) – Pink noise
321 sine-table (7) – Sine table
322 ticks (8) – Periodic Ticks
323 gaussian-noise (9) – White Gaussian noise
324 red-noise (10) – Red (brownian) noise
325 blue-noise (11) – Blue noise
326 violet-noise (12) – Violet noise
328 int, default 1024, Number of samples in each outgoing buffer. Must be at least twice 'freq'
332 [1] https://gstreamer.freedesktop.org/documentation/audiotestsrc/index.html?gi-language=python
337 if 'samplesperbuffer' in properties:
338 samples_per_buffer = properties.pop(
'samplesperbuffer')
339 return pipetools.make_element_with_src(pipeline,
None,
"audiotestsrc", freq=freq, volume=volume, wave=wave,
340 samplesperbuffer=samples_per_buffer, **properties)
344def fake(pipeline: pipetools.Pipeline, instrument: str, channel_name: str, blocksize: int =
None, volume: float = 1e-20,
345 is_live: bool =
False, wave: int = AudioTestWaveform.GaussianNoise, rate: int = 16384, **properties) -> pipetools.Element:
346 """Create an audio_test source with several additional, lal-specific caps specified
350 Gst.Pipeline, the pipeline to which the new element will be added
352 str, name of instrument
354 str, name of input channel
356 int, default 1 second * rate samples/second * 8
358 float, default 1e-20, the sample volume
360 bool, default False, whether or not audio_test source will behave like live source
362 int, default 9 (Gaussian Noise), see AudioTestWaveform enum for options
364 int, default 16384, sample rate
370 if blocksize
is None:
373 blocksize = 1 * rate * 8
374 caps = filters.caps(pipeline,
375 audio_test(pipeline, samples_per_buffer=int(blocksize / 8), wave=wave,
376 volume=volume, is_live=is_live, **properties),
377 "audio/x-raw, format=F64%s, rate=%d" % (BYTE_ORDER, rate))
378 return transform.tag_inject(pipeline, caps,
"instrument=%s,channel-name=%s,units=strain" % (instrument, channel_name))
381def files(pipeline: pipetools.Pipeline, paths: Iterable[Union[str, pathlib.Path]], instrument: str, channel_name: str,
382 cache_path: Optional[Union[str, pathlib.Path]] =
None) -> pipetools.Element:
383 """Create a source from a list of file paths
387 Gst.Pipeline, the pipeline to which the new element will be added
389 Iterable[Path or str], the full paths to the frame files
391 Path or str, default None, the path to write out the cache file if specified, else write to temporary directory
394 This is a convenience utility around cache source and framecppdemux that creates a cache file
395 from a list of file paths
400 cache_path = laltools.create_cache(entries=paths, cache_path=cache_path)
401 src =
cache(pipeline, location=cache_path.as_posix())
403 demux = mux.framecpp_channel_demux(pipeline, src, do_file_checksum=
False, channel_list=[
"%s:%s" % (instrument, channel_name)])
407 src = transform.queue(pipeline,
None, max_size_buffers=0, max_size_bytes=0, max_size_time=8 * pipetools.Gst.SECOND)
408 SrcDeferredLink(demux,
"%s:%s" % (instrument, channel_name), src.get_static_pad(
"sink"))
no_more_pads(element, srcpadname)
pad_added(element, pad, src_sink_ids)
pipetools.Element devshm(pipetools.Pipeline pipeline, str shm_dirname, **properties)
pipetools.Element cache(pipetools.Pipeline pipeline, str location, bool use_mmap=True, **properties)
Adds a lal_cachesrc element to a pipeline with useful default properties.
pipetools.Element nds(pipetools.Pipeline pipeline, str host, str instrument, str channel_name, str channel_type, int blocksize=16384 *8 *1, int port=31200)
pipetools.Element fake(pipetools.Pipeline pipeline, str instrument, str channel_name, int blocksize=None, float volume=1e-20, bool is_live=False, int wave=AudioTestWaveform.GaussianNoise, int rate=16384, **properties)
see documentation for mktaginject() mkcapsfilter() and mkaudiotestsrc()
pipetools.Element fake_avirgo(pipetools.Pipeline pipeline, str instrument=None, str channel_name=None, int blocksize=16384 *8 *1)
pipetools.Element segment(pipetools.Pipeline pipeline, List[Tuple[pipetools.TimeGPS, pipetools.TimeGPS]] segment_list, int blocksize=4096 *1 *1, bool invert_output=False)
Adds a lal_segmentsrc element to a pipeline with useful default properties.
pipetools.Element fake_ligo(pipetools.Pipeline pipeline, str instrument=None, str channel_name=None, int blocksize=16384 *8 *1)
pipetools.Element fake_aligo(pipetools.Pipeline pipeline, str instrument=None, str channel_name=None, int blocksize=16384 *8 *1)
pipetools.Element framexmit(pipetools.Pipeline pipeline, str multicast_group='0.0.0.0', int port=0, **properties)
pipetools.Element files(pipetools.Pipeline pipeline, Iterable[Union[str, pathlib.Path]] paths, str instrument, str channel_name, Optional[Union[str, pathlib.Path]] cache_path=None)
pipetools.Element audio_test(pipetools.Pipeline pipeline, float freq=440, float volume=0.8, int wave=AudioTestWaveform.Sine, int samples_per_buffer=1024, **properties)
Adds a audiotestsrc element to a pipeline with useful default properties.
pipetools.Element lvshm(pipetools.Pipeline pipeline, str shm_name, **properties)