LALApps 10.1.0.1-eeff03c
animate.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Jolien Creighton, Patrick Brady
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 * \file
22 * \ingroup lalapps_frametools
23 *
24 * <dl>
25 *
26 * <dt>Name</dt><dd>
27 * \c lal_animate --- produces an animated display showing the time
28 * series output of a selected channel in a lower window, and a simultaneously
29 * calculated FFT power spectrum in the upper window</dd>
30 *
31 * <dt>Synopsis</dt><dd>
32 * \c lal_animate [<tt>--help</tt>] [<tt>--channel</tt> \e name]
33 * [<tt>--duration</tt> \e secs] [<tt>--epoch</tt> \e sec
34 * \e nsec] [<tt>--framedir</tt> \e dirname]
35 * [<tt>--highpass</tt> \e freq \e attenuation]
36 * [<tt>--numpts</tt> \e npoints] \f$|\f$ xmgr -pipe</dd>
37 *
38 * <dt>Description</dt><dd>
39 * \c lal_animate produces an animated display showing the time
40 * series output of a selected channel in a lower window, and a simultaneously
41 * calculated FFT power spectrum in the upper window. The output from
42 * this program must be piped into the graphing program \c xmgr.</dd>
43 *
44 * <dt>Options</dt><dd>
45 * <ul>
46 * <li><tt>--help</tt>:
47 * Print a help message.
48 * <li><tt>--channel</tt> \e name:
49 * Name of frame channel
50 * <li><tt>--duration</tt> \e secs:
51 * How many seconds to look at
52 * <li><tt>--epoch</tt> \e sec \e nsec:
53 * Starting epoch
54 * <li><tt>--framedir</tt> \e dirname:
55 * Directory containing frame files
56 * <li><tt>--highpass</tt> \e freq \e attenuation:
57 * High-pass filter parameters
58 * <li><tt>--numpts</tt> \e npoints:
59 * Points per graph to display
60 * </ul></dd>
61 *
62 * <dt>Example</dt><dd>
63 * To run the program, type:
64 * \code
65 * lalapps_animate --channel H2:LSC-AS_Q --framedir ./h1 --numpts 16384 \
66 * --epoch 693768272 0 --duration 1 --highpass 300 0.01 | xmgr -pipe
67 * \endcode
68 * This will search in directory <tt>./h1</tt> for frame files containing
69 * the channel <tt>H2:LSC-AS_Q</tt> and pipe the data starting at 693768272
70 * GPS seconds and 0 GPS nanonseconds to xmgr in segments containing 16384
71 * points until 1 seconds of data has been reviewed. The data is highpass
72 * filtered to above 300 Hz with an attenuation of \f$0.1\f$; the output is
73 * shown in \ref f_animate "this figure".
74 *
75 * \anchor f_animate
76 * \image html animate.png "Example of output from \c lalapps_animate program"
77 *
78 * <dt>Author</dt><dd>
79 * Bruce Allen and Patrick Brady
80 * </dd>
81 * </dl>
82 */
83
84#include <stdio.h>
85#include <math.h>
86
87#include <lal/LALStdlib.h>
88#include <lal/AVFactories.h>
89#include <lal/PrintFTSeries.h>
90#include <lal/LALFrStream.h>
91#include <lal/Units.h>
92#include <lal/BandPassTimeSeries.h>
93
94#define TRUE 1
95#define FALSE 0
96
97#define FRAMEHEARSEEC_ENORM 0
98#define FRAMEHEARSEEC_EARG 2
99
100#define FRAMEHEARSEEC_MSGENORM "Normal exit"
101#define FRAMEHEARSEEC_MSGEARG "Error parsing arguments"
102
103/* Usage format string. */
104#define USAGE "Usage: %s [options] | xmgr -pipe\n"\
105 " --help Print this help message\n" \
106 " --channel name Name of frame channel\n" \
107 " [--duration secs] How many seconds to look at\n"\
108 " [--epoch sec nsec] The starting epoch\n"\
109 " [--framedir dirname] Directory containing frame files\n"\
110 " [--highpass freq attenuation] High-pass filter parameters \n"\
111 " [--numpts npoints] Points per graph displayed\n"
112
113
114#include <config.h>
115#ifndef HAVE_LIBLALFRAME
116int main( void )
117{
118 fputs( "Disabled: LALApps compiled with non-frame-enabled LAL\n", stderr );
119 return 77;
120}
121#else
122
123/* This routine is pipes output into the xmgr graphing program */
124static void graphout(float x1,float x2,int thistime, int last) {
125 static int count=0;
126 printf("&\n"); /* end of set marker */
127 /* first time we draw the plot */
128 if (count==0) {
129 printf("@doublebuffer true\n"); /* keeps display from flashing */
130 printf("@s0 color 3\n"); /* IFO graph is green */
131 printf("@view 0.1, 0.1, 0.9, 0.45\n"); /* set the viewport for IFO */
132 printf("@with g1\n"); /* reset the current graph to FFT */
133 printf("@view 0.1, 0.6, 0.9, 0.95\n");/* set the viewport FFT */
134 printf("@with g0\n"); /* reset the current graph to IFO */
135 printf("@world xmin %f\n",x1); /* set min x */
136 printf("@world xmax %f\n",x2); /* set max x */
137 printf("@autoscale\n"); /* autoscale first time through */
138 printf("@focus off\n"); /* turn off the focus markers */
139 printf("@xaxis label \"t (sec)\"\n"); /* IFO axis label */
140 printf("@fft(s0, 1)\n"); /* compute the spectrum */
141 printf("@s1 color 2\n"); /* FFT is red */
142 printf("@move g0.s1 to g1.s0\n"); /* move FFT to graph 1 */
143 printf("@with g1\n"); /* set the focus on FFT */
144 printf("@g1 type logy\n"); /* set FFT to log freq axis */
145 printf("@autoscale\n"); /* autoscale FFT */
146 printf("@subtitle \"Spectrum\"\n"); /* set the subtitle */
147 printf("@xaxis label \"f (Hz)\"\n"); /* FFT axis label */
148 printf("@with g0\n"); /* reset the current graph IFO */
149 printf("@subtitle \"IFO output %d\"\n",thistime);/* set IFO subtitle */
150 count++;/* set IFO subtitle */
151 if (!last) printf("@kill s0\n"); /* kill IFO; ready to read again */
152 }
153 else {
154 /* other times we redraw the plot */
155 printf("@s0 color 3\n"); /* set IFO green */
156 printf("@fft(s0, 1)\n"); /* FFT it */
157 printf("@s1 color 2\n"); /* set FFT red */
158 printf("@move g0.s1 to g1.s0\n"); /* move FFT to graph 1 */
159 printf("@subtitle \"IFO output %d\"\n",thistime);/* set IFO subtitle */
160 count++;
161 printf("@world xmin %f\n",x1); /* set min x */
162 printf("@world xmax %f\n",x2); /* set max x */
163 printf("@autoscale yaxes\n"); /* autoscale IFO */
164 printf("@clear stack\n"); /* clear the stack */
165 if (!last) printf("@kill s0\n"); /* kill IFO data */
166 printf("@with g1\n"); /* switch to FFT */
167 printf("@g1 type logy\n"); /* set FFT to log freq axis */
168 printf("@clear stack\n"); /* clear stack */
169 if (!last) printf("@kill s0\n"); /* kill FFT */
170 printf("@with g0\n"); /* ready to read IFO again */
171 }
172 return;
173}
174
175
176
177int main( int argc, char *argv[] )
178{
179 static LALStatus status;
180 LALFrStream *stream = NULL;
181 FrChanIn channelIn;
182 REAL4 itime, numSeconds=0;
183 INT4 i, numPoints=4096, inarg = 1;
184 CHAR *dirname;
186 LIGOTimeGPS epoch = {0,0};
187 BOOLEAN epochSet = FALSE;
188 BOOLEAN highpass = FALSE;
189 PassBandParamStruc highpassParam;
190
191 /* set default values for input */
192 dirname = getenv( "LAL_FRAME_PATH" );
193
194 /* Set up for a highpass filter */
195 highpassParam.nMax = 4;
196 highpassParam.f1 = -1.0;
197 highpassParam.a1 = -1.0;
198
199 /*******************************************************************
200 * PARSE ARGUMENTS (arg stores the current position) *
201 *******************************************************************/
202
203 if (argc <= 1){
204 LALPrintError( USAGE, *argv );
205 return 0;
206 }
207
208 while ( inarg < argc ) {
209 /* Parse output file option. */
210 if ( !strcmp( argv[inarg], "--help" ) ) {
211 if ( argc > inarg + 1 ) {
212 inarg++;
213 fprintf(stderr,"Should be a usage message\n");
214 exit(0);
215 }else{
216 LALPrintError( USAGE , *argv );
217 return FRAMEHEARSEEC_EARG;
218 }
219 }
220 else if ( !strcmp( argv[inarg], "--epoch" ) ) {
221 if ( argc > inarg + 1 ) {
222 inarg++;
223 epoch.gpsSeconds = atoi( argv[inarg++] );
224 epoch.gpsNanoSeconds = atoi( argv[inarg++] );
225 epochSet = TRUE;
226 }else{
227 LALPrintError( USAGE, *argv );
228 return FRAMEHEARSEEC_EARG;
229 }
230 }
231 else if ( !strcmp( argv[inarg], "--numpts" ) ) {
232 if ( argc > inarg + 1 ) {
233 inarg++;
234 numPoints = atoi( argv[inarg++] );
235 }else{
236 LALPrintError( USAGE, *argv );
237 return FRAMEHEARSEEC_EARG;
238 }
239 }
240 else if ( !strcmp( argv[inarg], "--highpass" ) ) {
241 if ( argc > inarg + 1 ) {
242 inarg++;
243 highpass = TRUE;
244 highpassParam.f2 = atof( argv[inarg++] );
245 highpassParam.a2 = atof( argv[inarg++] );
246 }else{
247 LALPrintError( USAGE, *argv );
248 return FRAMEHEARSEEC_EARG;
249 }
250 }
251 else if ( !strcmp( argv[inarg], "--duration" ) ) {
252 if ( argc > inarg + 1 ) {
253 inarg++;
254 numSeconds = atof( argv[inarg++] );
255 }else{
256 LALPrintError( USAGE, *argv );
257 return FRAMEHEARSEEC_EARG;
258 }
259 }
260 else if ( !strcmp( argv[inarg], "--channel" ) ) {
261 if ( argc > inarg + 1 ) {
262 inarg++;
263 channelIn.name = argv[inarg++];
264 channelIn.type = ADCDataChannel;
265 }else{
266 LALPrintError( USAGE, *argv );
267 return FRAMEHEARSEEC_EARG;
268 }
269 }
270 else if ( !strcmp( argv[inarg], "--framedir" ) ) {
271 if ( argc > inarg + 1 ) {
272 inarg++;
273 dirname = argv[inarg++];
274 }else{
275 LALPrintError( USAGE, *argv );
276 return FRAMEHEARSEEC_EARG;
277 }
278 }
279 /* Check for unrecognized options. */
280 else if ( argv[inarg][0] == '-' ) {
281 LALPrintError( USAGE, *argv );
282 return FRAMEHEARSEEC_EARG;
283 }
284 } /* End of argument parsing loop. */
285
286 /* Open frame stream */
287 LALFrOpen( &status, &stream, dirname, "*.gwf" );
288
289 /* Determine information about the channel */
290 series.data = NULL;
291 LALFrGetREAL4TimeSeries( &status, &series, &channelIn, stream);
292 if (epochSet ){
293 series.epoch.gpsSeconds = epoch.gpsSeconds;
294 series.epoch.gpsNanoSeconds = epoch.gpsNanoSeconds;
295 }
296 LALFrSeek(&status, &(series.epoch), stream);
297
298 /* allocate time series */
300
301 /* get the data */
302 LALFrGetREAL4TimeSeries( &status, &series, &channelIn, stream);
303
304 while ( !(status.statusCode) &&
305 (series.epoch.gpsSeconds < epoch.gpsSeconds + (INT4)(numSeconds))){
306
307 /* filter it if the highpass parameters were set */
308 if (highpass){
309 LALButterworthREAL4TimeSeries(&status, &series, &highpassParam);
310 }
311
312 /* print out the contents */
313 for (i=0 ; i<32 ; i++ ){
314 itime= i * series.deltaT;
315 printf("%e\t%e\n", itime,0.0);
316 }
317 for (i=32 ; i<numPoints ; i++) {
318 itime= i * series.deltaT;
319 printf("%e\t%e\n", itime, series.data->data[i]);
320 }
321
322 /* put out information for the graphing program */
323 graphout(0, 0+numPoints * series.deltaT, series.epoch.gpsSeconds,
324 (status.statusCode == FRAMESTREAMH_EDONE ||
325 (series.epoch.gpsSeconds + (INT4)(numPoints*series.deltaT)
326 >= epoch.gpsSeconds + (INT4)(numSeconds)) ));
327
328 /* get the data */
329 LALFrGetREAL4TimeSeries( &status, &series, &channelIn, stream);
330 }
331
332 /* close the frame stream */
333 LALFrClose( &status, &stream );
334
335 /*
336 * output the sound file
337 * sprintf(fname, "%s", channelIn.name);
338 * LALTimeSeriesToSound( &status, tSeries, fname, 1);
339 */
340
341 /* clean up */
344 return 0;
345}
346
347#endif
void LALFrSeek(LALStatus *status, const LIGOTimeGPS *epoch, LALFrStream *stream)
#define ADCDataChannel
void LALFrOpen(LALStatus *status, LALFrStream **stream, const CHAR *dirname, const CHAR *pattern)
void LALFrGetREAL4TimeSeries(LALStatus *status, REAL4TimeSeries *series, FrChanIn *chanin, LALFrStream *stream)
void LALFrClose(LALStatus *status, LALFrStream **stream)
void LALCheckMemoryLeaks(void)
#define fprintf
#define USAGE
Definition: animate.c:104
int main(void)
Definition: animate.c:116
#define TRUE
Definition: animate.c:94
#define FALSE
Definition: animate.c:95
#define FRAMEHEARSEEC_EARG
Definition: animate.c:98
void LALButterworthREAL4TimeSeries(LALStatus *stat, REAL4TimeSeries *series, PassBandParamStruc *params)
unsigned char BOOLEAN
char CHAR
int32_t INT4
float REAL4
int LALPrintError(const char *fmt,...)
void LALSDestroyVector(LALStatus *, REAL4Vector **)
void LALCreateVector(LALStatus *, REAL4Vector **, UINT4)
long long count
static LALStatus status
Definition: inspinj.c:552
int i
Definition: inspinj.c:596
ChannelType type
const CHAR * name
INT4 statusCode
Definition: series.h:36
float * data
Definition: series.h:46
enum @1 epoch
INT4 numPoints
Definition: tmpltbank.c:399