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
vis.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_vis lalfr-vis
22 * @ingroup lalframe_programs
23 *
24 * @brief Visualize frame data
25 *
26 * ### Synopsis
27 *
28 * lalfr-vis --channel=channel --frame-cache=cachefile --start-time=tstart --duration=deltat [--output=outfile] [--highpass=minfreq] [--lowpass=maxfreq] [--pad=padding] [--resample=srate] [--spectrum=resolution]
29 *
30 * lalfr-vis --channel=channel --frame-glob=globstring --start-time=tstart --duration=deltat [--output=outfile] [--highpass=minfreq] [--lowpass=maxfreq] [--pad=padding] [--resample=srate] [--spectrum=resolution]
31 *
32 *
33 * ### Description
34 *
35 * The `lalfr-vis` utility reads a requested interval
36 * [`tstart`,`tstart+deltat`) of `channel` data from frame files that are
37 * either indexed in the `cachefile` or matching the pattern `globstring` as
38 * described by `glob(3)`. The output is written to `outfile` and the format
39 * of the output is deter- mined by extension of `outfile` as described below.
40 * If `outfile` is not specified, the output is written to the standard output
41 * in two-column ascii format data.
42 *
43 * The `lalfr-vis` can optionally perform certain manipulations of the data
44 * that is read, including:
45 *
46 * * High-pass filtering of the data.
47 * * Low-pass filtering of the data.
48 * * Resampling of the data.
49 * * Computing the power spectrum of the data.
50 *
51 * If any of the filtering or resampling operations are performed, it is
52 * recommended additional `padding` is used. This additional data, before and
53 * after the requested interval, will be discarded before output (or before
54 * computing the power spectrum) which will remove filter transients. Note
55 * that data will be read for the entire interval
56 * [`tstart-padding`,`tstart+deltat+padding`) and must be available.
57 *
58 *
59 * ### Options
60 *
61 * <DL>
62 * <DT>`-h`, `--help`</DT>
63 * <DD>Prints the help message.</DD>
64 * <DT>`-c channel`, `--channel=channel`</DT>
65 * <DD>The channel name that is to be read.</DD>
66 * <DT>`-f cachefile`, `--frame-cache=cachefile`</DT>
67 * <DD>The cachefile indexing the frame files to be used.</DD>
68 * <DT>`-g globstring `, `--frame-glob=globstring`</DT>
69 * <DD>The globstring identifying the frame files to be used.</DD>
70 * <DT>`-o outfile`, `--output=outfile`</DT>
71 * <DD>The `outfile` to use. The extension of `outfile` is used to determine
72 * the format of the output. The output formats are described below. </DD>
73 * <DT>`-s tstart`, `--start-time=tstart`</DT>
74 * <DD>The time `tstart` GPS seconds of the data to read. If padding is
75 * specified with the `-P` option or the `--pad` option, an additional amount
76 * of data preceding `tstart` is also read, and discarded after any requested
77 * filtering of the data is complete.</DD>
78 * <DT>`-t deltat`, `--duration=deltat`</DT>
79 * <DD>The duration `deltat` in seconds of data to read. If padding is
80 * specified with the `-P` option or the `--pad` option, an additional amount
81 * of data is also read, and discarded after any requested filtering of the
82 * data is complete.</DD>
83 * <DT>`-H minfreq`, `--highpass=minfreq`</DT>
84 * <DD>High-pass filter the data at `minfreq` Hertz. An additional amount of
85 * data, which will be discarded after the filtering, should be specified with
86 * the `-P` option or the `--pad` option to remove filter transients.</DD>
87 * <DT>`-L maxfreq`, `--lowpass=maxfreq`</DT>
88 * <DD>Low-pass filter the data at `maxfreq` Hertz. An additional amount of
89 * data, which will be discarded after the filtering, should be specified with
90 * the `-P` option or the `--pad` option to remove filter transients.</DD>
91 * <DT>`-P padding`, `--pad=padding`</DT>
92 * <DD>Read padding additional seconds of data before and after the requested
93 * interval. This data is then dropped after all requested filtering has been
94 * performed in order to remove filter transients.</DD>
95 * <DT>`-R srate`, `--resample=srate`</DT>
96 * <DD>Resample the data to sampling rate `srate` Hertz. An additional amount
97 * of data, which will be discarded after the filtering, should be specified
98 * with the `-P` option or the `--pad` option to remove filter transients.</DD>
99 * <DT>`-S resolution`, `--spectrum=resolution`</DT>
100 * <DD>Compute the power spectrum of the data at the requested `resolution` in
101 * Hertz. Depending on the output format, either the amplitude spectral
102 * density or the power spectral density is output.</DD>
103 * </DL>
104 *
105 * ### Output Formats
106 *
107 * If the -o or --output option is used to specify an output file, the
108 * extension of that file is used to determine the output format. Supported
109 * output formats include:
110 * <DL>
111 * <DT>`.au`</DT>
112 * <DD>Au audio file format. This format is for time-series data only and may
113 * not be used if the `-S` or the `--spectrum` option is used.</DD>
114 * <DT>`.eps`</DT>
115 * <DD>Encapsulated PostScript (EPS) graphical file format. A plot of the data
116 * values as a function of time is produced using the `gnuplot(1)` program, if
117 * available. If the `-S` or the `--spectrum` option is used, a log-log plot
118 * of the amplitude spectrum is produced instead.</DD>
119 * <DT>`.gif`</DT>
120 * <DD>Graphics Interchange Format (GIF) graphical file format. A plot of the
121 * data values as a function of time is produced using the `gnuplot(1)`
122 * program, if available. If the `-S` or the `--spectrum` option is used, a
123 * log-log plot of the amplitude spectrum is produced instead.</DD>
124 * <DT>`.jpg`</DT>
125 * <DD>JPEG graphical file format. A plot of the data values as a function of
126 * time is produced using the `gnuplot(1)` program, if available. If the `-S`
127 * or the `--spectrum` option is used, a log-log plot of the amplitude spectrum
128 * is produced instead.</DD>
129 * <DT>`.pdf`</DT>
130 * <DD>Portable Document Format (PDF) graphical file format. A plot of the
131 * data values as a function of time is produced using the `gnuplot(1)`
132 * program, if available. If the `-S` or the `--spectrum` option is used, a
133 * log-log plot of the amplitude spectrum is produced instead.</DD>
134 * <DT>`.png`</DT>
135 * <DD>Portable Network Graphics (PNG) graphical file format. A plot of the
136 * data values as a function of time is produced using the `gnuplot(1)`
137 * program, if available. If the `-S` or the `--spectrum` option is used, a
138 * log-log plot of the amplitude spectrum is produced instead.</DD>
139 * <DT>`.ps`</DT>
140 * <DD>PostScript (PS) graphical file format. A plot of the data values as a
141 * function of time is produced using the `gnuplot(1)` program, if available.
142 * If the `-S` or the `--spectrum` option is used, a log-log plot of the
143 * amplitude spectrum is produced instead.</DD>
144 * <DT>`.svg`</DT>
145 * <DD>Scalable Vector Graphics (SVG) graphical file format. A plot of the
146 * data values as a function of time is produced using the `gnuplot(1)`
147 * program, if available. If the `-S` or the `--spectrum` optione used, a
148 * log-log plot of the amplitude spectrum is produced instead.</DD>
149 * <DT>`.wav`</DT>
150 * <DD>Waveform Audio File Format (WAVE) audio file format. This format is for
151 * time-series data only and may not be used if the `-S` or the `--spectrum`
152 * option is used.</DD>
153 * <DT>`.xml`</DT>
154 * <DD>XML-based LIGO-lightweight (LIGOLw) file format. If the `-S` or the
155 * `--spectrum` option is used, the power spectral density data is written to
156 * the file.</DD>
157 * </DL>
158 *
159 * If none of these extensions are used then the output will be in two-column
160 * ascii format. The first column will be the GPS time of each sample of data
161 * and the second column will be the sample values. However, if the `-S` or
162 * the `--spectrum` option is used, the first column will be the frequency of
163 * each sample of the spectrum and the second column will be the value of the
164 * power spectral density at that frequency.
165 *
166 *
167 * ### Environment
168 *
169 * The `LAL_DEBUG_LEVEL` can used to control the error and warning reporting of
170 * `lalfr-vis`. Common values are: `LAL_DEBUG_LEVEL=0` which suppresses error
171 * messages, `LAL_DEBUG_LEVEL=1` which prints error messages alone,
172 * `LAL_DEBUG_LEVEL=3` which prints both error messages and warning messages,
173 * and `LAL_DEBUG_LEVEL=7` which additionally prints informational messages.
174 *
175 *
176 * ### Exit Status
177 *
178 * The `lalfr-vis` utility exits 0 on success, and >0 if an error occurs.
179 *
180 * ### Examples
181 *
182 * The command:
183 *
184 * lalfr-vis -c H1:LSC-STRAIN -g "H-*.gwf" -s 1000000000 -t 16 -o out.wav
185 *
186 * will read 16 seconds beginning at GPS time 1000000000 of `H1:LSC-STRAIN`
187 * data from frame files matching `H-*.gwf` in the current directory and output
188 * the data as a WAVE audio file `out.wav`.
189 *
190 * The command:
191 *
192 * lalfr-vis -c L1:LSC-STRAIN -f LLO.cache -s 1000000001 -t 64 -R 2048 -H 10 -L 1000 -P 1 -S 0.25 -o out.png
193 *
194 * will read 66 seconds beginning at GPS time 1000000000 of `L1:LSC-STRAIN`
195 * data from frame files indexed in `LLO.cache`, and the following
196 * manipulations will be performed: the data will be resampled to a sampling
197 * rate of 2048 Hz, the data will be high-pass filtered at 10 Hz, the data will
198 * be low-pass filtered at 1000 Hz, the first and last 1 second of data will be
199 * dropped (to remove filter transients), a power spectrum will be computed
200 * with 0.25 Hz resolution, and a PNG file displaying a log-log plot of the
201 * amplitude spectral density will output in file `out.pnd`.
202 *
203 * @sa lalfr_stream
204 */
205
206#include <math.h>
207#include <stdio.h>
208#include <stdlib.h>
209#include <string.h>
210
211
212#include <lal/LALStdlib.h>
213#include <lal/LALgetopt.h>
214#include <lal/LALString.h>
215#include <lal/Date.h>
216#include <lal/FrequencySeries.h>
217#include <lal/TimeSeries.h>
218#include <lal/BandPassTimeSeries.h>
219#include <lal/ResampleTimeSeries.h>
220#include <lal/Window.h>
221#include <lal/TimeFreqFFT.h>
222#include <lal/Audio.h>
223#include <lal/LALFrStream.h>
224#include <lal/Units.h>
225
226#define FS "\t" /* field separator */
227#define RS "\n" /* record separator */
228#define MAXDUR 16.0 /* max segment duration (s) */
229#define MAXLEN 16384 /* max number of points in buffer */
230
231/* globals */
235double minfreq;
236double maxfreq;
237double srate;
238double pad;
239double df;
240double t0;
241double dt;
242
243int usage(const char *program);
244int parseargs(int argc, char **argv);
245void output_ts(const char *fname, REAL8TimeSeries *series);
246void gnuplot_output_ts(const char *fname, const char *fmt, REAL8TimeSeries *series);
247void output_fs(const char *fname, REAL8FrequencySeries *series);
248void gnuplot_output_fs(const char *fname, const char *fmt, REAL8FrequencySeries *series);
249
250void xml_output_ts(const char *fname, REAL8TimeSeries *series);
251void xml_output_fs(const char *fname, REAL8FrequencySeries *series);
252
253int main(int argc, char *argv[])
254{
255 LALFrStream *stream;
256 REAL8TimeSeries *series;
257 LIGOTimeGPS start;
258
260
261 parseargs(argc, argv);
262
263 /* get the data */
265 XLALGPSSetREAL8(&start, t0 - pad);
266 series = XLALFrStreamInputREAL8TimeSeries(stream, channel, &start, dt + 2.0 * pad, 0);
267 XLALFrStreamClose(stream);
268
269 /* manipulate the data */
270 if (srate > 0)
271 XLALResampleREAL8TimeSeries(series, 1.0 / srate);
272 if (minfreq > 0)
273 XLALHighPassREAL8TimeSeries(series, minfreq, 0.9, 8);
274 if (maxfreq > 0)
275 XLALLowPassREAL8TimeSeries(series, maxfreq, 0.9, 8);
276 if (pad > 0)
277 series = XLALResizeREAL8TimeSeries(series, pad / series->deltaT, dt / series->deltaT);
278
279 if (df > 0) { /* we are computing a spectrum */
280 REAL8FrequencySeries *spectrum;
281 REAL8FFTPlan *plan;
282 REAL8Window *window;
283 size_t seglen = 1.0 / (df * series->deltaT);
284
285 /* make sure that the time series length is commensurate with seglen */
286 if (((2 * series->data->length) % seglen) != 0) {
287 size_t newlen = ((2 * series->data->length) / seglen) * seglen;
288 series = XLALResizeREAL8TimeSeries(series, 0, newlen);
289 }
290
291 spectrum = XLALCreateREAL8FrequencySeries(series->name, &series->epoch, 0.0, df, &lalDimensionlessUnit, seglen/2 + 1);
292 plan = XLALCreateForwardREAL8FFTPlan(seglen, 0);
293 window = XLALCreateHannREAL8Window(seglen);
294 XLALREAL8AverageSpectrumWelch(spectrum, series, seglen, seglen/2, window, plan);
295 if (minfreq > 0 || maxfreq > 0) {
296 size_t first = minfreq / spectrum->deltaF;
297 size_t last = maxfreq > 0 ? maxfreq / spectrum->deltaF : spectrum->data->length;
298 spectrum = XLALResizeREAL8FrequencySeries(spectrum, first, last - first);
299 }
300 output_fs(outfile, spectrum);
304 } else { /* we are outputting a time series */
305 output_ts(outfile, series);
306 }
307
309 return 0;
310}
311
312int parseargs(int argc, char **argv)
313{
314 struct LALoption long_options[] = {
315 {"help", no_argument, 0, 'h'},
316 {"channel", required_argument, 0, 'c'},
317 {"frame-cache", required_argument, 0, 'f'},
318 {"frame-glob", required_argument, 0, 'g'},
319 {"output", required_argument, 0, 'o'},
320 {"start-time", required_argument, 0, 's'},
321 {"duration", required_argument, 0, 't'},
322 {"highpass", required_argument, 0, 'H'},
323 {"lowpass", required_argument, 0, 'L'},
324 {"pad", required_argument, 0, 'P'},
325 {"resample", required_argument, 0, 'R'},
326 {"spectrum", required_argument, 0, 'S'},
327 {0, 0, 0, 0}
328 };
329 char args[] = "hc:f:g:o:s:t:H:L:P:R:S:";
330 while (1) {
331 int option_index = 0;
332 int c;
333
334 c = LALgetopt_long_only(argc, argv, args, long_options, &option_index);
335 if (c == -1) /* end of options */
336 break;
337
338 switch (c) {
339 case 0: /* if option set a flag, nothing else to do */
340 if (long_options[option_index].flag)
341 break;
342 else {
343 fprintf(stderr, "error parsing option %s with argument %s\n",
344 long_options[option_index].name, LALoptarg);
345 exit(1);
346 }
347 case 'h': /* help */
348 usage(argv[0]);
349 exit(0);
350 case 'c': /* channel */
352 break;
353 case 'f': /* frame-cache */
355 break;
356 case 'g': /* frame-glob */
358 break;
359 case 'o': /* output */
361 break;
362 case 's': /* start-time */
363 t0 = atof(LALoptarg);
364 break;
365 case 't': /* duration */
366 dt = atof(LALoptarg);
367 break;
368 case 'H': /* highpass */
369 minfreq = atof(LALoptarg);
370 break;
371 case 'L': /* lowpass */
372 maxfreq = atof(LALoptarg);
373 break;
374 case 'P': /* pad */
375 pad = atof(LALoptarg);
376 break;
377 case 'R': /* start-time */
378 srate = atof(LALoptarg);
379 break;
380 case 'S': /* spectrum */
381 df = atof(LALoptarg);
382 break;
383 case '?':
384 default:
385 fprintf(stderr, "unknown error while parsing options\n");
386 exit(1);
387 }
388 }
389
390 if (LALoptind < argc) {
391 fprintf(stderr, "extraneous command line arguments:\n");
392 while (LALoptind < argc)
393 fprintf(stderr, "%s\n", argv[LALoptind++]);
394 exit(1);
395 }
396
397 /* sanity check parameters */
398
399 if (!channel) {
400 fprintf(stderr, "must specify a channel\n");
401 usage(argv[0]);
402 exit(1);
403 }
404 if (!cache) {
405 fprintf(stderr, "must specify a frame cache or frame files\n");
406 usage(argv[0]);
407 exit(1);
408 }
409
410 return 0;
411}
412
413int usage(const char *program)
414{
415 /* basename */
416 program = strrchr(program, '/') ? strrchr(program, '/') + 1 : program;
417 fprintf(stderr, "usage: %s [options]\n", program);
418 fprintf(stderr, "options:\n");
419 fprintf(stderr, "\t-h, --help \tprint this message and exit\n");
420 fprintf(stderr, "\t-c CHAN, --channel=CHAN \tchannel name CHAN\n");
421 fprintf(stderr, "\t-f CACHE, --frame-cache=CACHE\tframe cache file CACHE\n");
422 fprintf(stderr, "\t-g GLOB, --frame-glob=GLOB \tframe file glob string GLOB\n");
423 fprintf(stderr, "\t-o OUTFILE, --output=OUTFILE \toutput to file OUTFILE\n");
424 fprintf(stderr, "\t-s T0, --start-time=T0 \tGPS start time T0 (s)\n");
425 fprintf(stderr, "\t-t DT, --duration=DT \tduration DT (s)\n");
426 fprintf(stderr, "\t-H FMIN, --highpass=FMIN \thighpass filter at frequency FMIN (Hz)\n");
427 fprintf(stderr, "\t-L FMAX, --lowpass=FMAX \tlowpass filter at frequency FMAX (Hz)\n");
428 fprintf(stderr, "\t-P PAD, --pad=PAD \tadd PAD data at start and end (s)\n");
429 fprintf(stderr, "\t-R SRATE, --resample=SRATE \tresample to rate SRATE (Hz)\n");
430 fprintf(stderr, "\t-S DF, --spectrum=DF \tcompute spectrum with resolution DF (Hz)\n");
431 fprintf(stderr, "\nOUTPUT FORMATS:\n");
432 fprintf(stderr, "\t");
433 fprintf(stderr, ".au, ");
434 fprintf(stderr, ".eps, ");
435 fprintf(stderr, ".gif, ");
436 fprintf(stderr, ".jpg, ");
437 fprintf(stderr, ".pdf, ");
438 fprintf(stderr, ".png, ");
439 fprintf(stderr, ".ps, ");
440 fprintf(stderr, ".svg, ");
441 fprintf(stderr, ".wav, ");
442 fprintf(stderr, ".xml\n");
443 fprintf(stderr, "\nEXAMPLES:\n");
444 fprintf(stderr, "\n\tOutput 64s of strain data to a WAV file:\n");
445 fprintf(stderr, "\t\t%s -c \"H1:LSC-STRAIN\" -g H-H1_RDS_C03_L2-864903135-128.gwf -s 864903136 -t 64 -P 1 -H 10 -L 1000 -R 2048 -o data.wav\n", program);
446 fprintf(stderr, "\n\tOutput amplitude spectrum to a PDF file:\n");
447 fprintf(stderr, "\t\t%s -c \"H1:LSC-STRAIN\" -g H-H1_RDS_C03_L2-864903135-128.gwf -s 864903136 -t 64 -P 1 -H 10 -L 1000 -R 2048 -S 0.25 -o spec.pdf\n", program);
448 return 0;
449}
450
451void output_ts(const char *fname, REAL8TimeSeries *series)
452{
453 const char *ext;
454 FILE *fp;
455 /* determine output type from extension */
456 ext = strrchr(fname ? fname : "", '.');
457 ext = ext ? ext + 1 : "";
458 if (XLALStringCaseCompare(ext, "wav") == 0) {
459 fp = fopen(fname, "w");
461 fclose(fp);
462 }
463 else if (XLALStringCaseCompare(ext, "au") == 0) {
464 fp = fopen(fname, "w");
466 fclose(fp);
467 }
468 else if (
469 XLALStringCaseCompare(ext, "eps") == 0
470 || XLALStringCaseCompare(ext, "jpeg") == 0
471 || XLALStringCaseCompare(ext, "jpg") == 0
472 || XLALStringCaseCompare(ext, "gif") == 0
473 || XLALStringCaseCompare(ext, "png") == 0
474 || XLALStringCaseCompare(ext, "ps") == 0
475 || XLALStringCaseCompare(ext, "pdf") == 0
476 || XLALStringCaseCompare(ext, "svg") == 0
477 )
478 gnuplot_output_ts(fname, ext, series);
479 else if (XLALStringCaseCompare(ext, "xml") == 0)
480 xml_output_ts(fname, series);
481 else { /* default is an ascii file */
482 size_t i;
483 fp = fname ? fopen(fname, "w") : stdout;
484 for (i = 0; i < series->data->length; ++i) {
485 char tstr[32];
486 LIGOTimeGPS t = series->epoch;
487 XLALGPSToStr(tstr, XLALGPSAdd(&t, i * series->deltaT));
488 fprintf(fp, "%s\t%.15g\n", tstr, series->data->data[i]);
489 }
490 if (fname)
491 fclose(fp);
492 }
493 return;
494}
495
496void output_fs(const char *fname, REAL8FrequencySeries *series)
497{
498 const char *ext;
499 FILE *fp;
500 /* determine output type from extension */
501 ext = strrchr(fname ? fname : "", '.');
502 ext = ext ? ext + 1 : "";
503 if (XLALStringCaseCompare(ext, "wav") == 0) {
504 fprintf(stderr, "cannot output a spectrum to an audio file\n");
505 exit(1);
506 }
507 else if (XLALStringCaseCompare(ext, "au") == 0) {
508 fprintf(stderr, "cannot output a spectrum to an audio file\n");
509 exit(1);
510 }
511 else if (
512 XLALStringCaseCompare(ext, "eps") == 0
513 || XLALStringCaseCompare(ext, "jpeg") == 0
514 || XLALStringCaseCompare(ext, "jpg") == 0
515 || XLALStringCaseCompare(ext, "gif") == 0
516 || XLALStringCaseCompare(ext, "png") == 0
517 || XLALStringCaseCompare(ext, "ps") == 0
518 || XLALStringCaseCompare(ext, "pdf") == 0
519 || XLALStringCaseCompare(ext, "svg") == 0
520 )
521 gnuplot_output_fs(fname, ext, series);
522 else if (XLALStringCaseCompare(ext, "xml") == 0)
523 xml_output_fs(fname, series);
524 else { /* default is an ascii file */
525 size_t i;
526 fp = fname ? fopen(fname, "w") : stdout;
527 for (i = 0; i < series->data->length; ++i)
528 fprintf(fp, "%f\t%.15g\n", i * series->deltaF, series->data->data[i]);
529 if (fname)
530 fclose(fp);
531 }
532 return;
533}
534
535void gnuplot_output_ts(const char *fname, const char *fmt, REAL8TimeSeries *series)
536{
537 size_t i;
538 char *units;
539 FILE *gp = popen("gnuplot -persistent", "w");
540
541 if (!gp) {
542 fprintf(stderr, "require program gnuplot to output .%s files", fmt);
543 exit(1);
544 }
545
546 /* get the sample units as a string */
547 units = XLALUnitToString(&series->sampleUnits);
548 if (units == NULL || *units == '\0') {
549 LALFree(units);
550 units = XLALStringDuplicate("unknown units");
551 }
552
553 /* modify fmt as required by gnuplot */
554 if (strcmp(fmt, "jpg") == 0)
555 fmt = "jpeg";
556 else if (strcmp(fmt, "ps") == 0)
557 fmt = "postscript landscape";
558 else if (strcmp(fmt, "eps") == 0)
559 fmt = "postscript eps";
560
561 /* issue gnuplot commands */
562 fprintf(gp, "set terminal %s\n", fmt);
563 fprintf(gp, "set output '%s'\n", fname);
564 fprintf(gp, "set key off\n");
565 fprintf(gp, "set grid\n");
566 fprintf(gp, "set xlabel 'time (s)'\n");
567 fprintf(gp, "set ylabel 'value (%s)'\n", units);
568 fprintf(gp, "set title '%s @ %d.%09d\n", series->name, series->epoch.gpsSeconds, series->epoch.gpsNanoSeconds);
569 fprintf(gp, "plot '-' with lines\n");
570 for (i = 0; i < series->data->length; ++i)
571 fprintf(gp, "%.9f\t%e\n", i * series->deltaT, series->data->data[i]);
572 fprintf(gp, "e");
573
574 pclose(gp);
575 LALFree(units);
576 return;
577}
578
579void gnuplot_output_fs(const char *fname, const char *fmt, REAL8FrequencySeries *series)
580{
581 LALUnit asdunit;
582 char *units;
583 size_t i;
584 FILE *gp = popen("gnuplot -persistent", "w");
585
586 if (!gp) {
587 fprintf(stderr, "require program gnuplot to output .%s files", fmt);
588 exit(1);
589 }
590
591 /* get the sample units as a string */
592 XLALUnitSqrt(&asdunit, &series->sampleUnits);
593 units = XLALUnitToString(&asdunit);
594 if (units == NULL || *units == '\0') {
595 LALFree(units);
596 units = XLALStringDuplicate("unknown units");
597 }
598
599 /* modify fmt as required by gnuplot */
600 if (strcmp(fmt, "jpg") == 0)
601 fmt = "jpeg";
602 else if (strcmp(fmt, "ps") == 0)
603 fmt = "postscript landscape";
604 else if (strcmp(fmt, "eps") == 0)
605 fmt = "postscript eps";
606
607 /* issue gnuplot commands */
608 fprintf(gp, "set terminal %s\n", fmt);
609 fprintf(gp, "set output '%s'\n", fname);
610 fprintf(gp, "set key off\n");
611 fprintf(gp, "set grid xtics mxtics ytics\n");
612 fprintf(gp, "set xlabel 'frequency (Hz)'\n");
613 fprintf(gp, "set ylabel 'amplitude spectral density (%s)'\n", units);
614 fprintf(gp, "set title '%s @ %d.%09d\n", series->name, series->epoch.gpsSeconds, series->epoch.gpsNanoSeconds);
615 fprintf(gp, "set logscale\n");
616 fprintf(gp, "plot '-' with lines\n");
617 for (i = 0; i < series->data->length; ++i)
618 fprintf(gp, "%.9f\t%e\n", series->f0 + i * series->deltaF, sqrt(series->data->data[i]));
619 fprintf(gp, "e");
620
621 pclose(gp);
622 LALFree(units);
623 return;
624}
625
626
627
628void xml_begin_xml(FILE *fp);
629void xml_end_xml(FILE *fp);
630
631void xml_begin_freq_series(FILE *fp);
632void xml_begin_time_series(FILE *fp);
633void xml_end_series(FILE *fp);
634
635void xml_put_gps(LIGOTimeGPS *epoch, FILE *fp);
636void xml_put_f0(double f0, FILE *fp);
637void xml_put_det(const char *name, FILE *fp);
638
639void xml_begin_freq_array(REAL8FrequencySeries *series, FILE *fp);
640void xml_begin_time_array(REAL8TimeSeries *series, FILE *fp);
641void xml_end_array(FILE *fp);
642
643void xml_put_stream(REAL8Vector *vector, double dx, FILE *fp);
644
645void xml_begin_xml(FILE *fp)
646{
647 fputs("<?xml version='1.0' encoding='utf-8'?>\n", fp);
648 fputs("<!DOCTYPE LIGO_LW SYSTEM \"http://ldas-sw.ligo.caltech.edu/doc/ligolwAPI/html/ligolw_dtd.txt\">\n", fp);
649 fputs("<LIGO_LW>\n", fp);
650 return;
651}
652void xml_end_xml(FILE *fp)
653{
654 fputs("</LIGO_LW>\n", fp);
655 return;
656}
657
659{
660 fputs("\t<LIGO_LW Name=\"REAL8FrequencySeries\">\n", fp);
661 return;
662}
664{
665 fputs("\t<LIGO_LW Name=\"REAL8TimeSeries\">\n", fp);
666 return;
667}
668void xml_end_series(FILE *fp)
669{
670 fputs("\t</LIGO_LW>\n", fp);
671 return;
672}
673
674void xml_put_gps(LIGOTimeGPS *epoch, FILE *fp)
675{
676 char tstr[32];
677 XLALGPSToStr(tstr, epoch);
678 fprintf(fp, "\t\t<Time Type=\"GPS\" Name=\"epoch\">%s</Time>\n", tstr);
679 return;
680}
681void xml_put_f0(double f0, FILE *fp)
682{
683 fprintf(fp, "\t\t<Param Type=\"real_8\" Name=\"f0:param\" Unit=\"s^-1\">"
684 "%g</Param>\n", f0);
685 return;
686}
687void xml_put_det(const char *name, FILE *fp)
688{
689 const char *dets[] = {"G1", "H1", "H2", "K1", "L1", "T1", "V1"};
690 size_t ndet = XLAL_NUM_ELEM(dets);
691 size_t d;
692 fputs("\t\t<Param Type=\"lstring\" Name=\"instrument:param\">", fp);
693 for (d = 0; d < ndet; ++d)
694 if (strncmp(name, dets[d], 2) == 0) {
695 fputs(dets[d], fp);
696 break;
697 }
698 if (d == ndet)
699 fputs("??", fp);
700 fputs("</Param>\n", fp);
701 return;
702}
703
705{
706 fprintf(fp, "\t\t<Array Type=\"real_8\" Name=\"%s:array\" Unit=\"%s\">\n",
707 series->name, XLALUnitToString(&series->sampleUnits));
708 fprintf(fp, "\t\t\t<Dim Start=\"%g\" Scale=\"%.15g\" "
709 "Name=\"Frequency\" Unit=\"s^-1\">%u</Dim>\n", series->f0,
710 series->deltaF, series->data->length);
711 fputs("\t\t\t<Dim Name=\"Frequency,Real\">2</Dim>\n", fp);
712 return;
713}
715{
716 fprintf(fp, "\t\t<Array Type=\"real_8\" Name=\"%s:array\" Unit=\"%s\">\n",
717 series->name, XLALUnitToString(&series->sampleUnits));
718 fprintf(fp, "\t\t\t<Dim Start=\"0\" Scale=\"%.15g\" "
719 "Name=\"Time\" Unit=\"s\">%u</Dim>\n", series->deltaT,
720 series->data->length);
721 fputs("\t\t\t<Dim Name=\"Time,Real\">2</Dim>\n", fp);
722 return;
723}
724void xml_end_array(FILE *fp)
725{
726 fputs("\t\t</Array>\n", fp);
727 return;
728}
729
730void xml_put_stream(REAL8Vector *vector, double dx, FILE *fp)
731{
732#define DELIM ","
733 size_t i;
734 fputs("\t\t\t<Stream Delimiter=\"" DELIM "\" Type=\"Local\">\n", fp);
735 for (i = 0; i < vector->length; ++i)
736 fprintf(fp, "\t\t\t\t%.15g" DELIM "%.15g" DELIM "\n", i * dx,
737 vector->data[i]);
738 fputs("\t\t\t</Stream>\n", fp);
739 return;
740#undef DELIM
741}
742
743void xml_output_ts(const char *fname, REAL8TimeSeries *series)
744{
745 FILE *fp = fopen(fname, "w");
747
749
750 xml_put_gps(&series->epoch, fp);
751 xml_put_f0(series->f0, fp);
752
753 xml_begin_time_array(series, fp);
754
755 xml_put_stream(series->data, series->deltaT, fp);
756
758
759 xml_put_det(series->name, fp);
760
762
764
765 fclose(fp);
766 return;
767}
768
769void xml_output_fs(const char *fname, REAL8FrequencySeries *series)
770{
771 FILE *fp = fopen(fname, "w");
773
775
776 xml_put_gps(&series->epoch, fp);
777 xml_put_f0(series->f0, fp);
778
779 xml_begin_freq_array(series, fp);
780
781 xml_put_stream(series->data, series->deltaF, fp);
782
784
785 xml_put_det(series->name, fp);
786
788
790
791 fclose(fp);
792 return;
793}
int XLALLowPassREAL8TimeSeries(REAL8TimeSeries *series, REAL8 frequency, REAL8 amplitude, INT4 filtorder)
int XLALHighPassREAL8TimeSeries(REAL8TimeSeries *series, REAL8 frequency, REAL8 amplitude, INT4 filtorder)
const char * program
#define LALFree(p)
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
int XLALAudioAURecordREAL8TimeSeries(FILE *fp, REAL8TimeSeries *series)
int XLALAudioWAVRecordREAL8TimeSeries(FILE *fp, REAL8TimeSeries *series)
char * XLALGPSToStr(char *s, const LIGOTimeGPS *t)
REAL8FrequencySeries * XLALResizeREAL8FrequencySeries(REAL8FrequencySeries *series, int first, size_t length)
REAL8FrequencySeries * XLALCreateREAL8FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL8FrequencySeries(REAL8FrequencySeries *series)
LALCache * XLALCacheGlob(const char *dirstr, const char *fnptrn)
LALCache * XLALCacheImport(const char *fname)
#define XLAL_NUM_ELEM(x)
int XLALFrStreamClose(LALFrStream *stream)
Closes a LALFrStream.
Definition: LALFrStream.c:170
LALFrStream * XLALFrStreamCacheOpen(LALCache *cache)
Opens a LALFrStream associated with a LALCache.
Definition: LALFrStream.c:189
REAL8TimeSeries * XLALFrStreamInputREAL8TimeSeries(LALFrStream *stream, const char *channel, const LIGOTimeGPS *start, REAL8 duration, size_t lengthlimit)
Reads a time series channel from a LALFrStream stream with a specified start time and duration,...
char char * XLALStringDuplicate(const char *s)
int XLALStringCaseCompare(const char *s1, const char *s2)
void XLALDestroyREAL8FFTPlan(REAL8FFTPlan *plan)
REAL8FFTPlan * XLALCreateForwardREAL8FFTPlan(UINT4 size, int measurelvl)
int XLALResampleREAL8TimeSeries(REAL8TimeSeries *series, REAL8 dt)
int XLALREAL8AverageSpectrumWelch(REAL8FrequencySeries *spectrum, const REAL8TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL8Window *window, const REAL8FFTPlan *plan)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
REAL8TimeSeries * XLALResizeREAL8TimeSeries(REAL8TimeSeries *series, int first, size_t length)
char * XLALUnitToString(const LALUnit *input)
const LALUnit lalDimensionlessUnit
LALUnit * XLALUnitSqrt(LALUnit *output, const LALUnit *input)
void XLALDestroyREAL8Window(REAL8Window *window)
REAL8Window * XLALCreateHannREAL8Window(UINT4 length)
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)
ext
This structure details the state of the frame stream.
Definition: LALFrStream.h:95
const char * name
int * flag
INT4 gpsNanoSeconds
REAL8Sequence * data
CHAR name[LALNameLength]
REAL8Sequence * data
LALUnit sampleUnits
LIGOTimeGPS epoch
CHAR name[LALNameLength]
REAL8 * data
FILE * fp
enum @1 epoch
double dt
Definition: vis.c:241
double df
Definition: vis.c:239
int main(int argc, char *argv[])
Definition: vis.c:253
#define DELIM
void xml_begin_time_series(FILE *fp)
Definition: vis.c:663
LALCache * cache
Definition: vis.c:232
void xml_begin_time_array(REAL8TimeSeries *series, FILE *fp)
Definition: vis.c:714
double t0
Definition: vis.c:240
void xml_begin_xml(FILE *fp)
Definition: vis.c:645
int usage(const char *program)
Definition: vis.c:413
int parseargs(int argc, char **argv)
Definition: vis.c:312
void xml_put_det(const char *name, FILE *fp)
Definition: vis.c:687
void xml_output_ts(const char *fname, REAL8TimeSeries *series)
Definition: vis.c:743
void xml_put_stream(REAL8Vector *vector, double dx, FILE *fp)
Definition: vis.c:730
void xml_begin_freq_series(FILE *fp)
Definition: vis.c:658
double maxfreq
Definition: vis.c:236
void xml_end_xml(FILE *fp)
Definition: vis.c:652
void xml_put_f0(double f0, FILE *fp)
Definition: vis.c:681
double srate
Definition: vis.c:237
void xml_end_array(FILE *fp)
Definition: vis.c:724
void gnuplot_output_ts(const char *fname, const char *fmt, REAL8TimeSeries *series)
Definition: vis.c:535
char * channel
Definition: vis.c:233
void output_ts(const char *fname, REAL8TimeSeries *series)
Definition: vis.c:451
void xml_end_series(FILE *fp)
Definition: vis.c:668
void xml_put_gps(LIGOTimeGPS *epoch, FILE *fp)
Definition: vis.c:674
void xml_output_fs(const char *fname, REAL8FrequencySeries *series)
Definition: vis.c:769
char * outfile
Definition: vis.c:234
double minfreq
Definition: vis.c:235
void gnuplot_output_fs(const char *fname, const char *fmt, REAL8FrequencySeries *series)
Definition: vis.c:579
double pad
Definition: vis.c:238
void output_fs(const char *fname, REAL8FrequencySeries *series)
Definition: vis.c:496
void xml_begin_freq_array(REAL8FrequencySeries *series, FILE *fp)
Definition: vis.c:704