Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALSimulation 6.2.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALSimReadData.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#define _GNU_SOURCE /* for realpath() */
21
22#include <config.h>
23#include <stdlib.h>
24#include <limits.h>
25#include <string.h>
26#ifdef HAVE_UNISTD_H
27#include <unistd.h>
28#endif
29#include <lal/FileIO.h>
30#include <lal/LALStdlib.h>
31#include <lal/LALString.h>
32#include <lal/LALSimReadData.h>
33
34#ifndef PAGESIZE
35#ifdef _SC_PAGE_SIZE
36#define PAGESIZE _SC_PAGE_SIZE
37#else
38#define PAGESIZE 1024
39#endif
40#endif
41#ifndef LINE_MAX
42#ifdef _SC_LINE_MAX
43#define LINE_MAX _SC_LINE_MAX
44#else
45#define LINE_MAX 1024
46#endif
47#endif
48
49
50/**
51 * @brief Opens a specified data file, searching default path if necessary.
52 * @details Opens a data file for input with a specified path name.
53 * If the path name is an absolute path then this specific file is opened;
54 * otherwise, search for the file in paths given in the environment variable
55 * LAL_DATA_PATH, and finally search in the installed PKG_DATA_DIR path.
56 * @param[in] fname The path of the file to open.
57 * @return A pointer to a LALFILE structure or NULL on failure.
58 */
59LALFILE *XLALSimReadDataFileOpen(const char *fname)
60{
61 LALFILE *fp = NULL;
62 char *path = XLAL_FILE_RESOLVE_PATH(fname);
63 if (!path) /* could not find file */
64 XLAL_ERROR_FAIL(XLAL_EIO, "Could not find data file %s\n", fname);
66 if (!fp) /* open failure */
67 XLAL_ERROR_FAIL(XLAL_EIO, "Could not open data file %s\n", path);
68XLAL_FAIL:
70 return fp;
71}
72
73
74/**
75 * @brief Read a two-column data file.
76 * @details Read a data file containing two whitespace separated columns
77 * of data and create two arrays containing the data in each column.
78 * If any line begins with the character '#' then it is ignored.
79 * @param[out] xdat The x-data stored in the first column.
80 * @param[out] ydat The y-data stored in the second column.
81 * @param fp Pointer to a LALFILE structure opened for input.
82 * @return The number of data points read or <0 if an error occurs.
83 */
84size_t XLALSimReadDataFile2Col(double **xdat, double **ydat, LALFILE * fp)
85{
86 char line[LINE_MAX];
87 size_t size = PAGESIZE;
88 size_t lnum = 0;
89 size_t npts;
90 *xdat = XLALMalloc(size * sizeof(**xdat));
91 *ydat = XLALMalloc(size * sizeof(**ydat));
92 npts = 0;
93 while (XLALFileGets(line, sizeof(line), fp)) {
94 ++lnum;
95 if (strchr(line, '\n') == NULL) { /* line too long */
96 XLALFree(*xdat);
97 XLALFree(*ydat);
98 XLAL_ERROR(XLAL_EIO, "Line %zd too long\n", lnum);
99 }
100 if (*line == '#') /* ignore lines beginning with a '#' */
101 continue;
102 if (sscanf(line, "%lf %lf", *xdat + npts, *ydat + npts) != 2) {
103 XLALFree(*xdat);
104 XLALFree(*ydat);
105 XLAL_ERROR(XLAL_EIO, "Line %zd malformed\n", lnum);
106 }
107 if (++npts == size) {
108 size += PAGESIZE;
109 *xdat = XLALRealloc(*xdat, size * sizeof(**xdat));
110 *ydat = XLALRealloc(*ydat, size * sizeof(**ydat));
111 }
112 }
113 *xdat = XLALRealloc(*xdat, npts * sizeof(**xdat));
114 *ydat = XLALRealloc(*ydat, npts * sizeof(**ydat));
115 return npts;
116}
117
118
119/**
120 * @brief Read a multi-column data file.
121 * @details Read a data file containing multiple whitespace separated columns
122 * of data and create an array containing the data.
123 * If any line begins with the character '#' then it is ignored.
124 * The data is stored in the array in row-major format so that the data
125 * sample on row @c i (beginning with zero) and column @c j (beginning with
126 * zero) is found as the element <tt>[i * ncol + j]</tt> where @c ncol is the
127 * number of columns.
128 * @param[out] data The data stored in row-major order.
129 * @param[out] ncol The number of columns in the data file.
130 * @param fp Pointer to a LALFILE structure opened for input.
131 * @return The number of rows read or (size_t)(-1) if an error occurs.
132 */
133size_t XLALSimReadDataFileNCol(double **data, size_t *ncol, LALFILE *fp)
134{
135 char line[LINE_MAX];
136 size_t page = PAGESIZE;
137 size_t size = 0;
138 size_t lnum = 0;
139 size_t nrow = 0;
140
141 *data = NULL;
142 *ncol = 0;
143 while (XLALFileGets(line, sizeof(line), fp)) {
144 char *s;
145 char *endp;
146 size_t col;
147
148 ++lnum;
149
150 if (strchr(line, '\n') == NULL) { /* line too long */
151 XLALFree(*data);
152 XLAL_ERROR(XLAL_EIO, "Line %zd too long\n", lnum);
153 }
154
155 if (*line == '#') /* ignore lines beginning with '#' */
156 continue;
157
158 if (*ncol == 0) { /* count columns on first line */
159 endp = line;
160 while (1) {
161 s = endp;
162 /* work around bug in glibc < 2.16
163 * http://sourceware.org/bugzilla/show_bug.cgi?id=13970 */
164 double v = strtod(s, &endp);
165 (void)v;
166 if (s == endp || *endp == '\0')
167 break;
168 ++*ncol;
169 }
170 if (*ncol == 0) {
171 XLALFree(*data);
172 XLAL_ERROR(XLAL_EIO, "Line %zd malformed\n", lnum);
173 }
174 }
175
176 if (nrow == size) { /* allocate more memory for data */
177 size += page;
178 *data = XLALRealloc(*data, *ncol * size * sizeof(**data));
179 }
180
181 /* scan line for data values in each column */
182 endp = line;
183 for (col = 0; col < *ncol; ++col) {
184 s = endp;
185 (*data)[*ncol * nrow + col] = strtod(s, &endp);
186 if (s == endp || *endp == '\0') {
187 XLALFree(*data);
188 XLAL_ERROR(XLAL_EIO, "Line %zd malformed\n", lnum);
189 }
190 }
191
192 ++nrow;
193 }
194
195 *data = XLALRealloc(*data, *ncol * nrow * sizeof(**data));
196
197 return nrow;
198}
#define PAGESIZE
LALFILE * XLALSimReadDataFileOpen(const char *fname)
Opens a specified data file, searching default path if necessary.
size_t XLALSimReadDataFile2Col(double **xdat, double **ydat, LALFILE *fp)
Read a two-column data file.
#define LINE_MAX
size_t XLALSimReadDataFileNCol(double **data, size_t *ncol, LALFILE *fp)
Read a multi-column data file.
int s
Definition: bh_qnmode.c:137
sigmaKerr data[0]
LALFILE * XLALFileOpenRead(const char *path)
#define XLAL_FILE_RESOLVE_PATH(fname)
char * XLALFileGets(char *s, int size, LALFILE *file)
void * XLALMalloc(size_t n)
void * XLALRealloc(void *p, size_t n)
void XLALFree(void *p)
#define XLAL_ERROR(...)
#define XLAL_ERROR_FAIL(...)
XLAL_EIO
path
FILE * fp