Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALFrame 3.0.7.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
stream.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2013 Jolien Creighton
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20/**
21 * @defgroup lalfr_stream lalfr-stream
22 * @ingroup lalframe_programs
23 *
24 * @brief Output a frame data stream
25 *
26 * ### Synopsis
27 *
28 * lalfr-stream --channel=channel --frame-cache=cachefile [--start-time=tstart] [--duration=deltat]
29 *
30 * lalfr-stream --channel=channel --frame-glob=globstring [--start-time=tstart] [--duration=deltat]
31 *
32 * ### Description
33 *
34 * The `lalfr-stream` utility reads a requested interval
35 * [`tstart`,`tstart+deltat`) of `channel` data from frame files that are
36 * either indexed in the `cachefile` or matching the pattern `globstring` as
37 * described by `glob(3)`. If `tstart` is not specified, streaming begins at
38 * the beginning of the available data. If `deltat` is not specified,
39 * streaming continues until the end of the available data. The output is
40 * written to the standard output in two-column ascii format data in which the
41 * first column contains the GPS times of each sample and the second column
42 * contains the corresponding sample values.
43 *
44 * ### Options
45 *
46 * <DL>
47 * <DT>`-h`, `--help`</DT>
48 * <DD>Prints the help message.</DD>
49 * <DT>`-c channel`, `--channel=channel`</DT>
50 * <DD>The channel name that is to be read.</DD>
51 * <DT>`-f cachefile`, `--frame-cache=cachefile`</DT>
52 * <DD>The cachefile indexing the frame files to be used.</DD>
53 * <DT>`-g globstring `, `--frame-glob=globstring`</DT>
54 * <DD>The globstring identifying the frame files to be used.</DD>
55 * <DT>`-s tstart`, `--start-time=tstart`</DT>
56 * <DD>The time `tstart` GPS seconds of the data to read.</DD>
57 * <DT>`-t deltat`, `--duration=deltat`</DT>
58 * <DD>The duration `deltat` in seconds of data to read.</DD>
59 * </DL>
60 *
61 * ### Environment
62 *
63 * The `LAL_DEBUG_LEVEL` can used to control the error and warning reporting of
64 * `lalfr-stream`. Common values are: `LAL_DEBUG_LEVEL=0` which suppresses
65 * error messages, `LAL_DEBUG_LEVEL=1` which prints error messages alone,
66 * `LAL_DEBUG_LEVEL=3` which prints both error messages and warning messages,
67 * and `LAL_DEBUG_LEVEL=7` which additionally prints informational messages.
68 *
69 *
70 * ### Exit Status
71 *
72 * The `lalfr-stream` utility exits 0 on success, and >0 if an error occurs.
73 *
74 * ### Examples
75 *
76 * The command:
77 *
78 * lalfr-stream -c H1:LSC-STRAIN -g "H-*.gwf" -s 1000000000 -t 1000
79 *
80 * will stream 1000 seconds of `H1:LSC-STRAIN` data beginning at GPS time
81 * 1000000000 from frame files matching `H-*.gwf` in the current directory.
82 *
83 * @sa @ref lalfr_vis
84 */
85
86
87#include <math.h>
88#include <stdio.h>
89#include <stdlib.h>
90#include <string.h>
91
92
93#include <lal/Date.h>
94#include <lal/LALgetopt.h>
95#include <lal/LALStdlib.h>
96#include <lal/LALString.h>
97#include <lal/TimeSeries.h>
98#include <lal/LALFrStream.h>
99#include <lal/Units.h>
100
101#define FS "\t" /* field separator */
102#define RS "\n" /* record separator */
103#define MAXDUR 16.0 /* max segment duration (s) */
104#define MAXLEN 16384 /* max number of points in buffer */
105
106/* globals */
109double t0;
110double dt;
111
112int usage(const char *program);
113int parseargs(int argc, char **argv);
114void output_INT2(LALFrStream * stream, const char *channame,
115 LIGOTimeGPS * start, LIGOTimeGPS * end);
116void output_INT4(LALFrStream * stream, const char *channame,
117 LIGOTimeGPS * start, LIGOTimeGPS * end);
118void output_INT8(LALFrStream * stream, const char *channame,
119 LIGOTimeGPS * start, LIGOTimeGPS * end);
120void output_UINT2(LALFrStream * stream, const char *channame,
121 LIGOTimeGPS * start, LIGOTimeGPS * end);
122void output_UINT4(LALFrStream * stream, const char *channame,
123 LIGOTimeGPS * start, LIGOTimeGPS * end);
124void output_UINT8(LALFrStream * stream, const char *channame,
125 LIGOTimeGPS * start, LIGOTimeGPS * end);
126void output_REAL4(LALFrStream * stream, const char *channame,
127 LIGOTimeGPS * start, LIGOTimeGPS * end);
128void output_REAL8(LALFrStream * stream, const char *channame,
129 LIGOTimeGPS * start, LIGOTimeGPS * end);
130void output_COMPLEX8(LALFrStream * stream, const char *channame,
131 LIGOTimeGPS * start, LIGOTimeGPS * end);
132void output_COMPLEX16(LALFrStream * stream, const char *channame,
133 LIGOTimeGPS * start, LIGOTimeGPS * end);
134
135int main(int argc, char *argv[])
136{
137 LALFrStream *stream;
138 LALTYPECODE type;
139 LIGOTimeGPS start;
141
143
144 parseargs(argc, argv);
145
147
148 /* determine the start of the output stream */
149 if (t0 > 0.0) /* use value provide by user */
150 XLALGPSSetREAL8(&start, t0);
151 else { /* use start of input stream */
152 XLALFrStreamTell(&start, stream);
153 t0 = XLALGPSGetREAL8(&start);
154 }
155
156 /* determine the end of the output stream */
157 if (dt > 0.0) /* use value provide by user */
159 else { /* use end of input stream */
160 int mode = XLALFrStreamGetMode(stream);
161 /* we're seeking to the end, so don't complain! */
162 XLALFrStreamSetMode(stream,
165 XLALFrStreamSeekO(stream, 0, SEEK_END);
166 XLALFrStreamTell(&end, stream);
167 XLALFrStreamSetMode(stream, mode);
168 }
169
170 XLALFrStreamSeek(stream, &start);
171
173 switch (type) {
174 case LAL_I2_TYPE_CODE:
175 output_INT2(stream, channel, &start, &end);
176 break;
177 case LAL_I4_TYPE_CODE:
178 output_INT4(stream, channel, &start, &end);
179 break;
180 case LAL_I8_TYPE_CODE:
181 output_INT8(stream, channel, &start, &end);
182 break;
183 case LAL_U2_TYPE_CODE:
184 output_UINT2(stream, channel, &start, &end);
185 break;
186 case LAL_U4_TYPE_CODE:
187 output_UINT4(stream, channel, &start, &end);
188 break;
189 case LAL_U8_TYPE_CODE:
190 output_UINT8(stream, channel, &start, &end);
191 break;
192 case LAL_S_TYPE_CODE:
193 output_REAL4(stream, channel, &start, &end);
194 break;
195 case LAL_D_TYPE_CODE:
196 output_REAL8(stream, channel, &start, &end);
197 break;
198 case LAL_C_TYPE_CODE:
199 output_COMPLEX8(stream, channel, &start, &end);
200 break;
201 case LAL_Z_TYPE_CODE:
202 output_COMPLEX16(stream, channel, &start, &end);
203 break;
204 default:
205 fprintf(stderr, "unsupported channel type\n");
206 return 1;
207 }
208
209 XLALFrStreamClose(stream);
210 return 0;
211}
212
213int parseargs(int argc, char **argv)
214{
215 struct LALoption long_options[] = {
216 {"help", no_argument, 0, 'h'},
217 {"channel", required_argument, 0, 'c'},
218 {"frame-cache", required_argument, 0, 'f'},
219 {"frame-glob", required_argument, 0, 'g'},
220 {"start-time", required_argument, 0, 's'},
221 {"duration", required_argument, 0, 't'},
222 {0, 0, 0, 0}
223 };
224 char args[] = "hc:f:g:s:t:";
225 while (1) {
226 int option_index = 0;
227 int c;
228
229 c = LALgetopt_long_only(argc, argv, args, long_options, &option_index);
230 if (c == -1) /* end of options */
231 break;
232
233 switch (c) {
234 case 0: /* if option set a flag, nothing else to do */
235 if (long_options[option_index].flag)
236 break;
237 else {
238 fprintf(stderr, "error parsing option %s with argument %s\n",
239 long_options[option_index].name, LALoptarg);
240 exit(1);
241 }
242 case 'h': /* help */
243 usage(argv[0]);
244 exit(0);
245 case 'c': /* channel */
247 break;
248 case 'f': /* frame-cache */
250 break;
251 case 'g': /* frame-cache */
253 break;
254 case 's': /* start-time */
255 t0 = atof(LALoptarg);
256 break;
257 case 't': /* duration */
258 dt = atof(LALoptarg);
259 break;
260 case '?':
261 default:
262 fprintf(stderr, "unknown error while parsing options\n");
263 exit(1);
264 }
265 }
266
267 if (LALoptind < argc) {
268 fprintf(stderr, "extraneous command line arguments:\n");
269 while (LALoptind < argc)
270 fprintf(stderr, "%s\n", argv[LALoptind++]);
271 exit(1);
272 }
273
274 /* sanity check parameters */
275
276 if (!channel) {
277 fprintf(stderr, "must specify a channel\n");
278 usage(argv[0]);
279 exit(1);
280 }
281 if (!cache) {
282 fprintf(stderr, "must specify a frame cache or frame files\n");
283 usage(argv[0]);
284 exit(1);
285 }
286
287 return 0;
288}
289
290int usage(const char *program)
291{
292 fprintf(stderr, "usage: %s [options]\n", program);
293 fprintf(stderr, "options:\n");
294 fprintf(stderr, "\t-h, --help \tprint this message and exit\n");
295 fprintf(stderr, "\t-c, CHAN --channel=CHAN \tchannel name CHAN\n");
296 fprintf(stderr, "\t-f CACHE, --frame-cache=CACHE\tframe cache file CACHE\n");
297 fprintf(stderr, "\t-g GLOB, --frame-glob=GLOB \tframe file glob string GLOB\n");
298 fprintf(stderr, "\t-s T0, --start-time=T0 \tGPS start time T0 (s)\n");
299 fprintf(stderr, "\t-t DT, --duration=DT \tduration DT (s)\n");
300 return 0;
301}
302
303#define DEFINE_OUTPUT_FUNCTION(laltype, format, ...) \
304void output_ ## laltype (LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end) \
305{ \
306 double remaining; \
307 laltype ## TimeSeries *series; \
308 /* create zero-length time series */ \
309 series = XLALCreate ## laltype ## TimeSeries(channame, start, 0.0, 0.0, &lalDimensionlessUnit, 0); \
310 XLALFrStreamGet ## laltype ## TimeSeriesMetadata(series, stream); \
311 while ((remaining = XLALGPSDiff(end, start)) > series->deltaT) { \
312 size_t length; \
313 size_t i; \
314 remaining = (remaining > MAXDUR ? MAXDUR : remaining); \
315 length = (size_t)floor(remaining / series->deltaT); \
316 length = (length > MAXLEN ? MAXLEN : length); \
317 if (series->data->length != length) \
318 XLALResize ## laltype ## TimeSeries(series, 0, length); \
319 XLALFrStreamGet ## laltype ## TimeSeries(series, stream); \
320 for (i = 0; i < series->data->length; ++i) { \
321 char tstr[32]; \
322 laltype value = series->data->data[i]; \
323 LIGOTimeGPS t = series->epoch; \
324 XLALGPSAdd(&t, i * series->deltaT); \
325 fprintf(stdout, "%s", XLALGPSToStr(tstr, &t)); \
326 fputs(FS, stdout); \
327 fprintf(stdout, format, __VA_ARGS__); \
328 fputs(RS, stdout); \
329 } \
330 XLALGPSAdd(start, series->data->length * series->deltaT); \
331 } \
332 XLALDestroy ## laltype ## TimeSeries(series); \
333}
334
335/* *INDENT-OFF* */
336DEFINE_OUTPUT_FUNCTION(INT2, "%" LAL_INT2_PRId, value)
337DEFINE_OUTPUT_FUNCTION(INT4, "%" LAL_INT4_PRId, value)
338DEFINE_OUTPUT_FUNCTION(INT8, "%" LAL_INT8_PRId, value)
339DEFINE_OUTPUT_FUNCTION(UINT2, "%" LAL_INT2_PRIu, value)
340DEFINE_OUTPUT_FUNCTION(UINT4, "%" LAL_INT4_PRIu, value)
341DEFINE_OUTPUT_FUNCTION(UINT8, "%" LAL_INT8_PRIu, value)
342DEFINE_OUTPUT_FUNCTION(REAL4, "%.7g", value)
343DEFINE_OUTPUT_FUNCTION(REAL8, "%.15g", value)
344DEFINE_OUTPUT_FUNCTION(COMPLEX8, "(%.7g,%.7g)", crealf(value), cimagf(value))
345DEFINE_OUTPUT_FUNCTION(COMPLEX16, "(%.15g,%.15g)", creal(value), cimag(value))
346/* *INDENT-ON* */
const char * program
int LALgetopt_long_only(int argc, char *const *argv, const char *options, const struct LALoption *long_options, int *opt_index)
int LALoptind
char * LALoptarg
#define no_argument
#define required_argument
#define fprintf
LALCache * XLALCacheGlob(const char *dirstr, const char *fnptrn)
LALCache * XLALCacheImport(const char *fname)
LALTYPECODE
uint64_t UINT8
double complex COMPLEX16
double REAL8
int16_t INT2
int64_t INT8
uint16_t UINT2
uint32_t UINT4
float complex COMPLEX8
int32_t INT4
float REAL4
LAL_C_TYPE_CODE
LAL_U2_TYPE_CODE
LAL_Z_TYPE_CODE
LAL_S_TYPE_CODE
LAL_I2_TYPE_CODE
LAL_I8_TYPE_CODE
LAL_D_TYPE_CODE
LAL_I4_TYPE_CODE
LAL_U8_TYPE_CODE
LAL_U4_TYPE_CODE
int XLALFrStreamSeek(LALFrStream *stream, const LIGOTimeGPS *epoch)
Seeks a LALFrStream stream to data at a given time.
Definition: LALFrStream.c:542
int XLALFrStreamSeekO(LALFrStream *stream, double dt, int whence)
Seeks a LALFrStream stream by a time offset.
Definition: LALFrStream.c:676
int XLALFrStreamTell(LIGOTimeGPS *epoch, LALFrStream *stream)
Tells the current time of the current position of a LALFrStream stream.
Definition: LALFrStream.c:717
int XLALFrStreamClose(LALFrStream *stream)
Closes a LALFrStream.
Definition: LALFrStream.c:170
int XLALFrStreamGetMode(LALFrStream *stream)
Returns the current operating mode of a LALFrStream.
Definition: LALFrStream.c:284
LALFrStream * XLALFrStreamCacheOpen(LALCache *cache)
Opens a LALFrStream associated with a LALCache.
Definition: LALFrStream.c:189
int XLALFrStreamSetMode(LALFrStream *stream, int mode)
Change the operating mode of a LALFrStream.
Definition: LALFrStream.c:327
@ LAL_FR_STREAM_TIMEWARN_MODE
display warning for invalid time requests
Definition: LALFrStream.h:82
@ LAL_FR_STREAM_IGNORETIME_MODE
ignore invalid times requested
Definition: LALFrStream.h:86
LALTYPECODE XLALFrStreamGetTimeSeriesType(const char *chname, LALFrStream *stream)
Returns the type code for the data type of channel chname in the current frame in frame stream stream...
char char * XLALStringDuplicate(const char *s)
void XLALAbortErrorHandler(const char *func, const char *file, int line, int errnum)
XLALErrorHandlerType * XLALSetErrorHandler(XLALErrorHandlerType *newHandler)
LIGOTimeGPS * XLALGPSSetREAL8(LIGOTimeGPS *epoch, REAL8 t)
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
end
void output_INT2(LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end)
double dt
Definition: stream.c:110
int main(int argc, char *argv[])
Definition: stream.c:135
LALCache * cache
Definition: stream.c:107
double t0
Definition: stream.c:109
int usage(const char *program)
Definition: stream.c:290
#define DEFINE_OUTPUT_FUNCTION(laltype, format,...)
Definition: stream.c:303
int parseargs(int argc, char **argv)
Definition: stream.c:213
void output_UINT2(LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end)
void output_UINT8(LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end)
void output_REAL8(LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end)
void output_COMPLEX16(LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end)
void output_COMPLEX8(LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end)
char * channel
Definition: stream.c:108
void output_REAL4(LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end)
void output_UINT4(LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end)
void output_INT4(LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end)
void output_INT8(LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end)
This structure details the state of the frame stream.
Definition: LALFrStream.h:95
const char * name
int * flag