LALFrame 3.0.8.1-bf6a62b
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;
140 LIGOTimeGPS end;
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 */
158 end = start;
159 XLALGPSAdd(&end, dt);
160 } else { /* use end of input stream */
161 int mode = XLALFrStreamGetMode(stream);
162 /* we're seeking to the end, so don't complain! */
163 XLALFrStreamSetMode(stream,
166 XLALFrStreamSeekO(stream, 0, SEEK_END);
167 XLALFrStreamTell(&end, stream);
168 XLALFrStreamSetMode(stream, mode);
169 }
170
171 XLALFrStreamSeek(stream, &start);
172
174 switch (type) {
175 case LAL_I2_TYPE_CODE:
176 output_INT2(stream, channel, &start, &end);
177 break;
178 case LAL_I4_TYPE_CODE:
179 output_INT4(stream, channel, &start, &end);
180 break;
181 case LAL_I8_TYPE_CODE:
182 output_INT8(stream, channel, &start, &end);
183 break;
184 case LAL_U2_TYPE_CODE:
185 output_UINT2(stream, channel, &start, &end);
186 break;
187 case LAL_U4_TYPE_CODE:
188 output_UINT4(stream, channel, &start, &end);
189 break;
190 case LAL_U8_TYPE_CODE:
191 output_UINT8(stream, channel, &start, &end);
192 break;
193 case LAL_S_TYPE_CODE:
194 output_REAL4(stream, channel, &start, &end);
195 break;
196 case LAL_D_TYPE_CODE:
197 output_REAL8(stream, channel, &start, &end);
198 break;
199 case LAL_C_TYPE_CODE:
200 output_COMPLEX8(stream, channel, &start, &end);
201 break;
202 case LAL_Z_TYPE_CODE:
203 output_COMPLEX16(stream, channel, &start, &end);
204 break;
205 default:
206 fprintf(stderr, "unsupported channel type\n");
207 return 1;
208 }
209
210 XLALFrStreamClose(stream);
211 return 0;
212}
213
214int parseargs(int argc, char **argv)
215{
216 struct LALoption long_options[] = {
217 {"help", no_argument, 0, 'h'},
218 {"channel", required_argument, 0, 'c'},
219 {"frame-cache", required_argument, 0, 'f'},
220 {"frame-glob", required_argument, 0, 'g'},
221 {"start-time", required_argument, 0, 's'},
222 {"duration", required_argument, 0, 't'},
223 {0, 0, 0, 0}
224 };
225 char args[] = "hc:f:g:s:t:";
226 while (1) {
227 int option_index = 0;
228 int c;
229
230 c = LALgetopt_long_only(argc, argv, args, long_options, &option_index);
231 if (c == -1) /* end of options */
232 break;
233
234 switch (c) {
235 case 0: /* if option set a flag, nothing else to do */
236 if (long_options[option_index].flag)
237 break;
238 else {
239 fprintf(stderr, "error parsing option %s with argument %s\n",
240 long_options[option_index].name, LALoptarg);
241 exit(1);
242 }
243 case 'h': /* help */
244 usage(argv[0]);
245 exit(0);
246 case 'c': /* channel */
248 break;
249 case 'f': /* frame-cache */
251 break;
252 case 'g': /* frame-cache */
254 break;
255 case 's': /* start-time */
256 t0 = atof(LALoptarg);
257 break;
258 case 't': /* duration */
259 dt = atof(LALoptarg);
260 break;
261 case '?':
262 default:
263 fprintf(stderr, "unknown error while parsing options\n");
264 exit(1);
265 }
266 }
267
268 if (LALoptind < argc) {
269 fprintf(stderr, "extraneous command line arguments:\n");
270 while (LALoptind < argc)
271 fprintf(stderr, "%s\n", argv[LALoptind++]);
272 exit(1);
273 }
274
275 /* sanity check parameters */
276
277 if (!channel) {
278 fprintf(stderr, "must specify a channel\n");
279 usage(argv[0]);
280 exit(1);
281 }
282 if (!cache) {
283 fprintf(stderr, "must specify a frame cache or frame files\n");
284 usage(argv[0]);
285 exit(1);
286 }
287
288 return 0;
289}
290
291int usage(const char *program)
292{
293 fprintf(stderr, "usage: %s [options]\n", program);
294 fprintf(stderr, "options:\n");
295 fprintf(stderr, "\t-h, --help \tprint this message and exit\n");
296 fprintf(stderr, "\t-c, CHAN --channel=CHAN \tchannel name CHAN\n");
297 fprintf(stderr, "\t-f CACHE, --frame-cache=CACHE\tframe cache file CACHE\n");
298 fprintf(stderr, "\t-g GLOB, --frame-glob=GLOB \tframe file glob string GLOB\n");
299 fprintf(stderr, "\t-s T0, --start-time=T0 \tGPS start time T0 (s)\n");
300 fprintf(stderr, "\t-t DT, --duration=DT \tduration DT (s)\n");
301 return 0;
302}
303
304#define DEFINE_OUTPUT_FUNCTION(laltype, format, ...) \
305void output_ ## laltype (LALFrStream *stream, const char *channame, LIGOTimeGPS *start, LIGOTimeGPS *end) \
306{ \
307 laltype ## TimeSeries *series; \
308 /* create zero-length time series */ \
309 series = XLALCreate ## laltype ## TimeSeries(channame, start, 0.0, 0.0, &lalDimensionlessUnit, 0); \
310 /* get metadata including time of next sample and sample interval */ \
311 XLALFrStreamGet ## laltype ## TimeSeries(series, stream); \
312 while (XLALGPSCmp(&series->epoch, end) < 0) { \
313 double remaining; \
314 size_t length; \
315 size_t i; \
316 remaining = XLALGPSDiff(end, &series->epoch); \
317 remaining = (remaining > MAXDUR ? MAXDUR : remaining); \
318 length = (size_t)ceil(remaining / series->deltaT); \
319 length = (length > MAXLEN ? MAXLEN : length); \
320 if (series->data->length != length) \
321 XLALResize ## laltype ## TimeSeries(series, 0, length); \
322 XLALFrStreamGet ## laltype ## TimeSeries(series, stream); \
323 for (i = 0; i < series->data->length; ++i) { \
324 char tstr[32]; \
325 laltype value = series->data->data[i]; \
326 LIGOTimeGPS t = series->epoch; \
327 XLALGPSAdd(&t, i * series->deltaT); \
328 fprintf(stdout, "%s", XLALGPSToStr(tstr, &t)); \
329 fputs(FS, stdout); \
330 fprintf(stdout, format, __VA_ARGS__); \
331 fputs(RS, stdout); \
332 } \
333 XLALFrStreamTell(&series->epoch, stream); \
334 } \
335 XLALDestroy ## laltype ## TimeSeries(series); \
336}
337
338/* *INDENT-OFF* */
339DEFINE_OUTPUT_FUNCTION(INT2, "%" LAL_INT2_PRId, value)
340DEFINE_OUTPUT_FUNCTION(INT4, "%" LAL_INT4_PRId, value)
341DEFINE_OUTPUT_FUNCTION(INT8, "%" LAL_INT8_PRId, value)
342DEFINE_OUTPUT_FUNCTION(UINT2, "%" LAL_INT2_PRIu, value)
343DEFINE_OUTPUT_FUNCTION(UINT4, "%" LAL_INT4_PRIu, value)
344DEFINE_OUTPUT_FUNCTION(UINT8, "%" LAL_INT8_PRIu, value)
345DEFINE_OUTPUT_FUNCTION(REAL4, "%.7g", value)
346DEFINE_OUTPUT_FUNCTION(REAL8, "%.15g", value)
347DEFINE_OUTPUT_FUNCTION(COMPLEX8, "(%.7g,%.7g)", crealf(value), cimagf(value))
348DEFINE_OUTPUT_FUNCTION(COMPLEX16, "(%.15g,%.15g)", creal(value), cimag(value))
349/* *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)
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
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:291
#define DEFINE_OUTPUT_FUNCTION(laltype, format,...)
Definition: stream.c:304
int parseargs(int argc, char **argv)
Definition: stream.c:214
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