Loading [MathJax]/extensions/TeX/AMSmath.js
LALFrame 3.0.7.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
fmt.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Duncan Brown, Jolien Creighton, Robert Adam Mercer
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_fmt lalfr-fmt
22 * @ingroup lalframe_programs
23 *
24 * @brief Formats multicolumn text files into channels in a frame file
25 *
26 * ### Synopsis
27 *
28 * lalfr-fmt [file ...]
29 *
30 * ### Description
31 *
32 * The `lalfr-fmt` utility reads each multicolumn input `file` file and formats
33 * the columns into different channels that are output as a frame file to the
34 * standard output. The `file` operands are processed in command-line order.
35 * If `file` is a single dash (`-`) or absent, `lalfr-fmt` reads from the
36 * standard input.
37 *
38 * If `file` contains only one column of data, each row is interpreted as a
39 * sample of a single channel having a sample rate of 16384 Hz. If there are
40 * more than one column in `file` then the first column is interpreted as the
41 * GPS time of each sample. The remaining columns then describe the samples
42 * for separate channels. The output channels are named `C01`, `C02`, etc.
43 *
44 * If the first line of `file` begins with the `#` character followed
45 * tab-separated list of column names with units in parentheses then these
46 * are used for the channel names and the sample units.
47 *
48 * ### Examples
49 *
50 * The command:
51 *
52 * seq 0 0.02 99.98 | paste - - - - - | lalfr-fmt > file.gwf
53 *
54 * produces a frame file `file.gwf` containing four channels named `C01`,
55 * `C02`, `C03`, and `C04`, each with a sample rate of 10 Hz.
56 *
57 * The command:
58 *
59 * lalsim-detector-noise -s 1000000000 -t 64 --aligo-zerodet-highpower | lalfr-fmt > noise.gwf
60 *
61 * produces a frame file `noise.gwf` containing 64 seconds of simulated aLIGO
62 * noise.
63 *
64 * @sa @ref lalfr_print
65 */
66
67#include <limits.h>
68#include <math.h>
69#include <stdio.h>
70#include <stdlib.h>
71#include <string.h>
72#include <lal/LALString.h>
73#include <lal/LALFrameU.h>
74
75#define FAILURE(...) do { fprintf(stderr, __VA_ARGS__); exit(99); } while (0)
76
77char *mystrdup(const char *s);
78int readdata(size_t * ndim, size_t * size, double **data, char ***channames, char ***chanunits, FILE * fp);
79
80int main(int argc, char *argv[])
81{
82 char stdio[] = "-";
83 char *defaultfilev[1] = { stdio };
84 int filec = (argc == 1 ? 1 : argc - 1);
85 char **filev = (argc == 1 ? defaultfilev : &argv[1]);
86 LALFrameUFrFile *output;
87 int f;
88
89 output = XLALFrameUFrFileOpen(stdio, "w");
90 if (!output)
91 FAILURE("could not create output file\n");
92
93 for (f = 0; f < filec; ++f) {
94 char *fname = filev[f];
95 LALFrameUFrameH *frame;
96 LALFrameUFrChan *channel;
97 double srate = 16384.0; /* default sample rate */
98 double t0 = 0.0; /* default gps start time */
99 double dt;
102 int dtype = LAL_FRAMEU_FR_VECT_8R;
103 size_t ndim;
104 size_t dim;
105 size_t dimlen;
106 double *data;
107 double *vect;
108 char **channames;
109 char **chanunits;
110 FILE *fp;
111
112 if (strcmp(fname, "-") == 0)
113 fp = stdin;
114 else
115 fp = fopen(fname, "r");
116 if (!fp)
117 FAILURE("could not open file %s\n", fname);
118
119 readdata(&ndim, &dimlen, &data, &channames, &chanunits, fp);
120
121 if (ndim == 1) /* use default sample rate and start time */
122 dt = dimlen / srate;
123 else { /* first dimension is gps time */
124 /* assume sample rate in Hz is an integer */
125 srate =
126 floor(0.5 + (dimlen - 1) / (data[(dimlen - 1) * ndim] -
127 data[0]));
128 dt = dimlen / srate;
129 t0 = data[0];
130 }
131
132 frame = XLALFrameUFrameHAlloc(fname, t0, 0.0, dt, f);
133 XLALFrameUFrameHSetRun(frame, 0);
134
135 for (dim = (ndim == 1 ? 0 : 1); dim < ndim; ++dim) {
136 size_t i;
137
138 channel = XLALFrameUFrProcChanAlloc(channames[dim], type, subtype, dtype, dimlen);
139 XLALFrameUFrChanVectorAlloc(channel, dtype, dimlen);
140 XLALFrameUFrChanVectorSetName(channel, channames[dim]);
144
146 for (i = 0; i < dimlen; ++i)
147 vect[i] = data[i * ndim + dim];
148
151 free(channames[dim]);
152 free(chanunits[dim]);
153 }
154 free(data);
155 free(channames);
156 free(chanunits);
157
160 }
161
163 return 0;
164}
165
166int readdata(size_t * ndim, size_t * dimlen, double **data, char ***channames, char ***chanunits, FILE * fp)
167{
168 char header[LINE_MAX] = "";
169 char line[LINE_MAX];
170 char *hdr = header;
171 char *tok;
172 size_t block = 1024;
173 size_t bufsz = 0;
174 size_t rows = 0;
175 size_t cols = 0;
176 size_t col;
177 int c;
178
179 /* determine if the first line contains channel names and units */
180 if ((c = fgetc(fp)) == '#')
181 fgets(header, sizeof(header), fp); /* save header line */
182 else
183 ungetc(c, fp);
184
185 *data = NULL;
186 *channames = NULL;
187 *chanunits = NULL;
188
189 while (fgets(line, sizeof(line), fp)) {
190 char *s;
191 char *endp;
192 if (*line == '#') /* ignore lines beginning with '#' */
193 continue;
194 if (cols == 0) { /* count columns on first line */
195 endp = line;
196 while (1) {
197 s = endp;
198 /* work around bug in glibc < 2.16
199 * http://sourceware.org/bugzilla/show_bug.cgi?id=13970 */
200 double v = strtod(s, &endp);
201 (void)v;
202 if (s == endp || *endp == '\0')
203 break;
204 ++cols;
205 }
206 if (cols == 0)
207 FAILURE("format error on input line %zu\n", rows + 1);
208 }
209 endp = line;
210
211 if (rows == bufsz) {
212 bufsz += block;
213 *data = realloc(*data, bufsz * cols * sizeof(**data));
214 }
215 for (col = 0; col < cols; ++col) {
216 s = endp;
217 (*data)[rows * cols + col] = strtod(s, &endp);
218 if (s == endp || *endp == '\0')
219 FAILURE("format error on input line %zu\n", rows + 1);
220 }
221 ++rows;
222 }
223
224 *data = realloc(*data, rows * cols * sizeof(**data));
225 *ndim = cols;
226 *dimlen = rows;
227 *channames = calloc(cols, sizeof(**channames));
228 *chanunits = calloc(cols, sizeof(**chanunits));
229
230 /* now scan header for channel names and units */
231 for (col = 0; col < cols; ++col) {
232 char name[LINE_MAX] = "";
233 char unit[LINE_MAX] = "";
234 int n = 0;
235 if (hdr && (tok = XLALStringToken(&hdr, "\t", 0)))
236 n = sscanf(tok, "%s (%[^)])", name, unit);
237 if (n < 1)
238 snprintf(name, sizeof(name), "C%02zu", col);
239 (*channames)[col] = mystrdup(name);
240 (*chanunits)[col] = mystrdup(unit);
241 }
242
243 return 0;
244}
245
246/* strdup is not C99... */
247char *mystrdup(const char *str)
248{
249 size_t len = strlen(str);
250 char *dup = malloc(len + 1);
251 strcpy(dup, str);
252 dup[len] = '\0';
253 return dup;
254}
const char *const name
int main(int argc, char *argv[])
Definition: fmt.c:80
#define FAILURE(...)
Definition: fmt.c:75
char * mystrdup(const char *s)
Definition: fmt.c:247
int readdata(size_t *ndim, size_t *size, double **data, char ***channames, char ***chanunits, FILE *fp)
Definition: fmt.c:166
LALFrameUFrameH * XLALFrameUFrameHAlloc(const char *name, double start1, double start2, double dt, int frnum)
Allocate memory for a new frame header FrameH structure.
Definition: LALFrameU.c:210
int XLALFrameUFrameHWrite(LALFrameUFrFile *stream, LALFrameUFrameH *frame)
Write a FrameH structure to an output FrFile stream.
Definition: LALFrameU.c:220
void * XLALFrameUFrChanVectorQueryData(const LALFrameUFrChan *channel)
Query FrChan structure for the data pointer in its FrVect structure.
Definition: LALFrameU.c:360
void XLALFrameUFrameHFree(LALFrameUFrameH *frame)
Free a FrameH structure.
Definition: LALFrameU.c:205
void XLALFrameUFrChanFree(LALFrameUFrChan *channel)
Free a FrChan structure.
Definition: LALFrameU.c:280
int XLALFrameUFrChanVectorSetDx(LALFrameUFrChan *channel, double dx)
Set the sampling interval for the data in the FrVect structure contained in a FrChan structure.
Definition: LALFrameU.c:410
int XLALFrameUFrameHFrChanAdd(LALFrameUFrameH *frame, LALFrameUFrChan *channel)
Add a FrChan structure to a FrameH structure.
Definition: LALFrameU.c:225
struct tagLALFrameUFrameH LALFrameUFrameH
Incomplete type for a frame header FrameH structure.
Definition: LALFrameU.h:64
int XLALFrameUFrChanVectorSetUnitY(LALFrameUFrChan *channel, const char *unit)
Set the units of the data in the FrVect structure contained in a FrChan structure.
Definition: LALFrameU.c:425
int XLALFrameUFrChanVectorAlloc(LALFrameUFrChan *channel, int dtype, size_t ndata)
Allocate memory for a FrVect structure within a FrChan structure.
Definition: LALFrameU.c:330
int XLALFrameUFrameHSetRun(LALFrameUFrameH *frame, int run)
Set the run number in a FrameH structure.
Definition: LALFrameU.c:275
LALFrameUFrFile * XLALFrameUFrFileOpen(const char *filename, const char *mode)
Open a frame file FrFile stream.
Definition: LALFrameU.c:130
LALFrameUFrChan * XLALFrameUFrProcChanAlloc(const char *name, int type, int subtype, int dtype, size_t ndata)
Allocate memory for a new FrChan structure of FrAdcData type.
Definition: LALFrameU.c:300
int XLALFrameUFrChanVectorSetName(LALFrameUFrChan *channel, const char *name)
Set the name of the FrVect structure contained in a FrChan structure.
Definition: LALFrameU.c:405
void XLALFrameUFrFileClose(LALFrameUFrFile *stream)
Close a FrFile stream.
Definition: LALFrameU.c:125
int XLALFrameUFrChanVectorSetUnitX(LALFrameUFrChan *channel, const char *unit)
Set the units of the domain of the data in the FrVect structure contained in a FrChan structure.
Definition: LALFrameU.c:420
@ LAL_FRAMEU_FR_PROC_TYPE_TIME_SERIES
Id for time-series data.
Definition: LALFrameU.h:193
@ LAL_FRAMEU_FR_PROC_SUB_TYPE_UNKNOWN
Id for unknown or user-defined data.
Definition: LALFrameU.h:220
@ LAL_FRAMEU_FR_VECT_8R
Id for 64-bit double precision floating point data type.
Definition: LALFrameU.h:148
char * XLALStringToken(char **s, const char *delim, int empty)
double dt
Definition: stream.c:110
double t0
Definition: stream.c:109
char * channel
Definition: stream.c:108
FILE * fp
void output(int gps_sec, int output_type)
double srate
Definition: vis.c:237