LAL  7.5.0.1-89842e6
BandPassTest.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton, Teviet 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 #include <lal/LALStdio.h>
21 #include <lal/LALStdlib.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <lal/AVFactories.h>
26 #include <lal/BandPassTimeSeries.h>
27 #include <lal/StreamInput.h>
28 #include <lal/StreamOutput.h>
29 
30 /**
31  * \author Creighton, T. D.
32  * \file
33  * \ingroup BandPassTimeSeries_h
34  *
35  * \brief Tests time-domain high- and low-pass filters.
36  *
37  * ### Usage ###
38  *
39  * \code
40  * BandPassTest [-d debuglevel] [-i infile | -n npts dt offset] [-o outfile]
41  * [-f f1 f2 a1 a2 order]
42  * \endcode
43  *
44  * ### Description ###
45  *
46  * This program applies a Butterworth time-domain low-pass or high-pass
47  * filter to a time series, using the routine
48  * <tt>LALDButterworthREAL4TimeSeries()</tt>. The following option flags
49  * are accepted:
50  * <ul>
51  * <li>[<tt>-d</tt>] Changes the default debug level from 0 to
52  * \c debuglevel.</li>
53  * <li>[<tt>-i</tt>] Reads the input time series from \c infile
54  * using the routine LALSReadTSeries(); see \ref StreamInput_h
55  * for a description of the file format.</li>
56  * <li>[<tt>-n</tt>] Generates an input time series of length
57  * \c npts and sampling interval \c dt, containing just an
58  * impulse at sample index \c offset. If the <tt>-i</tt> option is
59  * also given, it overrides this option. If neither are given,
60  * <tt>-n 4096 1.0 1024</tt> is assumed.</li>
61  * <li>[<tt>-o</tt>] Writes the output time series to \c outfile,
62  * using the routine LALSWriteTSeries(); see StreamOutput_h
63  * for a description of the file format. If not specified, the routines
64  * are exercised, but no output is written.</li>
65  * <li>[<tt>-f</tt>] Sets the filter to have attenuation \c a1 and
66  * \c a2 at frequencies \c f1 and \c f2, with a maximum
67  * filter order of \c order; see \ref ButterworthTimeSeries_c for a
68  * description of how these values are interpreted. If not specified,
69  * <tt>-f 0.01 0.015 0.9 0.1 20</tt> is assumed.</li>
70  * </ul>
71  */
72 
73 /** \name Error Codes */
74 /** @{ */
75 #define BANDPASSTESTC_ENORM 0 /**< Normal exit */
76 #define BANDPASSTESTC_ESUB 1 /**< Subroutine failed */
77 #define BANDPASSTESTC_EARG 2 /**< Error parsing arguments */
78 #define BANDPASSTESTC_EBAD 3 /**< Bad argument values */
79 #define BANDPASSTESTC_EFILE 4 /**< Could not open file */
80 /** @} */
81 
82 /** \cond DONT_DOXYGEN */
83 #define BANDPASSTESTC_MSGENORM "Normal exit"
84 #define BANDPASSTESTC_MSGESUB "Subroutine failed"
85 #define BANDPASSTESTC_MSGEARG "Error parsing arguments"
86 #define BANDPASSTESTC_MSGEBAD "Bad argument values"
87 #define BANDPASSTESTC_MSGEFILE "Could not open file"
88 
89 /* Default parameters. */
90 #define NPTS 4096 /* Length of time series. */
91 #define DT 1.0 /* Sampling interval of time series. */
92 #define OFFSET 1024 /* Offset of the impulse from the start. */
93 #define F1 0.01 /* Lower frequency of transition band. */
94 #define F2 0.015 /* Upper frequency of transition band. */
95 #define A1 0.9 /* Desired attenuation at F1. */
96 #define A2 0.1 /* Desired attenuation at F2. */
97 #define ORDER 20 /* Maximum filter order. */
98 
99 /* Usage format string. */
100 #define USAGE "Usage: %s [-d debuglevel] [-i infile | -n npts dt offset]\n" \
101 "\t[-o outfile] [-f f1 f2 a1 a2 order]\n"
102 
103 /* Macros for printing errors and testing subroutines. */
104 #define ERROR( code, msg, statement ) \
105 do { \
106  if ( lalDebugLevel & LALERROR ) \
107  LALPrintError( "Error[0] %d: program %s, file %s, line %d, %s\n" \
108  " %s %s\n", (code), *argv, __FILE__, \
109  __LINE__, "$Id$", statement ? statement : \
110  "", (msg) ); \
111 } while (0)
112 
113 #define INFO( statement ) \
114 do { \
115  if ( lalDebugLevel & LALINFO ) \
116  LALPrintError( "Info[0]: program %s, file %s, line %d, %s\n" \
117  " %s\n", *argv, __FILE__, __LINE__, \
118  "$Id$", (statement) ); \
119 } while (0)
120 
121 #define SUB( func, statusptr ) \
122 do { \
123  if ( (func), (statusptr)->statusCode ) { \
124  ERROR( BANDPASSTESTC_ESUB, BANDPASSTESTC_MSGESUB, \
125  "Function call \"" #func "\" failed:" ); \
126  return BANDPASSTESTC_ESUB; \
127  } \
128 } while (0)
129 
130 int
131 main(int argc, char **argv)
132 {
133  static LALStatus stat; /* LALStatus pointer */
134  CHAR *infile = NULL; /* The input filename */
135  CHAR *outfile = NULL; /* The output filename */
136  INT4 arg; /* Argument counter */
137  UINT4 npts = NPTS; /* Number of points in time series */
138  UINT4 offset = OFFSET; /* Position of delta function */
139  REAL8 dt = DT; /* Sampling interval. */
140  static REAL4TimeSeries series; /* Time series */
141  static PassBandParamStruc params; /* Filter parameters */
142 
144 
145  /* Set up the default filter parameters. */
146  params.f1 = F1;
147  params.f2 = F2;
148  params.a1 = A1;
149  params.a2 = A2;
150  params.nMax = ORDER;
151 
152  /* Parse argument list. i stores the current position. */
153  arg = 1;
154  while ( arg < argc ) {
155  /* Parse debuglevel option. */
156  if ( !strcmp( argv[arg], "-d" ) ) {
157  if ( argc > arg + 1 ) {
158  arg++;
159  } else {
160  ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
161  LALPrintError( USAGE, *argv );
162  return BANDPASSTESTC_EARG;
163  }
164  }
165  /* Parse input file option. */
166  else if ( !strcmp( argv[arg], "-i" ) ) {
167  if ( argc > arg + 1 ) {
168  arg++;
169  infile = argv[arg++];
170  } else {
171  ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
172  LALPrintError( USAGE, *argv );
173  return BANDPASSTESTC_EARG;
174  }
175  }
176  /* Parse output file option. */
177  else if ( !strcmp( argv[arg], "-o" ) ) {
178  if ( argc > arg + 1 ) {
179  arg++;
180  outfile = argv[arg++];
181  } else {
182  ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
183  LALPrintError( USAGE, *argv );
184  return BANDPASSTESTC_EARG;
185  }
186  }
187  /* Parse filter options. */
188  else if ( !strcmp( argv[arg], "-f" ) ) {
189  if ( argc > arg + 5 ) {
190  arg++;
191  params.f1=atof(argv[arg++]);
192  params.f2=atof(argv[arg++]);
193  params.a1=atof(argv[arg++]);
194  params.a2=atof(argv[arg++]);
195  params.nMax=atoi(argv[arg++]);
196  } else {
197  ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
198  LALPrintError( USAGE, *argv );
199  return BANDPASSTESTC_EARG;
200  }
201  }
202  /* Parse time series options. */
203  else if ( !strcmp( argv[arg], "-n" ) ) {
204  if ( argc > arg + 3 ) {
205  arg++;
206  npts=atoi(argv[arg++]);
207  dt=atof(argv[arg++]);
208  offset=atoi(argv[arg++]);
209  } else {
210  ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
211  LALPrintError( USAGE, *argv );
212  return BANDPASSTESTC_EARG;
213  }
214  }
215  /* Unrecognized option. */
216  else {
217  ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 );
218  LALPrintError( USAGE, *argv );
219  return BANDPASSTESTC_EARG;
220  }
221  } /* End of argument parsing loop. */
222 
223  /* Check input values. */
224  if ( !infile ) {
225  if ( offset >= npts ) {
226  ERROR( BANDPASSTESTC_EBAD, BANDPASSTESTC_MSGEBAD, 0 );
227  LALPrintError( "\toffset=%i must be less than npts=%i\n", offset,
228  npts );
229  return BANDPASSTESTC_EBAD;
230  }
231  }
232 
233  /* Create the time series. */
234  if ( infile ) {
235  FILE *fp = fopen( infile, "r" );
236  if ( !fp ) {
237  ERROR( BANDPASSTESTC_EFILE, BANDPASSTESTC_MSGEFILE, infile );
238  return BANDPASSTESTC_EFILE;
239  }
240  SUB( LALSReadTSeries( &stat, &series, fp ), &stat );
241  fclose( fp );
242  } else {
243  snprintf( series.name, LALNameLength, "%s", "Impulse" );
244  series.deltaT = dt;
245  SUB( LALSCreateVector( &stat, &(series.data), npts ), &stat );
246  memset( series.data->data, 0, npts*sizeof(REAL4) );
247  series.data->data[offset] = 1.0;
248  }
249 
250  /* Filter the time series. */
251  SUB( LALDButterworthREAL4TimeSeries( &stat, &series, &params ),
252  &stat );
253 
254  /* Print the output, if the -o option was given. */
255  if ( outfile ) {
256  FILE *fp = fopen( outfile, "w" );
257  if ( !fp ){
258  ERROR( BANDPASSTESTC_EFILE, BANDPASSTESTC_MSGEFILE, outfile );
259  return BANDPASSTESTC_EFILE;
260  }
261  SUB( LALSWriteTSeries( &stat, fp, &series ), &stat );
262  fclose( fp );
263  }
264 
265  /* Free memory and exit. */
266  SUB( LALSDestroyVector( &stat, &(series.data) ), &stat );
268  INFO( BANDPASSTESTC_MSGENORM );
269  return BANDPASSTESTC_ENORM;
270 }
271 /** \endcond */
#define BANDPASSTESTC_EARG
Error parsing arguments.
Definition: BandPassTest.c:77
#define BANDPASSTESTC_EBAD
Bad argument values.
Definition: BandPassTest.c:78
#define BANDPASSTESTC_ENORM
Normal exit.
Definition: BandPassTest.c:75
#define BANDPASSTESTC_EFILE
Could not open file.
Definition: BandPassTest.c:79
#define USAGE
Definition: GzipTest.c:27
void LALCheckMemoryLeaks(void)
Definition: LALMalloc.c:784
#define SUB(func, statusptr)
#define ERROR(code, msg, statement)
#define INFO(statement)
void LALSReadTSeries(LALStatus *status, REAL4TimeSeries *series, FILE *stream)
void LALSWriteTSeries(LALStatus *status, FILE *stream, REAL4TimeSeries *series)
int main(int argc, char *argv[])
Definition: cache.c:25
void LALDButterworthREAL4TimeSeries(LALStatus *status, REAL4TimeSeries *series, PassBandParamStruc *params)
Deprecated.
double REAL8
Double precision real floating-point number (8 bytes).
char CHAR
One-byte signed integer, see Headers LAL(Atomic)Datatypes.h for more details.
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
float REAL4
Single precision real floating-point number (4 bytes).
@ LALNameLength
Definition: LALDatatypes.h:508
int LALPrintError(const char *fmt,...)
Definition: LALError.c:46
void LALSDestroyVector(LALStatus *, REAL4Vector **)
void LALSCreateVector(LALStatus *, REAL4Vector **, UINT4)
void XLALAbortErrorHandler(const char *func, const char *file, int line, int errnum)
The XLAL error handler that raises SIGABRT.
Definition: XLALError.c:599
XLALErrorHandlerType * XLALSetErrorHandler(XLALErrorHandlerType *newHandler)
Sets the error handler to a new handler and returns the old handler.
Definition: XLALError.c:372
LAL status structure, see The LALStatus structure for more details.
Definition: LALDatatypes.h:947
This structure stores data used for constructing a low- or high-pass filter: either the order and cha...
REAL8 a1
The minimal desired attenuation factors at the reference frequencies.
REAL8 a2
The minimal desired attenuation factors at the reference frequencies.
REAL8 f1
The reference frequencies of the transition band.
INT4 nMax
The maximum desired filter order (actual order may be less if specified attenuations do not require a...
REAL8 f2
The reference frequencies of the transition band.
Time series of REAL4 data, see DATATYPE-TimeSeries types for more details.
Definition: LALDatatypes.h:570
CHAR name[LALNameLength]
The name of the time series.
Definition: LALDatatypes.h:571
REAL4Sequence * data
The sequence of sampled data.
Definition: LALDatatypes.h:576
REAL8 deltaT
The time step between samples of the time series in seconds.
Definition: LALDatatypes.h:573
REAL4 * data
Pointer to the data array.
Definition: LALDatatypes.h:150
FILE * fp
Definition: tconvert.c:105