Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALFrame 3.0.7.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALFrStream.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Duncan Brown, Jolien Creighton, Kipp Cannon
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 * @addtogroup LALFrStream_c
21 * @brief Provides routines for opening, closing, positioning, and performing
22 * other manipulations on a \c LALFrStream.
23 *
24 * @details
25 * A frame stream is like a file stream except that it streams along the set
26 * of frames in a set of frame files. These routines are high-level routines
27 * that allow you to extract frame data. Many of these routines have names
28 * similar to the standard C file stream manipulation routines and perform
29 * similar functions.
30 *
31 * The routines XLALFrStreamOpen() and XLALFrStreamClose() are used to open
32 * and close a frame stream. The stream is created by XLALFrStreamOpen(),
33 * and must be a pointer to NULL before it is opened. It must have
34 * been created prior to calling XLALFrStreamClose(), and after this call,
35 * the stream will be a pointer to NULL. The routine
36 * XLALFrStreamOpen() requires the user to specify the directory name of the
37 * frame files and the head names. If the directory is NULL, the
38 * routine uses the current director (.). The head names specifies
39 * which files are the wanted files in the specified directory. Wildcards are
40 * allowed. For example, to get LLO frames only, the head names could be set
41 * to L-*.gwf. If the head name is NULL, the default value
42 * *.gwf is used. The routine XLALFrStreamCacheOpen() is like
43 * XLALFrStreamOpen() except that the list of frame files is taken from a
44 * frame file cache. [In fact, XLALFrStreamOpen() simply uses
45 * XLALFrCacheGenerate() and XLALFrStreamCacheOpen() to create the
46 * stream.]
47 *
48 * The routine XLALFrStreamSetMode() is used to change the operating mode
49 * of a frame stream, which determines how the routines try to accomodate
50 * gaps in data and requests for times when there is no data (e.g., before
51 * the beginning of the data, after the end of the data, or in some missing
52 * data).
53 * The default mode, which is given the value
54 * ::LAL_FR_STREAM_DEFAULT_MODE, prints warnings if a time requested
55 * corresponds to a time when there is no data (but then skips to the first
56 * avaliable data) and prints an info message when a gap in the data occurs
57 * (but then skips beyond the gap). This default mode is equal to the
58 * combination
59 * ::LAL_FR_STREAM_VERBOSE_MODE | ::LAL_FR_STREAM_IGNOREGAP_MODE | ::LAL_FR_STREAM_IGNORETIME_MODE
60 * where ::LAL_FR_STREAM_VERBOSE_MODE is equal to the combination
61 * ::LAL_FR_STREAM_TIMEWARN_MODE | ::LAL_FR_STREAM_GAPINFO_MODE. Use
62 * ::LAL_FR_STREAM_VERBOSE_MODE to print out warnings when requesting times
63 * with no data and print out an info message when a gap in the data is
64 * encountered. Unless the mode is supplemented with
65 * ::LAL_FR_STREAM_IGNOREGAP_MODE, gaps encountered in the data will cause
66 * a routine to exit with a non-zero status code; similarly,
67 * ::LAL_FR_STREAM_IGNORETIME_MODE prevents routines from failing if a time
68 * when there is not data is requested. Set the mode to
69 * ::LAL_FR_STREAM_SILENT_MODE to suppress the warning and info messages but
70 * still cause routines to fail when data is not available.
71 * Note: the default value ::LAL_FR_STREAM_DEFAULT_MODE is assumed initially,
72 * but this is not necessarily the recommended mode --- it is adopted for
73 * compatibility reasons.
74 *
75 * The routine XLALFrStreamEnd() determines if the end-of-frame-data flag for
76 * the data stream has been set.
77 *
78 * The routine XLALFrStreamNext() advances the frame stream to the
79 * beginning of the next frame.
80 *
81 * The routine XLALFrStreamRewind() rewinds the frame stream to the first
82 * frame.
83 *
84 * The routine XLALFrStreamSeek() sets the frame stream to a specified time,
85 * or the earliest time after the specified time if that time is not available
86 * (e.g., if it is before the beginning of the frame stream or if it is in a
87 * gap in the frame data). The routine XLALFrStreamTell() returns the
88 * current time within the frame stream.
89 *
90 * The routine XLALFrStreamGetpos() returns a structure containing the
91 * current frame stream position. The frame stream can later be restored to
92 * this position using XLALFrStreamSetpos().
93 *
94 * @{
95 */
96
97#include <config.h>
98#ifndef HAVE_GETHOSTNAME_PROTOTYPE
99int gethostname(char *name, int len);
100#endif
101
102#include <math.h>
103#include <stdio.h>
104#include <stdlib.h>
105#include <string.h>
106#include <lal/Date.h>
107#include <lal/LALStdio.h>
108#include <lal/LALStdlib.h>
109#include <lal/LALString.h>
110#include <lal/LALCache.h>
111#include <lal/LALFrameIO.h>
112#include <lal/LALFrStream.h>
113
114/* INTERNAL ROUTINES */
115/** @cond */
116
117static int XLALFrStreamFileClose(LALFrStream * stream)
118{
119 XLALFrFileClose(stream->file);
120 stream->file = NULL;
121 stream->pos = 0;
122 return 0;
123}
124
125static int XLALFrStreamFileOpen(LALFrStream * stream, UINT4 fnum)
126{
127 if (!stream->cache || !stream->cache->list)
128 XLAL_ERROR(XLAL_EINVAL, "No files in stream file cache");
129 if (fnum >= stream->cache->length)
130 XLAL_ERROR(XLAL_EINVAL, "File index too large");
131 if (stream->file)
132 XLALFrStreamFileClose(stream);
133 stream->pos = 0;
134 stream->fnum = fnum;
135 stream->file = XLALFrFileOpenURL(stream->cache->list[fnum].url);
136 if (!stream->file) {
139 }
140 if (stream->mode & LAL_FR_STREAM_CHECKSUM_MODE) {
141 if (!XLALFrFileCksumValid(stream->file)) {
142 stream->state |= LAL_FR_STREAM_ERR;
143 XLALFrStreamFileClose(stream);
144 XLAL_ERROR(XLAL_EIO, "Invalid checksum in file %s",
145 stream->cache->list[fnum].url);
146 }
147 }
148 XLALFrFileQueryGTime(&stream->epoch, stream->file, 0);
149 return 0;
150}
151
152/** @endcond */
153
154/* EXPORTED ROUTINES */
155
156/**
157 * @name Routines to Open, Close and Get/Set Modes of a LALFrStream
158 * @{
159 */
160
161/**
162 * @brief Closes a LALFrStream
163 * @details
164 * This routine closes all file pointers and deallocates memory associated
165 * with a given \c LALFrStream. It performs no action if @p stream is NULL.
166 * @param stream Pointer to the \c LALFrStream structure to be closed.
167 * @retval 0 Success.
168 * @retval <0 Failure.
169 */
171{
172 if (stream) {
173 XLALDestroyCache(stream->cache);
174 XLALFrStreamFileClose(stream);
175 LALFree(stream);
176 }
177 return 0;
178}
179
180/**
181 * @brief Opens a LALFrStream associated with a LALCache
182 * @details
183 * This routine creates a \c LALFrStream that is a stream associated with
184 * the frame files contained in a LALCache.
185 * @param cache Pointer to a LALCache structure describing the frame files to stream.
186 * @returns Pointer to a newly created \c LALFrStream structure.
187 * @retval NULL Failure.
188 */
190{
191 LALFrStream *stream;
192 size_t i;
193
194 if (!cache)
196
197 stream = LALCalloc(1, sizeof(*stream));
198 if (!stream)
200 stream->cache = XLALCacheDuplicate(cache);
201
202 /* check cache entries for t0 and dt; if these are not set then read
203 * the framefile to try to get them */
204 for (i = 0; i < stream->cache->length; ++i) {
205 if (stream->cache->list[i].t0 == 0 || stream->cache->list[i].dt == 0) {
207 size_t nFrame;
208 if (XLALFrStreamFileOpen(stream, i) < 0) {
209 XLALFrStreamClose(stream);
211 }
212 nFrame = XLALFrFileQueryNFrame(stream->file);
213 stream->cache->list[i].t0 = stream->epoch.gpsSeconds;
214 XLALFrFileQueryGTime(&end, stream->file, nFrame - 1);
215 XLALGPSAdd(&end, XLALFrFileQueryDt(stream->file, nFrame - 1));
216 stream->cache->list[i].dt =
217 ceil(XLALGPSGetREAL8(&end)) - stream->cache->list[i].t0;
218 XLALFrStreamFileClose(stream);
219 }
220 }
221
222 /* sort and uniqify the cache */
223 if (XLALCacheSort(stream->cache) || XLALCacheUniq(stream->cache)) {
224 XLALFrStreamClose(stream);
226 }
227
229
230 /* open up the first file */
231 if (XLALFrStreamFileOpen(stream, 0) < 0) {
232 XLALFrStreamClose(stream);
234 }
235 return stream;
236}
237
238/**
239 * @brief Opens a LALFrStream for specified frame files.
240 * @details
241 * This routine creates a \c LALFrStream that is a stream associated with
242 * the frame files in the specified directory matching the specified pattern.
243 * The directory containing the frame files is specified by the parameter
244 * @p dirname, or the current directory (@p .) if NULL. Files matching
245 * @p pattern will included in the stream. Wildcards are allowed. For
246 * example, to get LLO frames only, @p pattern could be set to `L-*.gwf`.
247 * If @p pattern is NULL, the default value `*.gwf` is used.
248 * @param dirname String containing the director name containing the frame files
249 * @param pattern Pattern matching the desired frame files.
250 * @returns Pointer to a newly created \c LALFrStream structure.
251 * @retval NULL Failure.
252 */
253LALFrStream *XLALFrStreamOpen(const char *dirname, const char *pattern)
254{
255 LALFrStream *stream;
257
258 cache = XLALCacheGlob(dirname, pattern);
259 if (!cache)
261
263 if (!stream)
265
267 return stream;
268}
269
270/**
271 * @brief Returns the current operating mode of a LALFrStream
272 * @details
273 * The operating mode of a \c LALFrStream determines how routines try
274 * to accommodate gaps in data and requests for times when there is
275 * no data (e.g., before the beginning of the data, after the end of
276 * the data, or in some period of missing data). See XLALFrStreamSetMode()
277 * for a description of the \c LALFrStreamMode modes.
278 * @param stream Pointer to a \c LALFrStream structure whose mode will be
279 * determined.
280 * @returns
281 * The current \c LALFrStreamMode mode, which is a bit field flag of indicating
282 * the current operating modes of the \c LALFrStream.
283 */
285{
286 return stream->mode;
287}
288
289/**
290 * @brief Change the operating mode of a LALFrStream
291 * @details
292 * The operating mode of a \c LALFrStream determines how routines try
293 * to accommodate gaps in data and requests for times when there is
294 * no data (e.g., before the beginning of the data, after the end of
295 * the data, or in some period of missing data).
296 *
297 * The default \c LALFrStreamMode mode, which is given the value
298 * ::LAL_FR_STREAM_DEFAULT_MODE, prints warnings if a time requested
299 * corresponds to a time when there is no data (but then skips to the first
300 * avaliable data) and prints an info message when a gap in the data occurs
301 * (but then skips beyond the gap). This default mode is equal to the
302 * combination
303 * ::LAL_FR_STREAM_VERBOSE_MODE | ::LAL_FR_STREAM_IGNOREGAP_MODE | ::LAL_FR_STREAM_IGNORETIME_MODE
304 * where ::LAL_FR_STREAM_VERBOSE_MODE is equal to the combination
305 * ::LAL_FR_STREAM_TIMEWARN_MODE | ::LAL_FR_STREAM_GAPINFO_MODE. Use
306 * ::LAL_FR_STREAM_VERBOSE_MODE to print out warnings when requesting times
307 * with no data and print out an info message when a gap in the data is
308 * encountered. Unless the mode is supplemented with
309 * ::LAL_FR_STREAM_IGNOREGAP_MODE, gaps encountered in the data will cause
310 * a routine to exit with a non-zero status code; similarly,
311 * ::LAL_FR_STREAM_IGNORETIME_MODE prevents routines from failing if a time
312 * when there is not data is requested. Set the mode to
313 * ::LAL_FR_STREAM_SILENT_MODE to suppress the warning and info messages but
314 * still cause routines to fail when data is not available.
315 * To enable frame file checksum checking, set the ::LAL_FR_STREAM_CHECKSUM_MODE
316 * bit.
317 *
318 * @note The default value ::LAL_FR_STREAM_DEFAULT_MODE is assumed initially,
319 * but this is not necessarily the recommended mode --- it is adopted for
320 * compatibility reasons.
321 *
322 * @param stream Pointer to a \c LALFrStream structure whose mode will be changed.
323 * @param mode Bit lag field specifying the operating modes.
324 * @retval 0 Success.
325 * @retval <0 Current file does not pass frame file checksum.
326 */
327int XLALFrStreamSetMode(LALFrStream * stream, int mode)
328{
329 stream->mode = mode;
330 /* if checksum mode is turned on, do checksum on current file */
331 if ((mode & LAL_FR_STREAM_CHECKSUM_MODE) && (stream->file))
332 return XLALFrFileCksumValid(stream->file) ? 0 : -1;
333 return 0;
334}
335
336/** @} */
337
338/**
339 * @name Routines for Positioning and Manipulating the State of a LALFrStream
340 * @{
341 */
342
343/**
344 * @brief Gets the current state of a LALFrStream
345 * @details
346 * Gets the \c LALFrStreamState state value in a \c LALFrStream structure. The
347 * value returned is a bit field specifying the combination of states described
348 * by the \c LALFrStreamState bits.
349 * @param stream Pointer to a \c LALFrStream structure whose state will be returned.
350 * @returns
351 * The \c LALFrStreamState state of the \c LALFrStream.
352 */
354{
355 return stream->state;
356}
357
358/**
359 * @brief Checks to see if a LALFrStream is at the end of the stream
360 * @details
361 * Determines if the ::LAL_FR_STREAM_END bit is set in the \c LALFrStreamState
362 * state value in a \c LALFrStream structure, indicating that the stream is
363 * at the end.
364 * @param stream Pointer to a \c LALFrStream structure.
365 * @retval 0 The ::LAL_FR_STREAM_END bit is not set in @p stream.
366 * @retval 1 The ::LAL_FR_STREAM_END bit is set in @p stream.
367 */
369{
370 return stream->state & LAL_FR_STREAM_END;
371}
372
373/**
374 * @brief Checks to see if a LALFrStream has encountered an error
375 * @details
376 * Determines if the ::LAL_FR_STREAM_ERR bit is set in the \c LALFrStreamState
377 * state value in a \c LALFrStream structure, indicating that there has been
378 * an error in the stream.
379 * @param stream Pointer to a \c LALFrStream structure.
380 * @retval 0 The ::LAL_FR_STREAM_ERR bit is not set in @p stream.
381 * @retval 1 The ::LAL_FR_STREAM_ERR bit is set in @p stream.
382 */
384{
385 return stream->state & LAL_FR_STREAM_ERR;
386}
387
388/**
389 * @brief Resets the state of a LALFrStream
390 * @details
391 * Sets the \c LALFrStreamState state of a \c LALFrStream structure to the
392 * value ::LAL_FR_STREAM_OK.
393 * @param stream Pointer to a \c LALFrStream structure.
394 * @retval 0 Success.
395 */
397{
398 stream->state = LAL_FR_STREAM_OK;
399 return 0;
400}
401
402/**
403 * @brief Rewinds a LALFrStream stream
404 * @details
405 * Rewinds a \c LALFrStream stream to the beginning and resets the state
406 * to ::LAL_FR_STREAM_OK.
407 * @param stream Pointer to a \c LALFrStream structure.
408 * @retval 0 Success.
409 * @retval <0 Failure.
410 */
412{
413 XLALFrStreamFileClose(stream);
414 stream->state = LAL_FR_STREAM_OK;
415 if (XLALFrStreamFileOpen(stream, 0) < 0)
417 return 0;
418}
419
420/**
421 * @brief Advance a LALFrStream stream to the beginning of the next frame
422 * @details
423 * The position of a LALFrStream is advanced so that the next read will
424 * be at the next frame. If the stream is at the end, the ::LAL_FR_STREAM_END
425 * bit of the LALFrStreamState state is set, and the routine returns the
426 * return code 1. If there is a gap in the data before the next frame,
427 * the ::LAL_FR_STREAM_GAP bit of the LALFrStreamState state is set, and the
428 * routine returns the return code 2. If, however, the
429 * ::LAL_FR_STREAM_IGNOREGAP_MODE bit is not set in the LALFrStreamMode mode
430 * then the routine produces an error if a gap is encountered.
431 * @param stream Pointer to a \c LALFrStream structure.
432 * @retval 2 Gap in the data is encountered.
433 * @retval 1 End of stream encountered.
434 * @retval 0 Normal success.
435 * @retval <0 Failure.
436 */
438{
439 /* timing accuracy: tenth of a sample interval for a 16kHz fast channel */
440 const INT8 tacc = (INT8) floor(0.1 * 1e9 / 16384.0);
441 const char *url1;
442 const char *url2;
443 int pos1;
444 int pos2;
445 INT8 texp = 0;
446 INT8 tact;
447
448 if (stream->state & LAL_FR_STREAM_END)
449 return 1; /* end code */
450
451 /* turn off gap bit */
452 stream->state &= ~LAL_FR_STREAM_GAP;
453
454 url2 = url1 = stream->cache->list[stream->fnum].url;
455 pos2 = pos1 = stream->pos;
456
457 /* open a new file if necessary */
458 if (!stream->file) {
459 if (stream->fnum >= stream->cache->length) {
460 stream->state |= LAL_FR_STREAM_END;
461 return 1;
462 }
463 if (XLALFrStreamFileOpen(stream, stream->fnum) < 0)
465 }
466 if (stream->file) {
467 INT4 nFrame = XLALFrFileQueryNFrame(stream->file);
468 if (stream->pos < nFrame) {
469 LIGOTimeGPS gpstime;
470 XLALGPSToINT8NS(XLALFrFileQueryGTime(&gpstime, stream->file,
471 stream->pos));
472 texp =
474 XLALFrFileQueryDt(stream->file, stream->pos)));
475 ++stream->pos;
476 }
477 if (stream->pos >= nFrame) {
478 XLALFrStreamFileClose(stream);
479 ++stream->fnum;
480 }
481 pos2 = stream->pos;
482 }
483 /* open a new file if necessary */
484 if (!stream->file) {
485 if (stream->fnum >= stream->cache->length) {
486 stream->state |= LAL_FR_STREAM_END;
487 return 1;
488 }
489 if (XLALFrStreamFileOpen(stream, stream->fnum) < 0)
491 url2 = stream->cache->list[stream->fnum].url;
492 pos2 = stream->pos;
493 }
494 /* compute actual start time of this new frame */
495 tact =
497 stream->pos));
498
499 /* INT8 is platform dependent, cast to long long for llabs() call */
500 if (llabs((long long)(texp - tact)) > tacc) { /* there is a gap */
501 stream->state |= LAL_FR_STREAM_GAP;
502 if (stream->mode & LAL_FR_STREAM_GAPINFO_MODE) {
503 XLAL_PRINT_INFO("Gap in frame data between times %.6f and %.6f",
504 1e-9 * texp, 1e-9 * tact);
505 }
506 if (!(stream->mode & LAL_FR_STREAM_IGNOREGAP_MODE)) {
507 XLAL_PRINT_ERROR("Gap in frame data");
508 XLAL_PRINT_ERROR("Time %.6f is end of frame %d of file %s",
509 1e-9 * texp, pos1, url1);
510 XLAL_PRINT_ERROR("Time %.6f is start of frame %d of file %s",
511 1e-9 * tact, pos2, url2);
513 }
514 return 2; /* gap code */
515 }
516 return 0;
517}
518
519/**
520 * @brief Seeks a LALFrStream stream to data at a given time
521 * @details
522 * The position of a LALFrStream is set so that the next read will
523 * be at the specified time. ::LAL_FR_STREAM_END and ::LAL_FR_STREAM_GAP
524 * bits are turned off in the \c LALFrStreamState state. If the time is before
525 * the beginning of the stream, the stream position is set to the beginning of
526 * the stream and the routine returns with code 1. If the time is after the
527 * end of the stream, the ::LAL_FR_STREAM_END bit is set in the
528 * \c LALFrStreamState state, and the routine returns with code 2. If the time
529 * is in a gap in the data, the ::LAL_FR_STREAM_GAP bit is set in the
530 * \c LALFrStreamState state, the position is advanced to the next data, and the
531 * routine returns with code 3. If, however, the
532 * ::LAL_FR_STREAM_IGNORETIME_MODE bit is not set in the LALFrStreamMode mode
533 * then these conditions result in an error.
534 * @param stream Pointer to a \c LALFrStream structure.
535 * @param epoch The LIGOTimeGPS time of the next data to read.
536 * @retval 3 Time requested is in a gap in the data.
537 * @retval 2 Time requested is after the end of the stream.
538 * @retval 1 Time requested is before the beginning of the stream.
539 * @retval 0 Normal success.
540 * @retval <0 Failure.
541 */
542int XLALFrStreamSeek(LALFrStream * stream, const LIGOTimeGPS * epoch)
543{
544 double twant = XLALGPSGetREAL8(epoch);
545 LALCacheEntry *entry;
546
547 /* close file if one is open */
548 XLALFrStreamFileClose(stream);
549
550 /* clear EOF or GAP states; preserve ERR state */
551 if (stream->state & LAL_FR_STREAM_ERR)
552 stream->state = LAL_FR_STREAM_ERR;
553 else
554 stream->state = LAL_FR_STREAM_OK;
555
556 /* is epoch before first file? */
557 if (epoch->gpsSeconds < stream->cache->list->t0) {
558 XLALFrStreamRewind(stream);
559 stream->state |= LAL_FR_STREAM_GAP;
560 /* is this reported as an error? */
561 if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) {
562 /* FIXME: if this is an error, should the stream state say so? */
563 /* stream->state |= LAL_FR_STREAM_ERR; */
565 }
566 if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
567 XLAL_PRINT_WARNING("Requested time %d before first frame",
568 epoch->gpsSeconds);
569 return 1; /* before first file code */
570 }
571
572 /* seek for the time in the cache */
573 entry = XLALCacheEntrySeek(stream->cache, twant);
574 if (!entry) { /* seek failed: only happens if time is past end of cache */
575 stream->fnum = stream->cache->length;
576 stream->epoch = *epoch;
577 stream->state |= LAL_FR_STREAM_END;
578 /* is this reported as an error? */
579 if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) {
580 /* FIXME: if this is an error, should the stream state say so? */
581 /* stream->state |= LAL_FR_STREAM_ERR; */
583 }
584 if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
585 XLAL_PRINT_WARNING("Requested time %d after last frame",
586 epoch->gpsSeconds);
587 return 2; /* after last file code */
588 }
589
590 /* now we must find the position within the frame file */
591 for (stream->fnum = entry - stream->cache->list;
592 stream->fnum < stream->cache->length; ++stream->fnum) {
593 /* check the file contents to determine the position that matches */
594 size_t nFrame;
595 if (XLALFrStreamFileOpen(stream, stream->fnum) < 0)
597 if (epoch->gpsSeconds < stream->cache->list[stream->fnum].t0) {
598 /* detect a gap between files */
599 stream->state |= LAL_FR_STREAM_GAP;
600 break;
601 }
602 nFrame = XLALFrFileQueryNFrame(stream->file);
603 for (stream->pos = 0; stream->pos < (int)nFrame; ++stream->pos) {
604 LIGOTimeGPS start;
605 int cmp;
606 XLALFrFileQueryGTime(&start, stream->file, stream->pos);
607 cmp = XLALGPSCmp(epoch, &start);
608 if (cmp >= 0
610 &start) < XLALFrFileQueryDt(stream->file, stream->pos))
611 break; /* this is the frame! */
612 if (cmp < 0) {
613 /* detect a gap between frames within a file */
614 stream->state |= LAL_FR_STREAM_GAP;
615 break;
616 }
617 }
618 if (stream->pos < (int)nFrame) /* we've found the frame */
619 break;
620 /* oops... not in this frame file, go on to the next one */
621 /* probably the frame file was mis-named.... */
622 XLALFrStreamFileClose(stream);
623 }
624
625 if (stream->fnum >= stream->cache->length) {
626 /* we've gone right to the end without finding it! */
627 stream->fnum = stream->cache->length;
628 stream->epoch = *epoch;
629 stream->state |= LAL_FR_STREAM_END;
630 /* is this reported as an error? */
631 if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) {
632 /* FIXME: if this is an error, should the stream state say so? */
633 /* stream->state |= LAL_FR_STREAM_ERR; */
635 }
636 if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
637 XLAL_PRINT_WARNING("Requested time %d after last frame",
638 epoch->gpsSeconds);
639 return 2; /* after last file code */
640 }
641
642 /* set the time of the stream */
643 if (stream->state & LAL_FR_STREAM_GAP) {
644 XLALFrFileQueryGTime(&stream->epoch, stream->file, stream->pos);
645 if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
646 XLAL_PRINT_WARNING("Requested time %.6f in gap in frame data",
647 twant);
648 if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE))
650 return 3; /* in a gap code */
651 }
652 stream->epoch = *epoch;
653 return 0;
654}
655
656/**
657 * @brief Seeks a LALFrStream stream by a time offset
658 * @details
659 * The position of a LALFrStream is set so that the next read will
660 * be at the specified time offset. The offset @p dt is a number of
661 * seconds relative to the @p whence postion, which can be
662 * @p SEEK_SET to seek relative to the beginning of the stream,
663 * @p SEEK_CUR to seek relative to the current position of the stream,
664 * or @p SEEK_END to seek relative to the end of the stream.
665 * The return codes and conditions are the same as XLALFrStreamSeek().
666 * @param stream Pointer to a \c LALFrStream structure.
667 * @param dt The offset time in seconds.
668 * @param whence The position whence to seek: one of @p SEEK_SET, @p SEEK_CUR,
669 * or @p SEEK_END.
670 * @retval 3 Time requested is in a gap in the data.
671 * @retval 2 Time requested is after the end of the stream.
672 * @retval 1 Time requested is before the beginning of the stream.
673 * @retval 0 Normal success.
674 * @retval <0 Failure.
675 */
676int XLALFrStreamSeekO(LALFrStream * stream, double dt, int whence)
677{
679 switch (whence) {
680 case SEEK_SET:
681 if (XLALFrStreamRewind(stream) < 0)
683 /* FALL THROUGH */
684 case SEEK_CUR:
685 epoch = stream->epoch;
686 break;
687 case SEEK_END:
688 /* go to the last frame */
689 XLALFrStreamFileClose(stream);
690 if (XLALFrStreamFileOpen(stream, stream->cache->length - 1) < 0)
692 if ((stream->pos = XLALFrFileQueryNFrame(stream->file) - 1) < 0)
694 if (XLALFrFileQueryGTime(&epoch, stream->file, stream->pos) == NULL)
696 /* add duration of last frame to dt */
697 dt += XLALFrFileQueryDt(stream->file, stream->pos);
698 break;
699 default:
701 "Invalid whence value: use SEEK_SET, SEEK_CUR, or SEEK_END");
702 }
704 if (XLALFrStreamSeek(stream, &epoch) < 0)
706 return 0;
707}
708
709/**
710 * @brief Tells the current time of the current position of a LALFrStream
711 * stream
712 * @param[out] epoch Pointer to a LIGOTimeGPS structure that will contain the
713 * time of the current position of the stream.
714 * @param[in] stream Pointer to a \c LALFrStream structure.
715 * @retval 0 Success.
716 */
718{
719 *epoch = stream->epoch;
720 return 0;
721}
722
723/**
724 * @brief Gets the current position of a LALFrStream stream
725 * @details
726 * The XLALFrStreamGetpos() and XLALFrStreamSetpos() provide the ability
727 * to save the position of a \c LALFrStream stream and to return the stream
728 * to that previously saved position. This can be useful, e.g., when reading
729 * several different channels from the data files.
730 * @param[out] position Pointer to a \c LALFrStreamPos structure that will save
731 * the current position.
732 * @param[in] stream Pointer to a \c LALFrStream structure.
733 * time of the current position of the stream.
734 * @retval 0 Success.
735 */
737{
738 position->epoch = stream->epoch;
739 position->fnum = stream->fnum;
740 position->pos = stream->pos;
741 return 0;
742}
743
744/**
745 * @brief Sets the current position of a LALFrStream stream
746 * @details
747 * The XLALFrStreamGetpos() and XLALFrStreamSetpos() provide the ability
748 * to save the position of a \c LALFrStream stream and to return the stream
749 * to that previously saved position. This can be useful, e.g., when reading
750 * several different channels from the data files.
751 * @param[in, out] stream Pointer to a \c LALFrStream structure.
752 * @param[in] position Pointer to a \c LALFrStreamPos structure that has a
753 * previously saved position.
754 * @retval 0 Success.
755 */
756int XLALFrStreamSetpos(LALFrStream * stream, const LALFrStreamPos * position)
757{
758 /* clear EOF or GAP states; preserve ERR state */
759 if (stream->state & LAL_FR_STREAM_ERR)
760 stream->state = LAL_FR_STREAM_ERR;
761 else
762 stream->state = LAL_FR_STREAM_OK;
763
764 if (stream->fnum != position->fnum) {
765 XLALFrStreamFileClose(stream);
766 if (position->fnum >= stream->fnum) {
767 stream->fnum = stream->cache->length;
768 stream->state |= LAL_FR_STREAM_END;
770 }
771 if (XLALFrStreamFileOpen(stream, position->fnum) < 0)
773 }
774 stream->epoch = position->epoch;
775 stream->pos = position->pos;
776 if (stream->pos > (INT4) XLALFrFileQueryNFrame(stream->file)) {
777 stream->state |= LAL_FR_STREAM_ERR;
779 }
780 return 0;
781}
782
783/** @} */
784
785/** @} */
#define LALCalloc(m, n)
#define LALFree(p)
LALCacheEntry * XLALCacheEntrySeek(const LALCache *cache, double t)
void XLALDestroyCache(LALCache *cache)
LALCache * XLALCacheGlob(const char *dirstr, const char *fnptrn)
int XLALCacheUniq(LALCache *cache)
LALCache * XLALCacheDuplicate(const LALCache *cache)
int XLALCacheSort(LALCache *cache)
int64_t INT8
uint32_t UINT4
int32_t INT4
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 XLALFrStreamState(LALFrStream *stream)
Gets the current state of a LALFrStream.
Definition: LALFrStream.c:353
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
int XLALFrStreamEnd(LALFrStream *stream)
Checks to see if a LALFrStream is at the end of the stream.
Definition: LALFrStream.c:368
LALFrStream * XLALFrStreamCacheOpen(LALCache *cache)
Opens a LALFrStream associated with a LALCache.
Definition: LALFrStream.c:189
int XLALFrStreamRewind(LALFrStream *stream)
Rewinds a LALFrStream stream.
Definition: LALFrStream.c:411
int XLALFrStreamGetpos(LALFrStreamPos *position, LALFrStream *stream)
Gets the current position of a LALFrStream stream.
Definition: LALFrStream.c:736
int XLALFrStreamNext(LALFrStream *stream)
Advance a LALFrStream stream to the beginning of the next frame.
Definition: LALFrStream.c:437
LALFrStream * XLALFrStreamOpen(const char *dirname, const char *pattern)
Opens a LALFrStream for specified frame files.
Definition: LALFrStream.c:253
int XLALFrStreamSetMode(LALFrStream *stream, int mode)
Change the operating mode of a LALFrStream.
Definition: LALFrStream.c:327
int gethostname(char *name, int len)
int XLALFrStreamSetpos(LALFrStream *stream, const LALFrStreamPos *position)
Sets the current position of a LALFrStream stream.
Definition: LALFrStream.c:756
int XLALFrStreamClearErr(LALFrStream *stream)
Resets the state of a LALFrStream.
Definition: LALFrStream.c:396
int XLALFrStreamError(LALFrStream *stream)
Checks to see if a LALFrStream has encountered an error.
Definition: LALFrStream.c:383
@ LAL_FR_STREAM_CHECKSUM_MODE
ensure that file checksums are OK
Definition: LALFrStream.h:88
@ LAL_FR_STREAM_DEFAULT_MODE
ignore time/gaps but report warnings & info
Definition: LALFrStream.h:87
@ LAL_FR_STREAM_IGNOREGAP_MODE
ignore gaps in data
Definition: LALFrStream.h:85
@ 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
@ LAL_FR_STREAM_GAPINFO_MODE
display info for gaps in data
Definition: LALFrStream.h:83
@ LAL_FR_STREAM_GAP
gap in frame stream
Definition: LALFrStream.h:74
@ LAL_FR_STREAM_OK
nominal
Definition: LALFrStream.h:71
@ LAL_FR_STREAM_URL
error opening frame URL
Definition: LALFrStream.h:75
@ LAL_FR_STREAM_ERR
error in frame stream
Definition: LALFrStream.h:72
@ LAL_FR_STREAM_END
end of frame stream
Definition: LALFrStream.h:73
double XLALFrFileQueryDt(const LALFrFile *frfile, size_t pos)
Query a frame file for the duration of a particular frame.
Definition: LALFrameIO.c:143
int XLALFrFileCksumValid(LALFrFile *frfile)
Use checksum to determine if a frame file is valid.
Definition: LALFrameIO.c:205
size_t XLALFrFileQueryNFrame(const LALFrFile *frfile)
Query a frame file for the number of frames contained in the file.
Definition: LALFrameIO.c:130
LIGOTimeGPS * XLALFrFileQueryGTime(LIGOTimeGPS *start, const LALFrFile *frfile, size_t pos)
Query a frame file for the start time of a particular frame.
Definition: LALFrameIO.c:135
LALFrFile * XLALFrFileOpenURL(const char *url)
Open frame file for reading and return a LALFrFile structure.
Definition: LALFrameIO.c:70
int XLALFrFileClose(LALFrFile *frfile)
Close a frame file described by a LALFrFile structure.
Definition: LALFrameIO.c:54
#define XLAL_PRINT_INFO(...)
#define XLAL_ERROR_NULL(...)
#define XLAL_ERROR(...)
#define XLAL_PRINT_WARNING(...)
#define XLAL_PRINT_ERROR(...)
XLAL_ENOMEM
XLAL_EFAULT
XLAL_EFUNC
XLAL_EIO
XLAL_EINVAL
XLAL_ETIME
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
int XLALGPSCmp(const LIGOTimeGPS *t0, const LIGOTimeGPS *t1)
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
INT8 XLALGPSToINT8NS(const LIGOTimeGPS *epoch)
end
double dt
Definition: stream.c:110
LALCache * cache
Definition: stream.c:107
CHAR * url
INT4 t0
INT4 dt
UINT4 length
LALCacheEntry * list
This structure details the state of the frame stream.
Definition: LALFrStream.h:95
LALFrStreamState state
Definition: LALFrStream.h:96
LIGOTimeGPS epoch
Definition: LALFrStream.h:98
LALCache * cache
Definition: LALFrStream.h:99
LALFrFile * file
Definition: LALFrStream.h:101
This structure contains a record of the state of a frame stream; this record can be used to restore t...
Definition: LALFrStream.h:110
UINT4 fnum
the file number of a list of frame files that was open when the record was made
Definition: LALFrStream.h:112
LIGOTimeGPS epoch
the GPS time of the open frame when the record was made
Definition: LALFrStream.h:111
INT4 pos
the position within the frame file that was open when the record was made
Definition: LALFrStream.h:113
enum @1 epoch