Read40mData.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Bernd Machenschalk, Jolien Creighton
00003 *
00004 *  This program is free software; you can redistribute it and/or modify
00005 *  it under the terms of the GNU General Public License as published by
00006 *  the Free Software Foundation; either version 2 of the License, or
00007 *  (at your option) any later version.
00008 *
00009 *  This program is distributed in the hope that it will be useful,
00010 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 *  GNU General Public License for more details.
00013 *
00014 *  You should have received a copy of the GNU General Public License
00015 *  along with with program; see the file COPYING. If not, write to the
00016 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00017 *  MA  02111-1307  USA
00018 */
00019 
00020 /**** <lalVerbatim file="Read40mDataCV">
00021  * Author: Jolien D. E. Creighton
00022  * $Id: Read40mData.c,v 1.6 2007/06/08 14:41:46 bema Exp $
00023  **** </lalVerbatim> */
00024 
00025 /**** <lalLaTeX>
00026  * \subsection{Program \texttt{Read40mData.c}}
00027  * 
00028  * Tests the low-level frame stream routines by reading Caltech 40m-prototype
00029  * data from Nov1994.
00030  *
00031  * \subsubsection*{Usage}
00032  *
00033  * \begin{verbatim}
00034  * Read40mData
00035  * \end{verbatim}
00036  *
00037  * \subsubsection*{Description}
00038  *
00039  * This program reads the channels \verb+IFO_DMRO+ and \verb+IFO_Lock+ from
00040  * all the frames in the directory set in the environment \verb+LAL_FRAME_PATH+
00041  * (or the current directory if this environment is not set) and prints them
00042  * to new frame files containing only the in-lock \verb+IFO_DMRO+ channel.
00043  *
00044  **** </lalLaTeX> */
00045 
00046 #include <math.h>
00047 #include <stdio.h>
00048 #include <unistd.h>
00049 #include <lal/LALStdlib.h>
00050 #include <lal/AVFactories.h>
00051 #include <lal/PrintFTSeries.h>
00052 #include <lal/FrameStream.h>
00053 
00054 #include <lal/LALRCSID.h>
00055 NRCSID (READ40MDATAC,"$Id: Read40mData.c,v 1.6 2007/06/08 14:41:46 bema Exp $");
00056 
00057 #define TESTSTATUS( pstat ) \
00058   if ( (pstat)->statusCode ) { REPORTSTATUS(pstat); return 1; } else ((void)0)
00059 
00060 #define CHANNEL "IFO_DMRO"
00061 
00062 INT4 lalDebugLevel = LALMSGLVL3;
00063 
00064 int main( void )
00065 {
00066   static LALStatus status;
00067   const float duration = 60.0; /* seconds of data to read at a time */
00068   const short lockmax  = 10;
00069   const short lockmin  = 1;
00070   REAL4TimeSeries tser;
00071   INT2TimeSeries  dmro;
00072   INT2TimeSeries  lock;
00073   FrChanIn  dmroin = { CHANNEL, ADCDataChannel };
00074   FrChanIn  lockin = { "IFO_Lock", ADCDataChannel };
00075   FrStream *stream = NULL;
00076   FrOutPar  outpar = { "C1:" CHANNEL, "REDUCED", ADCDataChannel, 6, 0, 0 };
00077   char *dirname = getenv( "LAL_FRAME_PATH" );
00078   int  locklost = 1;
00079 
00080 
00081   /*
00082    *
00083    * Open the frame stream.
00084    *
00085    */
00086 
00087   LALFrOpen( &status, &stream, dirname, "C1-*.F" );
00088   TESTSTATUS( &status );
00089 
00090 
00091   /*
00092    *
00093    * Set up time series to read DMRO and Lock channels.
00094    *
00095    */
00096 
00097   dmro.data = NULL;
00098   lock.data = NULL;
00099   LALFrGetINT2TimeSeries( &status, &dmro, &dmroin, stream );
00100   TESTSTATUS( &status );
00101   LALFrGetINT2TimeSeries( &status, &lock, &lockin, stream );
00102   TESTSTATUS( &status );
00103   LALI2CreateVector( &status, &dmro.data, duration / dmro.deltaT );
00104   TESTSTATUS( &status );
00105   LALI2CreateVector( &status, &lock.data, duration / lock.deltaT );
00106   TESTSTATUS( &status );
00107   memcpy( &tser, &dmro, sizeof( tser ) );
00108   tser.data = NULL;
00109   LALSCreateVector( &status, &tser.data, duration / tser.deltaT );
00110   TESTSTATUS( &status );
00111 
00112 
00113   /*
00114    *
00115    * Scan frame data writing locked data (after 3 minutes into lock).
00116    *
00117    */
00118 
00119   while ( 1 )
00120   {
00121     FrPos frpos;
00122     UINT4 i;
00123     INT8  tacc = 0.1 * 1e9 / 16384;
00124     INT8  texp;
00125     INT8  tact;
00126     int   locked;
00127 
00128 
00129     /* find a segment that is locked */
00130     do
00131     {
00132       locked = 1;
00133 
00134       /* save the position of the start of this segment */
00135       LALFrGetPos( &status, &frpos, stream );
00136       TESTSTATUS( &status );
00137 
00138       /* read the lock channel */
00139       LALFrGetINT2TimeSeries( &status, &lock, &lockin, stream );
00140       if ( status.statusCode == FRAMESTREAMH_EDONE )
00141       {
00142         goto end;
00143       }
00144       TESTSTATUS( &status );
00145 
00146       /* see if there were any periods out of lock */
00147       for ( i = 0; i < lock.data->length; ++i )
00148       {
00149         if ( lock.data->data[i] < lockmin || lock.data->data[i] > lockmax )
00150         {
00151           locked = 0;
00152           locklost = 1;
00153         }
00154       }
00155       if ( locklost )
00156       {
00157         printf( "\nsearching for lock..." );
00158       }
00159     }
00160     while ( ! locked );
00161 
00162 
00163     /* if lock has been lost, skip ahead 3 minutes and re-check lock */
00164     if ( locklost )
00165     { /* skip 3 minutes into locked segment */
00166       LIGOTimeGPS epoch;
00167       puts( " acquired: skipping three minutes" );
00168       LALFrTell( &status, &epoch, stream );
00169       TESTSTATUS( &status );
00170       epoch.gpsSeconds += 3 * 60;
00171       LALFrSeek( &status, &epoch, stream );
00172       TESTSTATUS( &status );
00173       locklost = 0;
00174       continue;
00175     }
00176 
00177 
00178     /* reset stream position to start of locked segment */
00179     LALFrSetPos( &status, &frpos, stream );
00180     TESTSTATUS( &status );
00181 
00182 
00183     /* compute expected stop time for this segment (assuming no gaps) */
00184     texp  = (INT8)1000000000 * (INT8)dmro.epoch.gpsSeconds;
00185     texp += (INT8)dmro.epoch.gpsNanoSeconds;
00186     texp += (INT8)( 1e9 * dmro.data->length * dmro.deltaT );
00187 
00188 
00189     /* read the DMRO channel */
00190     LALFrGetINT2TimeSeries( &status, &dmro, &dmroin, stream );
00191     if ( status.statusCode == FRAMESTREAMH_EDONE )
00192     {
00193       goto end;
00194     }
00195     TESTSTATUS( &status );
00196 
00197 
00198     /* compute the actual stop time for this segment */
00199     tact  = (INT8)1000000000 * (INT8)dmro.epoch.gpsSeconds;
00200     tact += (INT8)dmro.epoch.gpsNanoSeconds;
00201 
00202 
00203     /* warn if a gap in the data is found */
00204     if ( abs( texp - tact ) > tacc && ! locklost )
00205       puts( "Gap in frame data!" );
00206 
00207 
00208     /* copy data to tser and output it */
00209     printf( "%s-%s-%d-%d.gwf\n", outpar.source, outpar.description,
00210         tser.epoch.gpsSeconds,
00211         (int)ceil( 1e-9 * tser.epoch.gpsNanoSeconds
00212           + tser.data->length * tser.deltaT ) );    
00213     tser.epoch = dmro.epoch;
00214     for ( i = 0; i < tser.data->length; ++i )
00215     {
00216       tser.data->data[i] = dmro.data->data[i];
00217     }
00218     LALFrWriteREAL4TimeSeries( &status, &tser, &outpar );
00219     TESTSTATUS( &status );
00220   }
00221 
00222 
00223   /*
00224    *
00225    * Cleanup and exit.
00226    *
00227    */
00228 
00229 end:
00230 
00231   LALFrClose( &status, &stream );
00232   TESTSTATUS( &status );
00233 
00234   LALI2DestroyVector( &status, &dmro.data );
00235   TESTSTATUS( &status );
00236 
00237   LALI2DestroyVector( &status, &lock.data );
00238   TESTSTATUS( &status );
00239 
00240   LALSDestroyVector( &status, &tser.data );
00241   TESTSTATUS( &status );
00242 
00243   LALCheckMemoryLeaks();
00244   return 0;
00245 }

Generated on Sat Sep 6 03:07:26 2008 for LAL by  doxygen 1.5.2